轮廓检测和边缘检测的区别
轮廓检测的目标是确定闭合物体的形状,特别是因为对于具有相同颜色强度的连续点,寻找轮廓的方法是确定的,而边缘检测是通过检测颜色强度内的变化来进行的。对整个图像进行边缘检测,而仅对图像内的对象进行轮廓检测。
边缘检测
边缘检测是一种用于定位图像中对象边界的图像处理技术。它是图像处理、图像模式识别和计算机视觉技术的基本步骤之一。边缘检测最流行和广泛使用的算法之一是 Canny 边缘检测器。Canny 边缘检测器是一种立足点检测算子,它使用多阶段算法来检测图像中的各种边缘。其步骤如下:
-
使用高斯模糊算法,过滤掉图像。
-
在 Sobel 滤波器的帮助下,找出边缘的强度和方向。
-
通过应用非极大值抑制来隔离更强的边缘并将它们细化为一条像素宽的线。
-
使用滞后来隔离最简单的边缘。
首先,安装依赖库,例如opencv等
pip3 install opencv-python matplotlib numpy
打开一个 编译器,导入使用到的库
import cv2
import numpy as np
import matplotlib.pyplot as plt
现在为了检测它的边缘,我们必须读取图像
# read the image
image = cv2.imread("little_flower.jpg")
将图像转换为灰度
# convert it to grayscale
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# show the grayscale image
plt.imshow(gray, cmap="gray")
plt.show()
然后,将图像输入图像首先传递给 cv2.Canny() 函数,然后用于边缘检测。
# perform the canny edge detector to detect image edges
edges = cv2.Canny(gray, threshold1=30, threshold2=100)
其中阈值 1(threshold1) 和阈值 2 (threshold2) 之间的最小值用于边缘链接。最重要的值用于寻找强边缘的初始段。可以尝试微调边缘值,看看你是否会让它变得更好。
如果使用实时摄像头,这里是完整的代码:
import NumPy as np
import cv2
cap = cv2.VideoCapture(0)
while True:
_, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 30, 100)
cv2.imshow("edges", edges)
cv2.imshow("gray", gray)
if cv2.waitKey(1) == ord("q"):
break
cap.release()
cv2.destroyAllWindows()
轮廓检测
一个轮廓可以描述为一条曲线,将所有具有相同颜色或强度的连续点组合在一起。基本上,它们显示图片中包含的对象的形状。轮廓检测可能是一种用于形状分析和对象检测和识别的有用技术。
(轮廓检测并不是图像分割的唯一算法,还有很多其他算法,例如目前最先进的语义分割、霍夫变换和 K-Means 分割。)
下面是检测图像中的轮廓的整个流程:
-
输入图像的标准化是它应该始终是二进制形式。这就是为什么我们需要将其转换为二进制格式。
-
用于查找轮廓的 OpenCV 函数是 findContours()。
-
最后,我们必须绘制这些轮廓来显示图像。
首先,安装依赖库,例如opencv等
pip3 install matplotlib opencv-python
打开一个 编译器,导入使用到的库
import cv2
import matplotlib.pyplot as plt
读取图像
# read the image
image = cv2.imread("little_flower.jpg")
将图像转换RGB后转换为为灰度
# convert to RGB
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# convert to grayscale
gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
转换为二值图像,这表明图像的每个像素要么是黑色的,要么是白色的。以下是输出图像:
# create a binary thresholded image
_, binary = cv2.threshold(gray, 225, 255, cv2.THRESH_BINARY_INV)
# show it
plt.imshow(binary, cmap="gray")
plt.show()
现在,对于 OpenCV 来说,这通常很容易检测轮廓:
# find the contours from the thresholded image
contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# draw all contours
image = cv2.drawContours(image, contours, -1, (0, 255, 0), 2)
# show the image with the drawn contours
plt.imshow(image)
plt.show()
为了在不同的世界图像上获得良好的结果,你需要调整阈值或执行边缘检测。例如,对于煎饼图像,将边缘减少到 127,结果如下