0
$\begingroup$

I've started to work with a leaf classification dataset on Kaggle. All input images have different rectangular shapes. I want to transform the input into squares of a fixed size (say, 224x224) with a symmetric zero-padding either on top and bottom or on the left and right sides of the rectangle. Prior to that, I think that I need to rescale the image (some images in the dataset have shapes >1000). I've encountered the next two problems:

  1. torchvision.transforms.Resize(size) rescales the image so that its smaller side is matched to size (size is a scalar). I want the opposite, the bigger side to be matched to size.
  2. torchvision.transforms.Pad(padding) seemingly works only with some fixed padding, but this transform will not always output a square.

How would you resolve this problem? I'm aware of RandomSizedCrop, but I feel like some datasets (like this one) aren't good for this method (some of the input images are too oblong). Also, I heard that RandomSizedCrop shouldn't be used for the test data loaders.

More generally, how do you deal with input images of different rectangular shapes in PyTorch? Any help is appreciated.

$\endgroup$
  • $\begingroup$ I've found some good answers on this post $\endgroup$ – diplodoc Oct 14 '19 at 6:17
0
$\begingroup$

Try this function that uses cv2 resize function:

def leaf_image(image_id,target_length=160):
    """
    `image_id` should be the index of the image in the images/ folder

    Reture the image of a given id(1~1584) with the target size (target_length x target_length)

    """

    image_name = str(image_id) + '.jpg'
    leaf_img = plt.imread('images/'+image_name)  # Reading in the image 
    leaf_img_width = leaf_img.shape[1]
    leaf_img_height = leaf_img.shape[0]
    #target_length = 160
    img_target = np.zeros((target_length, target_length), np.uint8)
    if leaf_img_width >= leaf_img_height:
        scale_img_width = target_length
        scale_img_height = int( (float(scale_img_width)/leaf_img_width)*leaf_img_height )
        img_scaled = cv2.resize(leaf_img, (scale_img_width, scale_img_height), interpolation = cv2.INTER_AREA)
        copy_location = (target_length-scale_img_height)/2
        img_target[copy_location:copy_location+scale_img_height,:] = img_scaled
    else:
        # leaf_img_width < leaf_img_height:
        scale_img_height = target_length
        scale_img_width = int( (float(scale_img_height)/leaf_img_height)*leaf_img_width )
        img_scaled = cv2.resize(leaf_img, (scale_img_width, scale_img_height), interpolation = cv2.INTER_AREA)
        copy_location = (target_length-scale_img_width)/2
        img_target[:, copy_location:copy_location+scale_img_width] = img_scaled 

    return img_target


# Test the leaf_image function
leaf_id = 343
leaf_img = leaf_image(leaf_id, target_length=160); 

plt.imshow(leaf_img, cmap='gray'); plt.title('Leaf # '+str(leaf_id)); plt.axis('off'); plt.show()

Source: https://github.com/WenjinTao/Leaf-Classification--Kaggle/blob/master/Leaf_Classification_using_Machine_Learning.ipynb

| improve this answer | |
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.