extracting a subimage in shape of a polygon

opencv, python, python-2.7

Solution

I would suggest Extracting your region of interest (Any shape you'd want), by using Contours. Refer to this documentation: Drawing Contours

Your approach should be as follows:

- Mark points that make up your co-ordinates either on the image itself by attaching a MouseEventListener to the Window.

- Create a Mask Image by using. (All Zeros)

- Using these set of Coordinates, use the cv2.drawContours() method to draw the shape needed on the Mask Image and fill it with White Colour (255).

- Peform Bitwise_And Operation with the original Grayscale Image.

Sample Code:

#Function
def on_mouse(event, x, y, flags,(cPts,overlayImage,resetImage)):
    if event==cv.CV_EVENT_LBUTTONUP:
        cPts[0].append([x,y])
        cv2.circle(overlayImage,(x,y),5,(255),-1)
    elif event==cv.CV_EVENT_RBUTTONUP:
        cPts[0]=[]
        print cPts
        overlayImage[:]=resetImage[:]


#Main Program
cvImage=cv2.imread(inputImageFilePath)
grayscaleImage=cv2.cvtColor(cvImage,cv.CV_BGR2GRAY)
overlayImage=np.copy(grayscaleImage)

cv2.namedWindow('preview')
cPts=[[]]
cv2.setMouseCallback('preview',on_mouse,(cPts,overlayImage,grayscaleImage))
opacity=0.4
while True:
    displayImage=cv2.addWeighted(overlayImage,opacity,grayscaleImage,1-opacity,0)
    cv2.imshow('preview',displayImage)
    keyPressed=cv2.waitKey(5)
    if keyPressed==27:
        break
    elif keyPressed==32:
        print cPts
        cv2.drawContours(overlayImage,np.array(cPts),0,255)
        maskImage=np.zeros_like(grayscaleImage)
        cv2.drawContours(maskImage,np.array(cPts),0,255,-1)
        extractedImage=np.bitwise_and(grayscaleImage,maskImage)
        cv2.imshow('extractedImage',extractedImage)
cv2.destroyAllWindows()

Problem

Consider the following image: This is a frame from a video footage of the traffic. What I want to do is, to crop out only the oncoming traffic, and analyze it. I want a fast and efficient method with which I can extract, say, a polygon, by providing certain coordinates. I'm working on OpenCV and Python. EDIT: One option I see is treating image as Numpy array and using for loop to extract certain elements, but that won't be efficient and I don't know if its a proper thing to do.

Original source

Related problems