准备
- python环境
- pycharm编译器
- opencv库安装
实战
- 测试用图:
- 代码实现
import cv2 as cv
import numpy as np
card = cv.imread("D:/pics/card.png")
num = cv.imread("D:/pics/num.png")
def show_image(win_name, image_src):
cv.namedWindow(win_name, cv.WINDOW_AUTOSIZE)
cv.imshow(win_name, image_src)
def num_preInit():
show_image("num", num)
numGray = cv.cvtColor(num, cv.COLOR_BGR2GRAY)
ret, num2Value = cv.threshold(numGray, 10, 255, cv.THRESH_BINARY_INV)
contours, hierarchy = cv.findContours(num2Value, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
cv.drawContours(num, contours, -1, (0, 0, 255), 3)
single_num = {}
minBox = [cv.boundingRect(c) for c in contours]
nsize = len(minBox)
for i in range(nsize):
x, y, w, h = minBox[nsize-i-1]
roi = num2Value[y:y + h, x:x + w]
roi = cv.resize(roi,(57,88))
single_num[i] = roi
return single_num
def card_preInit():
show_image("card", card)
rectKernel = cv.getStructuringElement(cv.MORPH_RECT, (7, 7))
cardGray = cv.cvtColor(card, cv.COLOR_BGR2GRAY)
tophat = cv.morphologyEx(cardGray, cv.MORPH_TOPHAT, rectKernel)
tophat = cv.dilate(tophat, rectKernel, iterations=3)
tophat = cv.erode(tophat, rectKernel, iterations=2)
ret, card2Value = cv.threshold(tophat, 10, 255, cv.THRESH_BINARY_INV)
contours, hierarchy = cv.findContours(card2Value, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
count = 0
nums_rect= {}
minBox = [cv.boundingRect(c) for c in contours]
nsize = len(minBox)
for i in range(nsize):
xi, yi, wi, hi = minBox[i]
for j in range(nsize):
xj, yj, wj, hj = minBox[j]
if abs(yi-yj)<=3:
nums_rect[count] = minBox[j]
count = count + 1
if count>=3:
break
else:
count = 0
nums_rect.clear()
temp = {}
for i in range(len(nums_rect)):
x, y, w, h = nums_rect[i]
for j in range(len(nums_rect)):
x2, y2, w2, h2 = nums_rect[j]
if x2 > x:
temp[0] = nums_rect[j]
nums_rect[j] = nums_rect[i]
nums_rect[i] = temp[0]
nums_img = {}
for i in range(len(nums_rect)):
x, y, w, h = nums_rect[i]
nums_img[i] = card[y:y + h, x:x + w]
card_num = []
card_single_num = {}
count = 0
for i in range(len(nums_img)):
nums_img_gray = cv.cvtColor(nums_img[i], cv.COLOR_BGR2GRAY)
ret, tooValue = cv.threshold(nums_img_gray, 0, 255, cv.THRESH_OTSU)
contours, hierarchy = cv.findContours(tooValue, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
minBox = [cv.boundingRect(c) for c in contours]
nsize = len(minBox)
for j in range(nsize):
x, y, w, h = minBox[nsize-j-1]
if j == 0:
nw = w
if abs(w-nw)>10 :
continue
roi = tooValue[y:y + h, x:x + w]
roi = cv.resize(roi, (57, 88))
card_single_num[count] = roi
count = count + 1
card_num.append(card_single_num)
return card_num
def card_matchTemplate(mynums,mycard):
card_nums = []
scores = []
for i in range(16):
for j in range(10):
result = cv.matchTemplate(mycard[0][i], mynums[j], cv.TM_CCOEFF)
(_, score, _, _) = cv.minMaxLoc(result)
scores.append(score)
the_num = str((np.argmax(scores)))
card_nums.append(the_num)
scores.clear()
return card_nums
def main():
print("-------------- read_card demo----------------")
mynums = num_preInit()
mycard = card_preInit()
the_nums = card_matchTemplate(mynums,mycard)
print(the_nums)
cv.waitKey(0)
cv.destroyAllWindows()
main()
- 注意问题:
- 二值化也可以用系统自动设置阈值
- 二值化的图像注意分辨黑白,防止后续操作出问题