# How to delete additional circles in OpenCV's Finger Detection?

i'm developing an app to recognize hand gestures... My program detect 3 useless points.. how can I make sure they are not detected?

i am using opencv 4.0.1 and microsoft visual studio 2017.

this is the code:

//FIND CONVEX HULLS
int largestcontour = 0; int maxarea = 0;
for (int i = 0; i < contours.size(); i++) {
double a = contourArea(contours[i]);
if (a > maxarea)
{
maxarea = a;
largestcontour = i;
} }

vector<vector<Point> hull(contours.size());
vector<vector<int> >  hullsI(contours.size());
vector<vector<Vec4i>>  defects(contours.size());

for (int i = 0; i < contours.size(); i++) {
convexHull(contours[i], hull[i], false);
convexHull(contours[i], hullsI[i], false);
if (hullsI[i].size() > 3)
{
convexityDefects(contours[i], hullsI[i], defects[i]);
} }

if (maxarea > 100) {
drawContours(drawing, hull, largestcontour, Scalar(255, 0, 255),
3, 8, vector<Vec4i>(), 0, Point());

for (int j = 0; j < defects[largestcontour].size(); ++j)
{
const Vec4i& v = defects[largestcontour][j];
float depth = v[3] / 256;
if (depth > 5) //  filter defects by depth
{
int startidx = v[0]; Point ptStart(contours[largestcontour][startidx]);
int endidx = v[1]; Point ptEnd(contours[largestcontour][endidx]);
int faridx = v[2]; Point ptFar(contours[largestcontour][faridx]);

line(drawing, ptStart, ptEnd, Scalar(0, 255, 0), 1);
line(drawing, ptStart, ptFar, Scalar(0, 255, 0), 1);
line(drawing, ptEnd, ptFar, Scalar(0, 255, 0), 1);

//DRAW POINTS
circle(drawing, ptFar, 9, Scalar(0, 255, 0), 2);
circle(drawing, ptEnd, 9, Scalar(0, 0, 255), 2);

}
} }


thanks

edit retag close merge delete

1

i don't think, that you can avoid, that it detects the wrist joint

maybe the whole approach (counting convexity defects) is far too brittle ? (e.g. for an upraised thumb, there might be no point 2, and for an uprised little finger no point 1

( 2019-01-17 06:08:28 -0500 )edit
( 2019-01-17 13:06:38 -0500 )edit

Sort by » oldest newest most voted

Maybe try taking a different aproach, try to compute all distances between the hand centroid and each point in the contour, and then find the local maxima in this distances vector. A local maxima in this context is a point at which the distance to the centroid increases and then starts to decrease. Due to the nature of a hand, you expect that a fingertip will have a local peak distance to the centroid. This wouldn't detect the 1, 2 and 3 points you marked because they wouldn't verify these conditions.

If your contour has the size and detail of the image you posted, this approach should work quite well.

EDIT: Just realized you want also to detect the base intersection of the fingers. You can adapt this approach and include the local minima, and exclude any local minima that aren't between two local maxima.

more

@Pedro Batista. Can you post code? So I can translated to python.

( 2019-01-17 07:03:09 -0500 )edit
1

I gave you the direction and now it is your job to do the work. Use cv2.findContours() to calculate the countour coordinates, and you can calculate distances between points using the euclidean formula Distance = sqrt((X1 - X2)^2 + (Y1 - Y2)^2)

( 2019-01-17 08:53:24 -0500 )edit

Another question: is it possible with OpenCV to recognize two hands using this method? Last, is it possible to extrapolate and work with the hand's points? For now I'm only interested in knowing if it's possible.

Thanks a lot.

( 2019-01-17 10:31:39 -0500 )edit

This method will work with multiple hands in the same image if each one is a contour on its own. Once you detect fingertips you can work with hand points alone, yes.

( 2019-01-22 05:05:17 -0500 )edit

Official site

GitHub

Wiki

Documentation