I tried to reconstruct an image that I decomposed into patches. I tried either with sklearn.feature_extraction.image.reconstruct_from_patches_2d
or with my custom function but the result is the same
Here is my try:
image_path=r'C:\Users\User\Desktop\Thesis-Diabetic Retinopathy\Datasets\DIARETDB1\SeeFar Project\Images\Processed images\image001.png'
os.mkdir(r'C:\Users\User\Desktop\Patched Image')
def create_patches_from_lesions(image_path,patch_widht,patch_height):
im1=cv2.imread(image_path)
im2 = cv2.cvtColor(im1, cv2.COLOR_BGR2RGB)
x1,y1=im2.shape[0]//50,im2.shape[1]//50
x2,y2=x1*50,y1*50
im3 = cv2.resize(im2, (x2,y2))
print(im3.shape)
patches=[]
for row in range(0,im3.shape[0],50):
for column in range(0,im3.shape[1],50):
patch=im3[row:(row+patch_widht),column:(column+patch_height)]
patches.append(patch)
for i in tqdm(range(len(patches))): #### keep only the patches with non zero elememts
cv2.imwrite(os.path.join(r'C:\Users\User\Desktop\Patched Image','{}.png'.format(i)),patches[i])
return patches,x2,y2
patches,x2,y2=create_patches_from_lesions(image_path,50,50)
def reconstruct_image(patches,image_height,image_width):
patches=np.asarray(patches)
print(patches.shape)
reshaped_patches=np.reshape(patches,(image_height,image_width,3))
print([reshaped_patches.shape])
cv2.imwrite(r'C:\Users\User\Desktop\Reconstructed Image.png',reshaped_patches)
reconstruct_image(patches,x2,y2)
sklearn.feature_extraction.image.extract_patches_2d
reshapes a 2D image into a collection of overlapping patches. To decompose your image into non-overlapping blocks you could use skimage.util.view_as_blocks
.
The following snippet is a possible implementation of your custom functions. Notice that create_patches
gets rid of the bottom and right borders of the image if the image size is not an integer multiple of the patch size. I adopted this solution to avoid resizing of the image (an operation which is likely to introduce artifacts). The original image can be reconstructed either from the patch files (not implemented) or directly from the 4D array returned by create_patches
.
import os
import numpy as np
from skimage import io, util
def create_patches(img, folder, patch_width, patch_height):
# Trim right and bottom borders if image size is not
# an integer multiple of patch size
nrows, ncols = patch_height, patch_width
trimmed = img[:img.shape[0]//nrows*nrows, :img.shape[1]//ncols*ncols]
# Create folder to store results if necessary
patch_dir = os.path.join(folder, 'Patched Image')
if not os.path.isdir(patch_dir):
os.mkdir(patch_dir)
# Generate patches and save them to disk
patches = util.view_as_blocks(trimmed, (nrows, ncols))
for i in range(patches.shape[0]):
for j in range(patches.shape[1]):
patch = patches[i, j, :, :]
patch_name = f'patch_{i:02}_{j:02}.png'
io.imsave(os.path.join(patch_dir, patch_name), patch)
return patches
def reconstruct_image(patches):
img_height = patches.shape[0]*patches.shape[2]
img_width = patches.shape[1]*patches.shape[3]
return patches.transpose(0, 2, 1, 3).reshape(img_height, img_width)
In [134]: import matplotlib.pyplot as plt
...:
...: folder = r'C:\Users\User\path-to-your-folder'
...: filename = 'sample_image.png'
...:
...: original = io.imread(os.path.join(folder, filename))
...: patches = create_patches(original, folder, 50, 50)
...: reconstructed = reconstruct_image(patches)
...:
...: fig, (ax0, ax1) = plt.subplots(1, 2)
...: ax0.imshow(original, cmap='gray')
...: ax0.set_title('Original')
...: ax1.imshow(reconstructed, cmap='gray')
...: ax1.set_title('Reconstructed')
...: plt.show(fig)
...:
...: for patch in os.listdir(os.path.join(folder, 'Patched Image')):
...: print(patch)
...:
patch_00_00.png
patch_00_01.png
patch_00_02.png
patch_00_03.png
...
patch_07_05.png
patch_07_06.png
patch_07_07.png
patch_07_08.png
patch_07_09.png
The image used in the example above can be downloaded from here