这几天在读一篇论文,文中提到“当目标图像与原始图像的长宽比不同时,传统的归一化方法会使图像变形”,它提出一种按照目标图片(模型的输入)的比例缩放输入图片,步骤如下图所示:
我将上述方法进行了复现,分为两给py文件,一个是处理文件,一个是运行文件。
1.处理文件:image_processing.py
我将处理文件封装成了类,便于使用,如下。需要说明的一点是,cv2.imwrite(path,img)无法处理带有中文的路径,只能 cv2.imencode()了。
思路:(这个py文件可以单独运行)
(1)首先使用glob()函数获得一个文件夹下的所有图片文件的地址,它的返回值就是一个列表,超级好用,不用自己再写for循环手动将文件地址添加到列表中(可以对比接下来的另一个py文件,那个是手动添加的)
(2)之后处理每一个单独的文件,获取改文件的长边和短边,按照上图中的公式计算出len和step(文中step是4,因为文中再计算步长时除以了3,这个含义是说将长边和短边的差平均分为3份,每此剪裁走一份大小(len值),分3步剪裁完,加上最开始切割的i一步,一共是四步,如下午所示。)
(3)将图片以短边为基准,在长边上进行剪裁,剪裁成4张,实现了图片数量的扩增。
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author:Dr.Shang
import cv2
import numpy as np
import os
from glob import glob
class Preprocess(object):
def __init__(self, in_path, out_path):
self._output_path = out_path
self._image_path = in_path
# print(TEST_IMAGE_PATH) # 列表
@staticmethod
def get_min_max_len(weight, height):
if weight > height:
max_value = weight
min_value = height
else:
max_value = height
min_value = weight
len_value = min_value
return min_value, max_value, len_value
@staticmethod
def get_step(min_value, max_value):
return (max_value - min_value) // 3
def get_image(self):
image_paths = self._image_path
for num, image_path in enumerate(image_paths):
image_path_copy = image_path
img_name = image_path_copy.split('\\')[-1].split('.')[0]
imgs = cv2.imread(image_path)
try:
if imgs.shape[0] != 0:
print('读取文件%s成功' % image_path)
except:
print('读取失败')
weight = imgs.shape[0]
height = imgs.shape[1]
min, max, len = self.get_min_max_len(weight, height)
# print(min, max, len)
step = self.get_step(min, max)
# print(step)
new_img_list = np.zeros((4, len, len, 3), dtype=np.uint8)
begin = 0
len_plus = len
# print(img.shape)
for i in range(4):
# print(new_img_list[i, :, :, :].shape)
if weight > height:
new_img_list[i, :, :, :] = imgs[begin:len_plus, :]
else:
new_img_list[i, :, :, :] = imgs[:, begin:len_plus]
begin += step
len_plus += step
# print(new_img_list.shape)
for i, img in enumerate(new_img_list):
try:
new_img = img
path = os.path.join(self._output_path, '{}-{}-{}.jpg'.format(img_name, num, i))
cv2.imencode('.jpg', new_img)[1].tofile(path)
"""
cv2.imwrite(path,img)无法处理带有中文的路径,只能 cv2.imencode()了。
"""
print('图片{}预处理成功'.format(img_name))
except:
print('图片{}预处理失败'.format(img_name))
if __name__ == '__main__':
OUTPUT_PATH = r'D:\coding\论文复现\选择性卷积特征融合\output_image'
TEST_IMAGE_PATH = glob(r"D:\FlyAI\FlowerClassify_FlyAI\data\input\images\daisy\*")
image_path = TEST_IMAGE_PATH
output_path = OUTPUT_PATH
# img = Preprocess(image_path, output_path)
# img.get_image()
print(TEST_IMAGE_PATH) # 列表
2.运行文件
该文件是对父文件夹下不同子文件下的所有图片进行扩增,然后再目标文件夹创建相同父、子文件,将处理后的文件按照原所属关系放入新建的子文件夹内。
我的目录结构如下:
代码:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author:Dr.Shang
import image_processing as ip
import os
import cv2
from glob import glob
ORIGINAL_DIRECTORY = r'D:\FlyAI\FlowerClassify_FlyAI\data\input\images'
DIRECTORIES_LIST = os.listdir(ORIGINAL_DIRECTORY) # 列举原始文件夹内的所含文件夹
OUTPUT_DIRECTORY_PATH = r'D:\coding\论文复现\选择性卷积特征融合\output_image'
# print(DIRECTORIES_LIST)
for directory in DIRECTORIES_LIST:
output_directory = os.path.join(OUTPUT_DIRECTORY_PATH, directory)
is_exit = os.path.exists(output_directory)
if not is_exit:
os.mkdir(output_directory)
total_num_directory = len(DIRECTORIES_LIST)
files = os.listdir(os.path.join(ORIGINAL_DIRECTORY, directory))
files_directory =os.path.join(ORIGINAL_DIRECTORY, directory)
files_path = []
for file in files:
if file.endswith('.jpg' or '.jpeg' or '.bmp'):
files_path.append(os.path.join(files_directory, file))
# print(files_path)
process = ip.Preprocess(files_path, output_directory) # 创建Preprocess实例
process.get_image()