[英]OpenCV detecting drilled holes
I'm working on a project where I have to detect drilled holes on a surface. 我正在一个项目中,我必须检测表面上的钻孔。 (the top two holes and there for orientation purposes only) (顶部两个孔,仅用于定向目的)
After detecting the holes the pattern will judge the placement of the holes and give results. 在检测到孔之后,图案将判断孔的位置并给出结果。 I have created an overlay grid layout and placed it over the camera2api preview so the user can align the holes and scan (The real testing will not be of a picture from the LCD as shown in the screenshot) 我已经创建了一个覆盖网格布局,并将其放置在camera2api预览上,以便用户可以对齐孔并进行扫描(真正的测试不会是LCD屏幕上的图片,如屏幕截图所示)
Currently, I'm cropping the image based on the grid and resizing it to 1920x2560 to have a consistent frame for pattern judgement, which makes a single grid of roughly about 300px. 目前,我正在基于网格裁剪图像并将其大小调整为1920x2560,以具有用于模式判断的一致帧,这使得单个网格大约为300px。 I am unable to detect the blobs can someone suggest what sort of filtering I should choose for this work and if there is a better approach for doing this rather than using a grid layout as the placement of the holes in regard to the orientation holes matter for final results (both x and y axis) 我无法检测到斑点,是否有人可以建议我应该为这项工作选择哪种过滤方式,以及是否有比使用网格布局更好的方法,而不是使用网格布局,因为孔相对于定向孔的位置很重要最终结果(x和y轴)
Here is my code: 这是我的代码:
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";
}
}
And here is the blobby file configuration that I'm using: 这是我正在使用的大型文件配置:
<?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>
I am using Python. 我正在使用Python。
For the second image you provided I successfully detected the holes... 对于您提供的第二张图片,我成功检测到了孔...
...using this code... ...使用此代码...
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)
Now, the first is a bit different. 现在,第一个有点不同。 The same code will not work in detecting the right amount of holes. 相同的代码将无法检测正确数量的孔。 The program keep detecting also what is clearly not a hole (crack in left bottom angle..) with missing some main holes. 该程序还将继续检测明显缺少孔(缺少一些主要孔的孔)。
Here is an example of what I am talking about: 这是我正在谈论的示例:
Not only the counter in that case is wrong but also, the main problem, is that the hole at right bottom can't be detected. 不仅计数器在这种情况下是错误的,而且主要的问题是无法检测到右下角的孔。
So, I have managed to figure it by passing the mat directly to FeatureDetector class without any prior processing... 因此,我已经设法通过将垫子直接传递给FeatureDetector类来解决它,而无需任何事先处理...
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";
}
}
And my feature detector parameters file is: 我的特征检测器参数文件是:
<?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>0</filterByColor> <blobColor>0</blobColor> <filterByArea>1</filterByArea> <minArea>3000.</minArea> <maxArea>10000.</maxArea> <filterByCircularity>1</filterByCircularity> <minCircularity>0.3</minCircularity> <maxCircularity>1.0</maxCircularity> <filterByInertia>1</filterByInertia> <minInertiaRatio>0.3</minInertiaRatio> <maxInertiaRatio>1.0</maxInertiaRatio> <filterByConvexity>1</filterByConvexity> <minConvexity>0.3</minConvexity> <maxConvexity>1.0</maxConvexity> </opencv_storage>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.