4

I'm using version OpenCV 3.2.

I open the default camera:

VideoCapture cap;
cap.open(0);

and grab the current frame:

Mat frame;
cap.read(frame);

Now I want to reduce the number of colours shown in the image. Thus, I do an integer division and multiply the image by the same scalar value, let it be 10 for example. This can easily done with the C++ operators' overload.

Mat processedFrame = (frame / 10) * 10

However, frame values are in float format. The division is then not performed as an integer division, and the reduction of colours is not achieved.

I guess it can be fixed by making a cast of frame to integer values before doing the integer division. How could I do this cast taking into account that a camera can grab images in 1 (gray scale) or 3 (BGR) colour channels?

ZdaR
  • 22,343
  • 7
  • 66
  • 87
Santiago Gil
  • 1,292
  • 7
  • 21
  • 52
  • @Muscampester Yes, I have tried `Mat processedFrame = (static_cast>(frame) / 10) * 10;`. This returns me a whole black image (`frame` values are >> 10). – Santiago Gil Feb 18 '17 at 18:33

1 Answers1

3

The OpenCV provides the API for multiply and divide as well. You can use that API to get the desired results instead of using the overloaded operators as:

// Assuming the image to be RGB 
cv::divide(frame, cv::Scalar(10, 10, 10), frame, 1, CV_8UC3);
cv::multiply(frame, cv::Scalar(10, 10, 10), frame, 1, CV_8UC3);
Santiago Gil
  • 1,292
  • 7
  • 21
  • 52
ZdaR
  • 22,343
  • 7
  • 66
  • 87
  • It seemed it worked, but I have realized that this solutions **rounds** the division instead of making a **floor** (an integer division). A pixel with a value of 16 (suppose gray scale) and making a reduction of 10, will be translated into a pixel with a value of 20 (instead of 10). – Santiago Gil Feb 18 '17 at 20:17
  • Ok, this issue can be fixed as in [here](http://stackoverflow.com/questions/30833540/is-there-a-way-to-prevent-rounding-in-opencv-matrix-divison) – Santiago Gil Feb 19 '17 at 09:09