如何计算轮廓opencv中的非零像素

时间:2017-07-12 06:23:29

标签: java android opencv

我正在使用OMR库开发opencv扫描仪android应用程序。 我已经在工作表中检测到我的圆圈作为轮廓,现在我想从所有获得的轮廓中获得圆形轮廓 由于java对opencv的支持非常少,我无法弄清楚什么, 请为此提出一些方法。

    //paramview is my image     
    Utils.bitmapToMat(paramView, localMat1);
    Mat localMat2 = new Mat();
    double[] lo;
    Imgproc.GaussianBlur(localMat1, localMat2, new Size(5.0D, 5.0D), 7.0D, 6.5D);
    Object localObject = new Mat();
    Imgproc.cvtColor(localMat2, (Mat)localObject, COLOR_RGB2GRAY);
    Mat cloneMat= ((Mat) localObject).clone();
    localMat2 = localMat1.clone();
    bitwise_not(cloneMat,cloneMat);
    Imgproc.threshold(cloneMat,localMat2,127,255,Imgproc.THRESH_OTSU);
    Mat thresh=localMat2.clone();

    List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
    List<MatOfPoint> questions = new ArrayList<MatOfPoint>();
    List<MatOfPoint> sorted = new ArrayList<MatOfPoint>();

    //All contours detected 
    Mat hierarchy = new Mat();
    Imgproc.findContours(localMat2, contours, hierarchy, 
    Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);

Image of Detected circles here

2 个答案:

答案 0 :(得分:0)

我重写了自己的代码并找到了这个解决方案。希望它可能有所帮助。

 for (int contourIdx = 0; contourIdx < questionSortedR.size(); contourIdx++) {
        //creating rectangle around identified contour
        Rect rectCrop = boundingRect(questionSortedR.get(contourIdx));
        //creating crop of that contour from actual image
        Mat imageROI= thresh.submat(rectCrop);
        //apply countnonzero method to that crop
        int total = countNonZero(imageROI);
        double pixel =total/contourArea(questionSortedR.get(contourIdx))*100;
        //pixel is in percentage of area that is filled
        if(pixel>=100 && pixel<=130){
            //counting filled circles
            count++;
        }

    }

答案 1 :(得分:0)

我提出了一种替代已接受答案的方法:不要在边界矩形内计算像素,而是将轮廓绘制为蒙版,然后对原始图像进行蒙版并计算其中的像素。我在计算白色背景上的黑色像素,轮廓在边缘保留了几个像素,因此里程可能会有所不同。这是我在Python中的代码:

mask = np.zeros(bw_image.shape, np.uint8)
cv.drawContours(mask, [contour], 0, 255, -1)
inverted = cv.bitwise_not(bw_image)
masked = cv.bitwise_not(cv.bitwise_and(inverted, inverted, mask = mask))

# Grab masked image inside contour
x, y, w, h = cv.boundingRect(contour)
pixels = masked[y:y+h, x:x+w]

# Check if black is only a line, in which case whiteness is 1
kernel = np.ones((3, 3), np.uint8)
dilated = cv.dilate(pixels, kernel, iterations = 1)
whiteness = np.sum(dilated) / (255 * w * h)