当前位置:网站首页>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()
边栏推荐
猜你喜欢

User mode vs kernel mode, process vs thread

YOLO系列损失函数详解

DNA deoxyribonucleic acid modified platinum nanoparticles ptnps DNA | scientific research reagent

常用电子产品行业标准及认证

Digital management insight into retail and e-commerce operations -- Introduction to digital management

DNA modified rhodium RH nanoparticles rhnps DNA (DNA modified noble metal nanoparticles)

On deep paging

JUC atomic class: CAS, unsafe, CAS shortcomings, how to solve ABA problems in detail

Deeply analyze the implementation of singleton mode
![[Google] solve the problem that Google browser does not pop up the account and password save box and cannot save login information](/img/b3/2592e941f5d8f3505fb9763e8947a6.png)
[Google] solve the problem that Google browser does not pop up the account and password save box and cannot save login information
随机推荐
链表中倒数第k个节点——双指
再次出现用户净流失,大失颜面的中国移动推出超低价套餐争取用户
Matplotlib绘图笔记基础直线、折线、曲线
PCB design skills of EMC
调整数组顺序使奇数位于偶数前面——每日两题
合并两个排序的链表——每日两题
华为交换机拆解,学EMC基本操作
Near infrared two region agzs quantum dots wrapped deoxyribonucleic acid dna|dna agzsqds (Qiyue)
EMC中的基石-电磁兼容滤波知识大全!
On deep paging
铜铟硫CuInSe2量子点修饰DNA(脱氧核糖核酸)DNA-CuInSe2QDs(齐岳)
两个链表的第一个公共节点——每日两题
DNA modified noble metal nanoparticles | DNA modified copper nanoparticles cunps-dna | research points
Essential performance optimization topics in the interview~
The penultimate node in the linked list - Double finger
ESD静电不用怕,本文告诉你一些解决方法
Which of class A and class B is more stringent in EMC?
2022年湖南工学院ACM集训第五次周测AD题题解
@Documented 的作用
Tutorial (7.0) 06. Zero trust network access ztna * forticlient EMS * Fortinet network security expert NSE 5