md1hunox
md1hunox

Reputation: 3955

extracting a subimage in shape of a polygon

Consider the following image:

Image of traffic

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.

Upvotes: 5

Views: 3742

Answers (3)

Colenso Castellino
Colenso Castellino

Reputation: 900

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:

  1. Mark points that make up your co-ordinates either on the image itself by attaching a MouseEventListener to the Window.
  2. Create a Mask Image by using. (All Zeros)
  3. 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).
  4. 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()

Upvotes: 5

pradyunsg
pradyunsg

Reputation: 19416

Well, I propose you do something like:

  1. Separate the image into different regions, according to various things mainly lighting.
  2. Then for each region, apply a threshold to separate the important areas(traffic), from the unimportant areas(trees etc). (cv2.threshold)
  3. Using contours, you can distinguish the vehicles from the other stuff.(cv2.findContours and more)

If you have a stream of video or something like it, you can use something like Motion Detection too.

Some links you might find useful:

Upvotes: 1

Ann  Orlova
Ann Orlova

Reputation: 1348

I can propose a version of the algorithm:

  1. First discard the part of image, that you are not interested in. If it a static camera, you can just calculate this region manually. In other case try to use Line Detection Algorithm
  2. Then extract background with cvThreshold (good example of using background extraction).
  3. After extraction, you can find contours and analyze their shape to distinguish objects (cars, people, etc.).

Hope this will be helpful.

Upvotes: 1

Related Questions