Ask Your Question

improving poor blob contours

asked 2015-10-23 16:44:26 -0500

widgetman gravatar image

A human can see where the edges of the hand and arm are quite easily in this picture, wouldn't you say? Are there any image processing techniques that can be performed to draw the contour that we humans imagine the perimeter to have when we look at this?

Morhological operations such as eroding and dilating will not work so well to my knowledge as the location of all finger tips will not be preserved.

image description

edit retag flag offensive close merge delete


Why do you mean by "location of all finger tips will not be preserved."?

If you use closing results is like @berak answer

LBerger gravatar imageLBerger ( 2015-10-24 09:27:28 -0500 )edit

hmm, your image looks a bit like you'd slightly overdone on morhpological operations already ?

berak gravatar imageberak ( 2015-10-24 10:29:24 -0500 )edit

3 answers

Sort by ยป oldest newest most voted

answered 2015-10-24 00:03:40 -0500

berak gravatar image

updated 2015-10-24 00:04:56 -0500

// blur like hell !
int B=8;

//then threshold again:
ocv = (ocv > 30);

blur and threshold

edit flag offensive delete link more

answered 2015-10-24 12:47:57 -0500

LorenaGdL gravatar image

Another alternative. This one, just a little upgrade to @berak 's answer - using closing and opening morphological operations after the blur, you can get one final and single contour:

Mat image = imread("hand.jpg", 0);
blur(image, image, Size(8, 8));
image = image > 30;
morphologyEx(image, image, MORPH_CLOSE, Mat(25, 2, CV_8U));
morphologyEx(image, image, MORPH_OPEN, Mat(10, 10, CV_8U));

vector<vector<Point>> contours;
findContours(image, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
Mat image_contour(image.rows, image.cols, CV_8UC1, Scalar(0));
drawContours(image_contour, contours, 0, Scalar(255));

And so we get this (image on the left, image_contour on the right):

image descriptionimage description

edit flag offensive delete link more

answered 2015-10-24 11:12:34 -0500

theodore gravatar image

also it seems that your image is not exactly binary so if you just apply some thresholding or some floodfill() you can get the whole arm easily:

Mat img = imread("img13.jpg", 0);

Mat bin;
threshold(img, bin, 0, 255, THRESH_BINARY);
imshow("bin", bin);

image description

cv::Mat mask = cv::Mat::zeros(img.rows + 2, img.cols + 2, CV_8U); // A image with size greater than the present object is created, needed from floodfil

cv::floodFill(img_c, mask, cv::Point(0,0), 255, 0, cv::Scalar(), cv::Scalar(), 4 + (255 << 8) + cv::FLOODFILL_MASK_ONLY);

imshow("mask", ~mask);

image description

edit flag offensive delete link more

Question Tools

1 follower


Asked: 2015-10-23 16:44:26 -0500

Seen: 475 times

Last updated: Oct 24 '15