Ask Your Question
0

RGB to c1c2c3 color space conversion

asked 2013-09-11 04:01:01 -0600

updated 2013-09-11 04:08:49 -0600

Moster gravatar image

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.

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
0

answered 2014-02-24 13:10:39 -0600

Yan gravatar image

updated 2014-02-24 13:10:58 -0600

I don't use Java, but c1c2c3 conversion is a simple 2 liner in python openCV. This is what I use for a 24 bit image stored in img obtained, for example, by img = cv2.imread("image.jpg")

im = img.astype(np.float32)+0.001 #to avoid division by 0
c1c2c3 = np.arctan(im/np.dstack((cv2.max(im[...,1], im[...,2]), cv2.max(im[...,0], im[...,2]), cv2.max(im[...,0], im[...,1]))))
edit flag offensive delete link more

Comments

Well .. Python is certainly usefull to test idea, bur not really to make Android Java app... But i'll try thi sway, thank you

Pascal66 gravatar imagePascal66 ( 2014-02-25 06:54:02 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2013-09-11 04:01:01 -0600

Seen: 1,644 times

Last updated: Feb 24 '14