Python – Copy an area within an outline to another image

Copy an area within an outline to another image… here is a solution to the problem.

Copy an area within an outline to another image

I use the following code in Python to find the outline in the image:

import cv2

im = cv2.imread('test.jpg')
imgray = cv2.cvtColor(im, cv2. COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(imgray, 127, 255, 0)
im2, contours, hierarchy = cv2.findContours(thresh, cv2. RETR_TREE, cv2. CHAIN_APPROX_SIMPLE)

Now I want to copy the area inside the first outline to another image, but I can’t find any tutorial or sample code that explains how to do this.

Solution

Here is a complete example. It’s a bit overkill to output all the contours, but I think you might find a way to adjust it to your liking. Not sure what you mean by copy either, so I’m assuming you just want to output the outline to a file.

We’ll start with an image like this (in which case you’ll notice that I don’t need to threshold the image). The following script can be broken down into 6 main steps:

  1. The Canny filter finds the edge
  2. cv2.findContours tracks our outline, note that we only need the outer contour, hence cv2. RETR_EXTERNAL flag.
  3. cv2.drawContours draws the shape of each outline for our image
  4. Iterate through all the outlines and place bounding boxes around them.
  5. Use the box's x, y, w, h information to help us crop each outline
  6. Write the cropped image to a file.

import cv2

image = cv2.imread('images/blobs1.png')
edged = cv2. Canny(image, 175, 200)

contours, hierarchy = cv2.findContours(edged, cv2. RETR_EXTERNAL, cv2. CHAIN_APPROX_SIMPLE)
cv2.drawContours(image, contours, -1, (0,255,0), 3)

cv2.imshow("Show contour", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

for i,c in enumerate(contours):
    rect = cv2.boundingRect(c)
    x,y,w,h = rect
    box = cv2.rectangle(image, (x,y), (x+w,y+h), (0,0,255), 2)
    cropped = image[y: y+h, x: x+w]
    cv2.imshow("Show Boxes", cropped)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    cv2.imwrite("blobby"+str(i)+".png", cropped)

cv2.imshow("Show Boxes", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

Related Problems and Solutions