(持续更新,学习总结,经典基础概念,Ctrl+f 快速寻找你想了解的术语)
图像处理
图像分为两大类:模拟图像和数字图像
模拟图像到数字图像的转换是通过采样和量化,这个过程叫做栅格化。
下面我们普遍讨论的都是数字图像 ↓
图像分类与格式
常见图像可分为 位图(bitmap) 和 矢量图(vector)两大类
- 位图
由 像素 (Pixel)组成的网格,每个像素都有自己的颜色值。图像被分成许多小的方块,每个方块称为像素。 - 矢量图
使用数学公式描述图像,通过定义线段、曲线、形状等来创建图像;放大之后依旧平滑,不会出现像素点方块。
一般讨论的图像识别分类等以位图作为研究对象。
位图:
- 二值图 : 图像中只有黑和白两色(像素用0和1表示)
- 灰度图 : 图像中只有黑白色系即灰度(像素用0~255表示)
- RGB图: 图像色彩同时具有R(red)G(green)B(blue)三个通道
- … …
图像格式常见的有 .BMP、 .JPG/.JPEG、 .PNG、.SVG、.GIF等
- BMP ( Bitmap ) : 格式的特点是包含的图像信息较丰富,除了彩色分辨率可选,不采用其他任何压缩,因此缺点是占用磁盘空间过大。扫描格式是左 => 右, 下=>上
- JPG/JPEG (Joint Photographic Experts Group ): 是面向连续色调静止图像的一种压缩标准,该格式会导致图像质量损失 ,属于有损压缩格式。支持多种压缩级别,压缩比率通常在10:1到40:1
- PNG (Portable Network Graphics),便携式网络图形,是一种采用无损压缩算法的位图格式,支持索引、灰度、RGB三种颜色方案以及Alpha通道等特性。
直方图 histogram
灰度直方图 :统计图像中灰度分布的函数图像以直方图形式呈现
代码:
# 展示图像灰度直方图
import cv2 as cv
from matplotlib import pyplot as plt
# 参数0表示以灰度图像读入该图片
img = cv.imread('../imgs/Thanos.png', 0)
plt.hist(img.ravel(), 256, [0, 256])
plt.show()
效果:
可以通过直方图看到图像像素点在不同灰度上是不是呈现的比较细节,过渡比较自然光滑还是尖峰较多对比强烈。
应用:
- 图像增强:直方图均衡,通过算法让图像的直方图分布比较缓和平坦,让视觉感受到更多细节
- 图像分割:比如分割显微镜下细胞壁和细胞质,可以先获取直方图两者之间的波谷的对应灰度值作为分割的阈值
图像增强 image enhancement
噪声大 不清晰 => 按照特定需要突出或者去除某些信息,这就是图形增强
常用方法:
- 灰度变换 (线性变换、非线性变换)
- 代数运算 (加法运算、减法运算、乘法运算)
- 空间域滤波*(高通滤波 低通滤波…)*
- 频域滤波 (高通、低通等…)
前三者是直接对像素灰度级操作可归类作空间域增强;
最后的频域是需要先进行傅里叶变换,然后对变换后的系数进行操作,可归类于频域增强
空间域增强 Spatial Enhancement
特点:不改变像素点的位置,只改变图像像素的灰度
s
=
T
[
r
]
s = T[r]
s=T[r] 【r / s:输入/输出灰度级、 T: 灰度变化函数】
所以灰度变化函数是线性的那么就称为线性变换,非线性亦然。
比如:
- s = 255 - r // 效果为反转
- s = Ar + B // 效果为灰度拉伸
当然,很多时候需要在不同灰度段上做不同变化,可以是分段线性变换。
再比如:
- s = c * log (1+r)// [对数变换] 效果为将窄带低灰度图像转化为宽带高灰度图像,提亮较暗区域
- s = c * pow(r,γ)//[幂次变换] 效果是将高灰度的输入图像转换为宽带输出图像
低通滤波器 low pass filter
均值滤波器
一维离散系统:均值滤波器:h[k]={1,1,1}
二维离散系统:
均值滤波器:输出像素灰度值 = 输入图像像素及其周围8个点的灰度值的均值,h(m,n) =
效果:削弱噪声点的影响,看起来不那么突兀。
原因是均值滤波把噪声点的过大的像素差值弱化平摊到周围像素身上了,形成一个过渡
代码:
import cv2
import numpy as np
# 读取图像, 0表示以灰度模式读取
img = cv2.imread('../imgs/noise1.png', 0)
# 定义低通滤波器,这里使用均值滤波器
kernel = np.ones((5, 5), np.float32) / 25
# 应用低通滤波器 参数-1处:
# -1–代表与源图像的通道数一致
# 1–灰度图片–是单通道图像
# 2–RGB彩色图像–是3通道图像
# 3–带Alph通道的RGB图像–是4通道图像
dst = cv2.filter2D(img, -1, kernel)
cv2.imwrite('output_image.jpg', dst)
cv2.imshow('Original Image', img)
cv2.imshow('Low Pass Filtered Image', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
高斯低通滤波器
一维离散系统:高斯低通滤波器:h[k]={1,2,1}
二维离散系统:
滤波效果对比:
高斯低通滤波因为有加权平均的设计,并且中心像素点本身权重最高,滤波之后减弱噪声影响同时保留颗粒感,减少产生的模糊感粘滞感。
总结:低通滤波器实现的是 图像平滑
中值滤波器
对领域内的像素点的灰度进行排序,然后去中间值作为该点的新像素值
效果:滤波的同时不会对周围像素产生模糊,只是过滤高频噪声,显得更为平滑
总结:
- 中值滤波能是突出其亮点或暗点更接近它周围的点,并且消除孤立的亮点或暗点(这里确实指像素点而不是块)
- 去除噪声同时,较好地保留边缘
- 有效去除脉冲噪声(黑白点叠加在图像上)
高通滤波器 high-pass filter
效果和目的上:
如果低通滤波器是让图片变得平滑,那么高通滤波器就刚好反过来。
突出图像的细节,突出图像模糊的边缘,增加高频,这也就是图像的锐化;
运算手段上讲:
低通滤波的运算是积分运算,而高通滤波则是微分运算;
思想:
图像在某一点上的像素值,可以求出在水平方向和垂直方向的梯度,作为该点的变化方向的表征,那么作为边缘(灰度变化区域)的差分值不为0,这就找出了图像边缘。如果讲图像边缘的梯度找了出来,在原图像边缘处的原像素灰度值加上梯度值的绝对值,这样就可达到图像锐化。
像这样从梯度入手的思想也被成为基于梯度的图像增强。
形态学操作 Morphological operations
目的:对图像进行一系列操作突出某形态方面的特征
常见方式:膨胀 、腐蚀 、开运算 、闭运算 、顶帽运算 等…
使用场景:一般都是对二值图像或者是灰度图像使用,几乎不用在彩色图像上
[形态学 morphology,cv2的代码中形态学参数都是使用morph做前缀]
腐蚀 Erosion
- API: cv2.erode(img, kernel [, anchor, iterations, borderType ])
效果:将物体的边缘加以腐蚀
膨胀 Dilation
- API: cv2.dilate(img, kernel [, anchor, iterations, borderType ])
效果:膨胀能对图像的边界进行扩展,就是将图像的轮廓加以膨胀
import cv2
import numpy as np
import matplotlib.pyplot as plt
img1 = cv2.imread(r'../imgs/king.bmp')
kernel = np.ones((5, 5), np.uint8)
img2 = cv2.erode(img1,kernel)
img3 = cv2.dilate(img1,kernel)
fig, axes = plt.subplots(1, 3, figsize=(10, 5), dpi=200)
axes[0].imshow(img1)
axes[1].imshow(img2)
axes[2].imshow(img3)
axes[0].set_xlabel('img')
axes[1].set_xlabel('img-erode')
axes[2].set_xlabel('img-dilate')
plt.show()
输出:
开运算 open
步骤:对图像先腐蚀再膨胀
效果:让图像的特征区域之间减少粘黏,降低连通性,各自独立展示
用途:①可以去噪、②计数
API :cv2.morphologyEx(img1, cv2.MORPH_OPEN, kernel)
闭运算 close
步骤:对图像先膨胀再腐蚀
效果:和开运算相反,让图像的特征区域之间增强连通性,聚集相连。
API :cv2.morphologyEx(img1, cv2.MORPH_CLOSE, kernel)
形态学梯度 morphological GRADIENT
API :cv2.morphologyEx(img1, cv2.MORPH_GRADIENT, kernel)
示例:
import cv2
import numpy as np
import matplotlib.pyplot as plt
img0 = cv2.imread(r'../imgs/king.bmp')
kernel = np.ones((5, 5), np.uint8)
img1 = cv2.morphologyEx(img0,cv2.MORPH_GRADIENT,kernel)
img2 = cv2.morphologyEx(img0,cv2.MORPH_OPEN,kernel)
img3 = cv2.morphologyEx(img0,cv2.MORPH_CLOSE, kernel)
fig, axes = plt.subplots(1, 3, figsize=(10, 5), dpi=200)
axes[0].imshow(img1)
axes[1].imshow(img2)
axes[2].imshow(img3)
axes[0].set_xlabel('img-MORPH_GRADIENT')
axes[1].set_xlabel('img-MORPH_OPEN')
axes[2].set_xlabel('img-MORPH_CLOSE')
plt.show()
输出:
顶帽运算 tophat
步骤:原始图像 减(-) 开运算结果
效果:能够展示出图像的一些噪声信息,或得到比周围像素更亮的边缘信息
API :cv2.morphologyEx(img1, cv2.MORPH_TOPHAT, kernel)
黑帽运算 blackhat
步骤:闭运算结果 减(-) 原始图像
效果:能够展示出图像的一些噪声信息,或得到比周围像素更暗的边缘信息
API :cv2.morphologyEx(img1, cv2.MORPH_ BLACKHAT, kernel)
示例:
数学相关
点积 dot product
点积 dot product (内积,数量积)
两个向量相乘,返回一个标量结果(一个数值)
比如:
v = [2, 4, 6]
w = [1, 3, 5]
v . w = (2 x 1) + (4 x 3) + (6 x 5) = 2 + 12 + 30 = 44
在numpy可以通过np.dot()使用点积运算:
import numpy as np
v = np.array([2, 4, 6])
w = np.array([1, 3, 5])
dot_product = np.dot(v, w)
print(dot_product) #44
矩阵点乘:
将上面的一维扩大到二维即可:
C=A*B为例,运算思维是用A的第 i 行的行向量与B的第 j 列向量做点乘,结果作为C在i行j列的数值,A里的每一行都要和B里的每一列进行这样的点乘得出C的矩阵。
a11, a12
A = ( a21, a22 )
a31, a32
b11, b12
B = ( b21, b22 )
a11 * b11 + a12 * b21, a11 * b12 + a12 * b22
C = ( a21 * b11 + a22 * b21, a21 * b12 + a22 * b22 )
a31 * b11 + a32 * b21, a31 * b12 + a32 * b22
因此,这种运算也对矩阵的形状有要求,需要满足A的列数等于B的行数:
C
(
m
,
k
)
=
A
(
m
,
n
)
∗
B
(
n
,
k
)
C(m,k) = A(m,n) * B(n,k)
C(m,k)=A(m,n)∗B(n,k)
在numpy中多维向量乘法也可以通过调用np.dot(),或者下面A.dot(B)的形式
from numpy import array
A = array([[1, 2], [3, 4], [5, 6]])
B = array([[1, 2], [3, 4]])
C = A.dot(B)
意义与应用:
1.衡量某两样本的相似度,相关性:比如语义分析中拿两个词向量做点积看语义相似性多高
2.矩阵分解,因子分析,聚类运算等…
more about [点积 dot product 在机器学习中的N多应用场景](推荐)
叉积 cross product
卷积 convolution
运算法则:
(翻转然后对位相乘相加)
(1,2,3) * (4,5,6) = (4,13,28,27,18)
实质是一种结合了运算和组合的变化方式,通过依次挪动相对位置达到形成多个运算结果再组合在一起形成新的同维度输出。
在图像处理中会经常使用这样的处理方法:
import numpy as np
np.convolve((1,2,3),(4,5,6))
>>> array([4,13,27,18])
# FFT的方法,速度更快,空间换时间
import scipy.signal
scipy.signal.fftconvolve(arr1,arr2)
一维可视化:
二维可视化:
那么像这样处理图像,与输入图像做卷积运算的称为卷积核 或 核(Kernel) 或 滤波器(filter),转换结果成为特征图(feature map)
经过卷积之后图像特征会有所变化,比如模糊:
more about 什么是卷积
卷积核 convolution kernel
我们刚刚讲述了什么是卷积核,下面介绍一些常见的卷积核以及其举例:
//垂直边缘检测卷积核
1 0 -1
1 0 -1
1 0 -1
//水平边缘检测卷积核
1 1 1
0 0 0
-1 -1 -1
//Sobel 卷积核 (用于图像边缘检测)
1 0 -1
2 0 -2
1 0 -1
and
1 2 1
0 0 0
-1 -2 -1
根据元素值排布和大小特点,可以看到同时Sobel卷积核吸收了垂直边缘检测和水平边缘检测的能力:
//高斯卷积核 :用于图像模糊处理和降噪
1 2 1
2 4 2
1 2 1
//Laplacian卷积核:用于图像锐化处理 比如
0 1 0
1 -4 1
0 1 0 (3X3)
--------------
0 1 1 1 0
1 -2 -2 -2 1
1 -2 12 -2 1
1 -2 -2 -2 1
0 1 1 1 0 (5X5)
//边缘增强卷积核:用于增强图像的边缘
-1 -1 -1
-1 9 -1
-1 -1 -1
more about 常用卷积核
Q: 为什么这么多常用卷积核都是3X3的规格呢?
感知域
欧几里得空间 Euclidean space
欧氏空间是一个内积空间,其中内积定义为两向量的点积。把这些数学空间扩展应用于任何有限维度,形成的空间叫做n维欧几里得空间,简称n维空间,或有限维实内积空间。
1.欧氏空间就是在实数域上的线性空间上添加一个对称的正定双线性函数
2.内积的概念只能在实数域的线性空间上定义,且结果是一个实数
3.欧氏空间的定义中只给了内积应满足的4个性质,而没有给出内积的具体计算法则
4.欧氏空间对空间的维数并无要求,可以是有限维的,也可以是无限维的。
more about [欧几里得空间]
希尔伯特空间 Hilbert space
希尔伯特空间有许多与欧几里德空间相似的性质,例如,在希尔伯特空间中,可以定义向量正交、正交和、正交投影的概念,柯西一许瓦兹不等式成立、勾股定理和投影定理成立。在可分希尔伯特空间中,存在着完全的标准正交系,希尔伯特空间中的任一向量可以依任一完全的标准正交系分解。
more about [希尔伯特空间-完备性-内积]