Ask Your Question
1

count the number of objects from the edges

asked 2014-08-23 06:04:37 -0600

Dhara Shah gravatar image

updated 2014-08-23 06:20:48 -0600

Hi,

I am trying to detect the count of objects in an image captured on which several operations are performed. I capture an image, get the Hue channel and apply the following:

Imgproc.cvtColor(srcMat, dst, Imgproc.COLOR_RGB2HSV);
ArrayList<Mat> channels = new ArrayList<Mat>();
Core.split(srcMat, channels);
Mat satImg = channels.get(0);

Imgproc.medianBlur(satImg , satImg , 11);
Highgui.imwrite(imgPath + "blurred.jpg", satImg);

Imgproc.threshold(satImg, satImg, -1, 255, Imgproc.THRESH_BINARY + Imgproc.THRESH_OTSU);
Highgui.imwrite(imgPath + "satImg_thresh.jpg", satImg);

Once thresholding is applied to the image, i apply a gaussian blur and apply a threshold filter again, and then a bitwise_not operation on the image . Dilation is applied and then edges are obtained using:

Mat edge = new Mat();
Imgproc.Canny(satImg, edge, 35,90); // 40,120 -> to tr  
Log.e("tag","edge: "  + edge.cols());       
edge.convertTo(threshMat,CvType.CV_8U);     
Log.e("tag","dst cols " + threshMat.cols()); 
Highgui.imwrite(imgPath + "canny.jpg", threshMat);

This is the image i get: image description

I then perform dilation out of which i get the image below: image description

There are a couple of questions i have:

  1. I would like to actually fill those edges completely such that it would become a complete ellipse. Yes, i am using fitEllipse for the same but i would like to do it with an edge function if possible. I am using findContours to get the number of outer edges with the flat Imgproc.RETR_EXTERNAL but then as in the image there is that one line extra that gets counted, i wish to neglect that too. Could any one please guide me ?

  2. Sometimes shadows also form a polygon, i would like to ignore shadows also

  3. Is there a way i could only take into picture those contours that are ellipses or circles? Not lines that turn out to be ellipses, and not even those minor dots if there are any.

Please assist

P.S: I am using opencv for android, any help with c++ code is welcome, though i wish an android equivalent would be present.

EDIT:

I have also used this code to draw the contours but it seems that only one edge would be filled completely. rest are ignored

for (int idx = 0; idx < contours.size(); idx++) {
        MatOfPoint  matOfPoint = new MatOfPoint(contours.get(idx));

        double[] values = hierarchy.get(idx, 0);
        double[] secondLevelValues = hierarchy.get(idx, 1);
        if(values != null) {
            Log.e("tag","dst : 0 " + values[0]);
            if(values[0] != -1) {
                if(matOfPoint.total() >= 5) {
                    Log.e("tag","is convex inside first loop : " + Imgproc.isContourConvex(matOfPoint));
                    counter ++;
                }

                /*Moments moments = Imgproc.moments(matOfPoint);
                moments.get_m01();*/
                Imgproc.drawContours(threshMat, contours, idx, new Scalar(255), -1,8,hierarchy,0,new Point());
            }
        }else {
            if(secondLevelValues != null) {
                Log.e("tag","dst : 1 " + secondLevelValues[0]);
                if(secondLevelValues[0] != -1) {
                    if(matOfPoint.total() >= 5) {
                        counter ++;
                        Log.e("tag","is convex inside first loop : " + Imgproc.isContourConvex(matOfPoint));
                    }
                    Imgproc.drawContours(threshMat, contours, idx, new Scalar(255), -1,8,hierarchy,0,new Point());
                }
            }
        }
    }
edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted
1

answered 2014-08-25 01:06:33 -0600

Hi @Dhara Shah!

If your object size is always bigger than the noise & also it is closed, you can filter those contours by using the parameter contour Area. Here is an opencv example.

for(unsigned int i=0;i<contours.size(),i++)
{
     double minContourArea= 1000;
     if(contourArea(contours[i])> minContourArea)
     {
         //count this contour
     }

}
edit flag offensive delete link more

Comments

Hi, thank u for your answer, i dont want to involve area at the moment, is there any other way i could do this? becuase i am trying to capture capsules and small pills, whose proper area i know not. :( . Also there are times when a shadow gets included in the area :(. is there a way i could eliminate shadows ??

Dhara Shah gravatar imageDhara Shah ( 2014-08-25 03:49:16 -0600 )edit
1

answered 2014-08-25 11:22:44 -0600

Haris gravatar image

Probable solutions

  1. You can use Contours Hierarchy to ignore contour inside contour.

  2. Use the same Hierarchy to distinguish closed and open contour, so that you can avoid the lines, dots etc.. See an example here

  3. And one more thing is that in findContours() function use CV_RETR_CCOMP which retrieves all of the contours and organizes them into a two-level hierarchy.

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2014-08-23 06:04:37 -0600

Seen: 8,582 times

Last updated: Aug 25 '14