图像处理之图像的边缘、轮廓检测

来源:互联网 发布:淘宝固本安宫止血汤 编辑:程序博客网 时间:2024/05/16 09:11

图像的边缘、轮廓检测在人类视觉和计算机视觉中均起着重要的作用。人类能够仅凭一张背景剪影或一张草图就能识别出物体的类型和姿态。OpenCV提供了许多边缘检测l滤波函数,包括Laplacian( )、Sobel()以及Scharr()。这些函数都能将边缘转化为白色或其他饱和的颜色,将非边缘转化为黑色,但是,这些函数不能有效的区分噪声错误的判断为边缘。解决这个问题的办法是对图像进行模糊处理。这里介绍一种很方便却很实用的函数——Canny边缘检测。

Canny函数中包含两个阈值这也是与其他边缘检测函数不同的地方。阈值是来确定哪里是边缘位置。阈值越低,能够检测出的边线越多,结果也就越容易受到图片噪声的影响,并且越容易从图像中挑出不相关的特性。与此相反,一个高的阈值将会遗失细的或者短的线段。因此,Canny函数中要设置两个阈值是有不同用处的。高的那个阈值是将要提取轮廓的物体与背景区分开来,就像阈值分割的那个参数一样,是决定目标与背景对比度的,低的那个阈值是用来平滑边缘的轮廓,有时高的阈值设置太大了,可能边缘轮廓不连续或者不够平滑,通过低阈值来平滑轮廓线,或者使不连续的部分连接起来。

import cv2from matplotlib import pyplot as pltimg = cv2.imread("water_coins.jpg", 0)edges = cv2.Canny(img, 200, 300)plt.subplot(1,2,1), plt.imshow(img,cmap = 'gray')plt.title('Original Image'), plt.xticks([]), plt.yticks([])plt.subplot(1,2,2), plt.imshow(edges,cmap = 'gray')plt.title('Edge Image'), plt.xticks([]), plt.yticks([])plt.show()



那么对图像的轮廓检测,先要将图像二值化操作,然后再调用findContours()函数。

import cv2import numpy as npimg = np.zeros((200, 200), dtype=np.uint8)img[50:150, 50:150] = 255# 二值化处理ret, th = cv2.threshold(img, 127, 255, 0)# findcontours()函数。有三个参数:输入图像、层次类型和轮廓逼近方法。# 由函数返回的层次树相当重要:cv2.RETR_TREE参数会得到图像中轮廓的整体层次结构(contours)。如果只想得到最外面的轮廓,可以使用cv2.RETR_EXTERNAL。这对消除包含在其他轮廓中的轮廓很有用。# 第三个参数有两种方法:#cv2.CHAIN_APPROX_NONE存储所有的轮廓点,相邻的两个点的像素位置差不超过1,即max(abs(x1-x2),abs(y2-y1))==1 cv2.CHAIN_APPROX_SIMPLE压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,例如一个矩形轮廓只需4个点来保存轮廓信息cv2.CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法image, contours, hierarchy = cv2.findContours(th, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)# 色彩空间转换函数cv2.cvtColor()color = cv2.cvtColor(img, cv2.COLOR_BAYER_BG2BGR)# 画出轮廓,-1,表示所有轮廓,画笔颜色为(0, 255, 0),即Green,粗细为2img = cv2.drawContours(color, contours, -1, (0, 255, 0), 2)cv2.imwrite("contours.png", color)cv2.waitKey()cv2.destroyAllWindows()


参考:

《OpenCV 3计算机视觉Python语言实现》

  OpenCV帮助文档:http://docs.opencv.org/3.0.0/da/d22/tutorial_py_canny.html