OpenCV检测钻孔

时间:2018-07-21 13:43:04

标签: java android opencv image-processing

我正在一个项目中,我必须检测表面上的钻孔。 (顶部的两个孔,仅用于定位目的)

Image: surface to scan sample 1 Image: surface to scan sample 2

检测到孔后,图案将判断孔的位置并给出结果。我已经创建了一个覆盖网格布局,并将其放置在camera2api预览上,以便用户可以对齐孔并进行扫描(真正的测试将不是屏幕截图中显示的LCD图片)

enter image description here

当前,我正在基于网格裁剪图像,并将其调整为1920x2560大小,以具有用于模式判断的一致帧,这使单个网格大约为300px。我无法检测到斑点,是否有人可以建议我应该为这项工作选择哪种过滤方式,以及是否有比使用网格布局更好的方法,而不是使用网格布局,因为孔相对于定向孔的位置很重要最终结果(x轴和y轴)

enter image description here

这是我的代码:

Mat srcMat = resizeAndCropMatToGrid(mats[0]);
        if (srcMat == null) {
            exception = new Exception("Cropping Failed");
            errorMessage = "Unable to crop image based on grid";
            return null;
        }
        matProgressTask = srcMat;
        Mat processedMat = new Mat();
        Imgproc.cvtColor(srcMat, processedMat, Imgproc.COLOR_BGR2GRAY);
    Imgproc.GaussianBlur(processedMat, processedMat, new org.opencv.core.Size(5, 5), 5);
    Imgproc.threshold(processedMat, processedMat, 115, 255, Imgproc.THRESH_BINARY);


        matProgressTask = processedMat;


        FeatureDetector featureDetector = FeatureDetector.create(FeatureDetector.SIMPLEBLOB);
        featureDetector.read(Environment.getExternalStorageDirectory() + "/Android/blob.xml");
        MatOfKeyPoint matOfKeyPoint = new MatOfKeyPoint();
        featureDetector.detect(processedMat, matOfKeyPoint);
        KeyPoint[] keyPointsArray = matOfKeyPoint.toArray();
        Log.e("keypoints", "" + Arrays.toString(keyPointsArray));
            if (keyPointsArray.length < 1) {
            exception = new Exception("Blobs Missing");
            errorMessage = "Error: Unable to filter blobs";
        } else {
            try {
                MatOfKeyPoint matOfKeyPointFilteredBlobs = new MatOfKeyPoint(keyPointsArray);
                Features2d.drawKeypoints(srcMat, matOfKeyPointFilteredBlobs, srcMat, new Scalar(255, 0, 0), Features2d.DRAW_OVER_OUTIMG);
            } catch (Exception e) {
                e.printStackTrace();
                exception = e;
                errorMessage = "Error: Unable to draw Blobs";
                return null;
            }
            matProgressTask = srcMat;
            onProgressUpdate();
            patterData = pinpointBlobsToGetData(keyPointsArray);
            if (patterData == null) {
                exception = new Exception("Unable to establish pattern");
                errorMessage = "Error: Key points array is null";
            }
        }

这是我正在使用的简单文件配置:

<?xml version="1.0"?>
<opencv_storage>
<format>3</format>
<thresholdStep>10.</thresholdStep>
<minThreshold>50.</minThreshold>
<maxThreshold>120.</maxThreshold>
<minRepeatability>2</minRepeatability>
<minDistBetweenBlobs>20.</minDistBetweenBlobs>
<filterByColor>1</filterByColor>
<blobColor>0</blobColor>
<filterByArea>1</filterByArea>
<minArea>2300.</minArea>
<maxArea>4500.</maxArea>
<filterByCircularity>1</filterByCircularity>
<minCircularity>0.2</minCircularity>
<maxCircularity>1.0</maxCircularity>
<filterByInertia>1</filterByInertia>
<minInertiaRatio>0.2</minInertiaRatio>
<maxInertiaRatio>1.0</maxInertiaRatio>
<filterByConvexity>1</filterByConvexity>
<minConvexity>0.2</minConvexity>
<maxConvexity>1.0</maxConvexity>
</opencv_storage>

2 个答案:

答案 0 :(得分:2)

我正在使用Python。

对于您提供的第二张图片,我成功检测到了孔...

res1

...使用此代码...

import cv2
import numpy as np

img = cv2.imread("C:\\Users\\Link\\Desktop\\2.jpg")
# cv2.imshow("original", img)

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# cv2.imshow("gray", gray)

blur = cv2.medianBlur(gray, 31)
# cv2.imshow("blur", blur)

ret, thresh = cv2.threshold(blur, 127, 255, cv2.THRESH_OTSU)
# cv2.imshow("thresh", thresh)

canny = cv2.Canny(thresh, 75, 200)
# cv2.imshow('canny', canny)

im2, contours, hierarchy = cv2.findContours(canny, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

contour_list = []
for contour in contours:
    approx = cv2.approxPolyDP(contour, 0.01 * cv2.arcLength(contour, True), True)
    area = cv2.contourArea(contour)
    if 5000 < area < 15000:
        contour_list.append(contour)

msg = "Total holes: {}".format(len(approx)//2)
cv2.putText(img, msg, (20, 40), cv2.FONT_HERSHEY_PLAIN, 2, (0, 0, 255), 2, cv2.LINE_AA)

cv2.drawContours(img, contour_list, -1, (0, 255, 0), 2)
cv2.imshow('Objects Detected', img)

cv2.imwrite("detected_holes.png", img)

cv2.waitKey(0)

现在,第一个有点不同。相同的代码将无法检测正确数量的孔。该程序还会继续检测明显缺少一个主要孔的明显不是孔的孔(左底角裂纹)。

以下是我所谈论的例子:

res2

在这种情况下,不仅计数器是错误的,而且主要的问题是无法检测到右下角的孔。

答案 1 :(得分:1)

因此,我已经设法通过将垫子直接传递给FeatureDetector类来进行计算,而无需任何事先处理...

conda install -c conda-forge pdal

我的特征检测器参数文件是:

            Mat srcMat = mats[0];
        if (srcMat == null) {
            exception = new Exception("Cropping Failed");
            errorMessage = "Unable to crop image based on grid";
            return null;
        }
        matProgressTask = srcMat;

        FeatureDetector featureDetector = FeatureDetector.create(FeatureDetector.SIMPLEBLOB);
        featureDetector.read(Environment.getExternalStorageDirectory() + "/Android/blob.xml");
        Log.e("LoadingBlob", "wqfqfwq");
        MatOfKeyPoint matOfKeyPoint = new MatOfKeyPoint();
        featureDetector.detect(srcMat, matOfKeyPoint);
        KeyPoint[] keyPointsArray = matOfKeyPoint.toArray();
        Log.e("keypoints", "" + Arrays.toString(keyPointsArray));
            if (keyPointsArray.length < 1) {
            exception = new Exception("Blobs Missing");
            errorMessage = "Error: Unable to filter blobs";
        } else {
            try {
                MatOfKeyPoint matOfKeyPointFilteredBlobs = new MatOfKeyPoint(keyPointsArray);
                Features2d.drawKeypoints(srcMat, matOfKeyPointFilteredBlobs, srcMat, new Scalar(0, 255, 0), Features2d.DRAW_OVER_OUTIMG);
            } catch (Exception e) {
                e.printStackTrace();
                exception = e;
                errorMessage = "Error: Unable to draw Blobs";
                return null;
            }
            matProgressTask = srcMat;
            onProgressUpdate();
            patterData = pinpointBlobsToGetData(keyPointsArray);
            if (patterData == null) {
                exception = new Exception("Unable to establish pattern");
                errorMessage = "Error: Key points array is null";
            }
        }

结果图像: Result Image 1

Result Image 2