Ask Your Question

Revision history [back]

RGB to c1c2c3 color space conversion

Edit : Is this code does the corect color space conversion ? MixChannel or cvtcolor can't do it ?

I'm trying to implement this color space to improve shadow detection in a single image. According some search, formulas are : R,G,B are pixel value

C1 = arctan (R / max (G, B))
C2 = arctan (G / max (R, B))
C3 = arctan (B / max (G, R))

In openCV, i've done that :

Core.extractChannel(mRgba, mR, 0);
Core.extractChannel(mRgba, mG, 1);
Core.extractChannel(mRgba, mB, 2);

Mat imageC1 = mR.clone(); // I'm using the same size each channel for all
Mat imageC2 = mR.clone(); // dont care of that
Mat imageC3 = mR.clone(); 

Mat maxGB = new Mat();
Mat maxRB = new Mat();
Mat maxGR = new Mat();
Core.max(mG, mB, maxGB); // Can be deleted after
Core.max(mR, mB, maxRB); 
Core.max(mG, mR, maxGR);
Mat divC1 = new Mat();
Mat divC2 = new Mat();
Mat divC3 = new Mat();
Core.divide(mR, maxGB, divC1);
Core.divide(mG, maxRB, divC2);
Core.divide(mB, maxGR, divC3);

// imageSrc.convertTo(imageSrc, CvType.CV_64FC1);
int size = (int) (mG.total() * mG.channels()); // channel is equal to 1 for now
byte[] bC1 = new byte[size]; // use double[] instead of byte[]
byte[] bC2 = new byte[size];
byte[] bC3 = new byte[size];

divC1.get(0, 0, bC1); 
divC2.get(0, 0, bC2); 
divC3.get(0, 0, bC3);

for (int i = size; i-- > 0;) { 

    bC1[i] = (byte) Fatan(bC1[i]);
    bC2[i] = (byte) Fatan(bC2[i]);
    bC3[i] = (byte) Fatan(bC3[i]);
}
imageC1.put(0, 0, bC1);
imageC2.put(0, 0, bC2);
imageC3.put(0, 0, bC3);

With this custom atan formula:

double Fatan(double x) {
    return (Math.PI / 4) * x - x * (Math.abs(x) - 1) * (0.2447 + 0.0663 * Math.abs(x));
}

I've done both version with double and byte (because casting maybe wrong)

But i cant have a good result, as the C3 channel (the most usefull for shadow) never give something usable.

click to hide/show revision 2
retagged

RGB to c1c2c3 color space conversion

Edit : Is this code does the corect color space conversion ? MixChannel or cvtcolor can't do it ?

I'm trying to implement this color space to improve shadow detection in a single image. According some search, formulas are : R,G,B are pixel value

C1 = arctan (R / max (G, B))
C2 = arctan (G / max (R, B))
C3 = arctan (B / max (G, R))

In openCV, i've done that :

Core.extractChannel(mRgba, mR, 0);
Core.extractChannel(mRgba, mG, 1);
Core.extractChannel(mRgba, mB, 2);

Mat imageC1 = mR.clone(); // I'm using the same size each channel for all
Mat imageC2 = mR.clone(); // dont care of that
Mat imageC3 = mR.clone(); 

Mat maxGB = new Mat();
Mat maxRB = new Mat();
Mat maxGR = new Mat();
Core.max(mG, mB, maxGB); // Can be deleted after
Core.max(mR, mB, maxRB); 
Core.max(mG, mR, maxGR);
Mat divC1 = new Mat();
Mat divC2 = new Mat();
Mat divC3 = new Mat();
Core.divide(mR, maxGB, divC1);
Core.divide(mG, maxRB, divC2);
Core.divide(mB, maxGR, divC3);

// imageSrc.convertTo(imageSrc, CvType.CV_64FC1);
int size = (int) (mG.total() * mG.channels()); // channel is equal to 1 for now
byte[] bC1 = new byte[size]; // use double[] instead of byte[]
byte[] bC2 = new byte[size];
byte[] bC3 = new byte[size];

divC1.get(0, 0, bC1); 
divC2.get(0, 0, bC2); 
divC3.get(0, 0, bC3);

for (int i = size; i-- > 0;) { 

    bC1[i] = (byte) Fatan(bC1[i]);
    bC2[i] = (byte) Fatan(bC2[i]);
    bC3[i] = (byte) Fatan(bC3[i]);
}
imageC1.put(0, 0, bC1);
imageC2.put(0, 0, bC2);
imageC3.put(0, 0, bC3);

With this custom atan formula:

double Fatan(double x) {
    return (Math.PI / 4) * x - x * (Math.abs(x) - 1) * (0.2447 + 0.0663 * Math.abs(x));
}

I've done both version with double and byte (because casting maybe wrong)

But i cant have a good result, as the C3 channel (the most usefull for shadow) never give something usable.