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:
- The Canny filter finds the edge
cv2.findContours
tracks our outline, note that we only need the outer contour, hencecv2. RETR_EXTERNAL
flag.cv2.drawContours
draws the shape of each outline for our image- Iterate through all the outlines and place bounding boxes around them.
- Use the
box's x, y, w, h
information to help us crop each outline - 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()