1 | initial version |
You can use machine learning to do a lot of stuff but often there is a simpler way... for example you could start trying color filter... remove all green and look if anything survives in the image. Following StevePuttemans suggestions
Get colors in the image
Mat src, hsv,hue;
src = imread("../img/ball-grass-green.jpg");
cv::cvtColor(src, hsv, CV_BGR2HSV_FULL);
vector<cv::Mat> hsvPlanes;
cv::split(hsv, hsvPlanes);
hue = hsvPlanes[0];
Green has Hue values at 120°+/-45° in the standard 0..360° RGB color wheel (https://en.wikipedia.org/wiki/Hue).
COLOR | HUE |
--------------+-----+
Red | 0°
Orange | 30°
Yellow | 60° ------+ 42#
+--------> 75° |
| Green-Yellow | 90° | Grass
Greens --| Green |120° |
| Cyan-green |150° ------+ 106#
+-------> 165°
Cyan |180°
+-------> 195°
| Blue-Cyan |210°
Blue-----| Blue |240°
| Magenta-Blue |270°
+-------> 285°
Magenta |300°
Red-Magenta |330°
Red |360°
Is common that grass has a bit of yellow. Because CV_BGR2HSV_FULL
returns Hue between 0..255#
you can get grass filtering the range 42#..106#
A large smooth would help to remove discontinuities in grass
Mat greenMask;
GaussianBlur(hsv, hsv, Size(7, 7), 0);
inRange(hue, 42, 106, greenMask);
//Because you are expecting only green objects...
Mat obstacle;
obstacle = 255 - greenMask;
// do a morphology to reduce blobs complexity
morphologyEx(obstacle, obstacle, MORPH_CLOSE, getStructuringElement(MORPH_RECT, Size(5, 5)));
imshow("obstacle", obstacle);
Finally use contours to detect blobs removing very small one
vector<vector<Point>> contours;
findContours(obstacle, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
int minArea = cvRound(0.002*src.cols*src.rows);
for (size_t i = 0; i < contours.size(); i++)
{
Rect rr = boundingRect(contours[i]);
if (rr.area() < minArea) continue; //ignore small
rectangle(src, rr, Scalar(0, 0, 255), 2);
}
imshow("Findings", src);
waitKey(0);