图像算法
1. transform
图像的形变与缩放等使用的是 skimage 的transform
模块,函数比较多,功能齐全:
transform.resize(image, output_shape)
:将一个image
缩放到一个output_shape
的尺寸dst=transform.resize(img, (80, 60))
transform.rescale(image, scale[, …])
:scale
可以是单个float
数,表示缩放的倍数;- 也可以是一个
float
型的 tuple,如[0.2, 0.5],表示将行和列分别进行缩放;
from skimage import transform,data img = data.camera() print(img.shape) #图片原始大小 print(transform.rescale(img, 0.1).shape) #缩小为原来图片大小的0.1 print(transform.rescale(img, [0.5,0.25]).shape) #缩小为原来图片行数一半,列数四分之一 print(transform.rescale(img, 2).shape) #放大为原来图片大小的2倍
transform.rotate(image, angle[, …], resize=False)
:angle
参数为一个float
,表示旋转的度数;resize
用于控制在旋转时是否改变大小,默认为False
transform.pyramid_gaussian(image, downscale=2)
:高斯图像金字塔。当然还有其他金字塔,如
paramid_laplacian()
等霍夫变换:
transform.hough_line(image)
:transform.hough_circle(image)
:transform.hough_ellipse(image, threshold, min_size, max_size)
:
2. exposure
图像对比度与亮度调整等,在 skimage 包的 exposure
模块里面:
代码 | 作用 | 补充说明 |
---|---|---|
exposure.adjust_gamma(image, gamma=1) | 伽马调整。 1) 若 gamma > 1,新图像变暗; 2) 若 gamma < 1,新图像变亮) | ![]() |
exposure.adjust_log(image) | 对数调整 | ![]() |
exposure.is_low_contrast(image) | 判断图像对比度是否偏低 | 返回值为 bool 类型 |
exposure.rescale_intensity(image, in_range='image', out_range='dtype') | in_range 默认为'image' 表示用图像的最大/最小像素值作为范围;out_range 默认为'dtype' 表示用图像的类型的最大/最小值作为范围 | 输入图片的[min, max]范围被拉伸到[dtype.min, dtype.max],如是 dtype=uint8,那么 dtype.min=0, dtype.max=255 |
exposure.histogram(image, nbins=256) | 计算 image 的直方图 | 返回值为一个含两个 array 的 tuple,(hist, bins_center),hist 为直方图的统计量,bins_center 是每个 bin 的中间值。绘图可用 plt.hist()函数 |
exposure.equalize_hist(image) | 直方图均衡化 | |
exposure.equalize_adapthist(image) | 直方图均衡化 |
3. filters
对图像进行滤波,可以有两种效果:
- 一种是平滑滤波,用来抑制噪声;
- 另一种是微分算子,可以用来检测边缘和特征提取。
skimage 的 filters
模块进行滤波操作。
滤波器
一些算子或滤波器:
filters.sobel(image, mask=None)
:sobel 算子,检测边缘filters.roberts(image)
:roberts 算子,检测边缘filters.scharr(image)
:scharr 算子,检测边缘filters.prewitt(image)
:prewitt 算子,检测边缘filters.gabor_filter(image, frequency)
:gabor 滤波,进行边缘检测和纹理特征提取filters.gaussian_filter(image, sigma)
:gaussian 滤波,平滑滤波,可以消除高斯噪声filters.median(image, skimage.morphology.disk(5))
:中值滤波,平滑滤波,可以消除噪声水平边缘与垂直边缘版:
水平边缘 垂直边缘 水平边缘:
filters.sobel_h(image)
.prewitt_h()
.scharr_h()
垂直边缘:
filters.sobel_v(image)
.prewitt_v()
.scharr_v()
filters.roberts_neg_diag(image)
:Roberts 的十字交叉边缘检测
阈值分割
图像自动阈值分割,以下返回值均为一个阈值:
filters.threshold_otsu(image, nbins=256)
:Otsu 阈值分割(阈值 87)filters.threshold_yen(image)
:阈值 198filters.threshold_li(image)
:阈值 64.5filters.threshold_isodate(image)
:阈值 87filters.threshold_adpative(image, block_size, method='gaussian')
:此函数直接返回一个阈值后的图像,而不是阈值dst = filters.threshold_adaptive(image, 15) dst1 = filters.threshold_adaptive(image,31,'mean') dst2 = filters.threshold_adaptive(image,5,'median')
rank子模块
skimage.filters.rank
子模块(import skimage.filters.rank as sfr
)实际提供了更强大的滤波方法,这些方法需要用户自己设定滤波器的形状和大小,因此需要导入 morphology
模块来设定。
函数 | 作用 | 示例 |
---|---|---|
sfr.autolevel(image, selem) | 自动色阶 | 用局部直方图来对图片进行滤波分级,该滤波器局部地拉伸灰度像素值的直方图,以覆盖整个像素值范围。 |
sfr.bottomhat(image, selem) | 类似黑帽操作 | 此滤波器先计算图像的形态学闭运算,然后用原图像减去运算的结果值,有点像黑帽操作。![]() |
sfr.tophat(image, selem) | 类似白帽操作 | 此滤波器先计算图像的形态学开运算,然后用原图像减去运算的结果值,有点像白帽操作。 |
sfr.enhance_contrast(image, selem) | 对比度增强 | 求出局部区域的最大值和最小值,然后看当前点像素值最接近最大值还是最小值,然后替换为最大值或最小值![]() |
sfr.entropy(image, selem) | 求局部熵 | 将局部区域的灰度值分布进行二进制编码,返回编码的最小值。![]() |
sfr.equalize(image, selem) | 均衡化滤波 | 利用局部直方图对图像进行均衡化滤波![]() |
sfr.gradient(image, selem) | 梯度滤波 | 返回图像的局部梯度值(如最大-最小值),用此梯度值代替区域内所有像素值)![]() |
… | …… | …… |
4. feature
- canny 算子
feature.canny(image[, sigma, …])
:提取边缘特征
5. measure
measure
模块的一些操作:
查找轮廓:
measure.find_contours(array, level)
array
:一个二维二值图像level
:在图像中查找轮廓的级别值return
:轮廓的列表
600 多边形逼近曲线:
measure.subdivide_pylogon(coords, degree=2, preserve_ends=False)
参数 作用 coords 坐标点序列 degree B 样条的度数,默认为 2 preserve_ends 如果曲线为非闭合曲线,是否保存开始和结束点坐标,默认为 False 返回值 返回细分为的坐标点序列 measure.approximate_polygon(coords, tolerance)
参数 作用 coords 坐标点序列 tolerance 容忍值 返回值 近似的多边形曲线坐标序列
Lewiner 移动立方体算法在三维体数据中寻找表面:
measure.marching_cubes_lewiner( volume, level=None, spacing=(1.0, 1.0, 1.0), gradient_direction='descent', step_size=1, allow_degenerate=True, use_classic=False)
volume
:(M, N, P) arraylevel
:floatreturn
:verts
: (V, 3) arrayfaces
: (F, 3) arraynormals
: (V, 3) arrayvalues
: (V, ) array
连通区域标记:
measure.label(image, connectivity=None)
参数 作用 image 二值图像 connectivity 连接的模式,1 代表 4 邻接,2 代表 8 邻接 返回值 返回一个标记数组,从 0 开始标记 一个标记图像的每一个连通区域的性质:
measure.regionprops(label_image)
返回值为所有连通区域的属性列表,按照 label 的值从小到大排序,常用属性有:
属性 类型 描述 area int 区域内像素点总数 bbox tuple 边界外接框(min_row, min_col, max_row, max_col) centroid ndarray 质心坐标 convex_area int 凸包内像素点总数 convex_image ndarray 和边界外接框同大小的凸包图像 coords ndarray 区域内像素点坐标 eccentricity float 离心率 equivalent_diameter float 和区域面积相同的圆的直径 euler_number float 区域欧拉数 filled_area int 区域面积和外接框之间填充的像素点总数 image ndarray Sliced binary region image which has the same size as bounding box. perimeter float 区域周长 label int 区域标记 slice tuple of slices A slice to extract the object from the source image. … … …
6. morphology
此模块对图像进行形态学滤波,形态学操作的对象一般为灰度图或二值图,一般可import skimage.morphology as sm
。
结构元
sm 中的结构元类型有:
代码 | 结构元 |
---|---|
sm.square() | 正方形 |
sm.rectangle() | 矩形 |
sm.cube() | 立方体形 |
sm.disk() | 圆形 |
sm.ball() | 球形 |
sm.octagon() | 八角形 |
sm.octahedron() | 八面体 |
sm.star() | 星形 |
sm.diamond() | 钻石形 |
基本的形态学滤波
基本形态学滤波函数如下,对于二值图像可特意调用它的二值化形式进行操作,这种情况下运算速度较快:
膨胀:可以扩大白色值范围,压缩黑色值范围,一般用来扩充边缘或填充小的孔洞(selem 表示所用结构元)。
sm.dilation(image, selem=None)
sm.binary_dilation(image, selem=None)
腐蚀:扩大黑色部分,减小白色部分,可用来提取骨干信息,去掉毛刺,去掉孤立的像素。
sm.erosion(image. selem=None)
sm.binary_erosion(image, selem=None)
开运算:先腐蚀再膨胀,可以消除小物体或小斑块
sm.opening(image, selem=None)
sm.binary_opening(image, selem=None)
闭运算:与上反
sm.closing(image, selem=None)
sm.binary_closing(image, selem=None)
白帽:将原图像减去它的开运算值,返回比结构元小的白点
sm.white_tophat(image, selem=None)
黑帽:将原图像减去它的闭运算值,返回比结构元小的黑点,且将这些黑点反色
sm.black_tophat(image, selem=None)
高级形态学处理
求凸包
将整张图片的所有目标看作一个整体:
sm.convex_hull_image(image)
输入为二值图像,输出为逻辑二值图像,在凸包内的点为 True,否则为 False。
求图片中每一个目标的凸包:
sm.convex_hull_object(image, neighbors=8)
删除小块区域:
sm.remove_small_objects(arr, min_size=64, connectivity=1, in_place=False)
参数 作用 arr 待操作的 bool 型数组 min_size 最小连通区域尺寸,小于该尺寸的都将被删除,默认为 64 connectivity 邻接模式,1 表示 4 邻接,2 表示 8 邻接 in_place 是否原位操作 骨架提取:
sm.skeletonize(image)
输入和输出都是一幅二值图像
骨架提取(中轴变换法):
sm.medial_axis(image, mask=None, return_distance=False)
参数 说明 image 输入图像 mask 掩膜 若给定掩膜,则在掩膜内的像素值才执行骨架算法 return_distance bool 型值 若为 True,则不仅返回骨架,还将返回距离变换值(这里的距离指中轴线上的所有点与背景点的距离)
7. 其他
skimage 与 ndimage 的 label 函数
对于三维图片 image,ndimage 与 skimage 的如下写法两两等效(每一行的结果相同):
连通域判断方式 | 接触情况 | from skimage import measure | from scipy import ndimage as ndi |
---|---|---|---|
?邻接 | 面接触 | measure.label(image, return_num=True, connectivity=1) | ndi.label(image, structure=ndi.generate_binary_structure(image.ndim, 1)) |
4 邻接 | 面、线接触 | measure.label(image, return_num=True, connectivity=2) | ndi.label(image, structure=ndi.generate_binary_structure(image.ndim, 2)) |
8 邻接 | 面、线、点接触 | measure.label(image, return_num=True, connectivity=3) | ndi.label(image, structure=ndi.generate_binary_structure(image.ndim, 3)) |