import cv2
import os
import numpy as np
# 定义原始图片路径和增强后图片路径
original_path = ''
rotate_flip_path = ''
scale_path = ''
output_path = ''
# 定义旋转的角度和缩放的比例
rotate_angles = [30, 60, 90, 120, 150, 180]
scale_factors = [0.5,1.5]
# 中心裁剪
def crop_image(img, crop_size):
height, width = img.shape[:2]
y_start = int(height / 2 - crop_size[0] / 2)
y_end = y_start + crop_size[0]
x_start = int(width / 2 - crop_size[1] / 2)
x_end = x_start + crop_size[1]
return img[y_start:y_end, x_start:x_end]
# 遍历文件夹下的所有图片,进行数据增强
for filename in os.listdir(original_path):
if filename.endswith('.png'): # 判断文件是否为png格式的图像文件
# 读取原始图像
img = cv2.imread(os.path.join(original_path, filename))
# 对原始图像进行旋转、翻转、缩放
for angle in rotate_angles:
# 旋转操作
M = cv2.getRotationMatrix2D((img.shape[1] / 2, img.shape[0] / 2), angle, 1)
rotated_img = cv2.warpAffine(img, M, (img.shape[1], img.shape[0]))
cv2.imwrite(os.path.join(rotate_flip_path, filename.split('.')[0] + '_rotate_' + str(angle) + '.png'), rotated_img)
# 翻转操作
flipped_img = cv2.flip(rotated_img, 1)
cv2.imwrite(os.path.join(rotate_flip_path, filename.split('.')[0] + '_rotate_' + '_flip_' + str(angle) + '.png'), flipped_img)
for filename in os.listdir(rotate_flip_path):
if filename.endswith('.png'): # 判断文件是否为png格式的图像文件
# 读取原始图像
img = cv2.imread(os.path.join(rotate_flip_path, filename))
for factor in scale_factors:
# 缩放操作
scaled_img = cv2.resize(img, None, fx=factor, fy=factor, interpolation=cv2.INTER_LINEAR)
cv2.imwrite(os.path.join(scale_path, filename.split('.')[0] + '_scale_' + str(factor) + '.png'), scaled_img)
# 将文件中心裁剪后放入同一文件夹
for filename in os.listdir(original_path):
if filename.endswith('.png'): # 判断文件是否为png格式的图像文件
# 读取原始图像
img=cv2.imread(os.path.join(original_path, filename))
new_img = crop_image(img, (320, 320))
cv2.imwrite(os.path.join(output_path, filename), new_img)
for filename in os.listdir(rotate_flip_path):
if filename.endswith('.png'): # 判断文件是否为png格式的图像文件
# 读取原始图像
img=cv2.imread(os.path.join(rotate_flip_path, filename))
new_img = crop_image(img, (320, 320))
cv2.imwrite(os.path.join(output_path, filename), new_img)
for filename in os.listdir(scale_path):
if filename.endswith('.png'): # 判断文件是否为png格式的图像文件
# 读取原始图像
img=cv2.imread(os.path.join(scale_path, filename))
new_img = crop_image(img, (320, 320))
cv2.imwrite(os.path.join(output_path, filename), new_img)
旋转、翻转和缩放:首先将original_path的图片按照不同角度进行旋转,再将每一张旋转后的图片进行水平翻转,存入rotate_flip_path,然后将rotate_flip_path的图片按照不同比例进行缩放,存入scale_path,最后将rotate_flip_path和scale_path的图片进行中心裁剪(注意原图宽高要大于320,裁剪出来的图片不是320*320)后存入output_path。
import numpy as np
import cv2
def addGaussNoise(img): # 添加高斯噪声函数
# 添加高斯噪声
mean = 0
variance = 0.1
sigma = np.sqrt(variance)
gaussian = np.random.normal(mean, sigma, img.shape).astype('float32')
# 将图像类型转换为相同类型
img = img.astype(np.float32)
gaussian = gaussian.astype(np.float32)
noisy_image = cv2.add(img, gaussian)
return noisy_image
def addSaltNoise(img): # 添加椒盐噪声函数
# 添加椒盐噪声
s_vs_p = 0.5
amount = 0.004
out = np.copy(img)
# 椒盐噪声数量
num_salt = np.ceil(amount * img.size * s_vs_p)
coords = [np.random.randint(0, i - 1, int(num_salt)) for i in img.shape]
out[coords] = 1
# 椒盐噪声数量
num_pepper = np.ceil(amount * img.size * (1. - s_vs_p))
coords = [np.random.randint(0, i - 1, int(num_pepper)) for i in img.shape]
out[coords] = 0
return out
def addSpeckleNoise(img): # 添加乘法噪声函数
# 生成均值为1,标准差为0.1的乘法噪声
noise = np.random.normal(loc=1, scale=0.1, size=img.shape[:2])
# 将噪声与图像相乘
noisy_img = (img * noise[:, :, np.newaxis]).astype(np.uint8)
return noisy_img
import random
import glob
import shutil
# 获取文件夹下所有png文件的路径列表
png_files = glob.glob('*.png')
# 随机选择30个文件
random_files = random.sample(png_files, 30)
# 将随机选择的文件复制到指定文件夹
for file in random_files:
img = cv2.imread(file)
Gauss_img = addGaussNoise(img)
cv2.imwrite(file.split('.')[0] + '_Gauss_' + '.png', Gauss_img)
添加高斯噪声、椒盐噪声和乘法噪声:通过glob.glob('*.png')提取所有png图像文件,然后使用random.sample(png_files, 30)随机选择30个文件,再遍历每一个文件添加噪声后存入指定文件夹。
import os
import cv2
source_path = ''
target_path = ''
target_size = (320, 320)
if not os.path.exists(target_path):
os.makedirs(target_path)
for filename in os.listdir(source_path):
if filename.endswith('.png'):
img_path = os.path.join(source_path, filename)
img = cv2.imread(img_path)
img_resized = cv2.resize(img, target_size)
target_file = os.path.join(target_path, filename)
cv2.imwrite(target_file, img_resized)
输出统一尺寸大小图片
注意事项:
1、为什么有文件却不能读取到?
可能有几个原因导致无法读取到文件:
-
路径不正确:如果文件路径不正确,程序将无法找到文件。请确保您提供的文件路径是正确的。
-
文件名拼写错误:如果您的文件名拼写有误,则可能会导致无法找到文件。请确保文件名拼写正确。
-
文件权限问题:如果您没有访问文件的权限,则可能无法读取文件。请检查文件权限。
-
文件已被占用:如果另一个程序正在使用该文件,则您可能无法访问该文件。请确保文件没有被其他程序锁定。
-
文件损坏:如果文件已损坏,则可能无法读取文件。请检查文件是否已正确下载或是否存在其他问题。
2、为什么输出图片的颜色不一样?
1. 当使用OpenCV读取图片时,默认情况下会按照BGR顺序读取,而不是常见的RGB顺序。如果需要按RGB顺序读取图片。可以使用以下代码:
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
2. 这可能是由于图像被压缩导致的色彩失真问题。你可以尝试修改保存图片时的参数,比如指定保存为无损压缩格式,来避免这个问题。可以使用以下代码:
cv2.imwrite('noisy_image.png', noisy_img, [cv2.IMWRITE_PNG_COMPRESSION, 0])
3、cv2处理的数据类型是什么?
cv2处理的数据类型是numpy.ndarray,即cv2.imread()的输入是图像数据(heihgt*width*channel个整数),输出是numpy.ndarray三维数组。即cv2.imwrite()的输入是numpy.ndarray三维数组,输出是(heihgt*width*channel个整数)