matlab二值图像轮廓坐标_OpenCV轮廓识别

这篇博客介绍了如何使用OpenCV的findContours函数来查找和处理MATLAB二值图像中的轮廓。通过设置不同的模式和方法参数,可以提取图像的外部轮廓、所有轮廓及其层级关系。在代码示例中,作者展示了从原始图像进行二值化处理,然后在黑色背景上绘制轮廓,并获取轮廓的关键点和外框的过程,帮助读者理解轮廓识别的步骤。
摘要由CSDN通过智能技术生成

OpenCV主要通过findContours()函数来查找检测物体的轮廓,返回轮廓线上所有的像素点坐标,多个轮廓的序号、层级关系。

def findContours(image: Any,                 mode: Any,                 method: Any,                 contours: Any = None,                 hierarchy: Any = None,                 offset: Any = None) -> None

参数解释:

image:输入的图像,单通道二值图像,可以使用compare,  inRange,  threshold ,  adaptiveThreshold,  Canny等函数创建得到。

mode:cv.RETR_EXTERNAL只识别外部轮廓;cv.RETR_LIST识别所有轮廓不记录层级关系;cv.RETR_TREE识别轮廓及树形的层级关系;cv.RETR_CCOMP检测所有轮廓,但所有轮廓都只建立两个等级关系。

method:cv.CV_CHAIN_APPROX_NONE 边界上所有连续的轮廓点; cv.CHAIN_APPROX_SIMPLE仅保存轮廓的拐点信;息 cv.CHAIN_APPROX_TC89_L1一种算法 cv.CHAIN_APPROX_TC89_KCOS另一种算法

写程序演示下,原始图片如下:

8472049c66fd792c103bac4089feced6.png

首先打开图片,进行二值化处理:

import cv2 as cvimg = cv.imread("resouse/contour1.png")imgGray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)  # 转成灰度图imgBlur = cv.GaussianBlur(imgGray, (3, 3), 1)  # 高斯降噪imgCanny = cv.Canny(imgBlur, 50, 50)  # 转成二值轮廓图像#  #  后续代码会添加到这一位置#cv.imshow("Original", img)  # 显示原始图像cv.imshow("Gray", imgGray)  # 显示灰度图cv.imshow("Canny", imgCanny)  # 显示二值图cv.waitKey(0)

357f4e836e50c3776f26154d54e23b47.png

145f1f3751621d5b9255b3f09f583720.png

c4cc17006941029d99cd585607f654b0.png

抽取轮廓之前,我们先准备一个绘画轮廓的黑板,用来显示我们抽取的轮廓:

imgContour = img.copy()imgContour[:, :, :] = 0  # 置成黑背景(使用了numpy切片操作

正式获取轮廓:

contours, hierarchy = cv.findContours(imgCanny,                              cv.RETR_EXTERNAL,                              cv.CHAIN_APPROX_NONE)

返回的hierarchy用来描述轮廓的拓扑,每个轮廓返回一个,是个四元组,分别表示[Next, Previous, First_Child, Parent] 即下一个轮廓编号,前一个轮廓编号,第一个子轮廓,父轮廓。

显示下相关信息:

for cnt,hier in zip(contours,hierarchy[0]):    print("==================")    area = cv.contourArea(cnt)  # 轮廓面积    print("hierarchy:", hier,           "\nfirst pixel: ", cnt[:1],           "\npixel nu: ", len(cnt),           "\narea: ", area)    # 以后代码默认处于此for循环中

1b9fc4937f945a729f99100df58abd6d.png

在我们制作的幕布上绘制轮廓:

for cnt,hier in zip(contours,hierarchy[0]):    # ...other codes...    cv.drawContours(imgContour, cnt, -1, (0, 0, 252), 1)  # 绘制轮廓    # ...other codes...cv.imshow("Contour",imgContour) 

385e7ca6c38d469420607cd3dccbb93a.png

获取轮廓的关键点,可以通过点的数量位置来判断是什么形状:

 for cnt,hier in zip(contours,hierarchy[0]):    # ...other codes...    perimeter = cv.arcLength(cnt, True) # 轮廓周长    approx = cv.approxPolyDP(cnt, 0.01 * perimeter, True)  # 近似多边形,道格拉斯皮克算法 approximate polygon Douglas-Peucker    print('spot nu:', len(approx))    cv.drawContours(imgContour, approx, -1, (0, 255, 0), 6)  # 绘制关键点    # ...other codes...cv.imshow("Contour",imgContour)

09c2599d7a5590398220e0c549430d15.png

获取轮廓的外框:

 for cnt,hier in zip(contours,hierarchy[0]):    # ...other codes...    x, y, w, h = cv.boundingRect(approx)  # 获取点集的边界矩形    # x,y,w,h分别是矩形坐标点和宽度高度    cv.rectangle(imgContour, (x, y), (x + w, y + h), (224, 0, 0), 1)  # 绘制矩形     # ...other codes...cv.imshow("Contour",imgContour)

cc7c743b92cc7ee9cb85b6cf0fbddd21.png

以下是完整的代码:

import cv2 as cvimg = cv.imread("resouse/contour1.png")imgGray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)imgBlur = cv.GaussianBlur(imgGray, (3, 3), 1)  # 高斯降噪imgCanny = cv.Canny(imgBlur, 50, 50)cv.imshow("Original", img)cv.imshow("Gray", imgGray)cv.imshow("Blur", imgBlur)cv.imshow("Canny", imgCanny)imgContour = img.copy()imgContour[:, :, :] = 0  # 置成黑背景print(imgContour.shape)contours, hierarchy = cv.findContours(imgCanny, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_NONE) # 发现形状#print(contours)print(hierarchy)for cnt,hier in zip(contours,hierarchy[0]):    print("==================")    area = cv.contourArea(cnt)  # 轮廓面积    print("hierarchy:", hier, "\nfirst pixel: ", cnt[:1], "\npixel nu: ", len(cnt), "\narea: ", area)        # 绘制轮廓    cv.drawContours(imgContour, cnt, -1, (0, 0, 252), 1)          # 获取关键点    perimeter = cv.arcLength(cnt, True) # 轮廓周长    approx = cv.approxPolyDP(cnt, 0.02 * perimeter, True)  # 近似多边形,道格拉斯皮克算法 approximate polygon Douglas-Peucker    print('spot nu:', len(approx))    cv.drawContours(imgContour, approx, -1, (0, 255, 0), 6)  # 绘制轮廓        # 获取轮廓边框    x, y, w, h = cv.boundingRect(approx)  # 获取点集的边界矩形    cv.rectangle(imgContour, (x, y), (x + w, y + h), (224, 0, 0), 1)  # 绘制矩形cv.imshow("Contour",imgContour)cv.waitKey(0)cv.destroyAllWindows()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值