【问题标题】:How to crop the largest circle out of an image (shooting target) using OpenCV如何使用 OpenCV 从图像(射击目标)中裁剪出最大的圆圈
【发布时间】:2020-05-30 19:55:31
【问题描述】:

正如标题所述,我正在尝试从图像中裁剪出最大的圆圈。我在 python 中使用 OpenCV。确切地说,它是一个射击目标,它始终具有相同的格式,但可以使用任何移动设备在不同的光照条件下拍摄它的照片(我会在下面提供一些示例)。

我对图像识别完全陌生,所以我一直在尝试许多不同的方法来做到这一点,但无法找到一个适用于我所有目标图像的通用解决方案。

我为什么要这样做:

我的任务是计算给定目标图像上的一个或多个镜头的得分。我已经尝试过颜色分割来查找镜头,但由于镜头可以在不同的背景上,这将无法正常工作。所以现在我想看看空的拍摄目标图像和已经拍摄的目标图像之间的区别。另外,我需要能够分辨出它是在哪个目标上射击(有两种目标类型)。因此,我尝试仅从图像中裁剪出目标以消除背景干扰,然后继续进行镜头识别。

到目前为止我所尝试的:

1) 用 HoughCircles 找到最大的圆。我的下一步是以某种方式移除找到的圆圈的外部。我已经使用 HoughCircles 方法的配置有一段时间了,但总是有一个示例图像没有正确突出最外圈或没有突出任何圆圈:/。

我的最终配置如下所示:

img = cv2.GaussianBlur(img, (3, 3), 0)
cv2.HoughCircles(img, cv2.HOUGH_GRADIENT, 2, 10000, param1=50, param2=100, minRadius=200, maxRadius=0)

似乎使用 HoughCircles 不是正确的方法,所以我转向了我在互联网上找到的另一种可能的解决方案。

2)通过过滤圆圈似乎在图片上的“黑色”颜色范围来查找所有计数,而不是找到最大的计数。这个解决方案的问题似乎是有时图片有一个阴影破坏了外圈,因此似乎无法通过它进行裁剪。

我的代码如下所示:

# black color boundaries [B, G, R]
lower = [0, 0, 0]
upper = [150, 150, 150]

# create NumPy arrays from the boundaries
lower = np.array(lower, dtype="uint8")
upper = np.array(upper, dtype="uint8")

# find the colors within the specified boundaries and apply the mask
mask = cv2.inRange(img, lower, upper)
output = cv2.bitwise_and(img, img, mask=mask)

ret, thresh = cv2.threshold(mask, 40, 255, 0)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

if len(contours) != 0:
    # draw in blue the contours that were founded
    cv2.drawContours(output, contours, -1, 255, 3)

    # find the biggest countour (c) by the area
    c = max(contours, key=cv2.contourArea)
    x, y, w, h = cv2.boundingRect(c)

之后,我会尝试用找到的最大轮廓 (c) 画一个圆并按它裁剪。但是我已经看到绘制的圆圈不完整(可能是由于图片上有一些阴影),因此无论如何这都行不通。

在这些失败之后,我在这里尝试了很多其他问题的解决方案,但没有一个可以解决我的问题。

示例图片:

Target example 1

Target example 2

Target to calc score 1

Target to calc score 2

老实说,我真的不知道该怎么做。我将不胜感激任何帮助、建议或任何事情。

【问题讨论】:

    标签: python opencv image-recognition


    【解决方案1】:

    您的样本中有两种不同类型的目标。您可能希望单独处理它们或询问用户输入,它是什么类型的目标。基本上,你想知道目标的黑色部分有多大,覆盖7-10还是4-10。

    二值化您的图像。沿 X 和 Y 构建直方图 - 您会发现目标黑色部分的位置为 (x_left, x_right, y_top, y_bottom)。一旦知道了,就可以计算中心((top+bottom)/2, (left+right)/2)。之后,您可以轻松计算图像每个像素的得分,因为您知道中心、黑点大小以及其中不同得分区域的数量。

    【讨论】:

    • 这个应用程序的一个想要的功能是它能够真正识别用户上传的目标类型。我将尝试建立一个直方图并以这种方式进行。但是根据我对直方图的了解,也许只做目标的直方图而不是它背后的背景仍然是有益的(它也可以在某处有黑色,因此结果不准确)。因此,我仍在寻找有关删除图像背景的答案,之后,我将不得不弄清楚如何找到弹孔。谢谢你的回复。最好的问候。
    • 能否提供一些代码来获取中间黑色部分的坐标?我试图制作直方图,但无法弄清楚如何获取坐标(正如您在评论中提到的那样)。我的意思是(x_left,x_right,y_top,y_bottom)。提前致谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-24
    • 2018-09-09
    • 2014-01-31
    相关资源
    最近更新 更多