Python OpenCV硬币检测和自动结果检查

Python OpenCV硬币检测和自动结果检查,python,opencv,image-processing,computer-vision,feature-detection,Python,Opencv,Image Processing,Computer Vision,Feature Detection,我正在做一个硬币识别的项目。 我遇到的第一件事是从图像中正确提取硬币,即使是从非常简单的图像中。 有很多很好的硬币检测工作方法,但我认为所有这些方法在应用后都需要手动检查。我测试了其中两个: cv2.HoughCircles和阈值,其后为findig计数 以下是一些成功的处理示例: cv2.houghscircles,效果良好 cv2.HoughCircles,坏结果 但对于第二幅图像,我们可以找到一个很好的解决方案,即对其进行阈值选择并在其之后找到计数: 大概是这样的: gray = cv

我正在做一个硬币识别的项目。 我遇到的第一件事是从图像中正确提取硬币,即使是从非常简单的图像中。 有很多很好的硬币检测工作方法,但我认为所有这些方法在应用后都需要手动检查。我测试了其中两个:

cv2.HoughCircles和阈值,其后为findig计数

以下是一些成功的处理示例:

cv2.houghscircles,效果良好

cv2.HoughCircles,坏结果

但对于第二幅图像,我们可以找到一个很好的解决方案,即对其进行阈值选择并在其之后找到计数:

大概是这样的:

gray = cv2.GaussianBlur(gray, (15, 15), 0)

#gray = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY_INV, 11, 1)
    (_,gray) = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
  contours, hierarchy = cv2.findContours(gray, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

for i,cnt in enumerate(contours):
    ellipse = cv2.fitEllipse(cnt)
    print ellipse,type(ellipse)
    cv2.ellipse(color_img, ellipse, (0,255,0), 2)
产生非常好的效果:

但对于其他一些图像,它的效果非常纯净

这种情况之所以发生,是因为硬币之间的距离越来越近,模糊将它们合并在一起。这是非常简单的cas,对于它,我可以检查结果是否只有一个。但有时候更复杂。我想实现一些算法,尝试不同的分割方法并选择最好的方法。但对我来说,编码这个指标很难——有人知道怎么做吗

示例中的原始图像: 这3个是相当真实的,但实际上不是规则-其中一些有背景,一些甚至没有硬币-这就是为什么我考虑一些后检查过程


我成功地使用了具有以下参数的水滴探测器:

Ptr<SimpleBlobDetector> detector;
SimpleBlobDetector::Params params;
params.minThreshold = 150;
params.maxThreshold = 230;
params.filterByArea = true;
params.minArea = 50;
params.maxArea = 50000;
params.filterByConvexity = true;
params.minConvexity = 0.9;
params.maxConvexity = 1.0;

params.filterByCircularity = false;
params.filterByInertia = false;
params.filterByColor = false;
detector = SimpleBlobDetector::create(params);
Ptr检测器;
SimpleBlobDetector::Params Params;
params.minThreshold=150;
参数maxThreshold=230;
params.filterByArea=true;
参数s.minArea=50;
参数maxArea=50000;
params.filterByConvexity=true;
params.min凸度=0.9;
params.Max凸度=1.0;
params.filterByCircularity=假;
params.filterByInertia=false;
params.filterByColor=false;
检测器=SimpleBlobDetector::创建(参数);
然后找到斑点并画出圆圈:

Mat SearchImage; // set to whatever picture contains coins
Mat DrawImage; // image to draw on with drawKeypoints
SearchImage.copyTo(DrawImage);
vector<cv::KeyPoint> keypoints;
detector->detect(SearchImage, keypoints);
drawKeypoints(SearchImage, keypoints, DrawImage, Scalar(0, 0, 0), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
Mat SearchImage;//设置为任何包含硬币的图片
Mat DrawImage;//要使用drawKeypoints绘制的图像
SearchImage.copyTo(DrawImage);
矢量关键点;
检测器->检测(搜索图像、关键点);
drawKeypoints(搜索图像、关键点、DrawImage、标量(0,0,0)、DrawMatchesFlags::DRAW_RICH_关键点);
编辑:
这个例子代码是在C++中。对于Python接口,请参见示例。

您的意思是类似(没有大津和一些减小的最大阈值)cv2.threshold(灰色,0250,cv2.thresh_BINARY_INV)cv2.threshold(灰色,160,255,cv2.thresh_BINARY_INV)的东西适用于这种情况,但仅适用于这种情况吗?图像上始终只有一个硬币(两面)?如果您能够使用这些信息精确地找到2个(几乎相同大小)轮廓,那么这项任务应该很容易解决。将图像划分为2个分区子图像会有帮助吗?在圆/椭圆检测之前?>图像上是否总是有一个硬币(两条边)-实际上没有,但我可以从物体的高度/宽度很有可能找到这些信息。感谢BlobDetector,我喜欢这种方法。但问题是无论如何都存在。在某些情况下,它在某些情况下不起作用。我必须微调阈值参数以获得正确答案。事实上,MintThreshold上的brutferoce不是一个坏主意,但不清楚如何检查algo的结果——什么是好答案,什么是坏答案。没有关键点是不好的。但有一个关键点可能是错误的答案(如第三个例子),但可能不是。