# Convert rgb (brg) to rg chromaticity I simply can't for the love of god do a simple damn conversion and it's been bugging me over the last weekend: https://en.wikipedia.org/wiki/Rg_chro...

Can anyone help out with an efficient way to do this in OpenCV? I keep getting black images, here's my current attempt:

for (int i = 0; i < mRgb.cols; i++) {
for (int j = 0; j < mRgb.rows; j++) {

Vec3b intensity = mRgb.at<Vec3b>(j, i);
float b = intensity.val;
float g = intensity.val;
float r = intensity.val;

float rgbSum = (float) (r + g + b);
float redNorm = (float) (r / rgbSum);
float greenNorm = (float) (g / rgbSum);
float blueNorm = (float) (b / rgbSum);

res.at<Vec3b>(j, i) = blueNorm;
res.at<Vec3b>(j, i) = greenNorm;
res.at<Vec3b>(j, i) = redNorm;
}
}


I am positive this can be done more efficiently, please help me out.

Isn't there a way in which you can split the channels, divide them to the channel sum and then add up the 3 new channels into a new image? In matlab it's done like this: http://stackoverflow.com/questions/21...

Edit, here's a second attempt using channels:

    Mat channel;
split(mRgb, channel);

double alpha = 1.0;
double beta = 1.0;
Mat tmpSum;
Mat rgbSum;
addWeighted(channel, alpha, channel, beta, 0.0, tmpSum);
addWeighted(tmpSum, alpha, channel, beta, 0.0, rgbSum);

Mat newR;
Mat newG;
Mat newB;
divide(channel, rgbSum, newB);
divide(channel, rgbSum, newG);
divide(channel, rgbSum, newR);

Mat in[] = { newB, newG, newR };
int from_to[] = { 0, 0, 1, 1, 2, 2 };
mixChannels(in, 3, &mRgb, 1, from_to, 3);


I get the famous fatal signal 11 on Android using OpenCV in ndk.

Regards!

edit retag close merge delete

Well reading a bit on your own wikipedia page, it seems that: The sum of rgb will always equal one, because of this property the b dimension can be thrown away without causing any loss in information. If you think about this than getting a black image is completely normal if you visualise all 3 channels together! The idea is to do data reduction and convert your 3 channel BGR image into a 2 channel GR image. I will post some code soon!

Sort by » oldest newest most voted Try this code

#include <opencv2\opencv.hpp>
#include<iostream>

using namespace cv;
using namespace std;

int main (int argc, char** argv)
{

Mat A(img.size(),img.type());

if(!img.data)
{
cout<<"could not open or find the image"<<endl;
return -1;
}

namedWindow("Original",0);
imshow("Original",img);

for (int i=0;i<img.rows;i++)
{
for(int j=0;j<img.cols;j++)
{
Vec3f intensity = img.at<Vec3b>(i,j);
float blue=intensity.val;
float green=intensity.val;
float red=intensity.val;

double sum=red+blue+green;
double r= red/sum;
double g= green/sum;
double b = blue/sum;

A.data[A.step*i + A.step* j + 0] = (b*255);
A.data[A.step*i + A.step* j + 1] = (g*255);
A.data[A.step*i + A.step* j + 2] = (r*255);

}
}

namedWindow("chrom",0);

imshow("chrom",A);

waitKey(0);

}  more

Yep, I need to normalize the new values, thanks! Any chance to adapt this to make it work as my 2nd version? Operating directly on channels?

Please keep your answers combined :) It is not a new approach! :)

The code below splits the channels and applies the transformation as documented by wikipedia. It also outputs the in between channels.

#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main(int argc, char* argv[])
{
// OpenCV reads its channels as BGR, not as RGB!
// You need to be aware of this in order to get the correct output
Mat original = imread("/data/test/face.jpg");
imshow("original", original);

// Lets split the channels
// index 0 = Blue / index 1 = Green / index 2 = Red
vector<Mat> channels;
split(original, channels);

// Now perform the conversion from BGR to bgr - which is the chroma normalized image
// First create empty containers for the end result
Mat b = Mat::zeros(original.rows, original.cols, CV_32FC1);
Mat g = b.clone(); Mat r = b.clone();
// Grab the single channels through a meaningfull pointer
Mat B = channels;
Mat G = channels;
Mat R = channels;
for(int row=0; row < original.rows; row++){
for(int col=0; col < original.cols; col++){
b.at<float>(row,col) = (float)B.at<uchar>(row,col) / ((float)B.at<uchar>(row,col) + (float)G.at<uchar>(row,col) + (float)R.at<uchar>(row,col));
g.at<float>(row,col) = (float)G.at<uchar>(row,col) / ((float)B.at<uchar>(row,col) + (float)G.at<uchar>(row,col) + (float)R.at<uchar>(row,col));
r.at<float>(row,col) = (float)R.at<uchar>(row,col) / ((float)B.at<uchar>(row,col) + (float)G.at<uchar>(row,col) + (float)R.at<uchar>(row,col));
}
}

// Visualise the seperate BGR channels and the combined bgr channels
Mat combined_BGR = Mat(original.rows, original.cols*3, CV_8UC1);
Mat combined_bgr = Mat(original.rows, original.cols*3, CV_32FC1);
B.copyTo(combined_BGR(Rect(0,0,original.cols, original.rows)));
G.copyTo(combined_BGR(Rect(original.cols,0,original.cols, original.rows)));
R.copyTo(combined_BGR(Rect(original.cols*2,0,original.cols, original.rows)));
b.copyTo(combined_bgr(Rect(0,0,original.cols, original.rows)));
g.copyTo(combined_bgr(Rect(original.cols,0,original.cols, original.rows)));
r.copyTo(combined_bgr(Rect(original.cols*2,0,original.cols, original.rows)));
imshow("original channels", combined_BGR);
imshow("rg chromacity channels", combined_bgr);

// Combine them together
Mat bgr = Mat(original.rows, original.cols, CV_32FC3);
Mat in[] = { b, g, r };
int from_to[] = { 0,0, 1,1, 2,2 };
mixChannels( in, 3, &bgr, 1, from_to, 3 );

// Show the result
imshow("rg chromacity", bgr);

waitKey(0);
}


But still the question for me is what you are trying to achieve. For visualisation purposes this data representation is pretty useless.

more

mr.Razvan wanted to calculate chromaticity of the given image. He tried some program and he wants to visualize the output. he got only black screen in his attempt. the problem is according to the formula the value in the matrix is between 0 and 1 in decimals. i just multiplies the r,g,b, values with 255 to visualize the chromaticity values as image.

1

In the end the scope is to try to make a better segmentation and remove shadows from the road surface. I wanted to explore the option of rg-chromaticity. Thank you very much for the answer, I will try it the next days!

Official site

GitHub

Wiki

Documentation

## Stats

Asked: 2015-02-08 18:06:26 -0500

Seen: 3,672 times

Last updated: Feb 11 '15