- 👋 Hi, I’m @货又星
- 👀 I’m interested in …
- 🌱 I’m currently learning …
- 💞️ I’m looking to collaborate on …
- 📫 How to reach me …
概要
计算机视觉 模型训练 图像预处理 图像识别 深度学习 卷积神经网络CNN 图像分类
在计算机视觉领域,图像预处理是CNN等深度学习模型训练的重要步骤。它包括一系列操作,如椒盐噪声、高斯噪声、调整图像的昏暗和亮度、旋转、翻转、随机裁剪、缩放、随机旋转、平移以及高斯模糊处理等。这些操作不仅可以改善图像的质量,增加图像的识别率,而且可以提升计算机视觉模型的性能。
第三方库需求和技术名词解释
库的需求
- random
- cv2
- numpy
- os
- torchvision
- PIL
这些库的安装都比较简单,大部分是自带库,剩下的也都是用pip可以完成的。参考简单包torchvision、PIL、cv2的安装
技术名词解释
- image: 用 cv2.imread()读取 或者 image.load_img()后img_to_array()读取 的图像RGB array数组
- percetage: 图像处理的比例
- angle: 图像旋转的角度
- 函数返回PTL Image对象便于保存展示
去除噪声
主要说说椒盐噪声和高斯噪声
椒盐噪声和高斯噪声都是在数字图像处理中常见的噪声类型,通常由图像传感器、传输信道及解码处理等因素产生。
椒盐噪声,如其名称所示,是随机的黑色和白色像素点混杂在图像中,这使得图像中的一些像素点变得十分明显且不规则。这种噪声可能由于传感器损坏、传输错误或压缩等原因而产生。因为椒盐噪声可以看做是一种逻辑噪声,用线性滤波器滤除的效果往往并不理想,一般采用中值滤波器可以得到较好的去噪效果。
# 椒盐噪声
def SaltAndPepper(self,image,percetage):
SP_NoiseImg=image.copy()
h, w = image.shape[:2]
SP_NoiseNum=int(percetage*h*w)
for i in range(SP_NoiseNum):
randR=np.random.randint(0,h-1)
randG=np.random.randint(0,w-1)
randB=np.random.randint(0,3)
if np.random.randint(0,1)==0:
SP_NoiseImg[randR,randG,randB]=0
else:
SP_NoiseImg[randR,randG,randB]=255
return Image.fromarray(SP_NoiseImg)
另一方面,高斯噪声是指其概率密度函数服从高斯分布(即正态分布)的一类噪声。这种噪声的特点是某个强度的噪声点个数最多,离这个强度越远噪声点个数越少,且这个规律服从高斯分布。它是一种加性噪声,即噪声直接加到原图像上,因此可以用线性滤波器滤除。但是当高斯噪声的方差较大时,中值滤波可能会导致图像模糊和细节信息的丢失。
# 高斯噪声
def addGaussianNoise(self,image,percetage):
G_Noiseimg = image.copy()
h, w = image.shape[:2]
G_NoiseNum=int(percetage*h*w)
for i in range(G_NoiseNum):
temp_x = np.random.randint(0,h)
temp_y = np.random.randint(0,w)
G_Noiseimg[temp_x][temp_y][np.random.randint(3)] = np.random.randn(1)[0]
return Image.fromarray(G_Noiseimg)
总的来说,这两种噪声都会对图像质量产生负面影响,需要通过适当的去噪方法来改善图像质量。在图像处理中,可以通过滤波器来去除这些噪声,从而改善图像质量。
亮度调整
昏暗与明亮
通过调整图像的昏暗和明亮可以使图像更加清晰,突出图像的主要特征。这个比较容易理解,就不详细解释了,直接上代码。
# 昏暗
def darker(self,image,percetage=0.9):
image_copy = image.copy()
h, w = image.shape[:2]
#get darker
for xi in range(0,w):
for xj in range(0,h):
image_copy[xj,xi,0] = int(image[xj,xi,0]*percetage)
image_copy[xj,xi,1] = int(image[xj,xi,1]*percetage)
image_copy[xj,xi,2] = int(image[xj,xi,2]*percetage)
return Image.fromarray(image_copy)
# 亮度
def brighter(self,image,percetage=1.5):
image_copy = image.copy()
h, w = image.shape[:2]
#get brighter
for xi in range(0,w):
for xj in range(0,h):
image_copy[xj,xi,0] = np.clip(int(image[xj,xi,0]*percetage),a_max=255,a_min=0)
image_copy[xj,xi,1] = np.clip(int(image[xj,xi,1]*percetage),a_max=255,a_min=0)
image_copy[xj,xi,2] = np.clip(int(image[xj,xi,2]*percetage),a_max=255,a_min=0)
return Image.fromarray(image_copy)
几何变换
主要包括旋转、翻转、随机裁剪、缩放、随机旋转和平移
旋转、翻转、随机裁剪、缩放、随机旋转和平移等几何变换可以增加模型对物体形状和方向的鲁棒性。例如,通过随机裁剪和缩放可以扩充数据集,防止模型过拟合;旋转、翻转和平移等操作则可以提高模型的泛化能力。
# 旋转
def rotate(self,image,angle,center=None, scale=1.0):
h, w = image.shape[:2]
# If no rotation center is specified, the center of the image is set as the rotation center
if center is None:
center = (w / 2, h / 2)
m = cv2.getRotationMatrix2D(center, angle, scale)
rotated = cv2.warpAffine(image, m, (w, h))
return Image.fromarray(rotated)
# 翻转
def flip(self,image):
flipped_image = np.fliplr(image)
return Image.fromarray(flipped_image)
# 随机裁剪
def caijian(self,image):
h, w = image.shape[:2]
minsize = min(w, h)
transform = transforms.RandomCrop(minsize)
image=Image.fromarray(image)
return transform(image)
# 缩放 *2
def suofang(self,image):
h, w = image.shape[:2]
transform = transforms.Resize(( h * 2,w * 2))
image = Image.fromarray(image)
return transform(image)
# 随机旋转
def xuanzhuan(self,image):
transform_1 = transforms.RandomRotation(degrees=(45, 45), expand=True)
image = Image.fromarray(image)
return transform_1(image)
# 随机平移
def pingyi(self,image):
# 获取图像高度和宽度
h, w = image.shape[:2]
# 定义平移矩阵,向右移动x像素,向下移动y像素
# 平移矩阵(浮点数类型) x_shift +右移 -左移 y_shift -上移 +下移
x=random.randint(0,w)
y=random.randint(0,h)
M = np.float32([[1, 0, x], [0, 1, y]])
# 应用平移矩阵,实现图像平移
shifted = cv2.warpAffine(image, M, (w,h))
return Image.fromarray(shifted)
高斯模糊处理
高斯模糊处理
高斯模糊处理是一种常用的图像处理方法,它可以减少图像中的噪声并突出图像的主要特征。这对于提高计算机视觉模型的性能至关重要。
# 高斯模糊处理
def gaussianBlur(self,image,ksize,sigmaX):
blur = cv2.GaussianBlur(image, ksize, sigmaX)
# cv2.GaussianBlur(图像,卷积核,标准差)
return Image.fromarray(blur)
高斯模糊,又被称为高斯平滑,是一种广泛应用于图像处理软件如Adobe Photoshop、GIMP以及Paint.NET中的处理效果。这种处理方式通常用于减少图像噪声以及降低细节层次。
具体来说,高斯模糊实现的方式是将每个像素点和其周围像素点以某种方式进行混合。这样可以在不改变原图的大致形态的前提下,让图像看上去像是经过了模糊处理。
为了达到这个效果,高斯模糊采用了卷积运算。在这个过程中,每一个像素点的值,都是由其自身和邻域内的其他像素值按照一定的权重进行加权平均得到的。这个权重的分配,正是按照高斯函数的形式进行的。也就是说,距离当前像素点越远的像素,其对新的像素值的贡献越小。
因此,高斯模糊不仅可以有效地消除图像中的噪声,还能保持图像的整体轮廓,不会过分强调图像的细节部分。这使得高斯模糊成为了图像处理中常用的一种技术手段。
技术细节、源码分享
将以上图像预处理封装成类
class Picture_Enhancement(): # 图像处理类
# 传入 用cv2.imread()读取 或者 image.load_img()后img_to_array()读取 的图像RGB array数组
# 返回PTL Image对象便于保存展示
def __init__(self): # 没有参数的构造器,调用函数时必须传入图像的RGB array数组
pass
# 椒盐噪声
def SaltAndPepper(self,image,percetage):
SP_NoiseImg=image.copy()
h, w = image.shape[:2]
SP_NoiseNum=int(percetage*h*w)
for i in range(SP_NoiseNum):
randR=np.random.randint(0,h-1)
randG=np.random.randint(0,w-1)
randB=np.random.randint(0,3)
if np.random.randint(0,1)==0:
SP_NoiseImg[randR,randG,randB]=0
else:
SP_NoiseImg[randR,randG,randB]=255
return Image.fromarray(SP_NoiseImg)
# 高斯噪声
def addGaussianNoise(self,image,percetage):
G_Noiseimg = image.copy()
h, w = image.shape[:2]
G_NoiseNum=int(percetage*h*w)
for i in range(G_NoiseNum):
temp_x = np.random.randint(0,h)
temp_y = np.random.randint(0,w)
G_Noiseimg[temp_x][temp_y][np.random.randint(3)] = np.random.randn(1)[0]
return Image.fromarray(G_Noiseimg)
# 昏暗
def darker(self,image,percetage=0.9):
image_copy = image.copy()
h, w = image.shape[:2]
#get darker
for xi in range(0,w):
for xj in range(0,h):
image_copy[xj,xi,0] = int(image[xj,xi,0]*percetage)
image_copy[xj,xi,1] = int(image[xj,xi,1]*percetage)
image_copy[xj,xi,2] = int(image[xj,xi,2]*percetage)
return Image.fromarray(image_copy)
# 亮度
def brighter(self,image,percetage=1.5):
image_copy = image.copy()
h, w = image.shape[:2]
#get brighter
for xi in range(0,w):
for xj in range(0,h):
image_copy[xj,xi,0] = np.clip(int(image[xj,xi,0]*percetage),a_max=255,a_min=0)
image_copy[xj,xi,1] = np.clip(int(image[xj,xi,1]*percetage),a_max=255,a_min=0)
image_copy[xj,xi,2] = np.clip(int(image[xj,xi,2]*percetage),a_max=255,a_min=0)
return Image.fromarray(image_copy)
# 旋转
def rotate(self,image,angle,center=None, scale=1.0):
h, w = image.shape[:2]
# If no rotation center is specified, the center of the image is set as the rotation center
if center is None:
center = (w / 2, h / 2)
m = cv2.getRotationMatrix2D(center, angle, scale)
rotated = cv2.warpAffine(image, m, (w, h))
return Image.fromarray(rotated)
# 翻转
def flip(self,image):
flipped_image = np.fliplr(image)
return Image.fromarray(flipped_image)
# 随机裁剪
def caijian(self,image):
h, w = image.shape[:2]
minsize = min(w, h)
transform = transforms.RandomCrop(minsize)
image=Image.fromarray(image)
return transform(image)
# 缩放 *2
def suofang(self,image):
h, w = image.shape[:2]
transform = transforms.Resize(( h * 2,w * 2))
image = Image.fromarray(image)
return transform(image)
# 随机旋转
def xuanzhuan(self,image):
transform_1 = transforms.RandomRotation(degrees=(45, 45), expand=True)
image = Image.fromarray(image)
return transform_1(image)
# 随机平移
def pingyi(self,image):
# 获取图像高度和宽度
h, w = image.shape[:2]
# 定义平移矩阵,向右移动x像素,向下移动y像素
# 平移矩阵(浮点数类型) x_shift +右移 -左移 y_shift -上移 +下移
x=random.randint(0,w)
y=random.randint(0,h)
M = np.float32([[1, 0, x], [0, 1, y]])
# 应用平移矩阵,实现图像平移
shifted = cv2.warpAffine(image, M, (w,h))
return Image.fromarray(shifted)
# 高斯模糊处理
def gaussianBlur(self,image,ksize,sigmaX):
blur = cv2.GaussianBlur(image, ksize, sigmaX)
# cv2.GaussianBlur(图像,卷积核,标准差)
return Image.fromarray(blur)
对整个图像文件夹进行处理
# 使用时传入 需处理图像的文件夹路径,处理后图像保存的文件夹路径,以及Picture_enhancement类对象
def Main(file_dir_old,file_dir_new,pic):
for img_name in os.listdir(file_dir_old):
img_path = file_dir_old + img_name
img = cv2.imread(img_path)
# 增加噪声
img_salt = pic.SaltAndPepper(img,0.3 )
img_salt.save(file_dir_new + img_name[0:7] + '_salt.jpg')
img_gauss = pic.addGaussianNoise(img,0.3)
img_gauss.save(file_dir_new + img_name[0:-4] + '_noise.jpg')
#变亮、变暗
img_darker = pic.darker(img)
img_darker.save(file_dir_new + img_name[0:-4] + '_darker.jpg')
img_brighter = pic.brighter(img)
img_brighter.save(file_dir_new + img_name[0:-4] + '_brighter.jpg')
# 旋转
img_rotate=pic.rotate(img,45)
img_rotate.save(file_dir_new + img_name[0:-4] + '_rotate.jpg')
# 镜像
img_flipped = pic.flip(img)
img_flipped.save(file_dir_new +img_name[0:-4] + '_fli.jpg')
#随机裁剪
img_caijian = pic.caijian(img)
img_caijian.save(file_dir_new + img_name[0:-4] + '_caijian.jpg')
# 缩放*2
img_suofang = pic.suofang(img)
img_suofang.save(file_dir_new + img_name[0:-4] + '_suofang.jpg' )
# 随机旋转
img_xuanzhuan = pic.xuanzhuan(img)
img_xuanzhuan.save(file_dir_new + img_name[0:-4] + '_xuanzhuan.jpg')
# 随机平移
img_pingyi = pic.pingyi(img)
img_pingyi.save(file_dir_new + img_name[0:-4] + '_pingyi.jpg')
# 高斯模糊处理
img_blur = pic.gaussianBlur(img,(7, 7), 1.5)
img_blur.save(file_dir_new + img_name[0:-4] + '_blur.jpg')
对一张图片进行处理并可视化
# 使用时传入 需处理图像的路径,以及Picture_enhancement类对象
def Example(img_path,pic):
img = cv2.imread(img_path)
h, w = img.shape[:2]
canvas = Image.new('RGB', (w * 5, h * 3), color='white') # 创建一个空白图像
# 增加噪声
img_salt = pic.SaltAndPepper(img, 0.3)
canvas.paste(img_salt, (0, 0))
img_gauss = pic.addGaussianNoise(img, 0.3)
canvas.paste(img_gauss, (0 + w, 0))
# 变亮、变暗
img_darker = pic.darker(img)
canvas.paste(img_darker, (0 + 2 * w, 0))
img_brighter = pic.brighter(img)
canvas.paste(img_brighter, (0 + 3 * w, 0))
# 旋转
img_rotate = pic.rotate(img, 45)
canvas.paste(img_rotate, (0, 0 + h))
# 镜像
img_flipped = pic.flip(img)
canvas.paste(img_flipped, (0 + w, 0 + h))
# 随机裁剪
img_caijian = pic.caijian(img)
canvas.paste(img_caijian, (0 + 2 * w, 0 + h))
# 缩放*2
img_suofang = pic.suofang(img)
canvas.paste(img_suofang, (0 + 3 * w, 0 + h))
# 随机旋转
img_xuanzhuan = pic.xuanzhuan(img)
canvas.paste(img_xuanzhuan, (0, 0 + 2 * h))
# 随机平移
img_pingyi = pic.pingyi(img)
canvas.paste(img_pingyi, (0 + w, 0 + 2 * h))
# 高斯模糊处理
img_blur = pic.gaussianBlur(img, (7, 7), 1.5)
canvas.paste(img_blur, (0 + 2 * w, 0 + 2 * h))
canvas.show()
canvas.save("example.jpg")
效果图:
处理依次是:
椒盐噪声 高斯噪声 昏暗 亮度
旋转 翻转 随机裁剪 缩放
随机旋转 平移 高斯模糊处理
主函数
if __name__=="__main__":
pic=Picture_Enhancement() # Picture_Enhancement 对象,传入图像的RGB array数组,返回PTL Image对象便于保存展示
img_path = 'data/normal1.jpg'
Example(img_path=img_path, pic=pic)
Main(file_dir_old="./data/", file_dir_new="./new_data/", pic=pic) # 题目数据增强
Main(file_dir_old="./net_data/",file_dir_new="./new_data/",pic=pic) # 过采样数据增强,解决类别不平衡问题
# 传入图片文件夹路径(工作目录下的image文件夹)
# 对图像进行处理:
# 如:椒盐噪声 高斯噪声 昏暗 亮度 旋转 翻转 随机裁剪 缩放 随机旋转 平移 高斯模糊处理
小结
这里是总结
总的来说,图像预处理在计算机视觉、深度学习、CNN模型训练中起着至关重要的作用。通过对图像进行适当的预处理,我们可以改善图像质量,增加图像的识别率,并提升计算机视觉模型的性能。