最近做目标检测与图像分类,但是可以收集到的数据集太少了,于是想着做一个图像增强软件,可以实现有效的可视化多图增强。
查阅相关资料,知道了要做哪几种图像增强 。下面这边文章是理论部分
深度学习中的图像数据扩增(Data Augmentations)方法总结:常用传统扩增方法及应用
import sys
import cv2
import numpy as np
from PySide6.QtWidgets import QMainWindow, QApplication, QFileDialog
from PySide6.QtGui import QPixmap,QImage
from data_argument_ui import Ui_MainWindow
from image_processing import ImageProcessor
def convert_cv2_to_pixmap(cv2_image):
# 将cv2导出的图像转换为QImage
cv2_image = cv2.cvtColor(cv2_image, cv2.COLOR_BGR2RGB)
height, width, channel = cv2_image.shape
bytesPerLine = 3 * width
qImg = QImage(cv2_image.data, width, height, bytesPerLine, QImage.Format_RGB888)
# 使用QPixmap将QImage转换为可在界面中显示的格式
pixmap = QPixmap.fromImage(qImg)
return pixmap
class MainWindow(QMainWindow, Ui_MainWindow,ImageProcessor):
def __init__(self):
super(MainWindow, self).__init__()
self.setupUi(self)
self.textBrowser.ensureCursorVisible() # 使得文本自动换行
# 按键关联
self.bind_slots()
# -----按钮函数--start-----#
def open_image(self):
self.to_ui("打开图片")
file_path = QFileDialog.getOpenFileName(self, dir="", filter="*.jpg;*.png;*.jpeg")
if file_path:
self.path = file_path[0] # 不能少这一句
self.in0.setPixmap(QPixmap.fromImage(QImage(self.path)))
# 数据增强
self.renew()
def renew(self):
# -----数据增强处理--start-----#
# X轴翻转
image = self.cv_xflipping(self.path)
self.in1.setPixmap(convert_cv2_to_pixmap(image))
name = "result/ " +"1100003"+ "_01" +".jpg"
cv2.imwrite(name, image)
# 随机旋转
image,angle= self.cv_rotation(self.path)
name = "result/ " +"1100003"+ "_02" +".jpg"
cv2.imwrite(name, image)
print(f"随机角度: {round(angle,2)} ℃")
self.in2.setPixmap(convert_cv2_to_pixmap(image))
# 随机缩放
image,scale_percent = self.cv_scaling(self.path)
name = "result/ " +"1100003"+ "_03" +".jpg"
cv2.imwrite(name, image)
print(f"缩放比例 {round(scale_percent/100,2)} ")
self.in3.setPixmap(convert_cv2_to_pixmap(image))
# 平移
image = self.cv_translation(self.path) #
name = "result/ " +"1100003"+ "_04" +".jpg"
cv2.imwrite(name, image)
self.in4.setPixmap(convert_cv2_to_pixmap(image))
# 裁剪
image = self.cv_cropping(self.path,150,150) #
name = "result/ " +"1100003"+ "_05" +".jpg"
cv2.imwrite(name, image)
self.in5.setPixmap(convert_cv2_to_pixmap(image))
# 6 加入噪声,可选随机噪声,如高斯噪声、椒盐噪声
image = self.cv_noise(self.path,'gaussian') #
name = "result/ " +"1100003"+ "_06" +".jpg"
cv2.imwrite(name, image)
self.in6.setPixmap(convert_cv2_to_pixmap(image))
# 改变对比度
image = self.cv_Contrast(self.path) #
name = "result/ " +"1100003"+ "_07" +".jpg"
cv2.imwrite(name, image)
self.in7.setPixmap(convert_cv2_to_pixmap(image))
# 改变饱和度
image = self.cv_Saturation(self.path) #
name = "result/ " +"1100003"+ "_08" +".jpg"
cv2.imwrite(name, image)
self.in8.setPixmap(convert_cv2_to_pixmap(image))
# 改变亮度
image = self.cv_Light(self.path) #
name = "result/ " +"1100003"+ "_09" +".jpg"
cv2.imwrite(name, image)
self.in9.setPixmap(convert_cv2_to_pixmap(image))
# 直方图增强
image = self.cv_histogram(self.path) #
name = "result/ " +"1100003"+ "_10" +".jpg"
cv2.imwrite(name, image)
self.in10.setPixmap(convert_cv2_to_pixmap(image))
# 灰度图
image = self.cv_gray(self.path) #
name = "result/ " +"1100003"+ "_11" +".jpg"
cv2.imwrite(name, image)
self.in11.setPixmap(convert_cv2_to_pixmap(image))
# 随机擦除
image = self.cv_reasing(self.path) #
name = "result/ " +"1100003"+ "_12" +".jpg"
cv2.imwrite(name, image)
self.in12.setPixmap(convert_cv2_to_pixmap(image))
# -----数据增强处理--end-----#
def check(self):
pass
def saveAll(self):
pass
# -----按钮函数--end-----#
def func(self):
print(self)
# print(self.rotate.isChecked())
def checkOK(self):
pass
# 检测那个按钮被按下
# print(self.V3buttonGroup.checkedButton().text())
# print(self.rotate.isChecked())
def V1(self):
if self.xflipping.isChecked():
print("X 翻转")
if self.rotation.isChecked():
print("随机旋转")
if self.scaling.isChecked():
print("3")
if self.translation.isChecked():
print("4")
if self.cropping.isChecked():
print("5")
if self.noise.isChecked():
print("6")
if self.Contrast.isChecked():
print("7")
if self.Saturation.isChecked():
print("8")
if self.Light.isChecked():
print("9")
if self.histogram.isChecked():
image = self.cv_histogram(self.path) #
if self.gray.isChecked():
image = self.cv_gray(self.path) #
if self.reasing.isChecked():
image = self.cv_reasing(self.path) #
self.in13.setPixmap(convert_cv2_to_pixmap(image))
# -----其他-------#
def to_ui(self,str):
out= str
self.textBrowser.append(out)
def bind_slots(self):
# -----按钮-------#
self.picture.clicked.connect(self.open_image)
self.reLoad.clicked.connect(self.renew)
self.check.clicked.connect(self.checkOK)
self.save.clicked.connect(self.saveAll)
# -----其他-------#
self.buttonGroup.buttonClicked.connect(self.V1)
if __name__ == "__main__":
app = QApplication(sys.argv)
# print(11)
window = MainWindow()
window.show()
app.exec()
import cv2
import numpy as np
import random
from random import randint
class ImageProcessor:
def __init__(self):
pass
def cv_xflipping(self, image_path):
image = cv2.imread(image_path)
flipped_image = cv2.flip(image, 1)
return flipped_image
def cv_rotation(self, image_path):
# 读取图片
image = cv2.imread(image_path)
# 生成随机角度
angle = random.uniform(-20, 20)
# 获取图像尺寸
height, width = image.shape[:2]
center = (width / 2, height / 2)
# 旋转矩阵
rotation_matrix = cv2.getRotationMatrix2D(center, angle, 1.0)
# 执行旋转
rotated_image = cv2.warpAffine(image, rotation_matrix, (width, height), borderMode=cv2.BORDER_CONSTANT, borderValue=(255, 255, 255))
return rotated_image , angle
def cv_scaling(self,image_path):
# 读取图片
image = cv2.imread(image_path)
scale_percent = randint(80,99)
# 获取图像尺寸
width = int(image.shape[1] * scale_percent / 100)
height = int(image.shape[0] * scale_percent / 100)
dim = (width, height)
# 执行缩放
resized_image = cv2.resize(image, dim, interpolation=cv2.INTER_AREA)
# 创建空白画布
new_image = np.ones((height, width, 3), dtype=np.uint8) * 255
# 将缩放后的图片放置在新画布上
x_offset = (new_image.shape[1] - resized_image.shape[1]) // 2
y_offset = (new_image.shape[0] - resized_image.shape[0]) // 2
new_image[y_offset:y_offset+resized_image.shape[0], x_offset:x_offset+resized_image.shape[1]] = resized_image
return new_image ,scale_percent
def cv_translation(self,image_path):
# 读取图片
image = cv2.imread(image_path)
tx, ty = randint(-20,20), randint(-20,20)
# 构建平移矩阵
M = np.float32([[1, 0, tx], [0, 1, ty]])
# 执行平移
translated_image = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]), borderValue=(255, 255, 255))
return translated_image
def cv_cropping(self,image_path, crop_width, crop_height):
# 读取图片
image = cv2.imread(image_path)
# 获取图片的宽度和高度
image_height, image_width = image.shape[:2]
# 生成随机裁剪的起始点
start_x = random.randint(0, image_width - crop_width)
start_y = random.randint(0, image_height - crop_height)
# 执行裁剪
cropped_image = image[start_y:start_y+crop_height, start_x:start_x+crop_width]
# 创建白色背景
white_background = np.ones((crop_height, crop_width, 3), np.uint8) * 255
# 将裁剪的部分放到白色背景中
white_background[0:cropped_image.shape[0], 0:cropped_image.shape[1]] = cropped_image
return white_background
def cv_noise(self, image_path, noise_type):
# 读取图片
image = cv2.imread(image_path)
# 添加随机噪声
if noise_type == 'random':
noise = np.random.rand(*image.shape) * 255
noisy_image = cv2.addWeighted(image, 0.9, noise, 0.1, 0)
# 添加高斯噪声
elif noise_type == 'gaussian':
mean = 0
std_dev = 10
noise = np.random.normal(mean, std_dev, image.shape)
noisy_image = cv2.add(image, noise.astype(np.uint8))
# 添加椒盐噪声
elif noise_type == 'salt_pepper':
noisy_image = image.copy()
salt_vs_pepper = 0.5
num_salt = np.ceil(salt_vs_pepper * image.size * 0.5)
coords = [np.random.randint(0, i - 1, int(num_salt)) for i in image.shape]
noisy_image[coords] = 1
num_pepper = np.ceil(salt_vs_pepper * image.size * 0.5)
coords = [np.random.randint(0, i - 1, int(num_pepper)) for i in image.shape]
noisy_image[coords] = 0
else:
raise ValueError("不支持的噪声类型")
return noisy_image.astype(np.uint8)
def cv_Contrast(self,image_path):
# alpha 是对比度调整参数,它控制图像的白色和黑色之间的对比度。当 alpha 大于 1 时,对比度增加;当 alpha 小于 1 时,对比度减小。
# beta 是亮度调整参数,它控制整个图像的亮度。当 beta 大于 0 时,图像变亮;当 beta 小于 0 时,图像变暗。
# 读取图片
img = cv2.imread(image_path)
alpha = random.uniform(0.7,1.3)
# 调整对比度和亮度
adjusted_img = cv2.convertScaleAbs(img, alpha=alpha)
return adjusted_img
def cv_Saturation(self, image_path):
# 读取图片
img = cv2.imread(image_path)
saturation_factor = random.uniform(0,2)
# 将图片转换为HSV颜色空间
hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# 调整饱和度
h, s, v = cv2.split(hsv_img)
s = np.clip(s * saturation_factor, 0, 255).astype(np.uint8)
adjusted_hsv_img = cv2.merge([h, s, v])
# 将调整后的图片转换回BGR颜色空间
adjusted_img = cv2.cvtColor(adjusted_hsv_img, cv2.COLOR_HSV2BGR)
return adjusted_img
def cv_Light(self,image_path):
# alpha 是对比度调整参数,它控制图像的白色和黑色之间的对比度。当 alpha 大于 1 时,对比度增加;当 alpha 小于 1 时,对比度减小。
# beta 是亮度调整参数,它控制整个图像的亮度。当 beta 大于 0 时,图像变亮;当 beta 小于 0 时,图像变暗。
# 读取图片
img = cv2.imread(image_path)
beta = random.uniform(-30,30)
# 调整对比度和亮度
adjusted_img = cv2.convertScaleAbs(img, beta=beta)
return adjusted_img
def cv_histogram(self, image_path):
# 彩色图 好像不能做直方图增强
# 读取彩色图片
img = cv2.imread(image_path)
# 将彩色图片转换为YUV颜色空间
img_yuv = cv2.cvtColor(img, cv2.COLOR_BGR2YUV)
# 对Y通道进行直方图均衡化
img_yuv[:,:,0] = cv2.equalizeHist(img_yuv[:,:,0])
# 将增强后的YUV图片转换回BGR颜色空间
img_output = cv2.cvtColor(img_yuv, cv2.COLOR_YUV2BGR)
return img_output
def cv_gray(self, image_path):
# 读取彩色图片
img = cv2.imread(image_path)
# 将彩色图片转换为灰度图
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
return gray_img
def cv_reasing(self, image_path):
# 读取彩色图片
img = cv2.imread(image_path)
# 获取图片的高度和宽度
height, width, _ = img.shape
# 随机生成擦除框的起始点和大小
x = np.random.randint(0, width - 50)
y = np.random.randint(0, height - 50)
w = np.random.randint(50, 100)
h = np.random.randint(50, 100)
# 在图片上随机擦除
img[y:y+h, x:x+w] = np.random.randint(0, 256)
return img
# 使用示例
if __name__ == "__main__":
# 创建ImageProcessor对象,传入图像路径
processor = ImageProcessor()
img = cv2.imread('1100003.jpg')
cv2.imshow('original', img)
# 对图像进行X轴翻转
image= processor.cv_reasing('1100003.jpg')
# 显示翻转后的图像
cv2.imshow('output', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
工程链接,免费下载
还有需要完善的地方,交流联系:QQ 1727359387