# Store calculation result from RGB in Vec3b into new matrix instead of Mat Object

Hi, I've been learning to work with image processing. I'm trying to access RGB value from a Mat image :

Mat picture = imread("picture.png", CV_LOAD_IMAGE_COLOR);
int rows = picture.rows;
int cols = picture.cols;


So, I can get these BGR value

    picture.at<Vec3b>(i, j)[0]
picture.at<Vec3b>(i, j)[1]
picture.at<Vec3b>(i, j)[2]


Then I need to multiply each channel value with some values. For example channel B --> [0] :

for (int i = 0; i < picture.rows; i++) {
for (int j = 0; j < picture.cols; j++) {
output.at<Vec3b>(i, j)[0] = (picture.at<Vec3b>(i, j)[0] * 0.2) +
(picture.at<Vec3b>(i, j)[1] * 0.3) +
(picture.at<Vec3b>(i, j)[2] * 0.4);
}
}


For now, I'm storing the calculation result as a Mat image (output). Is there any other way I can store the result of multiplication (output.at<Vec3b>(i, j)[0]) by creating a new matrix instead of store it as Mat object ? Because I need to calculate this value later and store it as matrix instead of Mat will help a lot.

edit retag close merge delete

Sort by ยป oldest newest most voted

I think you can split data and later merge it if necessary :

    Mat picture = imread("picture.png", CV_LOAD_IMAGE_COLOR);
vector<Mat> p;
split(image, p);
vector<Mat> output(p.size());
output[0] = p[0] * 0.2+ p[1] * 0.3+p[2] * 0.4;
output[1] = p[0] * 0.4+ p[1] * 0.5+p[2] * 0.6;
output[2] = p[0] * 0.7+ p[1] * 0.8+p[2] * 0.9;
Mat res;
merge(output, res);


PS in opencv it is not RGB but BGR

more

Hi, thanks for replying. In the last line merge(output, res), is res referring to new Mat object ?
My bad, I didn't make my question clear.

I tried to implement your code, but I have difficulty in access the value in particular pixel location (i,j). Each pixel in an image has BGR channel value= [0][1][2], and inside a loop I need to multiply each channel with some values, for example :
B(i,j)[0]= pic.at<Vec3b>(i, j)[0]*0.2 + pic.at<Vec3b>(i, j)[1]*0.3 + pic.at<Vec3b>(i, j)[2]*0.4,
G(i,j)[1]= pic.at<Vec3b>(i, j)[0]*0.4 + pic.at<Vec3b>(i, j)[1]*0.5 + pic.at<Vec3b>(i, j)[2]*0.6,
R(i,j)[2]= pic.at<Vec3b>(i, j)[0]*0.7 + pic.at<Vec3b>(i, j)[1]*0.8 + pict.at<Vec3b>(i, j)[2]*0.9.

So ...(more)

( 2018-01-28 14:29:43 -0500 )edit

Ok I misunderstood your question. What do you want to do exactly? change color space ?

( 2018-01-28 14:36:35 -0500 )edit

Yes ! I'm trying to change colorspace.
So I need to calculate the sum of previous channel (BGR) after multiplying each channel with some values, and then store the result.

( 2018-01-28 14:38:26 -0500 )edit

so have you read cvtcolor doc and available conversion codes?

( 2018-01-28 14:41:57 -0500 )edit

I have. cvtcolor is not available for this, I'm trying to convert into LMS.
Reference of matrix transformation value to convert RGB --> LMS I got from paper (page 2)

( 2018-01-28 14:47:33 -0500 )edit

So it's better to convert original image in float :

  picture.convertTo(pict,CV_32F);

( 2018-01-28 14:51:26 -0500 )edit

It seems like I can't really understand why I need to convert the original image. Could you please give the brief idea about this ?
Do you have any suggestion about changing how to store the calculation ? Because I think the picture is fine with CV_8UC3, I think my issue is in storing and accessing the calculation result.
So I will have to do another calculation to the first calculation result, this is why I feel the need to store it in a new matrix instead of Mat.

( 2018-01-28 15:04:35 -0500 )edit

I haven't read the paper but it seems that there is two or three matrix products. It is better in float. When you will get good result try with uchar and you can estimate error

( 2018-01-29 02:00:30 -0500 )edit

@Hiro , can you take a look at this related question, and try to use transform() ?

( 2018-01-29 03:34:16 -0500 )edit

Official site

GitHub

Wiki

Documentation