【OpenCV】图像边缘检测学习

#来自学渣的问候~

这个是我在用Python学OpenCV的时候,对一张图片进行边缘检测时,遇到的情况和解决的学习过程。
因为我在思考这个东西的时候,感觉这个学习的过程很有趣,所以在这里叙述一下,和大家分享。如有错误,请指正,感激不尽!

第一次学Python,环境用的是anaconda。
边缘检测目前学了两种方法,一个是直接调用OpenCV的Canny函数,另一个是利用Sobel Lapalce 算子,来实现图像的边缘检测。
使用的图像是这个(仅供学习使用,侵删)
在这里插入图片描述

导入图片信息

import cv2
import numpy as np
import random
img = cv2.imread('image0.jpg',1)
imgInfo = img.shape
height,width,_  = imgInfo	#下划线是一个占位符,因为imgInfo返回三个数,第三个刚好用不到,也不想耗费变量去接收,就用下划线给空掉

灰度转换

这里用的也是现成的函数cv2.cvtColor(img, cv2.COLOR_BGR2GRAY),img 是图片信息,后面的是转换成的格式。

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)   #得到灰度图像

高斯滤波

这里用opencv 自带的函数,来进行滤波。

imgG = cv2.GaussianBlur(gray,(3,3),0)   #高斯滤波
cv2.imshow('imgG',imgG)

滤波前后的图像如下(左边是滤波前的灰度图,右边是滤波后的):
左边是滤波前的灰度图,右边是滤波后的

我一开始学这个高斯滤波的时候,感觉很奇怪,这和我学信号滤波有点不太一样。一般来说,信号中有噪音而需要滤波。滤波后的信号相比滤波前的信号会更清晰(以音频为例)。我把这个感觉带入到图片滤波,发现这个效果是反着来的,高斯滤波后的图像比原图看起来更糊了。
后来我查了一下,高斯滤波本来就是用来对图片进行模糊处理的,但是很奇怪的是,经过滤波后的图片在边缘检测上的线条更加清晰。

边缘检测

dst = cv2.Canny(imgG,100,90)    #边缘检测
cv2.imshow('dst1',dst)

左边未滤波的边缘检测,右边滤波后的边缘检测。(代码里我只给了一种代码,这里图像是分开的,方便讲解)在这里插入图片描述
从这个图里,能够明显的看出,经过了高斯滤波之后的图像,边缘特性更加明显。但是,造成这样的理由是什么呢?我查阅了一下,图像噪声这个概念。

图像噪声是指存在于图像数据中的不必要的或多余的干扰信息。各类图像处理系统在图像的采集、获取、传送和转换(如成像、复制扫描、传输以及显示等)过程中,均处在复杂的环境中,光照、电磁多变,所有的图像均不同程度地被可见或不可见的噪声干扰,导致图像质量的下降,掩盖图片重要细节

图片其实是由很多个像素点组成的,而每个像素点,其实表示的就是图像的二维数组中的地址,灰度值。而在图像的生成过程中,由于不可控因素(可以理解为是数字器件产生的随机误差或者噪音),会造成临近灰度值所形成的函数的导数过大——也就是噪声,让其与真实颜色产生误差,掩盖图片细节,之后的各种后期图像处理便会不断放大这种误差。
而滤波则是对图片预处理时消除噪音的一种重要方式。
这个博客有讲到高斯滤波,高斯滤波

简单边缘检测的代码(OpenCV)

#边缘检测 图像的卷积运算 
import cv2
import numpy as np
import random
img = cv2.imread('image0.jpg')
imgInfo = img.shape
height,width,_  = imgInfo
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)    #灰度图
cv2.imshow('gray',gray)
imgG = cv2.GaussianBlur(gray,(3,3),0)    #高斯滤波
cv2.imshow('imgG',imgG)
dst = cv2.Canny(imgG,100,90)    #边缘检测
cv2.imshow('dst0',dst)
cv2.waitKey(0)

一个简单的图像边缘检测就OK了!
~~ 这是一条没有什么存在感的分割线~~

前期题要:我和我的好姐妹都在学习open CV,所以我俩一脸懵逼的讨论了一下怎么优化这个边缘检测后的图像。由于对去噪原理一知半解,除了滤波之外,想了一个对图像显示的边缘线条进行去毛刺的办法。

图片膨胀

图片膨胀和图像反转写在一份代码里面了,线条黑色更加容易体现图像效果。

dst = cv2.dilate(dst,(400,500),iterations=1)  #图片膨胀
cv2.imshow('dst',dst)
dstc  = np.zeros((height,width,1),np.uint8)    #图像反转
for i in range(0,height):
    for j in range(0,width):
        gra = dst[i,j]
        dstc[i,j] = 255-gra
 cv2.imshow('src1',dstc)      

这个是图片膨胀前后的对比,可以发现,白色的线条更清晰了。关于图片膨胀的原理 和函数使用,可以查看这篇博客:博客园
在这里插入图片描述
关于cv2.deliate这个的用法,参考:

cv2.dilate(src, kernel, iteration)
参数说明: src表示输入的图片, kernel表示方框的大小, iteration表示迭代的次数
膨胀操作原理:存在一个kernel,在图像上进行从左到右,从上到下的平移,如果方框中存在白色,那么这个方框内所有的颜色都是白色

图像反转后的效果是这样的
在这里插入图片描述
非常漂亮的线稿图,经过了高斯滤波和图像膨胀。

//////////

发布了21 篇原创文章 · 获赞 26 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Ninquelote/article/details/105104649