Ad

Numpy: Crop Object Of Interest By Removing X And Y Axis That Are Black

- 1 answer

Problem: I have some images (in numpy) that have a black background. In the middle, I have an object that I am interested in. I would like to crop the object of interest, in a numpy way.

Lets say we have an image that looks like this:

a generated image for demo and testing

I need a function crop_region_of_interest, that detects and removes any X and Y axis if the entire axis is black or [0,0,0], in order to get this:

enter image description here

Some codes used in this demo:

# just a function to add colors to generate test image
def add_color(img, pixel_x, pixel_y, rgb):
    img[pixel_x][pixel_y][0] = rgb[0]
    img[pixel_x][pixel_y][1] = rgb[1]
    img[pixel_x][pixel_y][2] = rgb[2]

def generate_fake_image_for_stackoverflow():
    # a black background image
    base_img = np.zeros((16,16,3), dtype=int)

    # lets add some colors, these are the region we want
    for x in range(4,10):
        for y in range(6,12):
            if(x==y):
                continue
            if(x+y<12):
                continue
            if(x+y>16):
                continue
            add_color(base_img, x,y, [255,60,90])

    return base_img

# a hardcoded cropped to generate expected result 
def crop_region_of_interest(img):
    # crop first axis
    cropped = img[4:10]

    # transpose to second axis, so can crop
    cropped = cropped.transpose((1,0,2))
    cropped = cropped[6:12]

    # transpose back
    cropped = cropped.transpose((1,0,2))
    cropped = cropped.transpose((1,0,2))
    cropped = cropped.transpose((1,0,2))

    return cropped

img = generate_fake_image_for_stackoverflow() # to generate a test image
plt.imshow(img)
plt.show()

cropped = crop_region_of_interest(img) # a hardcoded cropped to generate expected result, this to be replaced 
plt.imshow(cropped)
plt.show()
Ad

Answer

just slight edit on the solution provided by [https://codereview.stackexchange.com/questions/132914/crop-black-border-of-image-using-numpy]

def crop_image(img,tol=0):
    # img is 2D or 3D image data
    # tol  is tolerance
    mask = img>tol
    if img.ndim==3:
        mask = mask.all(2)
    m,n = mask.shape
    mask0,mask1 = mask.any(0),mask.any(1)
    col_start,col_end = mask0.argmax(),n-mask0[::-1].argmax()
    row_start,row_end = mask1.argmax(),m-mask1[::-1].argmax()
    return img[row_start:row_end,col_start:col_end]

Thanks @jamal and @divakar

Ad
source: stackoverflow.com
Ad