(一)先对图像进行划分patch,再进行下采样最后成对,可以按照要求去设定步长、大小以及自身需要的数量等(参考github上的一个代码)
(1)划分patch,下采样使用 matlab 中的bicubic的方法
from typing import Tuple, List
import os
import random
import sys
import tarfile
import urllib.request
import skimage.io
import numpy as np
import scipy.io
import skimage.color
from PIL import Image
import numpy as np
def extract_image_centers(image: np.ndarray, patch_size: Tuple):
"""Return a patch from the center of the image with the given size"""
input_shape = image.shape
if patch_size[0] > input_shape[0] or patch_size[1] > input_shape[1]:
return None
start_point = [0, 0]
end_point = [0, 0]
for i in [0, 1]:
start_point[i] = (input_shape[i] - patch_size[i]) // 2
end_point[i] = start_point[i] + patch_size[i]
print(start_point[0],start_point[1],end_point[0],end_point[1])
return image[start_point[0]:end_point[0], start_point[1]:end_point[1]]
# path = r'D:\00\00_papers\1_Magid_Texture-Based_Error_Analysis_for_Image_Super-Resolution_CVPR_2022_paper(1)\30_related data set and others\datasets\0013.png'
# img = Image.open(path)
# img = np.array(img)
# print("原图的大小为:" + str(img.shape))
# point = extract_image_centers(img,(128,128))
# print(point.shape)
def _calculate_tiles(input_shape: Tuple, patch_size: Tuple, patch_stride=None) \
-> List:
"""Calculate the starting points of all tiles"""
if patch_stride is None:
patch_stride = (patch_size[0], patch_size[1])
if patch_stride[0] < 1 or patch_stride[1] < 1:
raise ValueError('Strides must be larger than 0')
if patch_size[0] > input_shape[0] or patch_size[1] > input_shape[1]:
return None
# result is a list of points (tuples)
result = []
# number of images that fit in each dimension
nr_images = [1, 1]
for i in [0, 1]:
nr_images[i] += (input_shape[i] - patch_size[i]) // patch_stride[i]
# starting coordinates for the tiles and total length of tiled area,
# the tiled area is centered
start_coord = [0, 0]
tiled_area_length = [0, 0]
for i in [0, 1]:
tiled_area_length[i] = patch_size[i] + (nr_images[i]-1)*patch_stride[i]
start_coord[i] = (input_shape[i] - tiled_area_length[i]) // 2
for i in range(nr_images[0]):
for j in range(nr_images[1]):
x = start_coord[0] + i * patch_stride[0]
y = start_coord[1] + j * patch_stride[1]
result.append((x, y))
return result
# path = r'D:\00\00_papers\1_Magid_Texture-Based_Error_Analysis_for_Image_Super-Resolution_CVPR_2022_paper(1)\30_related data set and others\datasets\0013.png'
# img = Image.open(path)
# img = np.array(img)
# print("原图的大小为:" + str(img.shape))
# point = _calculate_tiles((1368,2040),(128,128), (240,240))
# # point = extract_image_centers(img,(128,128))
# print(point)
# print(len(point))
def tile_image(image: np.ndarray, patch_size: Tuple, patch_stride=None) -> Tuple:
'''
Generate patches of size patch_size from the image that are patch_stride
pixels apart. The patches are centered. Returns the patches in a list, and the start points
of the patches in another
Args:
image: The image to tile
patch_size: tuple of 2 int containing the patch width and height
patch_stride: tuple of 2 int containing the strides, if None, the patch_size will be used as stride
Returns:
tuple of a list of the patches and a list of the start points of each patch
'''
points = _calculate_tiles(image.shape, patch_size, patch_stride)
# return a list of patches
patches = []
# print(points)
for i in range(len(points)):
start_point = points[i]
end_point = (start_point[0] + patch_size[0], start_point[1] + patch_size[1])
patch = image[start_point[0]:end_point[0], start_point[1]:end_point[1]]
# print(patch)
patches.append(patch)
return patches, points
# tile_image(image: np.ndarray, patch_size: Tuple, patch_stride=None)
'''
path = r'D:\00\00_papers\1_Magid_Texture-Based_Error_Analysis_for_Image_Super-Resolution_CVPR_2022_paper(1)\30_related data set and others\datasets\0010.png'
img = Image.open(path)
img = np.array(img)
# print("原图的大小为:" + str(img.shape))
patches,points = tile_image(img, (128,128), (100,100))
# print(points)
'''
def convert_data_tiled(image_directory, destination_dir,
patch_size: Tuple, patch_stride=None,
class_ids=None):
"""Convert the data sets. If class_ids is None then all classes will
be converted. Used image tiles to convert the original images. Images from the
same original image will end up in consecutively numbered files, so they should
be shuffled when used
Args:
data_set: the dataset to convert
destination_dir: directory where to write the files
dataset_dir: directory where the downloaded data was extracted
patch_size: size of patches
patch_stride: stride between patches, or none if patch size should be used
class_ids: the class ids that should be converted
"""
image_directory = r'D:\00\00_papers\1_Magid_Texture-Based_Error_Analysis_for_Image_Super-Resolution_CVPR_2022_paper(1)\30_related data set and others\datasets\DIV2K_train_HR'
random.seed(123) # 保证随机结果可复现
for i in os.listdir(image_directory):
imagepath = os.path.join(image_directory, i)
image = skimage.io.imread(imagepath)
patches, _ = tile_image(image, patch_size, patch_stride)
num = 0
if len(patches) < 50:
k = 0
while( len(patches) < 50):
k = k + 20
patches, _ = tile_image(image, patch_size, (200-k,200-k))
random.shuffle(patches)
for patch in patches:
num = num+1
patch_ubyte = skimage.img_as_ubyte(patch)
patch_name = '{:4}_{:2}.png'.format(i.split('.')[0],num)
filename = os.path.join(destination_dir, patch_name)
# save the patch
if num > 50:
break
skimage.io.imsave(filename, patch_ubyte, check_contrast=False)
return num
image_directory = r'D:\00\00_papers\1_Magid_Texture-Based_Error_Analysis_for_Image_Super-Resolution_CVPR_2022_paper(1)\30_related data set and others\datasets\DIV2K_train_HR'
destination_dir = r'D:\00\00_papers\1_Magid_Texture-Based_Error_Analysis_for_Image_Super-Resolution_CVPR_2022_paper(1)\30_related data set and others\datasets\DIV2K_train_HR_patches'
convert_data_tiled(image_directory, destination_dir, (128,128), (100,100))
(二)先下采样之后进行划分patch成对
def sample_patches(lr_img_path, hr_img_path, patch_size, scale,num_patches):
# Load images
random.seed(123)
lr_img = Image.open(lr_img_path)
hr_img = Image.open(hr_img_path)
# Convert images to numpy arrays
lr_arr = np.array(lr_img)
hr_arr = np.array(hr_img)
# Initialize arrays to store patches
lr_patches = np.zeros((num_patches, patch_size, patch_size, lr_arr.shape[2]))
hr_patches = np.zeros((num_patches, patch_size*scale, patch_size*scale, hr_arr.shape[2]))
# Sample patches randomly
for i in range(num_patches):
# Choose random location for patch
x = random.randint(0, lr_arr.shape[0] - patch_size)
y = random.randint(0, lr_arr.shape[1] - patch_size)
# Extract patch from LR and HR images
# Add patch to patch arrays
lr_patches[i] = lr_arr[x:x+patch_size, y:y+patch_size, :]
hr_patches[i] = hr_arr[x*scale:x*scale+patch_size*scale, y*scale:y*scale+patch_size*scale, :]
## convert them to uint8
lr_patches = lr_patches.astype("uint8")
hr_patches = hr_patches.astype("uint8")
return lr_patches, hr_patches
ps:第二种更适用一些