스택큐힙리스트

OpenCV-Python으로 간단한 숫자 인식 OCR 본문

카테고리 없음

OpenCV-Python으로 간단한 숫자 인식 OCR

스택큐힙리스트 2023. 4. 2. 00:07
반응형

저는 OpenCV-Python(cv2)에서 숫자 인식 OCR을 구현하려고 노력하고 있습니다. 이것은 학습 목적으로만 해당합니다. OpenCV에서 KNearest와 SVM 기능을 모두 배우고 싶습니다.

나는 각 숫자의 샘플 (즉, 이미지) 100 개를 가지고 있습니다. 그들과 함께 훈련하고 싶습니다.

OpenCV 샘플에는 샘플 letter_recog.py가 있습니다. 하지만 그것을 사용하는 방법을 아직 이해하지 못했습니다. 샘플, 응답 등이 무엇인지 이해하지 못합니다. 또한, 처음에 txt 파일을 로드합니다. 이것이 무엇인지 처음에 이해하지 못했습니다.

조금 찾아보니 cpp 샘플에서 letter_recognition.data를 찾을 수 있었습니다. 이것을 사용하여 letter_recog.py 모델에서 cv2.KNearest를 위한 코드를 작성하여 테스트했습니다.

import numpy as np

import cv2

fn = 'letter-recognition.data'

a = np.loadtxt(fn, np.float32, delimiter=',', converters={ 0 : lambda ch : ord(ch)-ord('A') })

samples, responses = a[:,1:], a[:,0]

model = cv2.KNearest()

retval = model.train(samples,responses)

retval, results, neigh_resp, dists = model.find_nearest(samples, k = 10)

print results.ravel()

20000 크기의 배열이 제공되었지만, 무엇인지 이해하지 못합니다.

질문:

1) letter_recognition.data 파일이 무엇인가요? 내 자신의 데이터 세트에서 그 파일을 어떻게 구축하는가요?

2) results.reval()은 무엇을 나타내나요?

3) letter_recognition.data 파일을 사용하여 간단한 숫자 인식 도구를 작성하는 방법은 무엇인가요 (KNearest 또는 SVM 중)?

답변 1

위의 문제를 해결하기 위해 스스로 운동을 하기로 결정했습니다. 원하는 것은 OpenCV의 KNearest 또는 SVM 기능을 사용하여 간단한 OCR을 구현하는 것입니다. 아래는 내가 한 것과 그 방법입니다. (간단한 OCR 용도로 KNearest를 사용하는 방법을 배우기 위한 것입니다).

1) 제 첫 질문은 OpenCV 샘플과 함께 제공되는 letter_recognition.data 파일에 대한 것이었습니다. 그 파일 안에 무엇이 있는지 알고 싶었습니다.

그것은 그 글자와 함께 그 글자의 16 개의 특징을 포함하고 있습니다.

그리고 this SOF 님이 제게 그것을 찾는 데 도움을 주셨습니다. 이 16가지 특징들은 Letter Recognition Using Holland-Style Adaptive Classifiers 논문에서 설명되어 있습니다. (마지막에 일부 특징을 이해하지 못했지만)

1) 그 기능들을 모두 이해하지 않고는, 그 방법을 수행하기가 어려웠습니다. 몇 가지 다른 논문들을 시도해봤지만, 모두 초보자에게는 조금 어려웠습니다.

그래서 나는 단순히 모든 픽셀 값들을 특징(feature)으로 채택하기로 결정했다. (정확도나 성능에 대해 걱정하지 않았고, 최소한의 정확도를 가지고 작동하길 원했을 뿐이다.)

제가 교육용 데이터로 아래 이미지를 사용했습니다:

(훈련 데이터 양이 적지만 모든 글자가 동일한 글꼴과 크기이므로, 제가 이것을 시도하기로 결정했습니다.)

학습을 위해 데이터를 준비하기 위해, 저는 OpenCV에서 작은 코드를 만들었습니다. 이 코드는 다음과 같은 작업을 수행합니다:

그것은 이미지를 로드합니다.

숫자를 선택합니다 (역시 윤곽선을 찾고 글자의 면적과 높이에 대한 제약 조건을 적용하여 거짓 감지를 피합니다).

하나의 문자 주위에 경계 사각형을 그리고 key press manually을 기다립니다. 이번에는 상자에 있는 문자에 해당하는 숫자 키를 우리가 직접 누릅니다.

해당 숫자 키를 누르면, 이 박스는 10x10 크기로 조정되며 100개의 픽셀 값이 배열(samples)에 저장되고 해당하는 수동 입력 숫자가 다른 배열(responses)에 저장됩니다.

그런 다음 두 배열을 별도의 .txt 파일에 저장하세요.

숫자의 수동 분류가 끝난 후, 학습 데이터의 모든 숫자 ( train.png )가 우리 자신에 의해 수동으로 라벨링되며, 이미지는 아래와 같이 보일 것입니다:

위는 위의 목적을 위해 내가 사용한 코드입니다 (물론, 너무 깨끗하지 않습니다):

import sys

import numpy as np

import cv2

im = cv2.imread('pitrain.png')

im3 = im.copy()

gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)

blur = cv2.GaussianBlur(gray,(5,5),0)

thresh = cv2.adaptiveThreshold(blur,255,1,1,11,2)

################# Now finding Contours ###################

contours,hierarchy = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)

samples = np.empty((0,100))

responses = []

keys = [i for i in range(48,58)]

for cnt in contours:

if cv2.contourArea(cnt)>50:

[x,y,w,h] = cv2.boundingRect(cnt)

if h>28:

cv2.rectangle(im,(x,y),(x+w,y+h),(0,0,255),2)

roi = thresh[y:y+h,x:x+w]

roismall = cv2.resize(roi,(10,10))

cv2.imshow('norm',im)

key = cv2.waitKey(0)

if key == 27: # (escape to quit)

sys.exit()

elif key in keys:

responses.append(int(chr(key)))

sample = roismall.reshape((1,100))

samples = np.append(samples,sample,0)

responses = np.array(responses,np.float32)

responses = responses.reshape((responses.size,1))

print training complete

np.savetxt('generalsamples.data',samples)

np.savetxt('generalresponses.data',responses)

이제 우리는 훈련과 테스트 부분에 들어가게 됩니다.

테스트 부분에서는 훈련 단계에서 사용한 동일한 유형의 글자를 사용한 아래 이미지를 사용했습니다.

트레이닝을 하기 위해 우리는 다음과 같이합니다 :

우리가 이전에 이미 저장한 .txt 파일들을 불러오세요.

우리가 사용하는 분류기(KNearest)의 인스턴스를 생성하십시오.

그런 다음 KNearest.train 함수를 사용하여 데이터를 학습합니다.

테스트 목적으로, 우리는 다음과 같이합니다.

테스트에 사용된 이미지를 로드합니다.

이미지를 이전과 같이 처리하고 윤곽선 방법을 사용하여 각 숫자를 추출합니다.

그에 대한 경계 상자를 그리고 크기를 10x10으로 조정한 다음, 이전과 같이 배열에 픽셀 값을 저장합니다.

그런 다음 KNearest.find_nearest() 함수를 사용하여 우리가 제공한 항목에 가장 가까운 항목을 찾습니다. (운이 좋다면 올바른 숫자를 인식합니다.)

저는 마지막 두 단계 (훈련 및 테스트)를 아래의 단일 코드에 포함시켰습니다.

import cv2

import numpy as np

####### training part ###############

samples = np.loadtxt('generalsamples.data',np.float32)

responses = np.loadtxt('generalresponses.data',np.float32)

responses = responses.reshape((responses.size,1))

model = cv2.KNearest()

model.train(samples,responses)

############################# testing part #########################

im = cv2.imread('pi.png')

out = np.zeros(im.shape,np.uint8)

gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)

thresh = cv2.adaptiveThreshold(gray,255,1,1,11,2)

contours,hierarchy = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)

for cnt in contours:

if cv2.contourArea(cnt)>50:

[x,y,w,h] = cv2.boundingRect(cnt)

if h>28:

cv2.rectangle(im,(x,y),(x+w,y+h),(0,255,0),2)

roi = thresh[y:y+h,x:x+w]

roismall = cv2.resize(roi,(10,10))

roismall = roismall.reshape((1,100))

roismall = np.float32(roismall)

retval, results, neigh_resp, dists = model.find_nearest(roismall, k = 1)

string = str(int((results[0][0])))

cv2.putText(out,string,(x,y+h),0,1,(0,255,0))

cv2.imshow('im',im)

cv2.imshow('out',out)

cv2.waitKey(0)

그리고 그것은 작동했습니다. 아래는 내가 얻은 결과입니다.

여기에서는 100%의 정확도로 작동했습니다. 모든 숫자가 같은 종류이고 크기가 같기 때문이라고 가정합니다.

어쨌든, 이것은 초보자들에게 좋은 시작이 되겠죠 (희망합니다).

답변 2

이 글에서는 OpenCV-Python을 사용하여 간단한 디지털 인식 OCR에 대해 다룹니다. OCR (Optical Character Recognition)은 이미지에서 문자를 인식하고 텍스트로 변환하는 기술입니다. 이 기술은 인간이 작성한 문서를 디지털화하거나, 기계 판독을 통해 이메일, 서적 등에서 문서를 추출하는 데 사용됩니다.

우리는 OpenCV-Python을 사용하여 간단한 숫자 인식 OCR을 구현할 것입니다. 이를 위해서는 먼저 OpenCV-Python을 설치해야 합니다. 그런 다음, 이미지에서 숫자를 인식하고 추출하는 데 필요한 몇 가지 기술을 사용해야 합니다.

첫 번째로, 이미지에서 숫자를 추출하기 위해 이미지를 전처리해야 합니다. 일반적인 전처리 단계는 이미지의 밝기를 조정하거나, 노이즈를 제거하거나, 이미지의 이진화를 수행하는 것입니다.

다음으로, 추출된 이미지에서 숫자를 인식합니다. OpenCV-Python에서 사용되는 일반적인 방법은 Contour Detection입니다. 이는 이미지에서 윤곽을 계산하고 숫자 영역을 추출하는 알고리즘입니다. 이후에는 추출된 이미지에서 각 숫자를 분리하고, 각 숫자가 어떤 것인지 인식하여 최종 결과를 도출합니다.

이와 같은 방법을 사용하여 OpenCV-Python에서 간단한 숫자 인식 OCR을 구현할 수 있습니다. 이를 통해 더 복잡한 문서 인식을 수행할 수 있으며, 이는 급속도로 확장되는 디지털 문서화 시장에서 매우 중요한 역할을 합니다.

따라서 OpenCV-Python을 사용한 디지털 인식 OCR은 현재 매우 중요한 기술이며, 이를 활용하는 기업들은 빠르게 성장하고 있습니다. 이제 여러분도 OpenCV-Python을 사용하여 우수한 디지털 인식 OCR을 만들 수 있습니다.

반응형
Comments