我试图分割下图的数字和/或字符,然后使用ocr将每个单独的num / char转换为文本:
这是使用的代码(在python中):
new, contours, hierarchy = cv2.findContours(gray, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
digitCnts = []
final = gray.copy()
# loop over the digit area candidates
for c in contours:
(x, y, w, h) = cv2.boundingRect(c)
# if the contour is sufficiently large, it must be a digit
if (w >= 20 and w <= 290) and h >= (gray.shape[0]>>1)-15:
x1 = x+w
y1 = y+h
digitCnts.append([x,x1,y,y1])
#print(x,x1,y,y1)
# Drawing the selected contour on the original image
cv2.rectangle(final,(x,y),(x1,y1),(0, 255, 0), 2)
plt.imshow(final, cmap=cm.gray, vmin=0, vmax=255)
我得到以下输出:
您会看到所有内容都可以正确检测,除了中间2的顶部只有边框而不是整个数字。我无法弄清楚为什么只有一个无法正确检测到,尤其是与其他相似。任何想法如何解决这个问题?
答案 0 :(得分:1)
据我所知,大多数用于二进制映像的OpenCV方法都运行white objects on the black background
。
Src:
阈值INV和变通打开:
按高度过滤并在src上绘制:
#!/usr/bin/python3
# 2018/10/25 08:30
import cv2
import numpy as np
# (1) src
img = cv2.imread( "car.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# (2) threshold-inv and morph-open
th, threshed = cv2.threshold(gray, 100, 255, cv2.THRESH_OTSU|cv2.THRESH_BINARY_INV)
morphed = cv2.morphologyEx(threshed, cv2.MORPH_OPEN, np.ones((2,2)))
# (3) find and filter contours, then draw on src
cnts = cv2.findContours(morphed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]
nh, nw = img.shape[:2]
for cnt in cnts:
x,y,w,h = bbox = cv2.boundingRect(cnt)
if h < 0.3 * nh:
continue
cv2.rectangle(img, (x,y), (x+w, y+h), (255, 0, 255), 1, cv2.LINE_AA)
cv2.imwrite("dst.png", img)
cv2.imwrite("morphed.png", morphed)
答案 1 :(得分:0)
您的图像有点吵,因此将其二值化就可以解决问题。
cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY, gray)
new, contours, hierarchy = cv2.findContours(gray, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
# cv2.drawContours(gray, contours, -1, 127, 5)
digitCnts = []
final = gray.copy()
# loop over the digit area candidates
for c in contours:
(x, y, w, h) = cv2.boundingRect(c)
# if the contour is sufficiently large, it must be a digit
if (w >= 20 and w <= 290) and h >= (gray.shape[0]>>1)-15:
x1 = x+w
y1 = y+h
digitCnts.append([x,x1,y,y1])
#print(x,x1,y,y1)
# Drawing the selected contour on the original image
cv2.rectangle(final,(x,y),(x1,y1),(0, 255, 0), 2)