如何在 OpenCV Python 中查找和绘制图像轮廓的凸包?

opencvpythonserver side programmingprogramming

凸包看起来类似于轮廓近似,但它并不完全是轮廓近似。凸包是物体周围的凸曲线。凸曲线总是凸起的,或者至少是平坦的。凸包会找到凸性缺陷并进行纠正。

语法

要找到凸包,我们使用以下函数 -

hull = cv2.convexHull(cnt, hull, clock, returnPoints)

参数

  • cnt 是轮廓点。它表示为轮廓点数组。

  • hull 是输出,通常我们会避免使用它。

  • chronological − 方向标志。如果为 True,则输出凸包为顺时针方向,否则为逆时针方向。

  • returnPoints − 默认设置为 True。

输出 − 当 returnPoints 设置为 True 时,它​​会返回 hull 点的坐标。如果设置为 False,则返回对应于船体点的轮廓点的索引。

因此,要获得凸包,我们通常使用以下函数 -

hull = cv2.convexHull(cnt)

要绘制船体点的轮廓,请使用此函数 -

cv2.drawContours(img, [hull], -1, (0,255,255), 3)

步骤

您可以使用以下步骤查找和绘制图像轮廓的凸包 -

导入所需的库。在以下所有 Python 示例中,所需的 Python 库都是 OpenCV。确保您已经安装了它。

import cv2

使用 cv2.imread() 读取输入图像并将其转换为灰度。

img = cv2.imread('shape.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

对灰度图像应用阈值以创建二值图像。

ret,thresh = cv2.threshold(gray,150,255,0)

使用 cv2.findContours() 函数查找图像中的轮廓。

contours, _ = cv2.findContours(thresh, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

选择一个轮廓cnt或循环遍历所有轮廓。使用 cv2.convexHull(cnt) 函数查找轮廓 cnt 的凸包。

cnt = contours[0]
hull = cv2.convexHull(cnt)

在输入图像上绘制凸包,并将 hull 点传递给以下函数。

cv2.drawContours(img, [hull], -1, (0,255,255), 3)

显示绘制了凸包的图像。

cv2.imshow("Convex Hull", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

让我们看一些例子以便更好地理解。

示例 1

在下面的 Python 程序中,我们检测图像中的轮廓并找到第一个轮廓的凸包。我们还在图像上绘制了第一个轮廓和凸包。

# import required libraries import cv2 # load the input image img = cv2.imread('six-point-star.png') # convert the input image to grayscale gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # apply thresholding to convert grayscale to binary image ret,thresh = cv2.threshold(img1,150,255,0) # find the contours contours,hierarchy = cv2.findContours(thresh, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) print("Number of contours detected:", len(contours)) # select the first contour cnt = contours[0] # find the convex hull using the contour hull = cv2.convexHull(cnt) # draw contour and convex hull on the input image img = cv2.drawContours(img,[cnt],0,(255,0,0),2) img = cv2.drawContours(img,[hull],0,(0,255,255),3) # display the image with drawn contour and convex hull cv2.imshow("Convex Hull", img) cv2.waitKey(0) cv2.destroyAllWindows()

我们将使用以下图像作为上述程序代码中的输入文件

输出

执行上述代码时,将产生以下输出

Number of contours detected: 1

我们得到以下输出窗口,显示图像中第一个检测到的轮廓和凸包−

轮廓用蓝色绘制,凸包用黄色绘制。注意轮廓和凸包之间的区别。

示例 2

在此示例中,我们检测图像中的轮廓并找到所有轮廓的凸包。我们还在图像上绘制了所有轮廓和凸包。

import cv2 img = cv2.imread('convexhull.png') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret,thresh = cv2.threshold(gray,100,255,0) contours,hierarchy = cv2.findContours(thresh, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) print("Number of contours detected:", len(contours)) # Find the convex hull for all the contours for cnt in contours: hull = cv2.convexHull(cnt) img = cv2.drawContours(img,[cnt],0,(0,255,0),2) img = cv2.drawContours(img,[hull],0,(0,0,255),3) # Display the image with convex hull drawn on it cv2.imshow("Convex Hull", img) cv2.waitKey(0) cv2.destroyAllWindows()

我们将在此程序中使用此图像作为输入文件 -

输出

执行上述代码时,将产生以下输出-

Number of contours detected: 3

我们得到以下输出窗口,显示图像中检测到的轮廓和凸包-

凸包显示在红色表示轮廓,绿色表示轮廓。注意轮廓和凸包之间的区别。


相关文章