教你如何使用 OpenCV检测图像中的轮廓
Posted 刘润森!
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了教你如何使用 OpenCV检测图像中的轮廓相关的知识,希望对你有一定的参考价值。
@Author:Runsen
轮廓是连接所有具有某种颜色或强度的连续点的闭合曲线,它们代表图像中发现的对象的形状。轮廓检测是一种用于形状分析和物体检测和识别的有用技术。
轮廓检测并不是图像分割的唯一算法,还有很多其他算法,例如当前最先进的语义分割、霍夫变换和K-Means 分割。
为了获得更好的准确性,以下是检测图像中轮廓的整个流程:
- 将图像转换为二值图像,通常的做法是将输入图像变为二值图像(应该是阈值图像或边缘检测的结果)。
- 使用findContours() OpenCV函数查找轮廓。
- 绘制这些轮廓并显示图像。
import cv2
import matplotlib.pyplot as plt
在这里,选择的图片如下所示。
`
image = cv2.imread("image.jpg")
将其转换为RGB,然后灰度:
# convert to RGB
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# convert to grayscale
gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
plt.imshow(gray, cmap="gray")
plt.show()
下一步,我们需要创建一个二值图像,这意味着图像的每个像素都是黑色或白色。这在OpenCV 中是必要的,找轮廓就像从黑色背景中找白色物体,要找的物体应该是白色的,背景应该是黑色的。
_, binary = cv2.threshold(gray, 225, 255, cv2.THRESH_BINARY_INV)
函数为cv2.threshold()
这个函数有四个参数,第一个原图像,第二个进行分类的阈值,第三个是高于(低于)阈值时赋予的新值,第四个是一个方法选择参数,常用的有:
- cv2.THRESH_BINARY(黑白二值)
- cv2.THRESH_BINARY_INV(黑白二值反转)
- cv2.THRESH_TRUNC (得到的图像为多像素值)
- cv2.THRESH_TOZERO
- cv2.THRESH_TOZERO_INV
上面的代码建立通过设置为二进制图像0,其具有小于一值的像素225和接通(设定为255),其具有大于一个值的像素225,这里是输出图像:
现在这对于OpenCV来说很容易检测轮廓:
# 从阈值图像中提取的轮廓
contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 绘制所有轮廓 第三个参数定绘制轮廓list中的哪条轮廓,如果是-1,则绘制其中的所有轮廓
image = cv2.drawContours(image, contours, -1, (0, 255, 0), 2)
上面的代码在二值图像中找到轮廓,并用粗绿线将它们绘制到图像上,让我们展示一下:
plt.imshow(image)
plt.show()
在 OpenCV检测图像中的轮廓关键是阈值的确定,在一般的计算机视觉中中设置为255 // 2,
。
下面使用cv2.VideoCapture
的方法调用摄像头,检测图像中的轮廓。
import cv2
cap = cv2.VideoCapture(0)
while True:
_, frame = cap.read()
# 灰度
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 阈值
_, binary = cv2.threshold(gray, 255 // 2, 255, cv2.THRESH_BINARY_INV)
# 提取的轮廓
contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 画轮廓
image = cv2.drawContours(frame, contours, -1, (0, 255, 0), 2)
# 展示
cv2.imshow("gray", gray)
cv2.imshow("image", image)
cv2.imshow("binary", binary)
if cv2.waitKey(1) == ord("q"):
break
cap.release()
cv2.destroyAllWindows()
以上是关于教你如何使用 OpenCV检测图像中的轮廓的主要内容,如果未能解决你的问题,请参考以下文章
youcans 的 OpenCV 例程200篇195.绘制图像轮廓(cv.drawContours)