Python OpenCV实现图片像素区域缩放
- 前言
- 项目
- 安装OpenCV和Pillow
- 思路
- 代码编写
前言
遇到一个要将大量图片缩放成统一规格的难题,并且这些图片周围还有很多空白像素,所以用Python实现一下。
项目
安装OpenCV和Pillow
pip install opencv-python
pip install pillow
思路
先把周围的空白像素去掉,再进行中心缩放,放到规定大小的矩形内即可。
代码编写
需要设置input_folder
和output_folder
还有缩放后的尺寸target_size
。
import cv2
from PIL import Image
import os
import numpy as npdef center_zoom(input_folder, output_folder, target_size):# 确保输出文件夹存在if not os.path.exists(output_folder):os.makedirs(output_folder)# 遍历输入文件夹中的所有文件for filename in os.listdir(input_folder):file_path = os.path.join(input_folder, filename)# 确保文件是图像if file_path.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.gif')):with Image.open(file_path) as img:img = img.convert('RGBA') # 确保图像有透明通道img_np = np.array(img)[:,:,0:3] # 只取RGB通道用于边缘检测edges = cv2.Canny(img_np, threshold1=30, threshold2=100) # 边缘检测y_indices, x_indices = np.where(edges > 0) # 找到边缘像素的坐标if len(x_indices) == 0 or len(y_indices) == 0: # 如果没有找到边缘,直接跳过continuex_min, x_max = np.min(x_indices), np.max(x_indices)y_min, y_max = np.min(y_indices), np.max(y_indices)# 根据裁剪区域裁剪出有像素区域img_np = np.array(img)img_np = img_np[y_min:y_max, x_min:x_max, :]img = Image.fromarray(img_np)# 创建一个完全透明的背景图像background = Image.new('RGBA', (target_size[0], target_size[1]), (0, 0, 0, 0))# 获取原始图像的宽度和高度original_width, original_height = img.size# 获取目标图像的宽度和高度target_width, target_height = target_size# 计算原始图像的长宽比original_aspect_ratio = original_width / original_height# 计算目标图像的长宽比target_aspect_ratio = target_size[0] / target_size[1]# 如果原始图像的长宽比大于目标图像的长宽比if original_aspect_ratio > target_aspect_ratio:# 计算调整后的宽度new_width = target_width# 计算调整后的高度new_height = int(target_width / original_aspect_ratio)else:# 计算调整后的高度new_height = target_height# 计算调整后的宽度new_width = int(target_height * original_aspect_ratio)# 调整图像大小,保持长宽比不变img = img.resize((new_width, new_height), Image.LANCZOS)# 创建一个完全透明的背景图像background = Image.new('RGBA', target_size, (0, 0, 0, 0))# 计算将图像放入背景图像的位置x_offset = (target_width - new_width) // 2y_offset = (target_height - new_height) // 2# 将图像粘贴到背景图像的中心位置background.paste(img, (x_offset, y_offset))# 保存到输出文件夹background.save(os.path.join(output_folder, filename))# 指定输入和输出文件夹以及目标图像尺寸
input_folder = r'D:\Project\Python_Project\AutomaticCardSynthesis\TestCardImage'
output_folder = r'D:\Project\Python_Project\AutomaticCardSynthesis\OutputCardImage'
target_size = (128, 128) # 传递一个包含宽和高的元组
center_zoom(input_folder, output_folder, target_size)