问题
I have character images like this:
Using following code I could get contours and convex hull, then I could draw convex for each character.
import cv2
img = cv2.imread('test.png', -1)
ret, threshed_img = cv2.threshold(cv2.cvtColor(img, cv2.COLOR_BGR2GRAY),
127, 255, cv2.THRESH_BINARY)
image, contours, hier = cv2.findContours(threshed_img, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
for cnt in contours:
# get convex hull
hull = cv2.convexHull(cnt)
cv2.drawContours(img, [hull], -1, (0, 0, 255), 1)
print(hull)
cv2.imwrite("contours.jpg", img)
The result is as follows:
I could get hull coordinates like this (for one character):
[[[546 134]]
[[534 149]]
[[532 151]]
[[527 153]]
[[523 154]]
[[522 154]]
[[520 109]]
[[521 107]]
[[524 106]]
[[533 106]]
[[539 111]]
[[543 117]]
[[546 122]]]
Now I want to separate each character using convexHull
coordinates.
After separating, images would be like,
The main reason I want to use convexHull
coordinates is then I can segment characters which were overlapped in vertical image space. You can understand what I have meant by using following image:
I can't segment characters accurately since most of the images contain characters like above. So I want to segment characters using convexHull
coordinates.
回答1:
- After obtaining the convex hull for one character, I found its corresponding contour and filled it.
- I masked each individual filed contour with the original image to obtain the segments
Here is the code:
import cv2
import numpy as np
img = cv2.imread(r'C:\Users\selwyn77\Desktop\letters.png', -1)
img2 = img.copy()
cv2.imshow("original.jpg", img)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, threshed_img = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
image, contours, hier = cv2.findContours(threshed_img, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
#--- Black image to be used to draw individual convex hull ---
black = np.zeros_like(img)
cv2.imshow("black.jpg", black)
contours = sorted(contours, key=lambda ctr: cv2.boundingRect(ctr)[0]) #added by OP : this sorts contours left to right, so images come in order
for cnt in contours:
hull = cv2.convexHull(cnt)
img3 = img.copy()
black2 = black.copy()
#--- Here is where I am filling the contour after finding the convex hull ---
cv2.drawContours(black2, [hull], -1, (255, 255, 255), -1)
g2 = cv2.cvtColor(black2, cv2.COLOR_BGR2GRAY)
r, t2 = cv2.threshold(g2, 127, 255, cv2.THRESH_BINARY)
cv2.imshow("t2.jpg", t2)
masked = cv2.bitwise_and(img2, img2, mask = t2)
cv2.imshow("masked.jpg", masked)
print(len(hull))
cv2.waitKey(0)
cv2.destroyAllWindows()
Now you can save each of the individual segments using cv2.imwrite()
.
Here are a few of the segmented characters:
来源:https://stackoverflow.com/questions/50392449/extract-characters-using-convex-hull-coordinates-opencv-python