Hi , I have attached the image below with an yellow bounding box. Is there any algorithm or (sequence of algorithms) in Opencv by which I can detect the yellow pixels and create a ROI mask (which will block out all the pixels outside of it).
-
1if it is always that yellow color tone you can easily use the inRange method. Then use findContours to get the outer contour. After that you can draw a filled mask from that contour and apply the mask to the image to only copy masked region to a new black image. – Micka Oct 12 '15 at 09:40
-
Do you have always the same contour color? It's guaranteed to be unique in the image (no other yellow background points)? There will be just one yellow contour per image, or can be multiple? – Miki Oct 12 '15 at 12:25
-
@Miki : There might be yellow pixels in the background. If we find such a case, we could use a different color in the future. And yes, there will be only one yellow contour per image – prog_guy Oct 21 '15 at 09:35
1 Answers
You can do:
- Find the yellow polygon
- Fill the inside of the polygon
- Copy only the inside of the polygon to a black-initialized image
Find the yellow polygon
Unfortunately, you used anti-aliasing to draw the yellow line, so the yellow color is not pure yellow, but has a wider range due to interpolation. This affects also the final results, since some not yellow pixels will be included in the result image. You can easily correct this by not using anti-aliasing.
So the best option is to convert the image in the HSV space (where it's easier to segment a single color) and keep only values in a range around the pure yellow.
If you don't use anti-aliasing, you don't even need to convert to HSV and simply keep points whose value is pure yellow.
Fill the inside of the polygon
You can use floodFill
to fill the polygon. You need a starting point for that. Since we don't know if a point is inside the polygon (and taking the baricenter may not be safe since the polygon is not convex), we can safely assume that the point (0,0), i.e. the top-left corner of the image is outside the polygon. We can then fill the outside of the polygon, and then invert the result.
Copy only the inside of the polygon to a black-initialized image
Once you have the mask, simply use copyTo
with that mask to copy on a black image the content under non-zero pixels in the mask.
Here the full code:
#include <opencv2\opencv.hpp>
using namespace cv;
int main()
{
Mat3b img = imread("path_to_image");
// Convert to HSV color space
Mat3b hsv;
cvtColor(img, hsv, COLOR_BGR2HSV);
// Get yellow pixels
Mat1b polyMask;
inRange(hsv, Scalar(29, 220, 220), Scalar(31, 255, 255), polyMask);
// Fill outside of polygon
floodFill(polyMask, Point(0, 0), Scalar(255));
// Invert (inside of polygon filled)
polyMask = ~polyMask;
// Create a black image
Mat3b res(img.size(), Vec3b(0,0,0));
// Copy only masked part
img.copyTo(res, polyMask);
imshow("Result", res);
waitKey();
return 0;
}
Result:
NOTES
Please note that there are almost yellow pixels in the result image. This is due to anti-aliasing, as explained above.

- 40,887
- 13
- 123
- 202
-
How did you find the range of yellow values in the HSV range ? I was using this site, http://www.colorspire.com/rgb-color-wheel/. My intution was that keeping the hue constant at 42 (or 60 degrees) and just adjusting the Saturation,Value would give the ranges. But I was wrong – prog_guy Oct 22 '15 at 04:09
-
1See [here](http://stackoverflow.com/a/31465462/5008845) for details. Yellow is HSV 60°,100%,100%, and in OpenCV this is coded as 30,255,255. H channel value is halved and is in range [0,180], S and V are in range [0,255] – Miki Oct 22 '15 at 10:07