Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用cv2.Minareact(cnt)获得多轮廓图像上唯一的最小面积矩形?_Python_Opencv_Image Processing_Contour_Opencv Contour - Fatal编程技术网

Python 如何使用cv2.Minareact(cnt)获得多轮廓图像上唯一的最小面积矩形?

Python 如何使用cv2.Minareact(cnt)获得多轮廓图像上唯一的最小面积矩形?,python,opencv,image-processing,contour,opencv-contour,Python,Opencv,Image Processing,Contour,Opencv Contour,我只想使用一个矩形覆盖此图像中的圆: 并使用cv2.minareact(cnt)获得此结果: 这张图片似乎被分成多个部分。可能是因为在这个图像的边缘有一些断点。你能告诉我如何只用一个矩形来覆盖我图像的这个圆吗?多谢各位 这是我的代码: def draw_min_rect_circle(img, cnts): # conts = contours img = np.copy(img) for cnt in cnts: x, y, w, h = cv2.bou

我只想使用一个矩形覆盖此图像中的圆:

并使用cv2.minareact(cnt)获得此结果:

这张图片似乎被分成多个部分。可能是因为在这个图像的边缘有一些断点。你能告诉我如何只用一个矩形来覆盖我图像的这个圆吗?多谢各位

这是我的代码:

def draw_min_rect_circle(img, cnts):  # conts = contours
    img = np.copy(img)

    for cnt in cnts:
        x, y, w, h = cv2.boundingRect(cnt)
        cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)  # blue

        min_rect = cv2.minAreaRect(cnt)  # min_area_rectangle
        min_rect = np.int0(cv2.boxPoints(min_rect))
        cv2.drawContours(img, [min_rect], 0, (0, 255, 0), 2)  # green

        (x, y), radius = cv2.minEnclosingCircle(cnt)
        center, radius = (int(x), int(y)), int(radius)  # center and radius of minimum enclosing circle
        img = cv2.circle(img, center, radius, (0, 0, 255), 2)  # red
return img

您需要做的是,您需要通过合并轮廓从图像中以某种方式仅获得1个轮廓,这有点困难,因此,如果您只希望在所有轮廓周围使用封闭矩形,您可以这样做

def draw_min_rect_circle(img, cnts):  # conts = contours
    img = np.copy(img)
    x1,y1 = np.inf
    x2,y2 = 0
    for cnt in cnts:
        x, y, w, h = cv2.boundingRect(cnt)
        if x > x1:
           x1=x
        if y > y1:
           y1=y
        if x2 < x+w
           x2 = x+w
        if y2 < y+h
           y2 = y+h
     w = x2 - x1
     h = y2 - y1
     r = math.sqrt((w*w) + (h*h)) / 2

     cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)
     cv2.circle(img, (x1+w/2,y1+h/2), r, (0, 0, 255), 2)
def draw_min_rect_圆(img,cnts):#conts=轮廓
img=np.copy(img)
x1,y1=np.inf
x2,y2=0
对于cnt中的cnt:
x、 y,w,h=cv2.boundingRect(cnt)
如果x>x1:
x1=x
如果y>y1:
y1=y
如果x2
您可能使用
cv2.findContours()
搜索轮廓,并在其中迭代以在图像上绘制矩形。问题是,你的图像没有一条相连的线组成圆圈,而是有许多虚线

轮廓是连接所有连续点(沿边界)的曲线,具有相同的颜色或强度(OpenCV文档)

所以为了得到更好的结果,你应该在搜索轮廓之前先准备好你的图像。可以使用各种工具对图像进行预处理(可以搜索OpenCV文档)。在本例中,我将尝试使用一个小内核执行名为“关闭”的过程。闭合是膨胀,接着是像素侵蚀。它可以帮助将您的小轮廓连接到一个大轮廓(圆)。然后,您可以选择最大的一个并绘制一个边框

例如:

输入图像:

结果:

执行关闭操作后的图像:


希望能有帮助。干杯

可以将所有轮廓合并为一个轮廓,因为它们只是描述轮廓的点坐标的numpy数组。您可以使用np.concatenate(等高线),cv2.minareact函数似乎并不关心新数组中的点是否连续。在我的例子中,这比使用关闭函数效果更好,因为我有更复杂的对象。如果你愿意,你可以试试,很简单。您的函数应该是这样的:

def draw_min_rect_circle(img, cnts):  # conts = contours
    img = np.copy(img)

    join_cnts = np.concatenate(cnts)

    x, y, w, h = cv2.boundingRect(join_cnts)
    cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)  # blue

    min_rect = cv2.minAreaRect(join_cnts)  # min_area_rectangle
    min_rect = np.int0(cv2.boxPoints(min_rect))
    cv2.drawContours(img, [min_rect], 0, (0, 255, 0), 2)  # green

    (x, y), radius = cv2.minEnclosingCircle(join_cnts)
    center, radius = (int(x), int(y)), int(radius)  # center and radius of minimum enclosing circle
    img = cv2.circle(img, center, radius, (0, 0, 255), 2)  # red
    
return img

当然,人们可以在提供的二进制图像上找到解决方案,但我认为,如果您提供原始输入图像会更好,因为您的问题可能有更好的整体解决方案。这是一个很好的解决方案。通过闭合轮廓然后迭代寻找最大值来消除噪声的方法很简单,但非常有效。简单的解决方案,如果有效的话,在我的经验中是最好的解决方案。很高兴它起了作用。@kavko谢谢你的帮助!你的解决方案有效。这真是一个伟大的解决方案!
def draw_min_rect_circle(img, cnts):  # conts = contours
    img = np.copy(img)

    join_cnts = np.concatenate(cnts)

    x, y, w, h = cv2.boundingRect(join_cnts)
    cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)  # blue

    min_rect = cv2.minAreaRect(join_cnts)  # min_area_rectangle
    min_rect = np.int0(cv2.boxPoints(min_rect))
    cv2.drawContours(img, [min_rect], 0, (0, 255, 0), 2)  # green

    (x, y), radius = cv2.minEnclosingCircle(join_cnts)
    center, radius = (int(x), int(y)), int(radius)  # center and radius of minimum enclosing circle
    img = cv2.circle(img, center, radius, (0, 0, 255), 2)  # red
    
return img