Ask Your Question

Revision history [back]

click to hide/show revision 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);