Reputation: 173
I want find Brown colour Object in Image.I have done following process:
cv::inRange(src, Scalar(9, 95, 95),Scalar(17, 255, 255), dest);
Input Image
Question
I want detect brown colour of eye in above image .When I use above range for brown colour i got zero contour.
is above range for brown colour is correct? what should be it?
Upvotes: 0
Views: 4712
Reputation: 41775
You can segment a brown object in an image playing around with HSV ranges. Since brown is somehow a darker red, you need to tweak the parameters a little. If you post a reference image we could find a more accurate range.
Once you have the object mask (you usually apply some morphology to clean the mask), you can easily get the contours with findContours
.
The example below explains this:
#include <iostream>
#include <vector>
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
int main()
{
Mat3b img = imread("path_to_image");
Mat3b hsv;
cvtColor(img, hsv, COLOR_BGR2HSV);
Mat1b mask1, mask2;
inRange(hsv, Scalar(0, 100, 20), Scalar(10, 255, 255), mask1);
inRange(hsv, Scalar(170, 100, 20), Scalar(180, 255, 255), mask2);
Mat1b mask = mask1 | mask2;
Mat1b kernel = getStructuringElement(MORPH_ELLIPSE, Size(7,7));
morphologyEx(mask, mask, MORPH_OPEN, kernel);
vector<vector<Point>> contours;
findContours(mask.clone(), contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
Mat3b res = img.clone();
for(int i=0; i<contours.size(); ++i)
{
drawContours(res, contours, i, Scalar(0,255,0));
RotatedRect r = minAreaRect(contours[i]);
Point2f pts[4];
r.points(pts);
for (int j = 0; j < 4; ++j)
{
line(res, pts[j], pts[(j + 1) % 4], Scalar(0,0,255));
}
Rect box = boundingRect(contours[i]);
rectangle(res, box, Scalar(255,0,0));
}
imshow("Original", img);
imshow("Segmented", res);
waitKey();
return 0;
}
Initial image
Segmented brown object (american football)
Update with actual image
Since the image you posted is somehow more difficult then the one in my former example (because you have a lot of almost brown color outside the pupil), you need also to:
This code show this:
#include <iostream>
#include <vector>
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
int main()
{
Mat3b img = imread("D:\\SO\\img\\eye.jpg");
Mat3b hsv;
cvtColor(img, hsv, COLOR_BGR2HSV);
Mat1b mask;
inRange(hsv, Scalar(2, 100, 65), Scalar(12, 170, 100), mask);
Mat1b kernel = getStructuringElement(MORPH_ELLIPSE, Size(3, 3));
morphologyEx(mask, mask, MORPH_OPEN, kernel);
vector<vector<Point>> contours;
findContours(mask.clone(), contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
if (contours.empty()) {return -1;}
int idx_largest_blob = 0;
int size_largest_blob = contours[0].size();
if (contours.size() > 1)
{
for (int i = 0; i < contours.size(); ++i)
{
if (size_largest_blob < contours[i].size())
{
size_largest_blob = contours[i].size();
idx_largest_blob = i;
}
}
}
Mat3b res = img.clone();
drawContours(res, contours, idx_largest_blob, Scalar(0, 255, 0));
RotatedRect r = minAreaRect(contours[idx_largest_blob]);
Point2f pts[4];
r.points(pts);
for (int j = 0; j < 4; ++j)
{
line(res, pts[j], pts[(j + 1) % 4], Scalar(0, 0, 255));
}
Rect box = boundingRect(contours[idx_largest_blob]);
rectangle(res, box, Scalar(255, 0, 0));
imshow("Original", img);
imshow("Segmented", res);
waitKey();
return 0;
}
Result:
Note: if you need something more accurate, you should post a new question asking specifically for pupil detection. I'll drop a few useful links, just in case:
http://answers.opencv.org/question/12034/face-eyes-and-iris-detection/
https://github.com/trishume/eyeLike
http://cmp.felk.cvut.cz/~uricamic/flandmark/
http://opencv-code.com/tutorials/pupil-detection-from-an-eye-image/
http://thume.ca/projects/2012/11/04/simple-accurate-eye-center-tracking-in-opencv/
http://opencv-code.com/tutorials/eye-detection-and-tracking/
Upvotes: 2