Após a última falha, aprendi a ser inteligente desta vez.
Não consigo fazer as coisas sozinho. Não é nada, sigo os outros, corro o código dos outros e aprendo com os outros.
Portanto, desta vez, uso python para reconhecimento de número de cartão do banco.
Não há muito a dizer, comece!
import cv2
import numpy as np
Definir função de desenho
def imshow (nome, img):
cv2.imshow (nome, img)
cv2.waitKey (0)
cv2.destroyAllWindows ()
1
2
3
4
5
6
7
8
cv2.imshow () Faça um desenho e um conjunto de punções combinados, Nós, jovens, não aguentamos depois de receber cabelo químico, vamos primeiro definir um pacote de funções.
Leia a imagem do modelo
0 significa que pode ser lida como uma imagem de canal único, ou seja, uma imagem em tons de cinza também pode ser usada
ref = cv2.cvtColor (img_num, cv2.COLOR_BGR2GRAY) convertido para tons de cinza
img_num = cv2.imread ('images / ocr_a_reference.png', 0)
imshow ('img_num', img_num)
1
2
3
4
5
Insira a descrição da imagem aqui
Converter para imagem binária
cv2.threshold (imagem de entrada, limite, atribuição, método) Aqui, o método é 0 para mais alto que o limite e 255 para mais baixo que o limite
cv2.threshold retorna dois valores O segundo valor é a imagem processada de que preciso
img_num_bin = cv2.threshold (img_num, 10,255, cv2.THRESH_BINARY_INV) [1]
imshow ('img_num_bin', img_num_bin)
1
2
3
4
Insira a descrição da imagem aqui
porque o próximo número do cartão do banco será branco, então será convertido para branco Fundo preto para facilitar a correspondência subsequente do modelo
Extração de contorno
Os parâmetros aceitos pela função cv2.findContours () é uma imagem binária, ou seja, preto e branco (não em tons de cinza), cv2.RETR_EXTERNAL detecta apenas o contorno externo, cv2.CHAIN_APPROX_SIMPLE apenas retém as coordenadas do ponto final
Cada elemento na lista retornada é um contorno na imagem
num_cnts lista, = cv2.findContours (img_num_bin.copy (), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours (img_num_bin, num_cnts_list, -1, (0,0,255), 3)
imshow_num ( 'img_num)
1
2
3
4
5 O contorno da
imagem inserida aqui
não é exibido, mas o contraste é mais estreito.É porque o contorno ficou preto automaticamente? Por enquanto, não se importe, então você tem que circular cada contorno e você saberá quando der uma olhada.
Classificação de contornos
num_rect_list = num_cnts_sort (num_cnts_list)
1
num_cnts_sort é minha função personalizada para classificar os contornos e retorná-los em uma determinada ordem
def num_cnts_sort (list, right = 1, up = 0):
up = 1 significa de cima para baixo, right = 1 significa da esquerda para a direita, -1 significa vice-versa
reverse = False
if up==-1 or right== -1:
reverse = True
if up == 0:
# 左右方向排序 权重选x
i = 0
if right == 0:
i = 1
# 找到的轮廓用外接矩形框起来 cv2.boundingRect(c)返回x,y,w,h
boundingBoxs = [cv2.boundingRect(c) for c in list] #生成器
# sorted(输入序列,排序规则,reverse=True 由小到大否则由大到小)
# lambda 匿名函数 输入序列的每个元素 输出b[i]
boxs = sorted(boundingBoxs,key= lambda b: b[i],reverse=reverse )
return boxs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Desenhe cada contorno circunscrevendo retângulo em ordem
para num_rect em num_rect_list:
(x, y, w, h) = num_rect
num_rect_img = cv2.rectangle (img_num_bin.copy (), (x, y), (x + w, y + h), (255,0,0 ), 2)
imshow ('num_rect_img', num_rect_img)
1
2
3
4
5
Não
há problema em inserir a descrição da imagem e classificar aqui e, em seguida, corte o modelo digital correspondente para corresponder ao número
Combine imagens com números
num_rect_dic = {}
para (i, num_rect) em enumerar (num_rect_list):
(x, y, w, h) = num_rect
num_rect_item = img_num_bin[y:y+h,x:x+w]
num_rect_item = num_resize(num_rect_item,h_size=88)
# 把数字和截下来的图像对应
num_rect_dic[i]=num_rect_item
imshow('num_rect_item', num_rect_item)
1
2
3
4
5
6
7
8
9
10
num_resize é uma função personalizada, insira a altura ou largura para calcular automaticamente o zoom
def num_resize (img, w_size = 0, h_size = 0):
(w, h) = img.shape # size 返回 总 元素 个数 和 matlab 不 一样
if w_size == 0:
r = h_size / float (h)
w_size = int (r h)
se h_size == 0:
r = w_size / float (w)
h_size = int (w h)
redimensionado = cv2.resize (img, (w_size, h_size))
retorno redimensionado
1
2
3
4
5
6
7
8
9
10
11
pares de pré-processamento de imagem de cartão bancário
Pré-processamento de imagem de cartão bancário
Leia a imagem
bank_img = cv2.imread ('images / credit_card_01.png')
bank_img_gray = cv2.cvtColor (bank_img, cv2.COLOR_BGR2GRAY)
imshow ('bank_img', bank_img)
imshow ('bank_img_gray', bank_img_gray)
Defina o kernel de convolução
rectKernel = cv2.getStructuringElement (cv2.MORPH_RECT, (9, 3)) # Kernel de convolução retangular
sqKernel = cv2.getStructuringElement (cv2.MORPH_RECT, (5,5))
A operação cartola destaca as partes brilhantes
bank_img_tophat = cv2.morphologyEx (bank_img_gray, cv2.MORPH_TOPHAT, rectKernel)
imshow ('bank_img_tophat', bank_img_tophat)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Insira
a linha horizontal do número de descrição da imagem aqui é muito escuro, eu acho Se estiver executando a binarização, escolha um parâmetro apropriado ou execute uma detecção de borda.
Detecção de borda
Processamento de detecção de borda na direção X
bank_img_grad = cv2.Sobel (bank_img_tophat, cv2.CV_32F, 1,0, ksize = -1)
imshow ('bank_img_tophat', bank_img_grad)
Normalizado
bank_img_grad_abs = np.absolute (bank_img_grad)
(max, min) = (np.max (bank_img_grad_abs), np.min (bank_img_grad_abs))
bank_img_grad_abs = (255 * (bank_img_grad_abs_abs-min) / (max-
mingradimg_gradimg_gradimg ) bank_gradimg_gradimg. astype ('uint8')
imshow ('s', bank_img_grad_abs)
A binarização cv2.THRESH_OTSU selecionará o limite apropriado para a binarização cv2.threshold retorna dois elementos e o segundo é a imagem processada
bank_img_bin = cv2.threshold (bank_img_grad_abs, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) [1]
imshow ('s', bank_img_bin)