对图片进行任意尺寸裁剪
提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
在做目标检测项目中,经常会遇到需要对图片中可用的目标信息进行裁剪 。下面是使用python实现的简易图片裁剪和根据标注数据是否全为单一像素值进行过滤的脚本,话不多说上代码:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
2.读入数据
代码如下(示例):
import cv2
import glob
import numpy as np
import os
import shutil
from PIL import Image
def copy_padded(img, output):
print(img)
image = cv2.imread(img)
height, width = image.shape[:2]
# 将左边和右边的边缘像素值修改为0
image[:, 0] = 255
image[:, width - 1] = 255
# # 将上边和下边的边缘像素值修改为0
# image[0, :] = 0
# image[height - 1, :] = 0
# crop_height = 1408
# crop_height = 4559
# # 计算裁剪的起始坐标
# y = (height - crop_height)
# # y1 = 1441
# # y2 = 2849
# # 裁剪图像
# cropped_image = image[y:y + 1408, :]
# cropped_image = image[y1:y2, :]
# print(height)
# 设置填充的大小和颜色
top = 0
bottom = 0
left = 0
right = 192
color = [0, 0, 0]
padded_image = cv2.copyMakeBorder(image, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)
# cv2.imwrite(os.path.join(output, img.split('\\')[4].split('.')[0] + "." + img.split('.')[-1]),padded_image)
copy_height, copy_width = padded_image.shape[:2]
# print(padded_image.shape[:2])
crop_width = 2048
crop_height = 704
rows = copy_height // crop_height
cols = copy_width // crop_width
print("rows: cols:", rows, cols)
for i in range(rows):
for j in range(cols):
# 计算裁剪的起始坐标
y_start = i * crop_height
y_end = (i + 1) * crop_height
x_start = j * crop_width
x_end = (j + 1) * crop_width
cropped_block = padded_image[y_start:y_end, x_start:x_end]
# print(img.split('\\')[5].split('.')[0])
dir_name,file_name = os.path.split(img)
# print(os.path.join(output, f"{i}_{j}_" + file_name))
cv2.imwrite(
os.path.join(output, f"{i}_{j}_" + file_name),
cropped_block)
def pd_r_128(fileList):
'''过滤没标注数据的mask数据'''
total = 0
for ids, file in enumerate(fileList):
if "_color_mask" in file:
rawFile = imageFold + file
print(rawFile)
rawImage = cv2.imread(rawFile)
height, width = rawImage.shape[:2]
rawImage[:, 0] = 128
rawImage[:, width - 1] = 128
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
closing_image = cv2.morphologyEx(rawImage, cv2.MORPH_OPEN, kernel)
for ti, loc in enumerate(locList):
x1, y1, x2, y2 = loc
cropImage1 = closing_image[y1:y2, x1:x2, :]
cropImage2 = cropImage1[:, :, 2]
all_128 = np.all(cropImage2 == 128)
if all_128:
saveimage = file[:-15] + "_%03d.png" % ti
os.remove(imageTrain + saveimage)
else:
total += 1
saveMaskName1 = file[:-15] + "_%03d_color_mask.png" % ti
cv2.imwrite(imageTrain + saveMaskName1, cropImage1)
else:
rawFile = imageFold + file
print(rawFile)
rawImage = cv2.imread(rawFile)
for ti, loc in enumerate(locList):
x1, y1, x2, y2 = loc
cropImage1 = rawImage[y1:y2, x1:x2, :]
# cropImage1 = cv2.cvtColor(cropImage1, cv2.COLOR_BGR2GRAY)
saveName1 = file[:-4] + "_%03d.png" % ti
cv2.imwrite(imageTrain + saveName1, cropImage1)
for list in os.listdir(imageTrain): # 注意修改输出尺寸
rawFile_resize = imageTrain + list
img = cv2.imread(rawFile_resize)
img = cv2.resize(img, (512, 288))
cv2.imwrite(rawFile_resize, img)
print("\nprocessed total: ", total * 2)
if __name__ == '__main__':
root_image = glob.glob(r'D:\data\mask_label_4000/*')
output_image = r'D:\data\mask_label_4000\20230912_SX_4000_Tc/'
os.makedirs(output_image, exist_ok=True)
for img in root_image:
copy_padded(img, output_image)
'''
其中函数copy_padded为裁剪函数。函数pd_r_128为判断裁剪标注图片是否全为128像素值,若是则删除该图片和裁剪的标注原图,并resize为相应的尺寸。可根据自己想要的数据进行修改。