5

l have a dataset of 100, 000 images of different sizes.

(36,77), (56,100), (89,14), (35,67), (78,34), (90,65),(96,38).......

l want to add padding to these images so that to get them into the same shape. To do so l loop over the whole dataset and take the max_width and max_height then make the images into this size. In this sample for instance max_height= 96 and max_width= 100. So my images will have all the shape of (96,100). However l get different shapes :

(96, 100, 3)
(97, 101, 3)
(97, 100, 3)
(96, 101, 3)
(96, 100, 3)
(97, 100, 3)
(97, 101, 3)
(97, 100, 3)
(97, 100, 3)
(96, 101, 3)
(97, 101, 3)
(96, 101, 3)
(96, 100, 3)
(97, 100, 3)
(96, 101, 3)

What's wrong with my code

from __future__ import division
import cv2
import numpy as np
import csv
import os
import pandas as pd
import glob
from matplotlib import pyplot as plt

def max_width_height(path):
    os.chdir(path)
    WIDTH=[]
    HEIGHT=[]

    images_name = glob.glob("*.png")
    set_img = set([x.rsplit('.', 1)[0] for x in images_name])
    for img in set_img:
        img_cv = cv2.imread(path+'/'+img+'.png')
        h=img_cv.shape[0]
        w=img_cv.shape[1]
        WIDTH.append(w)
        HEIGHT.append(h)
    max_width=max(WIDTH)
    max_height=max(HEIGHT)
    return max_height,max_width
def add_padding(max_height,max_width):

    path_char = '/cropped_images'
    output = 'dataset/'
    abby_label = []
    reference = []
    os.chdir(path_char)
    img_char= glob.glob("*.png")

    set_img_char = set([x.rsplit('.', 1)[0] for x in img_char])

    images = []
    size= []
    for img in img_char:
        img_cv = cv2.imread(path_char+'/'+img)
        h,w=img_cv.shape[0:2]

        width_diff=max_width-w
        height_diff=max_height-h

        left= width_diff/2
        right=width_diff/2
        top=height_diff/2
        bottom=height_diff/2
        if isinstance(left,float):
            left=int(left)
            right=left+1
        if isinstance(top,float):
            top=int(top)
            bottom=top+1

        white_pixels = [255, 255, 255]
        black_pixels = [0, 0, 0]


        constant = cv2.copyMakeBorder(img_cv,top,left,right,bottom, cv2.BORDER_CONSTANT, value=white_pixels)
        cv2.imwrite(output+img,constant)
        size.append(constant.shape)
        constant2 = cv2.copyMakeBorder(img_cv,top,left,right,bottom, cv2.BORDER_CONSTANT, value=black_pixels)
        cv2.imwrite(output+img,constant2)


        label, sep,rest = img.partition('_')
        abby_label.append(label)
        reference.append(rest)




    df = pd.DataFrame({'abby_label': abby_label, 'reference': reference})
    df.to_csv('abby_labels.csv')
    df2=pd.DataFrame({'dimension':size})
    df2.to_csv('dimension.csv')

    h,w=max_width_height(path)
    print(h,w)
    x=add_padding(h,w)
vincent
  • 1,558
  • 4
  • 21
  • 34

2 Answers2

4

The problem is here:

left= width_diff/2
right=width_diff/2
top=height_diff/2
bottom=height_diff/2

This will lead to different final width or height depending if the width_diff or height_diff is divisible by 2. You have a workaround implemented, but that will only work for Python 3 while you are apparently using Python 2.

You can fix this in this way:

left=width_diff/2
right=width_diff - left
top=height_diff/2
bottom=height_diff - top

In this way you will make sure that

  • left + right = width_diff
  • top + bottom = height_diff

Note that this in particular applicable to Python 2, you might be interested to read Python integer division yields float. My suggestion is to use floor division, so that your code is less vulnerable to the Python 2 and Python 3 differences.

left=width_diff//2
right=width_diff - left
top=height_diff//2
bottom=height_diff - top
Community
  • 1
  • 1
Antonio
  • 19,451
  • 13
  • 99
  • 197
1

It looks like a rounding error for images with an odd/even number of pixels.

If width_diff is an even number, it is ok to divide by 2 as you are doing it. But if it's odd, you need to add width_diff//2 to one side and (width_diff//2) + 1 to the other. The same applies to height.

Or just run the program in debug mode (since you have the images to be analyzed) and make sure images with odd/even dimensions are being handled the way you expect it.

jberrio
  • 972
  • 2
  • 9
  • 20