使用凸壳坐标提取字符 - opencv - python
Posted
技术标签:
【中文标题】使用凸壳坐标提取字符 - opencv - python【英文标题】:Extract Characters using convex Hull coordinates - opencv - python 【发布时间】:2018-10-27 18:44:58 【问题描述】:我有这样的角色图像:
使用以下代码,我可以获得轮廓和凸包,然后我可以为每个字符绘制凸包。
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)
结果如下:
我可以得到这样的船体坐标(对于一个角色):
[[[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]]]
现在我想使用convexHull
坐标分隔每个字符。
分离后的图像会是这样的,
。 . .
我想使用convexHull
坐标的主要原因是我可以分割在垂直图像空间中重叠的字符。您可以使用以下图片来理解我的意思:
我无法准确地分割字符,因为大多数图像都包含上述字符。所以我想用convexHull
坐标分割字符。
【问题讨论】:
【参考方案1】: 得到一个字符的凸包后,找到对应的轮廓并填充。 我用原始图像掩盖了每个单独的归档轮廓以获得片段代码如下:
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()
现在您可以使用cv2.imwrite()
保存每个单独的段。
以下是一些分段字符:
【讨论】:
感谢您的回答。我试过这个,好像我可以修改它并得到我想要的结果。但问题是结果来的顺序是错误的。订单对我很重要。你能为此做点什么吗? @IsharaMadhawa 也许轮廓的质心可以帮助排序! @IsharaMadhawa 是推荐的代码编辑实际工作吗?以上是关于使用凸壳坐标提取字符 - opencv - python的主要内容,如果未能解决你的问题,请参考以下文章
youcans 的 OpenCV 例程200篇122. 形态算法之边界提取
youcans 的 OpenCV 例程200篇125. 形态算法之提取连通分量
youcans 的 OpenCV 例程200篇130. 形态学之提取水平和垂直线