Reputation: 11
I have a set of images like below, where each image consist of the actual image part with the black borders of varying sizes around it. My objective is to remove those borders and just extract the image, which later can be used for other tasks.
I have tried using canny edge detector, to identify the border and get only the image out of it, however its not working as expected.
I have also tried techniques mentioned in other posts like below, but these too doesnot work in my case.
In [1]: from PIL import Image, ImageChops
In [3]: im = Image.open('iI3ZE.jpg')
In [4]: def trim(im):
...: bg = Image.new(im.mode, im.size, im.getpixel((0,0)))
...: diff = ImageChops.difference(im, bg)
...: diff = ImageChops.add(diff, diff, 2.0, -100)
...: bbox = diff.getbbox()
...: if bbox:
...: return im.crop(bbox)
Any leads for the above query would be helpful.
Upvotes: 0
Views: 2586
Reputation: 53089
Here is one way in Python/OpenCV. Read the image as grayscale. Then threshold at zero since background is black. Then apply morphology open to clean it up. Then find contours and get the bounding box of the largest one. Then crop using the bounding box.
Input:
import cv2
import numpy as np
# load image
img = cv2.imread("sonar.png", cv2.IMREAD_GRAYSCALE)
# threshold
thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY)[1]
# apply open morphology
#kernel = np.ones((5,5), np.uint8)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (15,15))
morph = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
# get bounding box coordinates from largest external contour
contours = cv2.findContours(morph, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
big_contour = max(contours, key=cv2.contourArea)
x,y,w,h = cv2.boundingRect(big_contour)
# crop image contour image
result = img.copy()
result = result[y:y+h, x:x+w]
# write result to disk
cv2.imwrite("sonar_thresh.jpg", thresh)
cv2.imwrite("sonar_morph.jpg", morph)
cv2.imwrite("sonar_cropped.png", result)
# display results
cv2.imshow("THRESH", thresh)
cv2.imshow("MORPH", morph)
cv2.imshow("CROPPED", result)
cv2.waitKey(0)
cv2.destroyAllWindows()
Morphology cleaned image:
Cropped image:
Upvotes: 2