当前位置: 首页 > news >正文

图像扭曲增强处理流程

图像扭曲增强处理流程
├── 1. 初始化与加载
│   ├── 读取输入图像
│   ├── 检查图像有效性
│   ├── 提取文件名和扩展名
│   └── 获取图像尺寸信息
│
├── 2. 扭曲变换方法
│   ├── 弹性变换(Elastic Transform)
│   │   ├── 生成随机仿射变换矩阵
│   │   ├── 创建复杂位移场(添加随机和周期性扰动)
│   │   └── 应用非线性扭曲
│   │
│   ├── 透视变换(Perspective Transform)
│   │   ├── 随机选择原图四个角点
│   │   ├── 计算透视变换矩阵(增强极端变换概率)
│   │   └── 应用透视扭曲
│   │
│   └── 仿射变换(Affine Transform)
│       ├── 随机缩放(0.4-2.2倍)
│       ├── 随机旋转(-70°至70°)
│       └── 随机剪切(-50°至50°)
│
├── 3. 裁剪与缩放
│   ├── 随机选择缩放因子(1.0-2.5倍原始尺寸)
│   ├── 若图像尺寸不足则直接缩放
│   └── 随机裁剪到目标尺寸
│
├── 4. 随机变换组合
│   ├── 高概率选择弹性变换(50%)
│   ├── 中概率选择透视变换(30%)
│   └── 低概率选择仿射变换(20%)
│
└── 5. 批量生成与保存├── 创建输出目录├── 循环生成指定数量的扭曲图像├── 保存图像到指定路径└── 每100张输出一次进度信息

安装好包,修改好文件路径后,可直接使用的代码展示:

import cv2
import numpy as np
import os
import random
from typing import Tuple, List, Callable, Dict#扭曲更强,图片范围1-2倍
class ImageDistortion:def __init__(self, input_path: str, output_dir: str):"""初始化图像扭曲增强器参数:input_path: 输入图像路径output_dir: 输出目录路径"""self.input_path = input_pathself.output_dir = output_dirself.image = self._load_image()self.filename, self.ext = os.path.splitext(os.path.basename(input_path))self.height, self.width = self.image.shape[:2]def _load_image(self) -> np.ndarray:"""加载输入图像"""image = cv2.imread(self.input_path)if image is None:raise FileNotFoundError(f"无法加载图像: {self.input_path}")return imagedef elastic_transform(self, alpha: float = 200, sigma: float = 8,alpha_affine: float = 20, random_state: np.random.RandomState = None) -> np.ndarray:"""应用增强的弹性变换参数:alpha: 位移场强度sigma: 位移场平滑度alpha_affine: 仿射变换强度random_state: 随机状态返回:变换后的图像"""if random_state is None:random_state = np.random.RandomState(None)shape = self.image.shapeshape_size = shape[:2]# 增强弹性变换效果center_square = np.float32(shape_size) // 2square_size = min(shape_size) // 3# 随机仿射变换pts1 = np.float32([center_square + square_size,[center_square[0] + square_size, center_square[1] - square_size],center_square - square_size])pts2 = pts1 + random_state.uniform(-alpha_affine, alpha_affine, size=pts1.shape).astype(np.float32)M = cv2.getAffineTransform(pts1, pts2)image = cv2.warpAffine(self.image, M, shape_size[::-1], borderMode=cv2.BORDER_REFLECT_101)# 创建更复杂的位移场dx = cv2.GaussianBlur((random_state.rand(*shape_size) * 2 - 1), (0, 0), sigma) * alphady = cv2.GaussianBlur((random_state.rand(*shape_size) * 2 - 1), (0, 0), sigma) * alpha# 添加周期性扰动增强扭曲效果grid_size = random_state.randint(2, 6)x, y = np.meshgrid(np.arange(shape[1]), np.arange(shape[0]))# 添加更强的正弦波扰动wave_strength = random_state.uniform(10, 30)wave_freq = random_state.uniform(0.01, 0.07)dx += np.sin(x * wave_freq) * wave_strengthdy += np.cos(y * wave_freq) * wave_strength# 添加多个频率的波if random.random() < 0.5:wave_strength2 = random_state.uniform(5, 15)wave_freq2 = random_state.uniform(0.03, 0.1)dx += np.sin(y * wave_freq2) * wave_strength2dy += np.cos(x * wave_freq2) * wave_strength2# 创建网格map_x = np.float32(x + dx)map_y = np.float32(y + dy)# 应用变换return cv2.remap(image, map_x, map_y, interpolation=cv2.INTER_LINEAR,borderMode=cv2.BORDER_REFLECT_101)def perspective_transform(self, scale: float = 0.3, tilt_prob: float = 0.7) -> np.ndarray:"""应用增强的透视变换参数:scale: 变换比例tilt_prob: 倾斜概率返回:变换后的图像"""height, width = self.image.shape[:2]# 原图四个角点pts1 = np.float32([[0, 0], [width, 0], [0, height], [width, height]])# 增加极端透视变换的可能性if random.random() < tilt_prob:# 强烈倾斜变换pts2 = np.float32([[random.uniform(0, width * scale), random.uniform(0, height * scale)],[width - random.uniform(0, width * scale), random.uniform(0, height * scale)],[random.uniform(0, width * scale), height - random.uniform(0, height * scale)],[width - random.uniform(0, width * scale), height - random.uniform(0, height * scale)]])else:# 常规透视变换pts2 = np.float32([[random.uniform(0, width * scale * 0.7), random.uniform(0, height * scale * 0.7)],[width - random.uniform(0, width * scale * 0.7), random.uniform(0, height * scale * 0.7)],[random.uniform(0, width * scale * 0.7), height - random.uniform(0, height * scale * 0.7)],[width - random.uniform(0, width * scale * 0.7), height - random.uniform(0, height * scale * 0.7)]])# 计算透视变换矩阵matrix = cv2.getPerspectiveTransform(pts1, pts2)# 应用变换return cv2.warpPerspective(self.image, matrix, (width, height),borderMode=cv2.BORDER_REFLECT_101,flags=cv2.INTER_CUBIC)def affine_transform(self, scale_range: Tuple[float, float] = (0.5, 2.0),rotation_range: Tuple[float, float] = (-60, 60),shear_range: Tuple[float, float] = (-45, 45)) -> np.ndarray:"""应用增强的仿射变换参数:scale_range: 缩放范围rotation_range: 旋转角度范围shear_range: 剪切角度范围返回:变换后的图像"""height, width = self.image.shape[:2]# 随机选择变换参数scale = random.uniform(*scale_range)rotation = random.uniform(*rotation_range)shear_x = random.uniform(*shear_range)shear_y = random.uniform(*shear_range)# 计算旋转矩阵rotation_matrix = cv2.getRotationMatrix2D((width / 2, height / 2), rotation, scale)# 应用旋转变换rotated = cv2.warpAffine(self.image, rotation_matrix, (width, height),borderMode=cv2.BORDER_REFLECT_101,flags=cv2.INTER_CUBIC)# 应用剪切变换shear_matrix = np.float32([[1, shear_x / 100, 0],[shear_y / 100, 1, 0]])return cv2.warpAffine(rotated, shear_matrix, (width, height),borderMode=cv2.BORDER_REFLECT_101,flags=cv2.INTER_CUBIC)def crop_and_resize(self, image: np.ndarray, scale_factor: float = None) -> np.ndarray:"""裁剪并调整图像大小,使最终图像尺寸在原始尺寸的1倍到2.5倍之间参数:image: 输入图像scale_factor: 缩放因子,如果为None则随机选择返回:裁剪并调整大小后的图像"""if scale_factor is None:# 在1.0到2.5倍之间随机选择缩放因子scale_factor = random.uniform(1.0, 2.5)h, w = image.shape[:2]# 计算目标尺寸target_h = int(self.height * scale_factor)target_w = int(self.width * scale_factor)# 如果图像尺寸小于目标尺寸,直接调整大小if h < target_h or w < target_w:return cv2.resize(image, (target_w, target_h), interpolation=cv2.INTER_CUBIC)# 随机裁剪y = random.randint(0, h - target_h)x = random.randint(0, w - target_w)cropped = image[y:y + target_h, x:x + target_w]return croppeddef apply_random_distortion(self) -> np.ndarray:"""应用随机选择的扭曲变换返回:变换后的图像"""# 增加弹性变换的概率,因其效果更丰富distortion_methods = ['elastic'] * 5 + ['perspective'] * 3 + ['affine'] * 2distortion_method = random.choice(distortion_methods)if distortion_method == 'elastic':# 随机调整弹性变换参数alpha = random.uniform(150, 250)sigma = random.uniform(5, 10)alpha_affine = random.uniform(15, 30)distorted = self.elastic_transform(alpha, sigma, alpha_affine)elif distortion_method == 'perspective':# 随机调整透视变换参数scale = random.uniform(0.2, 0.4)tilt_prob = random.uniform(0.6, 0.9)distorted = self.perspective_transform(scale, tilt_prob)else:  # affine# 随机调整仿射变换参数scale_range = (random.uniform(0.4, 0.8), random.uniform(1.5, 2.2))rotation_range = (random.uniform(-70, -30), random.uniform(30, 70))shear_range = (random.uniform(-50, -20), random.uniform(20, 50))distorted = self.affine_transform(scale_range, rotation_range, shear_range)# 应用裁剪和缩放return self.crop_and_resize(distorted)def generate_and_save(self, count: int) -> None:"""生成指定数量的扭曲图像并保存到输出目录参数:count: 要生成的图像数量"""# 确保输出目录存在os.makedirs(self.output_dir, exist_ok=True)print(f"开始生成 {count} 张扭曲图像...")for i in range(count):# 应用随机扭曲distorted_image = self.apply_random_distortion()# 构建输出文件名output_filename = f"{self.filename}_distorted_{i:04d}{self.ext}"output_path = os.path.join(self.output_dir, output_filename)# 保存图像cv2.imwrite(output_path, distorted_image)# 每生成100张图像打印一次进度if (i + 1) % 100 == 0:print(f"已生成 {i + 1}/{count} 张图像")print(f"所有 {count} 张扭曲图像已保存到: {self.output_dir}")def main():# 输入图像路径input_image_path = r"E:\project1\photo01\0_defect_1.bmp"# 确保路径中的目录分隔符正确input_image_path = input_image_path.replace('\\', '/')# 输出目录(与输入图像在同一目录)output_directory = os.path.dirname(input_image_path)# 创建图像扭曲增强器实例enhancer = ImageDistortion(input_image_path, output_directory)# 生成并保存3000张扭曲图像enhancer.generate_and_save(3000)if __name__ == "__main__":main()

http://www.xdnf.cn/news/1109953.html

相关文章:

  • 物联网设备数据驱动3D模型的智能分析与预测系统
  • frp内网穿透教程及相关配置
  • 【Redis实战】Widnows本地模拟Redis集群的2种方法
  • Git 相关的常见面试题及参考答案
  • 国产电钢琴电子琴手卷钢琴对比选购指南
  • 2025年亚太杯(中文赛项)数学建模B题【疾病的预测与大数据分析】原创论文讲解(含完整python代码)
  • ESP32使用freertos更新lvgl控件内容
  • 搭建云手机教程
  • 聊下easyexcel导出
  • Java可变参数
  • 从基础加热到智能生态跨越:艾芬达用创新重构行业价值边界!
  • Go mod 依赖管理完全指南:从入门到精通
  • 代码随想录day28贪心算法2
  • 【AI News | 20250711】每日AI进展
  • Spring(四) 关于AOP的源码解析与思考
  • Java SE--抽象类和接口
  • 如何查看服务器当前用户的权限
  • GD32 CAN1和TIMER0同时开启问题
  • 深度学习15(GRU、LSTM+词嵌入+seq2seq+attention)
  • 电子基石:硬件工程师的器件手册 (五) - 三极管:电流放大的基石与开关的利刃
  • 7. JVM类加载器与双亲委派模型
  • 关于两种网络攻击方式XSS和CSRF
  • 二分法寻找无序序列的峰值
  • [Token]Token merging for Vision Generation
  • 学python,PyCharm 和 VSCode哪个更好用?
  • ChatRex RexSeek RexThinker: 结合多模态大语言模型的目标检测模型构建
  • vue3+vit+vue-router路由,侧边栏菜单,面包屑导航设置层级结构
  • 商业机密保卫战:如何让离职员工带不走的客户资源?
  • 六年级数学知识边界总结思考-上册
  • Rust Web 全栈开发(五):使用 sqlx 连接 MySQL 数据库