First time here? Check out the FAQ!

Ask Your Question
1

improving poor blob contours

asked Oct 23 '15

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

Preview: (hide)

Comments

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 (Oct 24 '15)edit

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

berak gravatar imageberak (Oct 24 '15)edit

3 answers

Sort by » oldest newest most voted
3

answered Oct 24 '15

berak gravatar image

updated Oct 24 '15

// blur like hell !
int B=8;
blur(ocv,ocv,Size(B,B));

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

blur and threshold

Preview: (hide)
2

answered Oct 24 '15

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

Preview: (hide)
2

answered Oct 24 '15

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

Preview: (hide)

Question Tools

1 follower

Stats

Asked: Oct 23 '15

Seen: 758 times

Last updated: Oct 24 '15