Search code examples
pythonopencvimage-processingcrop

Remove gap between areas of image


I have merged two lung images using an online merging tool to display a full image.

enter image description here

The problem is that since the background of each image is black I got an unwanted gap between the lungs in the image displayed.

I would like to know if there is a way to remove an area from an image either with code with an algorithm or with an online tool and reduce the gap between the lungs.

Another approach I checked was using OpenCV with Python for a panoramic image stitching, which I will try as a last resort to connect my images.

My desired result:

enter image description here


Solution

  • The Concept:

    1. Using the cv2.findContours() method, we will get an array of all the contours detected in the image specified. Normally, we would preprocess the image (for example, with the cv2.Canny() method) before passing it into the cv2.findContours() method, but as the image we have now is a simple binary image with two very obvious blobs in it, it wouldn't be necessary.

    2. We use the cv2.boundingBox() method to find the x, y, w, h of each contour so that we can slice that part from the image.

    3. We use the x, y, w, h detected to get two slices of the image, apply a border to each slice using the cv2.copyMakeBorder() , and concatenate them together with the np.hstack() method.

    The Code:

    import cv2
    import numpy as np
    
    img = cv2.imread("lungs.png")
    
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    contours, _ = cv2.findContours(img_gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    
    (x1, y1, w1, h1), (x2, y2, w2, h2) = sorted(map(cv2.boundingRect, contours))
    
    lung_1 = cv2.copyMakeBorder(img[y1: y1 + h2, x1: x1 + w1], 20, 20, 20, 20, cv2.BORDER_CONSTANT)
    lung_2 = cv2.copyMakeBorder(img[y2: y2 + h2, x2: x2 + w2], 20, 20, 20, 20, cv2.BORDER_CONSTANT)
    
    cv2.imshow("result", np.hstack((lung_1, lung_2)))
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    The Output:

    enter image description here

    Notes:

    1. At the line:
    lung_1 = cv2.copyMakeBorder(img[y1: y1 + h2, x1: x1 + w1], 20, 20, 20, 20, cv2.BORDER_CONSTANT)
    

    notice that we used h2 instead of h1, as if we were to use the h1 we defined, the np.hstack() method would throw an error due to the different heights of the arrays.

    1. The sorted() at
    (x1, y1, w1, h1), (x2, y2, w2, h2) = sorted(map(cv2.boundingRect, contours))
    

    is to sort the x, y, w, h by their x property, so that the lungs are concatenated from left to right.