0

I tried to use bitwise_or on two CV_8UC1 images, but the result is not what I expected.

In my case, for image_1, every pixel value is set to 2, and for image_2, every pixel value is set to 3, the output of bitwise_or is an image with every pixel value set to 5, while what I expected is every pixel value is 2|3, which should be 2.

Can someone tell me why?

hby001
  • 145
  • 1
  • 2
  • 6
  • Actually, `2|3` would give you `3`, not `2`, but that still doesn't explaiin why you get `5`. – paxdiablo Mar 09 '14 at 22:02
  • Could you upload the images (or a part of them) for me to check..? The output of `2 | 3` is **3**, not 2. [0010 | 0011 == 0011].. – scap3y Mar 09 '14 at 22:02
  • Show your code please. – herohuyongtao Mar 09 '14 at 22:07
  • @scap3y Thank you. I think you answered my question. Since `bitwise_or ` performs OR operation on binary digits not decimal, so `2 | 3 = 2`, but `1 | 2 = 3`. – hby001 Mar 09 '14 at 23:03
  • Yup, that is correct. And referring to your comment to the answer, if you want the largest number, just iterate through the `cv::Mat` and write the value which is the highest into the result. Though, I am not sure how this will help. – scap3y Mar 10 '14 at 05:49

1 Answers1

4

The result of the bitwise or operation between 2 and 3 is 3. You can check it like this:

cout<<(2|3); // The result will be 3

Also, if you do a bitwise_or on two matrices that have all pixels 2 and 3 respectively, you should get a matrix with all its pixels set to 3, like in this example:

Mat m1 = Mat(3, 3, CV_8UC1, Scalar(2));
Mat m2 = Mat(3, 3, CV_8UC1, Scalar(3));
Mat r;
bitwise_or(m1, m2, r);
cout<<r;

Result:

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

Do you want to add the two images? If this is the case, you can simply use the + operator, like this:

Mat m1 = Mat(3, 3, CV_8UC1, Scalar(2));
Mat m2 = Mat(3, 3, CV_8UC1, Scalar(3));
Mat r = m1+m2;
cout<<r;

Result:

[5, 5, 5;
5, 5, 5;
5, 5, 5]

In decimal system, the equivalent of the or operation is the maximum operation. (Also, the equivalent of the and operation is the minimum operation).

If this is what you want, OpenCV provides a cv::max() function that calculates the elementwise maximum from two matrices of the same size. Here is an example:

Mat a = Mat::ones(3, 3, CV_8UC1) * 2;
Mat b = Mat::ones(3, 3, CV_8UC1) * 100;
cout<<a<<endl<<b<<endl;
Mat max = cv::max(a, b);
cout<<max;

The result is:

a=[2, 2, 2;
  2, 2, 2;
  2, 2, 2]
b=[100, 100, 100;
  100, 100, 100;
  100, 100, 100]
max=[100, 100, 100;
  100, 100, 100;
  100, 100, 100]
Ove
  • 6,227
  • 2
  • 39
  • 68
  • Is there anyway I can perform OR operation on decimal digit instead of bitwise, namely, the output image of the two source images has elements of the larger pixel value. For instance I have two `Mat`, one has all elements of 2 and another all elements of 100, how to make the output `Mat` all 100? – hby001 Mar 09 '14 at 23:10
  • Do you mean to calculate the maximum between the elements of two matrices? Then [`cv::max`](http://docs.opencv.org/modules/core/doc/operations_on_arrays.html?highlight=max#max) is what you need. I have updated my answer to provide an example. – Ove Mar 10 '14 at 07:16
  • @Ove "In decimal system, the equivalent of the or operation is the maximum operation." > A counter example is `2|5 == 7 != max(2,5)`. – BConic Mar 10 '14 at 14:01
  • @AldurDisciple `2|5==7` in base 2. But `2|5 == 5 == max(2,5)` in base 10. – Ove Mar 10 '14 at 14:07
  • @AldurDisciple Check out this answer: [Do bitwise operators (other than shifts) make any mathematical sense in base-10?](http://stackoverflow.com/a/3321137/80003) – Ove Mar 10 '14 at 14:10
  • Thanks for the link, that clarifies it. Although, with the given formula, it seems that `2|5 == (9 - (7*4 mod 10) mod 10) == 1` in base 10 ? Or did I missed something ? – BConic Mar 10 '14 at 14:28
  • Yes, there seems to be something wrong with those equations. I know that `&` is the equivalent of minimum and `|` is the equivalent of maximum, but I can't find a web reference right now that explains it. – Ove Mar 10 '14 at 15:01
  • @Ove Thank you for the answer. Somehow the function `cv::max` conflicts with STL `max`, so I have to `#undef max`. – hby001 Mar 11 '14 at 03:50
  • The STL `max` isn't #define'd (it's not a macro, it's a function). You can just put `cv::` in front of max and that should take care of it. Maybe you're conflicting with the `min` and `max` in windows.h. In that case, you can include this line before you include windows.h: `#define NOMINMAX`. Check out this link for more info: [Using STL in Windows Program Can Cause Min/Max Conflicts](http://support.microsoft.com/kb/143208) – Ove Mar 11 '14 at 06:20