当前位置: 首页 > 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.lryc.cn/news/586559.html

相关文章:

  • 计算机视觉 之 经典模型汇总
  • 粒子滤波|粒子滤波的相关算法理论介绍
  • 内容总监的效率革命:用Premiere Pro AI,实现视频画幅“一键重构”
  • 菜鸟的C#学习(二)
  • 直播录屏技术揭秘:以抖音直播录屏为例
  • 系统性学习C语言-第十五讲-深入理解指针(5)
  • 【华为OD】MVP争夺战2(C++、Java、Python)
  • JVM--虚拟线程
  • 数据结构之并查集和LRUCache
  • STP生成树划分实验
  • 飞算JavaAI:重新定义Java开发效率的智能引擎
  • 【机器学习实战笔记 16】集成学习:LightGBM算法
  • Waiting for server response 和 Content Download
  • 【离线数仓项目】——电商域DWS层开发实战
  • BugBug.io 使用全流程(202507)
  • 计算机毕业设计Java停车场管理系统 基于Java的智能停车场管理系统开发 Java语言实现的停车场综合管理平台
  • STM32中的RTC(实时时钟)详解
  • 《Spring 中上下文传递的那些事儿》Part 8:构建统一上下文框架设计与实现(实战篇)
  • 利用docker部署前后端分离项目
  • 【攻防实战】记一次DC2攻防实战
  • 电网失真下单相锁相环存在的问题
  • CANoe实操学习车载测试课程、独立完成CAN信号测试
  • Spring Boot整合MyBatis+MySQL+Redis单表CRUD教程
  • 前端面试宝典---项目难点2-智能问答对话框采用虚拟列表动态渲染可视区域元素(10万+条数据)
  • 快速排序递归和非递归方法的简单介绍
  • Armstrong 公理系统深度解析
  • 人机协作系列(三)个体创业者的“新物种革命”
  • Agent任务规划
  • 分布式系统高可用性设计 - 缓存策略与数据同步机制
  • PostgreSQL安装及简单应用