Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

count the number of objects from the edges

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.

count the number of objects from the edges

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());
                }
            }
        }
    }

count the number of objects from the edges

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());
                }
            }
        }
    }