deep learning 对图片进行划分 patch

(一)先对图像进行划分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:第二种更适用一些

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

S_h_a_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值