Ho Si Tuan
Ho Si Tuan

Reputation: 540

How to divide image into two parts without crossing any object using openCV?

I am using an object detection machine learning model (only 1 object). It working well in case there are a few objects in image. But, if my image has more than 300 objects, it can't recognize anything. So, I want to divide it into two parts or four parts without crossing any object.

I used threshold otsu and get this threshold otsu image. Actually I want to divide my image by this line expect image. I think my model will work well if make predictions in each part of image.

I tried to use findContour, and find contourArea bigger than a half image area, draw it into new image, get remain part and draw into another image. But most of contour area can't reach 1/10 image area. It is not a good solution.

I thought about how to detect a line touch two boundaries (top and bottom), how can I do it?

Any suggestion is appreciate. Thanks so much.

Upvotes: 4

Views: 847

Answers (1)

Prefect
Prefect

Reputation: 1777

Since your region of interests are separated already, you can use connectedComponents to get the bounding boxes of these regions. My approach is below.

img = cv2.imread('circles.png',0)
img = img[20:,20:] # remove the connecting lines on the top and the left sides

_, img = cv2.threshold(img,0,1,cv2.THRESH_BINARY)

labels,stats= cv2.connectedComponentsWithStats(img,connectivity=8)[1:3]

plt.imshow(labels,'tab10')
plt.show()

labels

As you can see, two regions of interests have different labels. All we need to do is to get the bounding boxes of these regions. But first, we have to get the indices of the regions. For this, we can use the size of the areas, because after the background (blue), they have the largest areas.

areas = stats[1:,cv2.CC_STAT_AREA] # the first index is always for the background, we do not need that, so remove the background index

roi_indices = np.flip(np.argsort(areas))[0:2] # this will give you the indices of two largest labels in the image, which are your ROIs 

# Coordinates of bounding boxes
left = stats[1:,cv2.CC_STAT_LEFT] 
top = stats[1:,cv2.CC_STAT_TOP] 
width = stats[1:,cv2.CC_STAT_WIDTH] 
height = stats[1:,cv2.CC_STAT_HEIGHT] 


for i in range(2):
    roi_ind = roi_indices[i]
    roi = labels==roi_ind+1

    roi_top = top[roi_ind]
    roi_bottom = roi_top+height[roi_ind]
    roi_left = left[roi_ind]
    roi_right = roi_left+width[roi_ind]


    roi = roi[roi_top:roi_bottom,roi_left:roi_right]
    plt.imshow(roi,'gray')
    plt.show()

roi_0 roi_1

For your information, my method is only valid for 2 regions. In order to split into 4 regions, you would need some other approach.

Upvotes: 1

Related Questions