- 博主简介:努力学习的22级计算机科学与技术本科生
- 博主主页: @是瑶瑶子啦
- 每日一言: 每一个不曾起舞的日子,都是对生命的辜负。——尼采
今天要讲的图像预处理,处理的是什么呢?也就是上一篇中讲到的经过成像系统得到的原始像素点矩阵,即原始图像数据。为什么要处理呢?这也是本文的重点,因为进行处理势必就篡改了原始数据的真实性,但是在某些情况下,经过预处理,才能更好的解决我们的问题——本文将从特征提取、检测出发,来讲述图像预处理以及带来的好处。
因为学到这里使对于什么是特征检测、特征提取、特征描述、特征匹配等概念脑海中还不是很清楚,经过一些搜索学习之后,特将整理在此,如果对这四个概念比较清晰的小伙伴可以跳过这一part,只需要明白:图像预处理的目的是为了更好的特征提取而准备图像
传统图像处理中图像特征匹配有三个基本步骤:特征检测和提取((Feature Detect))、特征描述(特征描述(Feature Descriptor))和特征匹配(Feature Match)。
前面说过,本文将从特征检测和特征描述的角度来讲述图像预处理,图像预处理会对特征提取的效果和图像分析的结果有很大的影响,因为直接从成像系统中获取的原始图像,很难达到很好的计算机视觉效果,而通过一个或者一系列图像预处理操作可以改善这个问题。(例如SIFT算法如果使用灰度数据的局部二值描述子,则需要将图像预处理成灰度图像,且在此基础上如果想获得更好的特征检测效果,还需要微调图像预处理)
此篇文章将基于计算机视觉领域的四类基本特征描述子来讨论图像预处理:
ps:基于篇幅原因,此篇博文主要介绍了图像预处理的一些方法,至于如何将图像预处理和这四个特征检测方法相结合,放在了下一篇
ps:图中画了
X
的表示这种预处理是有必要的
可以看到,图像预处理操作还是有很多种的,下面将对这其中的常见的预处理操作进行简单介绍分析(这里就先不结合四种特征描述方法来具体讲,结合特征描述的详细讲解将放在后面,这里主要讲解一下这些预处理操作的带来的一些效果)
这里将后续代码所需要的头文件给出,后续代码中就不再写进去了(默认已经引入)
import cv2
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.pylab as plt
import numpy as np
from skimage.io import imread
import cv2
import scipy.fftpack as fp
from PIL import Image
光照会引起较深的阴影,从而遮挡局部纹理和结构,或者整场景的光照不均匀可能会扭曲成像接股票。
一些光照校正的方法:
基本思想:保持像素数量不变,将像素进行重新分配,使每个灰度级上对应的像素数量差别不大。
算法思路:
上面博客对具体算法分析的比较详细,这里给出我自己的理解画出示意图来帮助理解。核心就是:找到两个直方图之间的映射关系,对不同像素值的像素进行映射(即重新分配这些“长条”,但长度(即一个像素值对应的像素数)和总像素数不变),目的是使这些长条能尽可能均匀分布在直方图上,而不是集中在某一块。
y = f(x)
简单理解: 在均衡前原始直方图中,像素值为x
的像素,经过f
这个映射关系后,像素值为x的像素,像素值改为y。对原始图像中所有像素值进行这样映射,然后得到右边的直方图,这个过程就是直方图均衡。目的是使像素在各个像素值上分配比较均匀。
特征:
可以看到直方图均衡能较好的增强图像对比度,凸显细节,但是也存在以下的一些问题,在上面给出的参考博客中已经做出详细分析,这里根据我自己的理解再简单概括一下。
自适应直方图均衡 Adaptive Histogram Equalization(AHE)
如果用两个词来简单区分一下自适应直方图均衡(AHE)和前面讲的直方图均衡(HE),我现在脑子里面的两个词是:局部、全局。
直方图是对整个图像进行直方图均衡,而自适应直方图则是对局部进行均衡。它会把图像分成几个小块,进行独自的均衡。这种均衡方法更容易突出细节,增强图像边缘信息。
但是自适应直方图均衡并没有解决直方图均衡中的噪声
问题。
而且得出来的图像会比较不连续
这个时候人们又想出了更好的方法。你不是说直方图均衡存在对齐问题嘛,在图像颜色值比较集中在一点时(某一个颜色值的像素数很多),会突然把这么多的像素啪的一下从这个颜色值移到另外一个,虽然增强也增强了对比度,但是会带来分色现象和扩大噪声的影响。
我们再仔细想想上面所说的那个问题的本质是什么?对,某一个颜色值/灰度值对应的像素数太多啦,导致其他颜色值都没多少像素。
基本思想:CLANE算法的思想就是在自适应直方图均衡的基础上,限制一下:某一个颜色值的像素数(频数)太多了(通常会指定一个阈值),不行,给我匀点到其他像素值上去一些像素。
等等,还有一个问题:不连续。
为了解决这个问题,提出了优化方案双线性插值的AHE,然后这个基础上再使用CLHE的截断对比度的思想,就变成了我们现在的CLAHE算法。
CLAHE算法的应用:对于医学图像,特别是医学红外图像的增强效果非常明显:这篇博客做出了非常详细的讲解CLAHE的实现和研究
这里放两张出自这篇博客的对比图感受一下:
# 读取图片
image_path = r'E:\1_Technological_Capability\Algorithm\CV\Projects\HSR\My_Work\Jie_Net\Learning\004401893_K1385515_1428_0_46.jpg'
image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE) # 以灰度图像格式读取图片
# 进行直方图均衡化
equalized_image = cv2.equalizeHist(image)
# 进行自适应直方图均衡化增强
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
enhanced_image = clahe.apply(image)
def plt_def():
# 显示原始图片、直方图均衡化后的图片和增强后的图片
plt.figure(figsize=(15, 5))
plt.subplot(1, 3, 1)
plt.imshow(image, cmap='gray')
plt.title('Original Image')
plt.subplot(1, 3, 2)
plt.imshow(equalized_image, cmap='gray')
plt.title('Equalized Image')
plt.subplot(1, 3, 3)
plt.imshow(enhanced_image, cmap='gray')
plt.title('Enhanced Image')
plt.tight_layout()
plt.show()
plt_def()
clip_limit
:也就是上面那张图的Nominal clipping level p
.我们不是讲过,在这种限制对比度的方法中,如果某个bin的像素频数超过某一阈值,就需要裁剪掉嘛,把超出部分平均分配到其他的bins上,以达到限制对比度的目的。而clip_limit
就是指的这个阈值。tilesGridSize
:图像被分成称为“tiles”(瓷砖、地砖、小方地毯、片状材料、块状材料)的小块,在OpenCV中,tilesGridSize默认为8x8 ,即整个图像被划分为8纵8横共64块。然后对每一个块进行直方图均衡处理首先说模糊把,焦点校正算是模糊的其中一个应用。我个人目前学习到的模糊(平滑)操作的应用
通过模糊操作(或者称平滑操作,可以去除噪声),得到更平滑的图像,避免噪声干扰,方便后续图像处理。
当然去噪的方法有很多很多种,可以参考下面该图:
我目前了解、接触和用过的是我框起来来的哲学,而在本节中,即图像平滑,我将对空间域滤波的最常见两种滤波:——均值滤波、高斯滤波、中值滤波进行讲解。(具体深入了解图像去噪,这里可以参考这篇博客,这里记下方便后续学习:https://blog.csdn.net/qq_33208851/article/details/97123411)
cv2.blur()
其语法格式为 dst=cv2.blur(src,ksize,anchor,borderType)
# 加载图像
image_path = r"F:\AI\Learning\yyz.png"
image = cv2.imread(image_path)
# 将图像转换为RGB(OpenCV读取的图像为BGR)
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# 添加椒盐噪声
def add_salt_and_pepper_noise(image, salt_prob, pepper_prob):
noisy_image = np.copy(image)
total_pixels = image.size
# 添加盐噪声
num_salt = np.ceil(salt_prob * total_pixels)
salt_coords = np.random.choice(range(image.size), size=int(num_salt), replace=False)
noisy_image.flat[salt_coords] = 255
# 添加椒噪声
num_pepper = np.ceil(pepper_prob * total_pixels)
pepper_coords = np.random.choice(range(image.size), size=int(num_pepper), replace=False)
noisy_image.flat[pepper_coords] = 0
return noisy_image
# 添加椒盐噪声
salt_prob = 0.01 # 盐噪声概率
pepper_prob = 0.01 # 椒噪声概率
noisy_image = add_salt_and_pepper_noise(image_rgb, salt_prob, pepper_prob)
# 使用均值滤波去噪
denoised_image = cv2.blur(noisy_image.astype('uint8'), (6, 6))
def plt_def():
# 显示原始图像、带噪声的图像和去噪图像
plt.figure(figsize=(15, 30))
plt.subplot(131)
plt.imshow(image_rgb)
plt.title('Original Image')
plt.axis('off')
plt.subplot(132)
plt.imshow(noisy_image)
plt.title('Noisy Image')
plt.axis('off')
plt.subplot(133)
plt.imshow(denoised_image)
plt.title('Denoised Image')
plt.axis('off')
plt.show()
plt_def()
前面讲的均值滤波是简单粗暴的平均对一个点周围像素进行求平均,但是实际上,一个点与周围的关系和距离也有关系。距离越远,关系越小,权重也更小,距离越近,影响和关系越大,权重也越大。
符合这种描述的是高斯函数,而运用这种理念的也就是高斯滤波:
基本原理:
在OpenCV中,实现高斯滤波的函数是cv2.GaussianBlur()
,该函数的语法格式是dst=cv2.GaussianBlur(src,ksize,sigmaX,sigmaY,borderType)
● dst是返回值,表示进行高斯滤波后得到的处理结果。
● src 是需要处理的图像,即原始图像。它能够有任意数量的通道,并能对各个通道 独立处理。图像深度应该是CV_8U、CV_16U、CV_16S、CV_32F 或者 CV_64F中的一 种。
● ksize 是滤波核的大小。滤波核大小是指在滤波处理过程中其邻域图像的高度和宽 度。需要注意,滤波核的值必须是奇数。
● sigmaX 是卷积核在水平方向上(X 轴方向)的标准差,其控制的是权重比例。
● sigmaY是卷积核在垂直方向上(Y轴方向)的标准差。如果将该值设置为0,则只采用sigmaX的值
如果sigmaX和sigmaY都是0,则通过ksize.width和ksize.height计算得到。其中sigmaX=0.3×[(ksize.width-1)×0.5-1] +0.8
sigmaY=0.3×[(ksize.height-1)×0.5-1]+0.8
● borderType是边界样式,该值决定了以何种方式处理边界。一般情况下,不需要考虑该值,直接采用默认值即可。 在该函数中,sigmaY和borderType是可选参数。sigmaX是必选参数,但是可以将该参数设置为0,让函数自己去计算sigmaX的具体值。
函数cv2.GaussianBlur()的常用形式为: dst=cv2.GaussianBlur(src,ksize,0,0)
# 加载图像
image_path = r"F:\AI\Learning\yyz.png"
image = cv2.imread(image_path)
# 将图像转换为RGB(OpenCV读取的图像为BGR)
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# 对图像添加高斯噪声
def add_gauss_noise(image, mean=0, val=0.01):
size = image.shape
# 对图像归一化处理
image = image / 255.0
gauss = np.random.normal(mean, val**0.05, size)
image = image + gauss
return image
noisy_image = add_gauss_noise(image_rgb)
# 高斯滤波
denoised_image = cv2.GaussianBlur(noisy_image, (5, 5), 0)
def plt_def():
# 显示原始图像、带噪声的图像和去噪图像
plt.figure(figsize=(15, 30))
plt.subplot(131)
plt.imshow(image_rgb)
plt.title('Original Image')
plt.axis('off')
plt.subplot(132)
plt.imshow(noisy_image)
plt.title('Noisy Image')
plt.axis('off')
plt.subplot(133)
plt.imshow(denoised_image)
plt.title('Denoised Image')
plt.axis('off')
plt.show()
plt_def()
前面讲到的均值滤波、高斯滤波,它们的策略都是将一个点周围的像素点的像素信息都考虑进来,进行加权求和的方法来得到该点的像素值,这些方法都是线性方法。缺点是噪声信息也会被考虑进来(虽然说相较于原图像,噪声已经变得柔和了许多)。
这一小节学习的方法是中值滤波,它是一种非线性的方法。
基本原理: 同样还是有一个nxn
的核,这次,对于这个核像素点的取值,就不是对nxn
个像素值进行加权求和了,而是把这nxn
个像素值排个序,找出中间那个值,赋给当前像素点。
比如在上面该图中,对九个点按照大小进行排序,中值是93,那么经过中值滤波后,该点的像素值就是93
opencv中值滤波的实现: dst=cv2.medianBlur(src,ksize)
# 加载图像
image_path = r"F:\AI\Learning\yyz.png"
image = cv2.imread(image_path)
# 将图像转换为RGB(OpenCV读取的图像为BGR)
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# 添加椒盐噪声
def add_salt_and_pepper_noise(image, salt_prob, pepper_prob):
noisy_image = np.copy(image)
total_pixels = image.size
# 添加盐噪声
num_salt = np.ceil(salt_prob * total_pixels)
salt_coords = np.random.choice(range(image.size), size=int(num_salt), replace=False)
noisy_image.flat[salt_coords] = 255
# 添加椒噪声
num_pepper = np.ceil(pepper_prob * total_pixels)
pepper_coords = np.random.choice(range(image.size), size=int(num_pepper), replace=False)
noisy_image.flat[pepper_coords] = 0
return noisy_image
# 添加椒盐噪声
salt_prob = 0.1 # 盐噪声概率
pepper_prob = 0.1 # 椒噪声概率
noisy_image = add_salt_and_pepper_noise(image_rgb, salt_prob, pepper_prob)
# 使用中值滤波去噪
denoised_image = cv2.medianBlur(noisy_image, 3)
def plt_def():
# 显示原始图像、带噪声的图像和去噪图像
plt.figure(figsize=(15, 30))
plt.subplot(131)
plt.imshow(image_rgb)
plt.title('Original Image')
plt.axis('off')
plt.subplot(132)
plt.imshow(noisy_image)
plt.title('Noisy Image')
plt.axis('off')
plt.subplot(133)
plt.imshow(denoised_image)
plt.title('Denoised Image')
plt.axis('off')
plt.show()
plt_def()
前面的三种方法,均值滤波核高斯滤波属于对图像空间进行加权平均的线性操作,它们的共同点都是有一个核,其实就是一个系数矩阵,被称作空间滤波器,用于在图像的二维空间进行线性操作。
由于经过滤波器滤波后,噪声会变得柔和,它们也被称为平滑滤波器。
以后我们看到模板、核、卷积核、窗口、滤波器、空间滤波器等等术语,都指的是这个东西。当然,卷积的真实含义与这里的操作有一点点的区别,但不必过于拘泥于术语的精确性
通过平滑滤波器,可以实现降噪,这是前面已经讲到的。但降噪只是它的一个应用。
模糊操作还有一个应用,就是目标提取。
基本原理: 通过空间滤波器,模糊掉小的、不感兴趣、亮度较高物体(类比于上面的“噪声”),然后再结合下面即将要讲到的二值化,对图像进行二值化操作,提取到大的、目标物体,过滤掉尺寸小,亮度高的物体。
这里给出一个例子:参考自https://blog.csdn.net/saltriver/article/details/78883989
下面是一张哈勃望远镜拍摄的星空原始图像(来自冈萨雷斯的《数字图像处理)
经过平滑滤波器后:
在上面学习模糊、滤波、去噪等操作时,了解到了还有一种叫做图像金字塔的概念,去大概学习和了解了一下。
压缩可能会用得到(降低图像分辨率)
具体的原理等,这里先给出学习的博客,等以后需要应用或者深入学习的时候,再来填这个坑。
本小节的讲解参考:https://zhuanlan.zhihu.com/p/343858207
目的:增强图像的边缘,突出细节
一些图像经过上面的平滑滤波器进行去噪之后,会变得模糊。而边缘增强/锐化则是增强图像边界和细节,这个时候我们利用的滤波器就叫做:“平滑滤波器”
基本原理::
图像边缘:
首先要明白什么是图像边缘,它的特征,由此来对其进行增强。区别一个物体主要是通过边缘,边缘处的往往像素值变化比较大,我们就是根据这种差异,进行差分操作来增强边缘信息。
边缘分类:(注意,边缘也有方向之分,下面展示的例子只是水平x方向的边缘而已)
一阶微分算子和二阶微分算子
- 简单来说,一阶微分算子就是求该方向的一一阶导数,而二阶微分算子是表示该方向的二阶导数
在图像处理里面,因为信息是以矩阵的形式存在,我们要根据上面表达式构造同意义差分矩阵,也就是 构造差分模板、核,从而对图像矩阵进行差分(微分)/梯度运算,从而得到/提取到边缘信息。
微分运算
梯度运算
上面的微分运算对颜色变化的方向性局限比较大,只能水平或者竖直,而梯度我们知道,它是一个向量,有方向。分别沿着X和Y计算;在X方向求一次微分,得到G(x)
;在Y方向求一次微分,得到G(y)
.这样就构成了矢量
梯度是矢量,我们需要变成标量,一个可测的量;将X和Y分别取绝对值相加,直接得到梯度,或者把这两个值取最大值,或者对这两个值,平方在开方;就得到梯度;
(我个人现在感觉,梯度本身是有方向的,但是它这样把他化成标量之后,感觉核上面讲的双向一次微分又没有区别了,好像也不能体现方向性,本质上还是在x,y方向上进行微分)
交叉微分运算
下面根据具体的微分模板,来讲解不同的锐化算法,它们的作用是提取边缘信息,它们的本质还是上面说的三种运算
Prewitt算子同样也是一种一阶微分算子。
和sobel算法唯一不同在系数上面,它不强调距离远近的影响
前面讲的两种算法都是一阶微分算法,而下面要讲的是laplacian是一种二阶微分算法。
前面讲到的三种算法,本质上都是提取边缘信息,提取到边缘信息的结果图像是一副整体比较按,边缘为白色或灰色的图像。要达到我们所想要的在保留图像原始信息的基础上,对图像进行增强,需要将边缘提取结果和原始图像进行叠加
import matplotlib.pyplot as plt
# 读取图像
image_path = r"F:AI/Learning/9022625033_K1609563_T001_4_13.jpg"
image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
# 使用Sobel算子进行边缘增强
sobelx = cv2.Sobel(image, cv2.CV_64F, 1, 0, ksize=3)
sobely = cv2.Sobel(image, cv2.CV_64F, 0, 1, ksize=3)
edge_enhanced_image = cv2.magnitude(sobelx, sobely) + image
def plt_def():
# 显示图像
plt.figure(figsize=(10, 10))
# 原始图像
plt.subplot(2, 2, 1)
plt.imshow(image, cmap='gray')
plt.title('Original Image')
plt.axis('off')
# 边缘增强后的图像
plt.subplot(2, 2, 4)
plt.imshow(edge_enhanced_image, cmap='gray')
plt.title('Edge Enhanced Image')
plt.axis('off')
plt.subplot(2, 2, 2)
plt.imshow(sobelx, cmap='gray')
plt.title('sobelx')
plt.axis('off')
plt.subplot(2, 2, 3)
plt.imshow(sobely, cmap='gray')
plt.title('sobely')
plt.axis('off')
plt.tight_layout()
plt.show()
plt_def()
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 读取图像
image_path = r"F:AI/Learning/9022625033_K1609563_T001_4_13.jpg"
image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
# 应用拉普拉斯算子进行高频增强
laplacian_image = cv2.Laplacian(image, cv2.CV_64F)
# 增强高频信息
enhanced_image = image + 2*laplacian_image
def plt_def():
# 显示图像
plt.figure(figsize=(12, 6))
# 原始图像
plt.subplot(1, 3, 1)
plt.imshow(image, cmap='gray')
plt.title('Original Image')
plt.axis('off')
# 拉普拉斯算子得到的高频信息
plt.subplot(1, 3, 2)
plt.imshow(laplacian_image, cmap='gray')
plt.title('Laplacian Image (High Frequency)')
plt.axis('off')
# 增强后的图像
plt.subplot(1, 3, 3)
plt.imshow(enhanced_image, cmap='gray')
plt.title('Enhanced Image (High Frequency Enhanced)')
plt.axis('off')
plt.tight_layout()
plt.show()
plt_def()
下面用代码实例展示一下:
# 读取图像
image_path = r"E:\1_Technological_Capability\Algorithm\CV\Projects\HSR\My_Work\Jie_Net\Learning\9022625033_K1609563_T001_4_13.jpg"
# image_path = image_path = r"E:\1_Technological_Capability\Algorithm\CV\Projects\HSR\My_Work\Jie_Net\Learning\kodim23.png"
image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
# 使用Otsu's二值化分割图像
_, mask = cv2.threshold(image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
def plt_def():
# 显示图像和掩码
plt.figure(figsize=(10, 5))
# 原始图像
plt.subplot(1, 2, 1)
plt.imshow(image, cmap='gray')
plt.title('Original Image')
plt.axis('off')
# 生成的掩码
plt.subplot(1, 2, 2)
plt.imshow(mask, cmap='gray')
plt.title('Generated Mask')
plt.axis('off')
plt.tight_layout()
plt.show()
plt_def()
使用Otsu’s二值化方法对灰度图像进行阈值分割时,可以使用OpenCV中的cv2.threshold()函数。该函数将灰度图像转换为二值图像,其中像素值只能为0或255,用于表示对象和背景。
使用Otsu’s二值化方法,我们不需要手动选择阈值,而是通过算法自动确定最佳阈值,以便将图像分割为对象和背景。这种方法适用于具有双峰直方图的图像,其中双峰分别对应于对象和背景的像素值。
通过使用cv2.threshold()函数并指定阈值类型为cv2.THRESH_BINARY +
cv2.THRESH_OTSU,我们可以得到一个二值化图像,其中大于阈值的像素值为255,小于等于阈值的像素值为0。这样就实现了对灰度图像的自动阈值分割,生成了一个二值化的掩码图像,用于表示对象和背景的像素。
什么是形态学处理?
是指一系列用来处理图像中物体形状特征的方法
原理是利用结构元(和卷积核类似的东西,都是一个"矩阵“。但操作不是线性求和,而是逻辑运算),来处理图像中物体的形状特征
基础是集合论(因为是做逻辑运算)
基本概念
结构元(Structuring Elements,SE)可以是任意形状,SE中的的值可以是0或1。常见的结构元有矩形和十字形。结构元有一个锚点O,O一般定义为结构元的中心(也可以自由定义位置)。如下图所示是几个不同形状的结构元,紫红色区域为锚点O。
不做特殊说明,输入图像为二值图像。图像中1是前景,0是背景。记 f为原图像, s为结构元
膨胀(Dilation)
将结构元s在图像f上移动,若结构元中为1的位置对应原图像相应位置中像素值最大的赋给当前锚点。
视觉体验如下:
在灰度图像中简记为:”白吃黑“
腐蚀(Erosion)
将结构元s在图像f上移动,若结构元中为1的位置对应原图像相应位置中像素值最小的赋给当前锚点。
视觉体验如下:
代码实例
下面我利用膨胀操作,将有影响作用的螺丝给膨胀掉,然后使用腐蚀,还原圆孔大小
# 读取图像
image_path = r"F:/AI/wheelData/VOC2007_LK/JPEGImages/LK0002.png"
image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
# 创建形态学操作的结构元素(这里使用一个3x3的正方形结构元素)
kernel = np.ones((3, 3), np.uint8)
# 膨胀操作
dilated_image = cv2.dilate(image, kernel, iterations=6)
# 对膨胀后的图像进行腐蚀操作
eroded_image = cv2.erode(dilated_image, kernel, iterations=7)
def plt_def():
# 显示图像
plt.figure(figsize=(12, 6))
# 原始图像
plt.subplot(1, 3, 1)
plt.imshow(image, cmap='gray')
plt.title('Original Image')
plt.axis('off')
# 膨胀后的图像
plt.subplot(1, 3, 2)
plt.imshow(dilated_image, cmap='gray')
plt.title('Dilated Image')
plt.axis('off')
# 腐蚀后的图像
plt.subplot(1, 3, 3)
plt.imshow(eroded_image, cmap='gray')
plt.title('Eroded Image')
plt.axis('off')
plt.tight_layout()
plt.show()
plt_def()
import cv2
import matplotlib.pyplot as plt
# 读取RGB图像
image_path = r"F:\AI\Learning\kodim23.png"
image = cv2.imread(image_path)
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # 转换为RGB
# 转换为其他颜色空间
image_bgr = image # BGR格式
image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 灰度图
image_hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) # HSV
image_ycrcb = cv2.cvtColor(image, cv2.COLOR_BGR2YCrCb) # YCrCb
image_hls = cv2.cvtColor(image, cv2.COLOR_BGR2HLS) # HLS
image_xyz = cv2.cvtColor(image, cv2.COLOR_BGR2XYZ) # XYZ
image_lab = cv2.cvtColor(image, cv2.COLOR_BGR2LAB) # LAB
image_yuv = cv2.cvtColor(image, cv2.COLOR_BGR2YUV) # YUV
def plt_def():
# 显示图像
plt.figure(figsize=(14, 10))
plt.subplot(3, 3, 1)
plt.imshow(image_rgb)
plt.title('RGB')
plt.axis('off')
plt.subplot(3, 3, 2)
plt.imshow(image_bgr)
plt.title('BGR')
plt.axis('off')
plt.subplot(3, 3, 3)
plt.imshow(image_gray, cmap='gray')
plt.title('GRAY')
plt.axis('off')
plt.subplot(3, 3, 4)
plt.imshow(image_hsv)
plt.title('HSV')
plt.axis('off')
plt.subplot(3, 3, 5)
plt.imshow(image_ycrcb)
plt.title('YCrCb')
plt.axis('off')
plt.subplot(3, 3, 6)
plt.imshow(image_hls)
plt.title('HLS')
plt.axis('off')
plt.subplot(3, 3, 7)
plt.imshow(image_xyz)
plt.title('XYZ')
plt.axis('off')
plt.subplot(3, 3, 8)
plt.imshow(image_lab)
plt.title('LAB')
plt.axis('off')
plt.subplot(3, 3, 9)
plt.imshow(image_yuv)
plt.title('YUV')
plt.axis('off')
plt.tight_layout()
plt.show()
plt_def()
图像预处理中的数学和统计处理涵盖了多种技术和方法,旨在对图像进行数学变换、特征提取、噪声去除和增强等操作。这些处理可以用于改善图像质量、准备图像数据以供后续分析或机器学习任务使用。
以下是一些常见的数学和统计处理技术,它们常用于图像预处理:
灰度变换:
直方图处理:
滤波器和卷积:
傅里叶变换:
形态学处理:
阈值分割:
降噪:
特征提取:
这些数学和统计处理方法可以根据特定任务的需求进行组合和调整,以实现预期的图像预处理效果。
写在最后:文章内容主要来自以下参考以及个人理解、实验室学长讲解和讨论,因为个人专业能力和知识还在提升中,若文章内容有错误或有失偏颇的地方,还请大家多多指出
后续还会围绕《计算机视觉度量从特征描述到深度学习》这本书的学习持续更新相关内容
参考: