OpenCV 查找轮廓

Ammar Ali 2022年5月17日
OpenCV 查找轮廓

本教程将讨论使用 Python 中 OpenCV 的 findContours() 函数查找图像中存在的轮廓。

在 Python 中使用 OpenCV 的 findContours() 函数查找图像中的轮廓

轮廓是通过将点与对象的边界连接起来形成的曲线。在图像中,存在多个对象,并且找到图像的轮廓,我们可以获得有关对象形状的信息,因为轮廓会突出图像中存在的对象的边界。

如果我们知道物体的形状,我们可以很容易地猜出图像中存在哪些物体。轮廓广泛用于分析形状以及检测和识别物体。

我们可以使用 OpenCV 的 findContours() 函数来查找图像中存在的轮廓。我们必须使用二值图像来找到轮廓以获得更好的精度。

如果给定的图像不是二进制的,我们可以将其转换为二进制。例如,在彩色图像的情况下,我们必须使用 OpenCV 的 cvtColor() 函数将图像转换为灰度。

我们可以使用 OpenCV 的 threshold() 函数中的灰度图像来找到二值图像。之后,我们可以使用 findContours() 函数和二值图像来查找轮廓。

如果我们想显示轮廓,我们必须创建一个绘图并使用 drawContours() 函数绘制轮廓。绘图应与给定图像大小相同,以更好地可视化轮廓。

我们可以使用 numpy 库的 zeros() 函数创建与给定图像相同大小的黑色绘图。

例如,让我们使用 imread() 函数读取图像,将其转换为二进制比例,然后找到轮廓并显示它们。请参阅下面的代码。

import cv2 
import numpy as np 

image =cv2.imread('cat.jpg')
cv2.imshow('Original Image',image)

gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
cv2.imshow('Gray Image',gray)

_,binary = cv2.threshold(gray,100,255,cv2.THRESH_BINARY)
cv2.imshow('Binary image',binary)

contours,hierarchy = cv2.findContours(binary,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
drawing = np.zeros((gray.shape[0], gray.shape[1], 3), dtype=np.uint8)
CountersImg = cv2.drawContours(drawing,contours, -1, (255,255,0),3)
cv2.imshow('Contours',CountersImg)
cv2.waitKey(0)

输出:

使用 opencv 查找轮廓

findContours() 函数返回两个输出参数。第一个输出参数包含轮廓的位置点和列表中的坐标。第二个输出参数包含轮廓的层次结构。

findContours() 函数的第一个输入是二进制或灰度图像。第二个输入参数是用于定义轮廓层次结构的检索模式。

我们可以在检索模式中传递不同的值,例如 cv2.RETR_LIST 检索所有轮廓,cv2.RETR_EXTERNAL 仅检索外部计数器,cv2.RETR_COMP 检索 2 级层次结构中的轮廓,以及 cv2.RETR_TREE 检索完整层次结构中的轮廓。findContours() 函数的第三个输入参数是用于存储边界点的近似方法。

cv2.CHAIN_APPROX_NONE 方法存储所有边界点,但有时我们不需要所有边界点。我们可以使用 cv2.CHAIN_APPROX_SIMPLE 方法来存储起点和终点轮廓。

我们还可以定义一个偏移量,它将根据 findContours() 函数中的偏移量移动每个轮廓。我们还可以使用 OpenCV 的 drawContours() 函数在给定图像上显示轮廓。

drawContours() 函数的第一个参数是我们要绘制轮廓的图像。第二个参数是轮廓,第三个是轮廓索引。

第三个参数是轮廓的颜色,可以定义为 RGB 三元组。第四个参数是轮廓的厚度,可以定义为整数。

例如,让我们在给定图像的顶部显示轮廓。请参阅下面的代码。

import cv2 
import numpy as np 

image =cv2.imread('cat.jpg')
cv2.imshow('Original Image',image)

gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
cv2.imshow('Gray Image',gray)

_,binary = cv2.threshold(gray,100,255,cv2.THRESH_BINARY)
cv2.imshow('Binary image',binary)

contours,hierarchy = cv2.findContours(binary,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
drawing = np.zeros((gray.shape[0], gray.shape[1], 3), dtype=np.uint8)
CountersImg = cv2.drawContours(drawing,contours, -1, (255,255,0),3)
cv2.imshow('Contours',CountersImg)
ImgWithCounter = cv2.drawContours(image,contours, -1, (255,255,0),3)
cv2.imshow('Image with counters',ImgWithCounter)
cv2.waitKey(0)

输出:

图像顶部的轮廓

Author: Ammar Ali
Ammar Ali avatar Ammar Ali avatar

Hello! I am Ammar Ali, a programmer here to learn from experience, people, and docs, and create interesting and useful programming content. I mostly create content about Python, Matlab, and Microcontrollers like Arduino and PIC.

LinkedIn Facebook

相关文章 - Python OpenCV