1
votes

I have some BGR image:

cv::Mat image;

I want to subtract from all the pixels in the image the vector:

[10, 103, 196]

Meaning that the blue channel for all the pixels will be reduced by 10, the green by 103 and the red by 196.

Is there a standard way to do that, or should I run for loops over all the channels and all the pixels?

1
Yes, subtract a scalar from that Mat or use a matrix expression to achieve the same. | " should I run for loops" if you're tempted to do that, peruse the documentation -- in vast majority cases (especially for something as trivial as your case) it's unnecessary and sub-optimal (as OpenCV is likely to contain a vectorized and parallelized implementation).Dan Mašek

1 Answers

4
votes

suppose we have image that all channels filled with zero and for instance it's dimension is 2x3

cv::Mat image = cv::Mat::zeros(2,3,CV_32SC3)

output will be:

 [0, 0, 0, 0, 0, 0, 0, 0, 0;
  0, 0, 0, 0, 0, 0, 0, 0, 0]

then if we want to add or subtract a singleton variable, then we can use cv::Scalar

1- suppose we want to add 3 in blue channel:

image = image + Scalar(3,0,0);  // the result will be same as image=image+3; 

with above code our matrix is now:

[3, 0, 0, 3, 0, 0, 3, 0, 0;
 3, 0, 0, 3, 0, 0, 3, 0, 0]

2- if you want to add to another channel you can use second or third argument(or forth) of cv::Scalar like below

image = image +Scalar(3,2,-3);

output will be

[3, 2, -3, 3, 2, -3, 3, 2, -3;
 3, 2, -3, 3, 2, -3, 3, 2, -3]

Using cv::subtract

cv::Mat image = cv::Mat::zeros(2,3,CV_32SC3);
subtract(image,Scalar(2,3,1),image);

output

[-2, -3, -1, -2, -3, -1, -2, -3, -1;
 -2, -3, -1, -2, -3, -1, -2, -3, -1]