转载链接:
https://www.cnblogs.com/wangxiaocvpr/p/11656589.html
图像简单滤波
对图像进行滤波,可以有两种效果:一种是平滑滤波,用来抑制噪声;另一种是微分算子,可以用来检测边缘和特征提取。
skimage库中通过filters模块进行滤波操作。
1、sobel算子
sobel算子可用来检测边缘
函数格式为:
None
from
![](https://upload-images.jianshu.io/upload_images/1496926-23f180abd14845c1.png)
2、roberts算子
roberts算子和sobel算子一样,用于检测边缘
调用格式也是一样的:
edges = filters.roberts(img)
3、scharr算子
功能同sobel,调用格式:
edges = filters.scharr(img)
4、prewitt算子
功能同sobel,调用格式:
edges = filters.prewitt(img)
5、canny算子
canny算子也是用于提取边缘特征,但它不是放在filters模块,而是放在feature模块
函数格式:
skimage.feature.canny(image,sigma=1.0)
可以修改sigma的值来调整效果
from
![](https://upload-images.jianshu.io/upload_images/1496926-1f09de41f24cd979.png)
从结果可以看出,sigma越小,边缘线条越细小。
6、gabor滤波
gabor滤波可用来进行边缘检测和纹理特征提取。
函数调用格式:
skimage
通过修改frequency值来调整滤波效果,返回一对边缘结果,一个是用真实滤波核的滤波结果,一个是想象的滤波核的滤波结果。
from
![](https://upload-images.jianshu.io/upload_images/1496926-e7f567d078639024.png)
以上为frequency=0.6的结果图。
![](https://upload-images.jianshu.io/upload_images/1496926-8fb5c17ca5c2d91e.png)
以上为frequency=0.1的结果图
7、gaussian滤波
多维的滤波器,是一种平滑滤波,可以消除高斯噪声。
调用函数为:
skimage
通过调节sigma的值来调整滤波效果
from
![](https://upload-images.jianshu.io/upload_images/1496926-61e5a0ec39a07549.png)
可见sigma越大,过滤后的图像越模糊
8.median
中值滤波,一种平滑滤波,可以消除噪声。
需要用skimage.morphology模块来设置滤波器的形状。
from
![](https://upload-images.jianshu.io/upload_images/1496926-7c6360cc12b948db.png)
从结果可以看出,滤波器越大,图像越模糊。
9、水平、垂直边缘检测
上边所举的例子都是进行全部边缘检测,有些时候我们只需要检测水平边缘,或垂直边缘,就可用下面的方法。
水平边缘检测:sobel_h, prewitt_h, scharr_h
垂直边缘检测: sobel_v, prewitt_v, scharr_v
from
![](https://upload-images.jianshu.io/upload_images/1496926-12b529c8b60b05e3.png)
上边左图为检测出的水平边缘,右图为检测出的垂直边缘。
10、交叉边缘检测
可使用Roberts的十字交叉核来进行过滤,以达到检测交叉边缘的目的。这些交叉边缘实际上是梯度在某个方向上的一个分量。
其中一个核:
0 1
-1 0
对应的函数:
roberts_neg_diag(image)
例:
from
![](https://upload-images.jianshu.io/upload_images/1496926-e7ef9cb3bab4679b.png)
另外一个核:
1 0
0 -1
对应函数为:
roberts_pos_diag(image)
from
![](https://upload-images.jianshu.io/upload_images/1496926-6f3beafefd6c5e76.png)
图像自动阈值分割
图像阈值分割是一种广泛应用的分割技术,利用图像中要提取的目标区域与其背景在灰度特性上的差异,把图像看作具有不同灰度级的两类区域(目标区域和背景区域)的组合,选取一个比较合理的阈值,以确定图像中每个像素点应该属于目标区域还是背景区域,从而产生相应的二值图像。
在skimage库中,阈值分割的功能是放在filters模块中。
我们可以手动指定一个阈值,从而来实现分割。也可以让系统自动生成一个阈值,下面几种方法就是用来自动生成阈值。
1、threshold_otsu
基于Otsu的阈值分割方法,函数调用格式:
skimage.filters.threshold_otsu(image, nbins=256)
参数image是指灰度图像,返回一个阈值。
from
返回阈值为87,根据87进行分割得下图:
![](https://upload-images.jianshu.io/upload_images/1496926-af66ed9806c0e08d.png)
2、threshold_yen
使用方法同上:
thresh = filters.threshold_yen(image)
返回阈值为198,分割如下图:
![](https://upload-images.jianshu.io/upload_images/1496926-55275739a35a0ea8.png)
3、threshold_li
使用方法同上:
thresh = filters.threshold_li(image)
返回阈值64.5,分割如下图:
![](https://upload-images.jianshu.io/upload_images/1496926-4e7ca07b119e637e.png)
4、threshold_isodata
阈值计算方法:
=
使用方法同上:
thresh = filters.threshold_isodata(image)
返回阈值为87,因此分割效果和threshold_otsu一样。
5、threshold_adaptive
调用函数为:
'gaussian'
block_size: 块大小,指当前像素的相邻区域大小,一般是奇数(如3,5,7。。。)
method: 用来确定自适应阈值的方法,有'mean', 'generic', 'gaussian' 和 'median'。省略时默认为gaussian
该函数直接访问一个阈值后的图像,而不是阈值。
from
![](https://upload-images.jianshu.io/upload_images/1496926-3cd305f29d757f8f.png)
大家可以修改block_size的大小和method值来查看更多的效果。如:
'mean'
两种效果如下:
![](https://upload-images.jianshu.io/upload_images/1496926-79ac718933fdf237.png)
基本图形的绘制
图形包括线条、圆形、椭圆形、多边形等。
在skimage包中,绘制图形用的是draw模块,不要和绘制图像搞混了。
1、画线条
函数调用格式为:
skimage
r1,r2: 开始点的行数和结束点的行数
c1,c2: 开始点的列数和结束点的列数
返回当前绘制图形上所有点的坐标,如:
rr, cc =draw.line(1, 5, 8, 2)
表示从(1,5)到(8,2)连一条线,返回线上所有的像素点坐标[rr,cc]
from
![](https://upload-images.jianshu.io/upload_images/1496926-bd8a946cc2c44a46.png)
如果想画其它颜色的线条,则可以使用set_color()函数,格式为:
skimage
例:
draw
则绘制红色线条。
from
![](https://upload-images.jianshu.io/upload_images/1496926-62640ef8be96f70a.png)
2、画圆
函数格式:
skimage
cy和cx表示圆心点,radius表示半径
from
![](https://upload-images.jianshu.io/upload_images/1496926-b880dc6b5a176551.png)
3、多边形
函数格式:
skimage
Y为多边形顶点的行集合,X为各顶点的列值集合。
from
![](https://upload-images.jianshu.io/upload_images/1496926-603a454da5d9a33d.png)
我在此处只设置了四个顶点,因此是个四边形。
4、椭圆
格式:
skimage
cy和cx为中心点坐标,yradius和xradius代表长短轴。
from
![](https://upload-images.jianshu.io/upload_images/1496926-8460edbe3f942820.png)
5、贝塞儿曲线
格式:
skimage
y1,x1表示第一个控制点坐标
y2,x2表示第二个控制点坐标
y3,x3表示第三个控制点坐标
weight表示中间控制点的权重,用于控制曲线的弯曲度。
from
![](https://upload-images.jianshu.io/upload_images/1496926-f09378d6d3e8d31f.png)
6、画空心圆
和前面的画圆是一样的,只是前面是实心圆,而此处画空心圆,只有边框线。
格式:
skimage
yx,yc是圆心坐标,radius是半径
from
![](https://upload-images.jianshu.io/upload_images/1496926-de9a2922c803b1d9.png)
7、空心椭圆
格式:
skimage
cy,cx表示圆心
yradius,xradius表示长短轴
from
![](https://upload-images.jianshu.io/upload_images/1496926-e148161105e727f5.png)
基本形态学滤波
对图像进行形态学变换。变换对象一般为灰度图或二值图,功能函数放在morphology子模块内。
1、膨胀(dilation)
原理:一般对二值图像进行操作。找到像素值为1的点,将它的邻近像素点都设置成这个值。1值表示白,0值表示黑,因此膨胀操作可以扩大白色值范围,压缩黑色值范围。一般用来扩充边缘或填充小的孔洞。
功能函数:
None
selem表示结构元素,用于设定局部区域的形状和大小。
from
分别用边长为5或15的正方形滤波器对棋盘图片进行膨胀操作,结果如下:
![](https://upload-images.jianshu.io/upload_images/1496926-cc053fec8d8e399a.png)
可见滤波器的大小,对操作结果的影响非常大。一般设置为奇数。
除了正方形的滤波器外,滤波器的形状还有一些,现列举如下:
morphology
注意,如果处理图像为二值图像(只有0和1两个值),则可以调用:
None
用此函数比处理灰度图像要快。
2、腐蚀(erosion)
函数:
None
selem表示结构元素,用于设定局部区域的形状和大小。
和膨胀相反的操作,将0值扩充到邻近像素。扩大黑色部分,减小白色部分。可用来提取骨干信息,去掉毛刺,去掉孤立的像素。
from
![](https://upload-images.jianshu.io/upload_images/1496926-aebad7bc51eef3fa.png)
注意,如果处理图像为二值图像(只有0和1两个值),则可以调用:
None
用此函数比处理灰度图像要快。
3、开运算(opening)
函数:
None
selem表示结构元素,用于设定局部区域的形状和大小。
先腐蚀再膨胀,可以消除小物体或小斑块。
from
![](https://upload-images.jianshu.io/upload_images/1496926-c5ac2d57f5fada1b.png)
注意,如果处理图像为二值图像(只有0和1两个值),则可以调用:
None
用此函数比处理灰度图像要快。
4、闭运算(closing)
函数:
None
selem表示结构元素,用于设定局部区域的形状和大小。
先膨胀再腐蚀,可用来填充孔洞。
from
![](https://upload-images.jianshu.io/upload_images/1496926-ec81be7c0c46d931.png)
注意,如果处理图像为二值图像(只有0和1两个值),则可以调用:
None
用此函数比处理灰度图像要快。
5、白帽(white-tophat)
函数:
None
selem表示结构元素,用于设定局部区域的形状和大小。
将原图像减去它的开运算值,返回比结构化元素小的白点
from
![](https://upload-images.jianshu.io/upload_images/1496926-89840c787e3d9fa6.png)
6、黑帽(black-tophat)
函数:
None
selem表示结构元素,用于设定局部区域的形状和大小。
将原图像减去它的闭运算值,返回比结构化元素小的黑点,且将这些黑点反色。
from
![](https://upload-images.jianshu.io/upload_images/1496926-ac517498498099a7.png)
高级滤波
本文提供更多更强大的滤波方法,这些方法放在filters.rank子模块内。
这些方法需要用户自己设定滤波器的形状和大小,因此需要导入morphology模块来设定。
1、autolevel
这个词在photoshop里面翻译成自动色阶,用局部直方图来对图片进行滤波分级。
该滤波器局部地拉伸灰度像素值的直方图,以覆盖整个像素值范围。
格式:
skimage
selem表示结构化元素,用于设定滤波器。
from
![](https://upload-images.jianshu.io/upload_images/1496926-6d63ab9836798c51.png)
2、bottomhat 与 tophat
bottomhat: 此滤波器先计算图像的形态学闭运算,然后用原图像减去运算的结果值,有点像黑帽操作。
bophat: 此滤波器先计算图像的形态学开运算,然后用原图像减去运算的结果值,有点像白帽操作。
格式:
skimage
selem表示结构化元素,用于设定滤波器。
下面是bottomhat滤波的例子:
from
![](https://upload-images.jianshu.io/upload_images/1496926-038756cd4404f095.png)
3、enhance_contrast
对比度增强。求出局部区域的最大值和最小值,然后看当前点像素值最接近最大值还是最小值,然后替换为最大值或最小值。
函数:
enhance_contrast(image, selem)
selem表示结构化元素,用于设定滤波器。
from
![](https://upload-images.jianshu.io/upload_images/1496926-4d0d926cc2598412.png)
4、entropy
求局部熵,熵是使用基为2的对数运算出来的。该函数将局部区域的灰度值分布进行二进制编码,返回编码的最小值。
函数格式:
entropy(image, selem)
selem表示结构化元素,用于设定滤波器。
from
![](https://upload-images.jianshu.io/upload_images/1496926-be677c5c9883a82e.png)
5、equalize
均衡化滤波。利用局部直方图对图像进行均衡化滤波。
函数格式:
equalize(image, selem)
selem表示结构化元素,用于设定滤波器。
from
![](https://upload-images.jianshu.io/upload_images/1496926-769c252317cb93e4.png)
6、gradient
返回图像的局部梯度值(如:最大值-最小值),用此梯度值代替区域内所有像素值。
函数格式:
gradient(image, selem)
selem表示结构化元素,用于设定滤波器。
from
![](https://upload-images.jianshu.io/upload_images/1496926-5a8a5b10323784e8.png)
7、其它滤波器
滤波方式很多,下面不再一一详细讲解,仅给出核心代码,所有的函数调用方式都是一样的。
最大值滤波器(maximum):返回图像局部区域的最大值,用此最大值代替该区域内所有像素值。
dst =sfr.maximum(img, disk(5))
最小值滤波器(minimum):返回图像局部区域内的最小值,用此最小值取代该区域内所有像素值。
dst =sfr.minimum(img, disk(5))
均值滤波器(mean) : 返回图像局部区域内的均值,用此均值取代该区域内所有像素值。
dst =sfr.mean(img, disk(5))
中值滤波器(median): 返回图像局部区域内的中值,用此中值取代该区域内所有像素值。
dst =sfr.median(img, disk(5))
莫代尔滤波器(modal) : 返回图像局部区域内的modal值,用此值取代该区域内所有像素值。
dst =sfr.modal(img, disk(5))
otsu阈值滤波(otsu): 返回图像局部区域内的otsu阈值,用此值取代该区域内所有像素值。
dst =sfr.otsu(img, disk(5))
阈值滤波(threshhold): 将图像局部区域中的每个像素值与均值比较,大于则赋值为1,小于赋值为0,得到一个二值图像。
dst =sfr.threshold(img, disk(5))
减均值滤波(subtract_mean): 将局部区域中的每一个像素,减去该区域中的均值。
dst =sfr.subtract_mean(img, disk(5))
求和滤波(sum) :求局部区域的像素总和,用此值取代该区域内所有像素值。
dst =sfr.sum(img, disk(5))