1 | initial version |
I assume you mean the brighter white rings on top.
I was able to do this by converting the color image to HSV, then splitting into separate channels.
When you look at the S channel the rings stand out more:
You can then invert this image, threshold, do a dilation to fill in some holes and find a bounding box around the contours of the rings.
Here is the code I used:
Mat srcImg, hsvImg, sImg, invertImg, thresholdImg, dilateImg, markupImg;
vector<Mat> hsvImgList(3);
srcImg = imread("yarn.png");
cvtColor(srcImg, hsvImg, COLOR_BGR2HSV);
split(hsvImg, hsvImgList);
sImg = hsvImgList[1];
invertImg = 255 - sImg,
threshold(invertImg, thresholdImg, 150, 255, THRESH_BINARY);
Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3));
dilate(thresholdImg, dilateImg, kernel, Point(-1, -1), 1);
cvtColor(thresholdImg, markupImg, COLOR_GRAY2BGR);
vector<vector<Point>> contourList;
findContours(thresholdImg, contourList, RETR_LIST, CHAIN_APPROX_NONE);
for (auto& contour : contourList) {
double area = contourArea(contour);
if (area > 200) {
Rect br = boundingRect(contour);
rectangle(markupImg, br, Scalar(200, 0, 200));
}
}
imwrite("yarn_markup.png", markupImg);