简体   繁体   中英

How to crop an image along major axis of the blob/contour with a rectangular bounding box using Python

I would like to crop an image which has a hand drawn highlighted area in orange as shown below,

在此处输入图像描述

The result should be a cropped image along the major axis of the blob or contour with a rectangular bounding box, as shown below,

在此处输入图像描述

Here's what i have tried,

 import numpy as np import cv2 # load the image image = cv2.imread("frame50.jpg", 1) #color boundaries [B, G, R] lower = [0, 3, 30] upper = [30, 117, 253] # create NumPy arrays from the boundaries lower = np.array(lower, dtype="uint8") upper = np.array(upper, dtype="uint8") # find the colors within the specified boundaries and apply # the mask mask = cv2.inRange(image, lower, upper) output = cv2.bitwise_and(image, image, mask=mask) ret,thresh = cv2.threshold(mask, 50, 255, 0) if (int(cv2.__version__[0]) > 3): contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) else: im2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) if len(contours):= 0, # find the biggest countour (c) by the area c = max(contours. key = cv2,contourArea) x,y,wh = cv2:boundingRect(c) ROI = image[y,y+h: x.x+w] cv2,imshow('ROI'.ROI) cv2.imwrite('ROI,png'.ROI) cv2.waitKey(0)

This does not seem to work most of the time.For some images, the following happens,

在此处输入图像描述

I would like to know if there is better way to go about this or how i can fix what i have right now.Note that the highlighted area is hand drawn and can be of any shape but it is closed and not left open and the colour of the highlight is that shade of orange itself in all cases. And is there a way to only retain content inside the circle and blackout everything outside it?

EDIT1: I was able to fix the wrong clipping by varying the threshold more. But my main query now is: is there a way to only retain content inside the circle and blackout everything outside it? I can see the mask as show below,

在此处输入图像描述

How do I fill this mask and retain content inside the circle and blackout everything outside it, with the same rectangular bounding box?

Have you tried

image[x:x+w, y:y+h]

And could you check bbox with below code

cv2.rectangle(thresh,(x,y),(x+w,y+h),(255,0,0),2)

First of all, it is always better to use an HSV image instead of BGR image for masking(extracting a color). You can do this by the following code.

HSV_Image = cv2.cvtColor(Image, cv2.COLOR_BGR2HSV)
ThreshImage = cv2.inRange(HSV_Image, np.array([0, 28, 191]), np.array([24, 255, 255]))

The range numbers here are found for orange color in this case.

Image is the input image and ThreshImage is the output image with the orange region colored as white and everything else as black.

Now finding the contour in ThreshImage with cv2.RETR_EXTERNAL flag will give only one contour that is the outer boundary of the orange region.

Contours, Hierarchy = cv2.findContours(ThreshImage, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

To crop the orange region:

BoundingRect = cv2.boundingRect(Contours[0])
(x, y, w, h) = BoundingRect
CroppedImage = Image[y:y+h, x:x+w].copy()

"CroppedImage" will store the cropped orange region as desired.

To get contents of only inside the contour:

Bitwise AND operation will be useful here as we already have detected the contour.

First, we have to create a black image of shape the same as that of input image and draw the contour with white color filled in it.

ContourFilledImage = np.zeros(Image.shape, dtype=np.uint8)
cv2.drawContours(ContourFilledImage, Contours, -1, (255, 255, 255), -1)

Now perform a bitwise AND operation on Input Image and "ContourFilledImage"

OnlyInnerData = cv2.bitwise_and(ContourFilledImage, Image)

"OnlyInnerData" image is the desired output image having only the content of inside the circle.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM