mad
mad

Reputation: 2789

Extract foreground images from a white background

I have the following image, which is a scanned printed paper with 4 images. I printed 4 images in the same sheet of paper to save printing resources:

Printed images that were scanned later However, now I need to extract image by image and, for each of them, create an individual image file. Is there any easy way of doing that with Python, Matlab or any other programming language?

Upvotes: 0

Views: 1272

Answers (1)

fmw42
fmw42

Reputation: 53081

Here is one way to do that in Python/OpenCV. But it requires that the pictures colors at their sides be sufficiently different from the background color. If so, you can threshold the image, then get contours and use their bounding boxes to crop out each image.

  • Read the input
  • Threshold based on the background color
  • Invert the threshold, so that the background is black
  • Apply morphology open and close to fill the picture regions and remove noise
  • Get the external contours
  • For each contour, get its bounding box and crop the input image and save it to disk

Input:

enter image description here

import cv2
import numpy as np

# read image
img = cv2.imread('4faces.jpg')

# threshold on background color
lowerBound = (230,230,230)
upperBound = (255,255,255)
thresh = cv2.inRange(img, lowerBound, upperBound)

# invert so background black
thresh = 255 - thresh

# apply morphology to ensure regions are filled and remove extraneous noise
kernel = np.ones((7,7), np.uint8)
thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
kernel = np.ones((11,11), np.uint8)
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)

# get contours
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]

# get bounding boxes and crop input
i = 1
for cntr in contours:
    # get bounding boxes
    x,y,w,h = cv2.boundingRect(cntr)
    crop = img[y:y+h, x:x+w]
    cv2.imwrite("4faces_crop_{0}.png".format(i), crop)
    i = i + 1


# save threshold
cv2.imwrite("4faces_thresh.png",thresh)

# show thresh and result    
cv2.imshow("thresh", thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()

Thresholded image after morphology cleaning:

enter image description here

Cropped Images:

enter image description here

enter image description here

enter image description here

enter image description here

Upvotes: 10

Related Questions