实现效果:
code
import cv2 as cv
import numpy as np
def sort_contours(cnts, method="left-to-right"):
reverse = False
i = 0
if method == "right-to-left" or method == "bottom-to-top":
reverse = True
if method == "top-to-bottom" or method == "bottom-to-top":
i = 1
boundingBoxes = [cv.boundingRect(c) for c in cnts]
(cnts, boundingBoxes) = zip(*sorted(zip(cnts, boundingBoxes),
key=lambda b: b[1][i], reverse=reverse))
return (cnts, boundingBoxes)
def cv_show(name, img):
cv.imshow(name, img)
def loadTemplate():
img = cv.imread('template.png')
cv_show('src', img)
ref = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
cv_show('gray', ref)
ref = cv.threshold(ref, 10, 255, cv.THRESH_BINARY_INV)[1]
cv_show('binary', ref)
refCnts, hierarchy = cv.findContours(ref.copy(), cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
print(np.array(refCnts).shape)
cv.drawContours(img, refCnts, -1, (0, 255, 0), 3)
cv_show('canny', img)
digits = {}
refCnts = sort_contours(refCnts)[0]
for (i, c) in enumerate(refCnts):
(x, y, w, h) = cv.boundingRect(c)
roi = ref[y:y + h, x:x + w]
roi = cv.resize(roi, (57, 88))
digits[i] = roi
return digits
def dealProcess(digits):
rectKernel = cv.getStructuringElement(cv.MORPH_RECT, (9, 3))
sqKernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5))
src = cv.imread('card.png')
cv_show('src', src)
inGray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
cv_show('inGray', inGray)
tophat = cv.morphologyEx(inGray, cv.MORPH_TOPHAT, rectKernel)
cv_show('tophat', tophat)
gradX = cv.Sobel(tophat, ddepth=cv.CV_32F, dx=1, dy=0, ksize=-1)
gradX = np.absolute(gradX)
(minVal, maxVal) = (np.min(gradX), np.max(gradX))
gradX = (255 * ((gradX - minVal) / maxVal - minVal))
gradX = gradX.astype("uint8")
cv_show('gradX', gradX)
gradX = cv.morphologyEx(gradX, cv.MORPH_CLOSE, rectKernel)
cv_show('MORPH_CLOSE', gradX)
thresh = cv.threshold(gradX, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)[1]
cv_show('thresh', thresh)
thresh = cv.morphologyEx(thresh, cv.MORPH_CROSS, sqKernel)
cv_show('thresh-close', thresh)
srcCnts, srcHierarchy = cv.findContours(thresh.copy(), cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
print(type(srcCnts))
src2 = src.copy()
cv.drawContours(src2, srcCnts, -1, (0, 255, 0), 3)
cv_show('src', src2)
locs = []
for (i, c) in enumerate(srcCnts):
(x, y, w, h) = cv.boundingRect(c)
ar = w / float(h)
if 2.8 < ar < 4.0:
if (50 < w < 65) and (15 < h < 33):
locs.append((x, y, w, h))
locs = sorted(locs, key=lambda x: x[0])
print('-------------------------')
print(locs)
output = []
for (i, (gX, gY, gW, gH)) in enumerate(locs):
groupOutput = []
group = inGray[gY - 5:gY + gH + 5, gX - 5:gX + gW + 5]
group = cv.threshold(group, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)[1]
cv_show('group', group)
digitCnts, hierarchy = cv.findContours(group.copy(), cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
digitCnts = sort_contours(digitCnts)[0]
for c in digitCnts:
(x, y, w, h) = cv.boundingRect(c)
roi = group[y:y + h, x:x + w]
roi = cv.resize(roi, (57, 88))
scores = []
for (digit, digitROI) in digits.items():
result = cv.matchTemplate(roi, digitROI, cv.TM_CCOEFF)
(minVal, maxVal, minLoc, maxLoc) = cv.minMaxLoc(result)
scores.append(maxVal)
groupOutput.append(str(np.argmax(scores)))
cv.rectangle(src, (gX - -5, gY - 5), (gX + gW + 5, gY + gH + 5), (0, 0, 255), 1)
cv.putText(src, "".join(groupOutput), (gX, gY - 15), cv.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2)
output.extend(groupOutput)
return (src, output)
if __name__ == '__main__':
digits = loadTemplate()
(src, output) = dealProcess(digits)
print("res:{}".format("".join(output)))
cv_show('res', src)
cv.waitKey()
用到的资源图片:
感谢支持,欢迎讨论交流,谢谢!
|