教你如何使用 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检测图像中的轮廓的主要内容,如果未能解决你的问题,请参考以下文章

利用OpenCV进行图像的轮廓检测

图像轮廓检测错误:OpenCV、C++

Python-OpenCV中的图像轮廓检测

youcans 的 OpenCV 例程200篇195.绘制图像轮廓(cv.drawContours)

youcans 的 OpenCV 例程200篇195.绘制图像轮廓(cv.drawContours)

youcans 的 OpenCV 例程200篇194.寻找图像轮廓(cv.findContours)