当前位置:网站首页>Opencv's practical learning of credit card recognition (4)
Opencv's practical learning of credit card recognition (4)
2022-07-28 07:52:00 【MioeC】
List of articles
Effect display


Process introduction
- First process the picture , Extract the digital part
- Divide the four numbers , And match the template
- Deal with numbers and areas , Marked on the original drawing
step
Do image processing
- The picture is too big , Need to zoom , When marking later, you need to zoom back .
- Perform a capping operation , Expansion characteristics
- use sobel Edge detection , It's used here x Direction detection , Then normalize , Control the value to 255 Inside
sobelX = cv.Sobel(top_hat, cv.CV_32F, 1, 0)
- cv_32F The goal is 32 Bit signed floating point number , because sobel The operator is to subtract the left from the right , It could be a negative number , So keep positive and negative numbers , Then perform the absolute value operation
sobelX = np.absolute(sobelX)
(min, max) = (np.min(top_hat), np.max(top_hat))
sobelX = (255 * ((sobelX - min)/ (max - min)))
sobelX = sobelX.astype('uint8')
- Carry out one-step closing operation , Remove noise
- Binary operation
- Do the closing operation , Connect into blocks
- Edge detection
- Filter selection area
- Carry out digital region segmentation and extraction
- Digital content recognition
def find_num(ori_path):
card_path = ori_path
card_img = cv.imread(card_path)
card_img = cv.resize(card_img, None, fx=0.7, fy=0.7)
# Graying
card_gray = cv.cvtColor(card_img, cv.COLOR_BGR2GRAY)
kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5))
rectKernel = cv.getStructuringElement(cv.MORPH_RECT, (13, 3))
top_hat = cv.morphologyEx(card_gray, cv.MORPH_TOPHAT, kernel)
# operator sobel
sobelX = cv.Sobel(top_hat, cv.CV_32F, 1, 0)
sobelX = np.absolute(sobelX)
(min, max) = (np.min(top_hat), np.max(top_hat))
sobelX = (255 * ((sobelX - min)/ (max - min)))
sobelX = sobelX.astype('uint8')
# Two valued
card_close = cv.morphologyEx(sobelX, cv.MORPH_CLOSE, rectKernel)
ret, threshold = cv.threshold(card_close, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
card_gray = cv.morphologyEx(threshold, cv.MORPH_CLOSE, kernel, iterations=1)
contours, hierachy = cv.findContours(card_gray, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
# cv.drawContours(card_img, contours, -1, (0, 255, 0), 4)
list = []
for cont in contours:
# Draw a rectangular
x, y, w, h = cv.boundingRect(cont)
rate = w/h
if 2.7 < rate < 3.5:
if (50 < w < 95) and (10 < h < 40):
# rect = cv.rectangle(card_img, (x, y), (x+w, y+h), (0, 255, 0), 1)
# cv.imshow('card1', card_img[y: y + h, x: x + w])
list.append(([x, y, w, h], card_img[y: y + h, x: x + w]))
# Sort from left to right
list = sorted(list, key= lambda a: a[0][0])
num_list = []
for cont, img in list:
four_list = ""
img1 = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
ret, img1 = cv.threshold(img1, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
contours1, hierachy = cv.findContours(img1, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
# cv.drawContours(img, contours1, -1, (0, 255, 0), 1)
temp_list = []
for cont1 in contours1:
# Draw a rectangle
x, y, w, h = cv.boundingRect(cont1)
rect = cv.rectangle(img1, (x, y), (x+w, y+h), (0, 255, 0), 1)
rect1 = img1[y: y + h , x : x + w ]
temp_list.append(([x, y, w, h], rect1))
temp_list = sorted(temp_list, key= lambda a: a[0][0])
for i, img2 in temp_list:
four_list += (match_img(img2))
num_list.append(four_list)
print(num_list)
return list, num_list
Template processing
- Divide directly with normal operation
- Write local data
def split_template():
reference_path = './data/reference.png'
img_base = cv.imread(reference_path)
img_gray = cv.cvtColor(img_base, cv.COLOR_BGR2GRAY)
ret, threshold = cv.threshold(img_gray, 0, 255, cv.THRESH_BINARY_INV)
contours, hierachy = cv.findContours(threshold, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
for i, cont in enumerate(contours):
x, y, w, h = cv.boundingRect(cont)
cv.imwrite('template/%s.png'%i, threshold[y- 5: y + h + 5, x - 5: x + w + 5])
Match template
- Because the image exported above is named

- So the number should be 9- Subscript , You should pay attention to .
import os
def match_img(img):
max = 0
max_index = 0
for i,name in enumerate(os.listdir("./template")):
img_bg = cv.imread('./template/%s'%name, 0)
img = cv.resize(img, (img_bg.shape[1], img_bg.shape[0]))
result = cv.matchTemplate(img_bg, img, cv.TM_CCOEFF_NORMED)
if result > max:
max = result
max_index = 9 - i
return str(max_index)
Show the matching effect
- Here you need to pass in the original image , Picture list , A list of numbers
- Traverse the annotation
def draw_card(img, list, num_list):
# Input coordinates list, Numbers list (list, numList)
for i, cont in enumerate(list):
x, y, w, h = cont[0]
x = int(x/0.7); y = int(y/0.7); w = int(w/0.7); h = int(h/0.7)
print(x, y, w, h)
cv.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
num_str = num_list[i]
cv.putText(img, num_str, (x, y - 10), cv.FONT_HERSHEY_COMPLEX, 1, (0, 255, 0), 2, cv.LINE_AA)
cv.imshow('card', img)
cv.waitKey(0)
cv.destroyAllWindows()
Call the main function
def main():
ori_path = './data/card3.png'
split_template()
list, num_list = find_num(ori_path)
draw_card(cv.imread(ori_path), list, num_list)
main()
effect

defects

- Here is a silver one with reflective effect , It's not handled very well , And the following English is also very similar to the ratio of numbers .
- There are students who have found a solution , Leave a comment
The resource acquisition
Complete code
import numpy as np
import cv2 as cv
from PIL import Image
import os
def match_img(img):
max = 0
max_index = 0
for i,name in enumerate(os.listdir("./template")):
img_bg = cv.imread('./template/%s'%name, 0)
img = cv.resize(img, (img_bg.shape[1], img_bg.shape[0]))
result = cv.matchTemplate(img_bg, img, cv.TM_CCOEFF_NORMED)
if result > max:
max = result
max_index = 9 - i
return str(max_index)
def draw_card(img, list, num_list):
# Input coordinates list, Numbers list (list, numList)
for i, cont in enumerate(list):
x, y, w, h = cont[0]
x = int(x/0.7); y = int(y/0.7); w = int(w/0.7); h = int(h/0.7)
print(x, y, w, h)
cv.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
num_str = num_list[i]
cv.putText(img, num_str, (x, y - 10), cv.FONT_HERSHEY_COMPLEX, 1, (0, 255, 0), 2, cv.LINE_AA)
cv.imshow('card', img)
cv.waitKey(0)
cv.destroyAllWindows()
def find_num(ori_path):
card_path = ori_path
card_img = cv.imread(card_path)
card_img = cv.resize(card_img, None, fx=0.7, fy=0.7)
# Graying
card_gray = cv.cvtColor(card_img, cv.COLOR_BGR2GRAY)
kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5))
rectKernel = cv.getStructuringElement(cv.MORPH_RECT, (13, 3))
top_hat = cv.morphologyEx(card_gray, cv.MORPH_TOPHAT, kernel)
# operator sobel
sobelX = cv.Sobel(top_hat, cv.CV_32F, 1, 0)
sobelX = np.absolute(sobelX)
(min, max) = (np.min(top_hat), np.max(top_hat))
sobelX = (255 * ((sobelX - min)/ (max - min)))
sobelX = sobelX.astype('uint8')
# Two valued
card_close = cv.morphologyEx(sobelX, cv.MORPH_CLOSE, rectKernel)
ret, threshold = cv.threshold(card_close, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
card_gray = cv.morphologyEx(threshold, cv.MORPH_CLOSE, kernel, iterations=1)
contours, hierachy = cv.findContours(card_gray, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
# cv.drawContours(card_img, contours, -1, (0, 255, 0), 4)
list = []
for cont in contours:
# Draw a rectangular
x, y, w, h = cv.boundingRect(cont)
rate = w/h
if 2.7 < rate < 3.5:
if (50 < w < 95) and (10 < h < 40):
# rect = cv.rectangle(card_img, (x, y), (x+w, y+h), (0, 255, 0), 1)
# cv.imshow('card1', card_img[y: y + h, x: x + w])
list.append(([x, y, w, h], card_img[y: y + h, x: x + w]))
# Sort from left to right
list = sorted(list, key= lambda a: a[0][0])
num_list = []
for cont, img in list:
four_list = ""
img1 = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
ret, img1 = cv.threshold(img1, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
contours1, hierachy = cv.findContours(img1, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
# cv.drawContours(img, contours1, -1, (0, 255, 0), 1)
temp_list = []
for cont1 in contours1:
# Draw a rectangle
x, y, w, h = cv.boundingRect(cont1)
rect = cv.rectangle(img1, (x, y), (x+w, y+h), (0, 255, 0), 1)
rect1 = img1[y: y + h , x : x + w ]
temp_list.append(([x, y, w, h], rect1))
temp_list = sorted(temp_list, key= lambda a: a[0][0])
for i, img2 in temp_list:
four_list += (match_img(img2))
num_list.append(four_list)
print(num_list)
return list, num_list
def split_template():
reference_path = './data/reference.png'
img_base = cv.imread(reference_path)
img_gray = cv.cvtColor(img_base, cv.COLOR_BGR2GRAY)
ret, threshold = cv.threshold(img_gray, 0, 255, cv.THRESH_BINARY_INV)
contours, hierachy = cv.findContours(threshold, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
for i, cont in enumerate(contours):
x, y, w, h = cv.boundingRect(cont)
cv.imwrite('template/%s.png'%i, threshold[y- 5: y + h + 5, x - 5: x + w + 5])
def main():
ori_path = './data/card4.png'
split_template()
list, num_list = find_num(ori_path)
draw_card(cv.imread(ori_path), list, num_list)
main()
边栏推荐
猜你喜欢

华为交换机拆解,学EMC基本操作

DNA modified osmium OS nanoparticles osnps DNA modified iridium nanoparticles irnps DNA

非关系型数据库之Redis【redis集群详细搭建】

Soft exam certificate can be used like this! Get a certificate = get a professional title?
C language explanation series - array explanation, one-dimensional array, two-dimensional array

ASP.NET Core 技术内幕与项目实战读后感

【13】加法器:如何像搭乐高一样搭电路(上)?

DNA deoxyribonucleic acid modified platinum nanoparticles ptnps DNA | scientific research reagent
![[JVM optimization] online JVM tuning practice](/img/e3/5fa128805af0ca03f0b6715b78d398.jpg)
[JVM optimization] online JVM tuning practice

DNA modified rhodium RH nanoparticles rhnps DNA (DNA modified noble metal nanoparticles)
随机推荐
[shaders realize negative anti color effect _shader effect Chapter 11]
And is two numbers of S - two questions per day
The cornerstone of EMC - complete knowledge of electromagnetic compatibility filtering!
非关系型数据库之Redis【redis集群详细搭建】
Isolation level RR, gap lock, unreal reading
DNA修饰贵金属纳米颗粒|DNA脱氧核糖核酸修饰金属钯Pd纳米颗粒PdNPS-DNA
node(一)
数据化管理洞悉零售及电子商务运营——数据化管理介绍
How to understand CMS collector to reduce GC pause time
Why is ESD protection so important for integrated circuits? How to protect?
How to analyze the taxi business problem of didi SQL interview question
ESD防护为何对集成电路如此重要?又该如何防护?
Mysql中有哪些不同的表格?
华为交换机拆解,学EMC基本操作
常用电子产品行业标准及认证
Niuke MySQL - SQL must know and know
Guava cache of guava
干货|分享一个EMC实际案例及整改过程
DNA cuinseqds near infrared CuInSe quantum dots wrapped deoxyribonucleic acid DNA
Industry standards and certification of common electronic products