边缘检测、边界框、最小矩形区域和最小闭圆的轮廓

准备

下面的所有示例使用图片均为如下:
在这里插入图片描述

所有绘图函数都会修改源图像


边缘检测

OpenCV提供了许多边缘检测滤波函数,包括Laplacian()Sobel()以及Scharr()。这些滤波函数都会将非边缘区域转化为黑色,边缘区域转化为白色或其他饱和的颜色(故在进行滤波画线过后需要进行归一化处理,将边缘部分编程黑色,然后使用卷积核进行卷积寻找边缘)。但是,这些函数都很容易将噪声错误的识别为边缘。缓解这个问题的方法是在找到边缘前对图像进行模糊处理(降噪)。OpenCV也提供了许多用于模糊滤波函数,包括blur()(简单的算术平均)、medianBlur()(中位值模糊)以及GaussianBlur()(高斯模糊)。边缘检测和模糊处理都有很多参数,但是他们都有一个Ksize参数,为奇数,表示滤波核的宽高。

降噪

不管什么信号,或多或少都会引入噪声,噪声为小部分,但是全部都用均值降噪 势必会造成图像模糊,只要是噪声处理都会或多或少的造成模糊问题,中值滤波是使用选取中位置的方法进行滤波,如果噪声是椒盐噪声(只有黑白二值),那么中值滤波就可以达到很好的效果,因为噪声一般都处于两极,使用中值滤波可以很好的达到降噪的目的,但是如果是高斯噪声分布(正态分布),这个时候使用均值滤波的效果会更好

边缘检测过程:

  1. 先进行模糊处理进行降噪
  2. 将图像转化为灰度图
  3. 使用边缘检测滤波函数将边缘转化为白色或其他饱和颜色,非边缘转化为黑色
  4. 在进行归一化处理,然后乘以源图像使原图像边缘部分变黑
  5. 使用边缘检测卷积核进行卷积,产生白色边缘
卷积核

OpenCV定义的许多滤波函数都会使用核。核可以看作一组权重,他决定如何通过邻近的点来计算新的像素点。核也可以称为卷积矩阵。卷积矩阵有奇数行、奇数列,感兴趣的像素对应于最中间个元素,其他元素对应于周围其他邻近的像素点,有如下核:

	kernel=numpy.array([[-1,-1,-1],
	                    [-1,9,-1],
	                    [-1,-1,-1]
	                            ])

其中感兴趣的像素点的权重为9,周围为0,对感兴趣的像素点*9减去8个相邻的像素点,如果卷积之前,感兴趣的像素点与周围存在差异,经过卷积核处理过后差距会越来越来,就可以达到锐化的效果了

不同的核可以达到不同的有趣的效果,如权重和为0的卷积核可以达到检测边缘的目的。

卷积过程:

在这里插入图片描述

可以预先定义一些常用的卷积核备用

卷积方法

OpenCV使用filter2D()方法对图像与核做卷积矩阵

cv2.filter2D(src,-1,kernel,dst)

第一个参数为源图像,第二个参数指定目标图像每个通道的位深度(如,位深度cv2.CV_8U 表示每个通道8位),如果为-1表示与源图像相同,第三个参数为使用的卷积核,最后一个参数为指向的目标图像。

对其做如下操作(需先使用边缘检测处理在做如下操作):

	import  numpy as np
	import  cv2
	image=cv2.imread('hello.jpg')
	kernel=np.array([[-1,-1,-1],
	                 [-1,8,-1],
	                 [-1,-1,-1]
	                 ])
	cv2.filter2D(image,-1,kernel,image)
	cv2.imshow('findEdge',image)
	cv2.waitKey()
	cv2.destroyAllWindows()

结果:
在这里插入图片描述

Canny边缘检测

OpenCV还提供了一个非常方便的Canny函数(以算法发明人命名)进行边缘检测

	#使用双阈值去除假阳性
	cv2.Canny( image, edges, threshold1,threshold2, aperture_size=3 );	

轮廓检测

主要使用OpenCV中的阈值处理函数(cv2.threshold)和查找轮廓函数(cv2.findContours)

在对图像查找轮廓之前必须对图像进行二值化处理(转化为只有黑白二值),使用threshold 函数处理

img=cv2.imread('hello.jpg',cv2.IMREAD_UNCHANGED)
# 转化为贵都图像
grayImage=cv2.cvtColor(img.copy(),cv2.COLOR_BGR2GRAY)
# 黑白二值 大于127 的变为255,最后一个参数为转化为黑白二值
# 返回阈值,二值处理后的图像
ret,thread=cv2.threshold(grayImage,127,255,cv2.THRESH_BINARY)
# 寻找轮廓,第二个参数代表检测外轮廓,第三个参数指定使用的算法
# 返回值 轮廓,层级
# 层级代表各轮廓之间的关系
contours,hier=cv2.findContours(thread,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
for c in contours:
    # 寻找边界矩形
    x,y,w,h=cv2.boundingRect(c)
    cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0))

    #最小矩形轮廓
    rect=cv2.minAreaRect(c)
    box=cv2.boxPoints(rect)
    box=np.int0(box)
    cv2.drawContours(img,[box],0,(0,0,255),1)

    #最小圆形轮廓
    (x,y),radius=cv2.minEnclosingCircle(c)
    center=(int(x),int(y))
    radius=int(radius)
    cv2.circle(img,center,radius,(255,0,0),1)


# 画轮廓 在img上  第三个参数为-1代表画所有轮廓,其余值代表相应的轮廓
# 第三个值为轮廓颜色 本例子中使用了绿色
# 第四个参数代表画轮廓的线宽
cv2.drawContours(img,contours,-1,(255,255,0))
cv2.imshow('findEdge',img)
cv2.waitKey()
cv2.destroyAllWindows()

结果:
在这里插入图片描述
说明:
蓝色:最小闭圆轮廓
绿色:边界矩形
红色:最小矩形轮廓
浅蓝色:轮廓

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值