Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert own image to MNIST's image

I am newbie of tensorflow. I trained the digit prediction model using MNIST's train data. And then I test the model using my own image. It cannot predict the actual result.

The problems are :

  1. MNIST's images are needed black and white
  2. The images are size normalized to fit in a 20x20 pixel box and there are centered in a 28x28 image using the center of mass.
  3. I don't want to use OpenCV

The question is How to shift my own handwritten digit image to the center of 28x28 image. Own image can be any color and that image to change Black and White MNIST's image

like image 455
Zephyr Lay Avatar asked Mar 07 '16 11:03

Zephyr Lay


2 Answers

from PIL import Image, ImageFilter


def imageprepare(argv):
    """
    This function returns the pixel values.
    The imput is a png file location.
    """
    im = Image.open(argv).convert('L')
    width = float(im.size[0])
    height = float(im.size[1])
    newImage = Image.new('L', (28, 28), (255))  # creates white canvas of 28x28 pixels

    if width > height:  # check which dimension is bigger
        # Width is bigger. Width becomes 20 pixels.
        nheight = int(round((20.0 / width * height), 0))  # resize height according to ratio width
        if (nheight == 0):  # rare case but minimum is 1 pixel
            nheight = 1
            # resize and sharpen
        img = im.resize((20, nheight), Image.ANTIALIAS).filter(ImageFilter.SHARPEN)
        wtop = int(round(((28 - nheight) / 2), 0))  # calculate horizontal position
        newImage.paste(img, (4, wtop))  # paste resized image on white canvas
    else:
        # Height is bigger. Heigth becomes 20 pixels.
        nwidth = int(round((20.0 / height * width), 0))  # resize width according to ratio height
        if (nwidth == 0):  # rare case but minimum is 1 pixel
            nwidth = 1
            # resize and sharpen
        img = im.resize((nwidth, 20), Image.ANTIALIAS).filter(ImageFilter.SHARPEN)
        wleft = int(round(((28 - nwidth) / 2), 0))  # caculate vertical pozition
        newImage.paste(img, (wleft, 4))  # paste resized image on white canvas

    # newImage.save("sample.png

    tv = list(newImage.getdata())  # get pixel values

    # normalize pixels to 0 and 1. 0 is pure white, 1 is pure black.
    tva = [(255 - x) * 1.0 / 255.0 for x in tv]
    print(tva)
    return tva

x=imageprepare('./image.png')#file path here
print(len(x))# mnist IMAGES are 28x28=784 pixels
like image 137
Naveen Kumar Dasari Avatar answered Nov 02 '22 13:11

Naveen Kumar Dasari


I would use numpy recipe like this one -- https://www.kaggle.com/c/digit-recognizer/forums/t/6366/normalization-and-centering-of-images-in-mnist

You could probably remap this to pure TensorFlow pipeline, but I'm not sure it's necessary given that it's tiny images.

Also you would get better accuracy if you went the other way -- instead of normalizing your input data, make your network robust to lack of normalization by training on a larger dataset of randomly shifted/rescaled MNIST digits.

like image 3
Yaroslav Bulatov Avatar answered Nov 02 '22 13:11

Yaroslav Bulatov