How to use CV2 to cut portions of an image into separate images?

Viewed 178

enter image description hereI have an image which contains many same sized rectangular panels separated by whitespace. I want to separate each rectangular panel into its own image. Any suggestions on how to go about it?

I thought of using cv2.floodfill to fill in the whitespace between panels and then invert the mask. However, that creates just a single mask and not an array of masks which I could use to identify coordinates and then split the panels into images.

Any pointers on how to do this smartly would be much appreciated.

1 Answers

You can try applying contours on an image, Use binary image cv2.THRESH_BINARY than Gray image for effective contours -> apply contours

Filter contours

1st Filter - which are first level with no parent Contours Hierarchy,

2nd Filter - which are with same range of rectangles with 1% deviation

Followed by Bounding box of contours and slicing image,

import numpy as np
import cv2 as cv
filename = r'UcbZn.jpg'
im = cv.imread(filename)
imgray = cv.cvtColor(im, cv.COLOR_BGR2GRAY)
ret, thresh = cv.threshold(imgray, 240, 255, cv.THRESH_BINARY)
contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)

# Filter -1 Filtering countours with first level with no parent
a = [[cv.contourArea(c), h, c] for c, h in zip(contours, hierarchy[0]) if h[3]==0]
a.sort(key=lambda x: -x[0])

base_contour = a[0]
# Filter-2 contours of rectangle size
res = [c for c in a if c[0] >= base_contour[0]*0.99]


count = 0
for c in res:
    x,y,w,h = cv.boundingRect(c[2])
    cv.imwrite('objects_{}.jpg'.format(str(count)), im[y:y+h,x:x+w, :])
    count+=1
      

enter image description here

Related