Numpy PIL Python : crop image on whitespace or crop text with histogram Thresholds
Question: How would I go about finding the bounding box or window for the region of
whitespace surrounding the numbers in the image below?:

# Original image:

![enter image description here](http://i.stack.imgur.com/Aet62.png)

Height: 762 pixels Width: 1014 pixels

# Goal:

Something like: `{x-bound:[x-upper,x-lower], y-bound:[y-upper,y-lower]}` so I
can crop to the text and input into tesseract or some OCR.

# Attempts:

I had thought of slicing the image into hard coded chunk sizes and analysing
at random, but i think it would be too slow.

Example code using `pyplot` adapted from ([Using python and PIL how can I grab
a block of text in an
image?](http://stackoverflow.com/questions/9402765/using-python-and-pil-how-
can-i-grab-a-block-of-text-in-an-image)):

    
    
    from PIL import Image
    import numpy as np
    import matplotlib.pyplot as plt
    im = Image.open('/home/jmunsch/Pictures/Aet62.png')
    p = np.array(im)
    p = p[:,:,0:3]
    p = 255 - p
    lx,ly,lz = p.shape
    
    plt.plot(p.sum(axis=1))
    plt.plot(p.sum(axis=0))
    
    #I was thinking something like this 
    #The image is a 3-dimensional ndarray  [[x],[y],[color?]]
    #Set each value below an axes mean to 0
    [item = 0 for item in p[axis=0] if item < p.mean(axis=0)]
    
    # and then some type of enumerated groupby for each axes
    #finding the mean index for each groupby(0) on axes
    
    plt.plot(p[mean_index1:mean_index2,mean_index3:mean_index4])
    

Based on the graphs each of the valleys would indicate a place to bound.

  * The first graph shows where lines of text would be
  * The second graph shows where characters would be

# Plot example `plt.plot(p.sum(axis=1))`:

![enter image description here](http://i.stack.imgur.com/sIFDT.png)

# Plot example output `plt.plot(p.sum(axis=0))`:

![enter image description here](http://i.stack.imgur.com/ZViU1.png)

Related posts/docs:

  * [Trim whitespace using PIL](http://stackoverflow.com/questions/10615901/trim-whitespace-using-pil)
  * [Using python and PIL how can I grab a block of text in an image?](http://stackoverflow.com/questions/9402765/using-python-and-pil-how-can-i-grab-a-block-of-text-in-an-image)
  * [Use Python / PIL or similar to shrink whitespace](http://stackoverflow.com/questions/9396312/use-python-pil-or-similar-to-shrink-whitespace/9398422#9398422)
  * [Crop the image using PIL in python](http://stackoverflow.com/questions/9983263/crop-the-image-using-pil-in-python)
  * [Rectangular bounding box around blobs in a monochrome image using python](http://stackoverflow.com/questions/9525313/rectangular-bounding-box-around-blobs-in-a-monochrome-image-using-python?rq=1)
  * [How can I improve my paw detection?](http://stackoverflow.com/questions/4087919/how-can-i-improve-my-paw-detection?lq=1)
  * <http://scipy-lectures.github.io/advanced/image_processing/>
  * <http://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html>

# update: solution by HYRY

![enter image description here](http://i.stack.imgur.com/uPeca.gif)


Answer: I think you can use Morphology functions in `scipy.ndimage`, here is an
example:

    
    
    import pylab as pl
    import numpy as np
    from scipy import ndimage
    img = pl.imread("Aet62.png")[:, :, 0].astype(np.uint8)
    img2 = ndimage.binary_erosion(img, iterations=40)
    img3 = ndimage.binary_dilation(img2, iterations=40)
    labels, n = ndimage.label(img3)
    counts = np.bincount(labels.ravel())
    counts[0] = 0
    img4 = labels==np.argmax(counts)
    img5 = ndimage.binary_fill_holes(img4)
    result = ~img & img5
    result = ndimage.binary_erosion(result, iterations=3)
    result = ndimage.binary_dilation(result, iterations=3)
    pl.imshow(result, cmap="gray")
    

the output is:

![enter image description here](http://i.stack.imgur.com/o1GKe.png)

