Aissa El Ouafi
Aissa El Ouafi

Reputation: 157

Automatically cropping an image using Python

I want to automatically crop an image using OpenCV into many images, the number of output images is variable. I started by replacing the white background by a transparent background.

The input image: enter image description here

I replace the white background by a transparent background using this script:

from PIL import Image

img = Image.open('./images/SPORTS/546.png')
img = img.convert("RGBA")
datas = img.getdata()

newData = []
for item in datas:
    if item[0] == 253 and item[1] == 252 and item[2] == 252:
        newData.append((255, 255, 255, 0))
    else:
        newData.append(item)

img.putdata(newData)
img.show()
img.save("split_image_example.png", "PNG")

So in this example I want to get 4 separated images.

enter image description hereenter image description hereenter image description hereenter image description here

Upvotes: 0

Views: 3690

Answers (1)

Soltius
Soltius

Reputation: 2261

You can use BoundingRect() on findContour() See http://docs.opencv.org/2.4/doc/tutorials/imgproc/shapedescriptors/bounding_rects_circles/bounding_rects_circles.html

For your case :

img=cv2.imread(path_to_your_image,0)
if img is None:
    sys.exit("No input image") #good practice

#thresholding your image to keep all but the background (I took a version of your
#image with a white background, you may have to adapt the threshold
thresh=cv2.threshold(img, 250, 255, cv2.THRESH_BINARY_INV);
res=thresh[1]

#dilating the result to connect all small components in your image
kernel=cv2.getStructuringElement(cv2.MORPH_CROSS,(3,3))
for i in range(10):
    res=cv2.dilate(res,kernel)

#Finding the contours
 img2,contours,hierarchy=
cv2.findContours(res,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)


cpt=0
for contour in contours:
    #finding the bounding rectangle of your contours
    rect=cv2.boundingRect(contour)
    #cropping the image to the value of the bounding rectangle
    img2=img[rect[1]:rect[1]+rect[3],rect[0]:rect[0]+rect[2]]
    cv2.imwrite("path_you_want_to_save"+str(cpt)+".png", img2)
    cpt=cpt+1;

This is a quick code, you may want to change : the saving method, the contour computing parameters, the dilatation method.... Most importantly, it suits the image you've given here but may not be appropriate for cases where your objects are closer by, or are more "sparse" (if dilating can't merge them together)

Upvotes: 2

Related Questions