OpenCV, segment image - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: General Coding Help (https://python-forum.io/forum-8.html) +--- Thread: OpenCV, segment image (/thread-1416.html) |
OpenCV, segment image - Standard_user - Jan-01-2017 Good day, let's say I have an image: How do I extract each coin and stitch up a new image, like this: I was able to draw contours around each coin: import cv2 im = cv2.imread('pic.jpg') imgray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY) ret,thresh = cv2.threshold(imgray, 127, 255, 0) contours = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cv2.drawContours(im, contours[1], -1, (0, 255, 0), 3) cv2.imshow('', im) cv2.waitKey(0)Result: But where do I go further? Not asking to write code for me, just for a few hints, because this area is totally new for me. RE: OpenCV, segment image - Mekire - Jan-01-2017 You want to find circles? You should probably start with a Hough method. Basically you create an edge image; then every point in the edge image votes for all points a given radius away (all possible circles it is a member of). After all edge points have voted you look for local maxima. Vaild circles will have been voted for by multiple points letting you pinpoint circles. Implementing it yourself is an absolute pain in the ass (trust me), but opencv comes with both a Canny edge detector and a Hough circles implementation. This tutorial should get you started: http://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_houghcircles/py_houghcircles.html RE: OpenCV, segment image - Standard_user - Jan-01-2017 Thanks for response! Need to extract whatever contrasting shapes, not necessarily circles, so I think, cv2.findContours is the best way. The coordinates of shapes I need to extract are already in "contours" list, but how do I cut the shapes from original image and put them side by side in a new image? Total brain freeze ) RE: OpenCV, segment image - Mekire - Jan-01-2017 Well, if you already know the coordinates of the places you are interested in you can just slice out the portions of that image and copy them into another array. I'm not convinced find contours is quite the right tool though as I don't know if it lets you distinguish between which contours belong to which distinct shapes. I could be wrong however. RE: OpenCV, segment image - Standard_user - Jan-01-2017 Quote:if you already know the coordinates of the places you are interested in you can just slice out the portions of that image Thats why I posted this question :) Seems trivial, but I'm fighting with this 3 days already, all the graphics stuff is damn complicated for me. RE: OpenCV, segment image - Mekire - Jan-01-2017 Well, I still think circle detection is the way to go here. Here is a working version. You might need to tweak slightly to get exactly what you want. Outputs: [Image: 5azvb1x.png] import cv2 import numpy as np INFILE = 'coins.jpg' OUTFILE = 'found_coins.png' def main(): img = cv2.imread(INFILE, cv2.IMREAD_COLOR) gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) rects = find_rects(gray_img) new_image = draw_new(img, rects) cv2.imshow(OUTFILE, new_image) cv2.waitKey(0) cv2.destroyAllWindows() def find_rects(img): blurred = cv2.medianBlur(img, 5) circles = cv2.HoughCircles(blurred, cv2.cv.CV_HOUGH_GRADIENT, 1, 20, param1=50, param2=30, minRadius=10, maxRadius=50) circles = np.uint16(np.around(circles)) return [(y-rad, y+rad, x-rad, x+rad) for x,y,rad in circles[0,:]] def draw_new(img, rects): height = max(rect[1]-rect[0] for rect in rects) width = sum(rect[3]-rect[2] for rect in rects) new_image = np.ones((height,width, 3), np.uint8) * 255 col = 0 for rect in rects: height, width = rect[1] - rect[0], rect[3] - rect[2] new_image[0:height, col:col+width] = img[rect[0]:rect[1],rect[2]:rect[3]] col += width return new_image if __name__ == "__main__": main() RE: OpenCV, segment image - Standard_user - Jan-01-2017 Saved me a bunch of nerve cells. Many thanks! I just had to replace cv2.cv.CV_HOUGH_GRADIENT to cv2.HOUGH_GRADIENT to work with OpenCV3. |