当前位置:网站首页>Opencv learning note 4 -- bank card number recognition
Opencv learning note 4 -- bank card number recognition
2022-07-01 14:55:00 【Cloudy_ to_ sunny】
opencv Study note 4 -- Bank card number identification
Early step
Import toolkit
from imutils import contours
import numpy as np
import argparse
import cv2
import myutils
import matplotlib.pyplot as plt#Matplotlib yes RGB
Specify the type of credit card
# Specify the type of credit card ( According to the first digit of the card number )
FIRST_NUMBER = {
"3": "American Express",
"4": "Visa",
"5": "MasterCard",
"6": "Discover Card"
}
Define the drawing function
# Graphic display
def cv_show(name,img):
b,g,r = cv2.split(img)
img_rgb = cv2.merge((r,g,b))
plt.imshow(img_rgb)
plt.show()
def cv_show1(name,img):
plt.imshow(img)
plt.show()
cv2.imshow(name,img)
cv2.waitKey()
cv2.destroyAllWindows()
Read in the data
# Read a template image
img = cv2.imread("./ocr_a_reference.png")
cv_show('img',img)

# grayscale
ref = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv_show1('ref',ref)

# Binary image
ref = cv2.threshold(ref, 10, 255, cv2.THRESH_BINARY_INV)[1]
cv_show1('ref',ref)

Template handling
Calculate the contour
#cv2.findContours() The parameters accepted by the function are binary graphs , Black and white ( It's not grayscale ),cv2.RETR_EXTERNAL Only the outer contour is detected ,cv2.CHAIN_APPROX_SIMPLE Keep only the end coordinates
# Back to list Each element in is an outline in the image
ref_, refCnts, hierarchy = cv2.findContours(ref.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(img,refCnts,-1,(0,0,255),3)
cv_show1('img',img)

print (np.array(refCnts).shape)
refCnts = myutils.sort_contours(refCnts, method="left-to-right")[0] # Sort , From left to right , From top to bottom
digits = {
}
(10,)
d:\Miniconda3\envs\learnCV\lib\site-packages\ipykernel_launcher.py:1: VisibleDeprecationWarning: Creating an ndarray from ragged nested sequences (which is a list-or-tuple of lists-or-tuples-or ndarrays with different lengths or shapes) is deprecated. If you meant to do this, you must specify 'dtype=object' when creating the ndarray
"""Entry point for launching an IPython kernel.
# Traverse every contour
for (i, c) in enumerate(refCnts):
# Calculate the circumscribed rectangle and resize To the right size
(x, y, w, h) = cv2.boundingRect(c)
roi = ref[y:y + h, x:x + w]
roi = cv2.resize(roi, (57, 88))
# Each number corresponds to each template
digits[i] = roi
# Initialize convolution kernel
rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3))
sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
Card processing
# Read input image , Preprocessing
image = cv2.imread("./images/credit_card_01.png")
cv_show('image',image)
image = myutils.resize(image, width=300)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv_show1('gray',gray)


# Hat operation , Highlight brighter areas
tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, rectKernel)
cv_show1('tophat',tophat)
# Calculation x Directional image gradient
gradX = cv2.Sobel(tophat, ddepth=cv2.CV_32F, dx=1, dy=0, #ksize=-1 Equivalent to using 3*3 Of
ksize=-1)

gradX = np.absolute(gradX)
(minVal, maxVal) = (np.min(gradX), np.max(gradX))
gradX = (255 * ((gradX - minVal) / (maxVal - minVal)))
gradX = gradX.astype("uint8")
print (np.array(gradX).shape)
cv_show1('gradX',gradX)
(189, 300)

# By closing ( Inflate first , Corrode again ) Put the numbers together
gradX = cv2.morphologyEx(gradX, cv2.MORPH_CLOSE, rectKernel)
cv_show1('gradX',gradX)
[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-8AcGUyGC-1656380868739)(https://gitcode.net/weixin_41756645/csdnimage/-/raw/master/ocr_match_files/ocr_match_19_0.png)]
#THRESH_OTSU Will automatically find the right threshold , Suitable for bimodal , The threshold parameter needs to be set to 0
thresh = cv2.threshold(gradX, 0, 255,
cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
cv_show1('thresh',thresh)

# Another close operation
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, sqKernel) # Another close operation
cv_show1('thresh',thresh)

# Calculate the contour
thresh_, threshCnts, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = threshCnts
cur_img = image.copy()
cv2.drawContours(cur_img,cnts,-1,(0,0,255),3)
cv_show('img',cur_img)
locs = []

# Traverse the outline
for (i, c) in enumerate(cnts):
# Calculate rectangle
(x, y, w, h) = cv2.boundingRect(c)
ar = w / float(h)
# Choose the right area , According to the actual task , It's basically a set of four numbers
if ar > 2.5 and ar < 4.0:
if (w > 40 and w < 55) and (h > 10 and h < 20):
# The right ones stay
locs.append((x, y, w, h))
# Sort the matching contours from left to right
locs = sorted(locs, key=lambda x:x[0])
output = []
# Go through the numbers in each profile
for (i, (gX, gY, gW, gH)) in enumerate(locs):
# initialize the list of group digits
groupOutput = []
# Extract each group from the coordinates
group = gray[gY - 5:gY + gH + 5, gX - 5:gX + gW + 5]
cv_show1('group',group)
# Preprocessing
group = cv2.threshold(group, 0, 255,
cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
cv_show1('group',group)
# Calculate the outline of each group
group_,digitCnts,hierarchy = cv2.findContours(group.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
digitCnts = contours.sort_contours(digitCnts,
method="left-to-right")[0]
# Calculate each value in each group
for c in digitCnts:
# Find the outline of the current value ,resize To the right size
(x, y, w, h) = cv2.boundingRect(c)
roi = group[y:y + h, x:x + w]
roi = cv2.resize(roi, (57, 88))
cv_show1('roi',roi)
# Calculate the match score
scores = []
# Calculate each score in the template
for (digit, digitROI) in digits.items():
# Template matching
result = cv2.matchTemplate(roi, digitROI,
cv2.TM_CCOEFF)
(_, score, _, _) = cv2.minMaxLoc(result)
scores.append(score)
# Get the most appropriate number
groupOutput.append(str(np.argmax(scores)))
# Draw out
cv2.rectangle(image, (gX - 5, gY - 5),
(gX + gW + 5, gY + gH + 5), (0, 0, 255), 1)
cv2.putText(image, "".join(groupOutput), (gX, gY - 15),
cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2)
# Get the results
output.extend(groupOutput)
























# Print the results
print("Credit Card Type: {}".format(FIRST_NUMBER[output[0]]))
print("Credit Card #: {}".format("".join(output)))
cv_show("Image", image)
#cv2.waitKey(0)
Credit Card Type: Visa
Credit Card #: 4000123456789010

Reference resources
边栏推荐
- 643. Maximum average number of subarrays I
- Pat 1065 a+b and C (64bit) (20 points) (16 points)
- [getting started with Django] 13 page Association MySQL "multi" field table (check)
- How to view the state-owned enterprises have unloaded Microsoft office and switched to Kingsoft WPS?
- tensorflow2-savedmodel convert to pb(frozen_graph)
- 炎炎夏日,这份安全用气指南请街坊们收好!
- [14. Interval sum (discretization)]
- [dynamic programming] p1004 grid access (four-dimensional DP template question)
- Cannot link redis when redis is enabled
- One of the first steps to redis
猜你喜欢

What problems should be considered for outdoor LED display?
![[Verilog quick start of Niuke series] ~ multi function data processor, calculate the difference between two numbers, use generate... For statement to simplify the code, and use sub modules to realize](/img/30/aea4ae24f418eb971bca77a1d46bef.png)
[Verilog quick start of Niuke series] ~ multi function data processor, calculate the difference between two numbers, use generate... For statement to simplify the code, and use sub modules to realize

opencv学习笔记六--图像拼接

241. Design priorities for operational expressions

JVM performance tuning and practical basic theory part II

竣达技术丨室内空气环境监测终端 pm2.5、温湿度TVOC等多参数监测

Task.Run(), Task.Factory.StartNew() 和 New Task() 的行为不一致分析

JVM第二话 -- JVM内存模型以及垃圾回收

The State Administration of Chia Tai market supervision, the national development and Reform Commission and the China Securities Regulatory Commission jointly reminded and warned some iron ores

Cannot link redis when redis is enabled
随机推荐
Guess lantern riddles, not programmers still can't understand?
关于软件测试的一些思考
Details of appium key knowledge
JVM第二话 -- JVM内存模型以及垃圾回收
写在Doris毕业后的第一天
Solid smart contract development - easy to get started
Markdown编辑器使用基本语法
保证生产安全!广州要求危化品企业“不安全不生产、不变通”
Vnctf2022 open web gocalc0
深度分析数据在内存中的存储形式
Salesforce、约翰霍普金斯、哥大 | ProGen2: 探索蛋白语言模型的边界
Opencv mat class
Word2vec yyds dry goods inventory
JVM performance tuning and practical basic theory part II
241. Design priorities for operational expressions
Solid basic basic grammar and definition function
The markdown editor uses basic syntax
购物商城6.27待完成
Apk signature principle
Use the npoi package of net core 6 C to read excel Pictures in xlsx cells and stored to the specified server