Search code examples
pythonimage-processingmnistskew

Deskew MNIST images


I found on https://fsix.github.io/mnist/Deskewing.html how to deskew the images of the MNIST dataset. It seems to work. My problem is that before deskewing each pixel has a value between 0 and 1. But after deskewing the image the values are not between 0 and 1 any more. They can be negative and can be greater than 1. How can this be fixed?

Here is the code:

def moments(image):
    c0,c1 = np.mgrid[:image.shape[0],:image.shape[1]] # A trick in numPy to create a mesh grid
    totalImage = np.sum(image) #sum of pixels
    m0 = np.sum(c0*image)/totalImage #mu_x
    m1 = np.sum(c1*image)/totalImage #mu_y
    m00 = np.sum((c0-m0)**2*image)/totalImage #var(x)
    m11 = np.sum((c1-m1)**2*image)/totalImage #var(y)
    m01 = np.sum((c0-m0)*(c1-m1)*image)/totalImage #covariance(x,y)
    mu_vector = np.array([m0,m1]) # Notice that these are \mu_x, \mu_y respectively
    covariance_matrix = np.array([[m00,m01],[m01,m11]]) # Do you see a similarity between the covariance matrix
    return mu_vector, covariance_matrix

def deskew(image):
    c,v = moments(image)
    alpha = v[0,1]/v[0,0]
    affine = np.array([[1,0],[alpha,1]])
    ocenter = np.array(image.shape)/2.0
    offset = c-np.dot(affine,ocenter)
    return interpolation.affine_transform(image,affine,offset=offset)

Solution

  • You can just normalize the image to a range between 0 and 1 after the skewing process.

    img = deskew(img)
    img = (img - img.min()) / (img.max() - img.min())
    

    See this question.

    To incorporate this in the deskew function, you could rewrite it like this:

    def deskew(image):
        c,v = moments(image)
        alpha = v[0,1]/v[0,0]
        affine = np.array([[1,0],[alpha,1]])
        ocenter = np.array(image.shape)/2.0
        offset = c-np.dot(affine,ocenter)
        img = interpolation.affine_transform(image,affine,offset=offset)
        return (img - img.min()) / (img.max() - img.min())