image = cv2.imread(pic)
opencv读image,读出来是BRG
gray = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
将BGR转换为RGB
gray = cv2.GaussianBlur(gray, (11, 11), 0)
高斯模糊,(11, 11)是ksize高斯内核大小。内核越大模糊效果越好,越平滑,越可以把不需要的边缘去除,也就是去噪。 ksize.width和ksize.height可以不同,但它们都必须为正数和奇数,也可以为零,然后根据sigma计算得出。
edged = cv2.Canny(gray, 50, 300)
- 应用双阈值确定边缘
完成上述步骤后,图像内的强边缘已经在当前获取的边缘图像内。但是,一些虚边缘可能也在边缘图像内。这些虚边缘可能是真实图像产生的,也可能是由于噪声所产生的。对于后者,必须将其剔除。
设置两个阈值,其中一个为高阈值 maxVal,另一个为低阈值 minVal。根据当前边缘像素的梯度值(指的是梯度幅度,下同)与这两个阈值之间的关系,判断边缘的属性。具体步骤为:
(1)如果当前边缘像素的梯度值大于或等于 maxVal,则将当前边缘像素标记为强边缘。
(2)如果当前边缘像素的梯度值介于 maxVal 与 minVal 之间,则将当前边缘像素标记为虚
边缘(需要保留)。
(3)如果当前边缘像素的梯度值小于或等于 minVal,则抑制当前边缘像素。
在上述过程中,我们得到了虚边缘,需要对其做进一步处理。一般通过判断虚边缘与强边缘是否连接,来确定虚边缘到底属于哪种情况。通常情况下,如果一个虚边缘:
- 与强边缘连接,则将该边缘处理为边缘。
- 与强边缘无连接,则该边缘为弱边缘,将其抑制。
r1=cv2.Canny(o,128,200)的效果如下
r2=cv2.Canny(o,32,128)的效果 如下
在我们的案例中,应将max阈值放大,以过滤掉不需要的边缘。
edged = cv2.dilate(edged, None, iterations=1) edged = cv2.erode(edged, None, iterations=1)
开操作,闭操作,在我们的案例中,好像就是把边缘变细了一点。
cnts, heir = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
寻边
img = cv2.drawContours(b, cnts, -1, (193,182,255), 2)
画出来
for c in cnts: (x, y, w, h) = cv2.boundingRect(c) cv2.rectangle(b, (x, y), (x + w, y + h), (0, 255, 0), 2)
根据边缘画个框