From 52f242245bcaff0021962477e384be40b70d8df5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E5=AE=B6=E4=B9=90?= <14352673+xujialellll@user.noreply.gitee.com> Date: Sun, 2 Jun 2024 15:04:17 +0000 Subject: [PATCH] update util.py. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 徐家乐 <14352673+xujialellll@user.noreply.gitee.com> --- util.py | 122 +++++++++++++++++++++++++------------------------------- 1 file changed, 55 insertions(+), 67 deletions(-) diff --git a/util.py b/util.py index c57a032..48662b9 100644 --- a/util.py +++ b/util.py @@ -1,3 +1,5 @@ +### 姓名:徐家乐 +### 学号:202252320405 import os # 导入os模块,用于处理文件和目录 import cv2 as cv # 导入cv2模块,用于图像处理 from zipfile import ZipFile # 从zipfile模块导入ZipFile,用于处理zip文件 @@ -11,82 +13,68 @@ import yaml # 导入yaml模块,用于处理YAML文件 # 这个函数用于对图像进行随机变换 # scale_min和scale_max用于设置缩放范围 # 函数返回处理后的图像 -def random_transform(img, scale_min=0.5, scale_max=1.5): # 定义random_transform函数,用于对图像进行随机变换 +# 这个函数用于对图像进行随机变换 +def random_transform(img, scale_min=0.5, scale_max=1.5): h, w = img.shape[:2] # 获取图像的高度和宽度 # 1. 把图像进行在scale_min到scale_max范围内的随机缩放,缩放后(从图像中心)裁剪回原始大小 - # TODO - - cropped_img = # TODO:这是裁剪后的图像 - - - # 结语正负45°之间的某一个角度随机旋转图像,并保持裁剪后的图像大小 - # TODO - rotated_img = # TODO:这是旋转后的图像 - - return rotated_img # 返回旋转后的图像 + scale = random.uniform(scale_min, scale_max) + new_h, new_w = int(h * scale), int(w * scale) + img = cv.resize(img, (new_w, new_h)) + + # 计算随机旋转角度 + angle = random.uniform(-45, 45) + + # 执行旋转和裁剪 + M = cv.getRotationMatrix2D((new_w / 2, new_h / 2), angle, 1) + rotated_img = cv.warpAffine(img, M, (new_w, new_h)) + x = random.randint(0, new_w - w) + y = random.randint(0, new_h - h) + cropped_img = rotated_img[y:y+h, x:x+w] + + return cropped_img # 这个函数用于处理zip文件中的图像,可以设置缩放范围、生成图像数量、进度回调、线程事件和输出类型 -# zip_path用于指定zip文件的路径 -# scale_min和scale_max用于设置缩放范围 -# num_images用于设置生成图像的数量 -# progress_callback用于设置进度回调,传入的是 batch_transform_app.py 中的 update_progress_callback 函数 -# thread_event用于设置线程事件 -# output_type用于设置输出图像通道数,可以是RGB、Grayscale或Binary -def process_images_from_zip(zip_path, scale_min=0.5, scale_max=1.5, num_images=10, progress_callback=None, thread_event=None, output_type='RGB'): - - # 如果没有,则创建 out 文件夹 +def process_images_from_zip(zip_path, scale_min=0.5, scale_max=1.5, num_images=10, progress_callback=None, thread_event=None, output_type='RGB'): out_path = 'out/' # 设置输出路径 if not os.path.exists(out_path): # 如果输出路径不存在 logging.info('创建输出目录 %s', out_path) # 记录日志,创建输出目录 - os.mkdir(out_path) # 创建输出目录 - + os.makedirs(out_path) # 创建输出目录 + # 打开zip文件并获取其中的文件列表 - logging.info('开始处理zip文件中的图像') # 记录日志,开始处理zip文件中的图像 - with ZipFile(zip_path, 'r') as zipped: # 打开zip文件 - namelist = [name for name in zipped.namelist() if name.lower().endswith(('.png', '.jpg', '.jpeg', '.tiff', '.bmp', '.gif'))] # 获取zip文件中所有图像的文件名 - length = len(namelist) # 获取文件名列表的长度 - - for name in namelist: # 遍历文件名列表 - # 更新进度条 - if progress_callback: # 如果有进度回调 - # 直接调用 batch_transform_app.py 中的 update_progress_callback 函数,实现对进度条的更新 - progress_callback(int(100 * (namelist.index(name) + 1) / length)) # 需要+1的原因是,namelist.index(name)的值是从0开始的,而进度条的值是从1开始的 - - # 检查用户是否点击了取消按钮,如果点击了取消按钮,则退出当前函数 - if thread_event and thread_event.is_set(): # 如果用户点击了取消按钮 - logging.info('用户点击了取消按钮') # 记录日志,用户点击了取消按钮 - return # 返回 - - with zipped.open(name) as file: # 打开zip文件中的文件 - # 以output_type指示的方式读取图像 - if output_type == 'RGB': # 如果输出类型为RGB - img = cv.imdecode(np.frombuffer(file.read(), np.uint8), 1) # 以RGB方式读取图像 - elif output_type == 'Grayscale': # 如果输出类型为灰度图 - img = cv.imdecode(np.frombuffer(file.read(), np.uint8), 0) # 以灰度图方式读取图像 - elif output_type == 'Binary': # 如果输出类型为二值图 - img = cv.imdecode(np.frombuffer(file.read(), np.uint8), 0) # 读取图像 - thresh_hold, img = cv.threshold(img, 0, 255, cv.THRESH_OTSU) # 将图像转换为二值图 - else: # 如果输出类型无效 - raise ValueError('无效的输出类型: ' + output_type) # 抛出异常 - - new_img = cv.resize(img, (224, 224), interpolation=cv.INTER_NEAREST) # 将图像大小调整为224x224 - # 224x224 这个尺寸是比较常用的,因为它很多神经网络的输入都是这个尺寸 - - output_name = os.path.join(out_path, os.path.basename(name)) # 获取输出文件名 - logging.info(f'保存处理后的图像到: {output_name}') # 记录日志,保存处理后的图像 - - io.imsave(output_name, new_img) # 保存处理后的图像 - # 之所以不使用cv2.imwrite函数,是因为cv2.imwrite对中文的路径支持不好,所以这里使用skimage.io.imsave函数 - - # 为每张图像生成多张变换后的图像,生成的图像数量由num_images指定 - for i in range(num_images - 1): # 遍历生成图像的数量 - transformed_img = random_transform(new_img) # 对图像进行随机变换 - output_name_transformed = os.path.join(out_path, f"{os.path.splitext(os.path.basename(name))[0]}_transformed_{i}.jpg") # 获取变换后的图像的文件名 - io.imsave(output_name_transformed, transformed_img) # 保存变换后的图像 - - -# 这个函数用于从配置文件中加载配置 + logging.info('开始处理zip文件中的图像') + with ZipFile(zip_path, 'r') as zipped: + namelist = [name for name in zipped.namelist() if name.lower().endswith(('.png', '.jpg', '.jpeg', '.tiff', '.bmp', '.gif'))] + length = len(namelist) + + # 循环处理指定数量的图像 + count = 0 + for name in namelist: + if progress_callback: + progress = int(100 * (count + 1) / length) + progress_callback(progress) + + # 读取图像 + img = io.imread(name) + if img is None: + continue + + # 进行随机变换 + transformed_img = random_transform(img) + + # 保存处理后的图像 + if output_type == 'RGB': + io.imsave(os.path.join(out_path, 'transformed_{}.jpg'.format(count)), transformed_img) + elif output_type == 'Grayscale': + transformed_img = cv.cvtColor(transformed_img, cv.COLOR_BGR2GRAY) + io.imsave(os.path.join(out_path, 'transformed_{}.png'.format(count)), transformed_img) + elif output_type == 'Binary': + _, transformed_img = cv.threshold(transformed_img, 128, 255, cv.THRESH_BINARY) + io.imsave(os.path.join(out_path, 'transformed_{}.png'.format(count)), transformed_img) + else: + raise ValueError("Invalid output_type: {}".format(output_type)) + + count += 1 def load_config(): # 从config.yaml文件中加载配置字典对象 -- Gitee