Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
416 views
in Technique[技术] by (71.8m points)

c++ - Snake Algorithm - opencv active contour - not working so well

I'm actually working on a contour detection for head side. As pictures are taken in front of a white wall, I decided to run a snake (active contour model algorithm) on the picture processed with a threshold.

Problem is the snake won't fit well around the nose, the mouth, and below the mouth (as you can see in these pictures below).

//load file from disk and apply threshold
IplImage* img = cvLoadImage (file.c_str (), 0);
cvThreshold(img, img, 170, 255, CV_THRESH_BINARY);

float alpha = 0.1; // Weight of continuity energy
float beta = 0.5; // Weight of curvature energy
float gamma = 0.4; // Weight of image energy

CvSize size; // Size of neighborhood of every point used to search the minimumm have to be odd
size.width = 5;
size.height = 5;

CvTermCriteria criteria;
criteria.type = CV_TERMCRIT_ITER;  // terminate processing after X iteration
criteria.max_iter = 10000; 
criteria.epsilon = 0.1;

// snake is an array of cpt=40 points, read from a file, set by hand
cvSnakeImage(img, snake, cpt, &alpha, &beta, &gamma, CV_VALUE, size, criteria, 0);

I tried to change the alpha/beta/gamma parameters or iterations number but I didn't find a better result than output show below. I cannot understand why the nose is cut, and face is not fit around the mouth. I have enough points i guess for the curvature, but there still be some lines composed with several (>2) points.

Input Image : Input Image - threshold

Output Snake :

  • blue : points set by hand

  • green : output snake

OutputSnake

Any help or ideas would be very appreciated. Thanks !

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

A typical snake or active contour algorithm converges during a trade-off between 3 kind of cost functions: edge strength/distance (data term), spacing and smoothness (prior terms). Immediately, you may notice a connection to your "nose-problem" - the nose has high curvature. Your snake also have troubles getting into concave regions since this certainly increases its curvature compared to a convex hull.

SOLUTIONS:
A. Since your snake performance isn't better than one of a convex hull, as one of the remedies I would proceed with a simpler convex hull algorithm and then rerun it on its inverted residuals. It will get a nose right and then concavities will turn into convexities in the residuals. Or you can use convexity defect function of openCV instead of working with convexHull.

B. Another fix can be to reduce snake curvature parameter to allow it to curve around the nose sharply. Since you have little noise and you can actually clean it up a bit I see no problem of enforcing some constraints instead of making "softer" trade-offs. Perhaps a head silhouette prior model can help here too.

Below I tried to write my own snake algorithm using various distance transforms and weights of a distance parameter. The conclusion - the parameter matters more than distance metrics and does have some effect (a left picture uses smaller parameter than the right and thus cuts the nose more). The distance from contour (red) is shown with grey, snake is green.

enter image description here left

C. Since your background is almost solid color, invest a bit into cleaning some residual noise (use morphological operations or connected components) and just findContrours() of the clean silhouette. I implemented this last solution below: a first image has noise deleted and the second is just a contour function from openCV. enter image description here enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...