-
OpenCV와 Tesseract OCR을 사용하여 카메라로부터 입력된 영상에서 숫자를 탐지하고 인식하는 Python 프로그램PYTHON(파이썬)/파이썬 활용 2024. 11. 14. 06:05728x90반응형import cv2import pytesseractimport logging
# Tesseract의 경로를 지정합니다. (윈도우에서 사용 시 필요)pytesseract.pytesseract.tesseract_cmd = r'e:\Tesseract\tesseract.exe'
# 로그 설정logging.basicConfig(filename='number_detection.log', level=logging.INFO, format='%(asctime)s - %(message)s')
# 카메라 초기화cap = cv2.VideoCapture(1)
last_recognized_text = ""
while True:# 카메라에서 프레임 읽기ret, frame = cap.read()if not ret:break
# 이미지를 그레이스케일로 변환하여 전처리gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)# 임계값을 이용한 이진화 처리_, thresh = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY_INV)# 컨투어 찾기 (윤곽선 검출)contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for contour in contours:# 컨투어의 경계 사각형을 계산합니다.x, y, w, h = cv2.boundingRect(contour)# 사각형 크기 제한 (너무 작은 노이즈 제거)if 350 > w > 200 and 100 > h > 50:# 숫자가 있는 영역에 대해 OCR 수행roi = gray[y:y + h, x:x + w]text = pytesseract.image_to_string(roi, config='--psm 8 digits').strip()
# 숫자 인식 결과를 로그로 남기기 및 출력if text and text != last_recognized_text:logging.info(f'Recognized number: {text}')print(f'Recognized number: {text}')last_recognized_text = text
# 숫자 인식 결과를 화면에 출력cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)cv2.putText(frame, text, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (36, 255, 12), 2)
# 결과 프레임 보여주기cv2.imshow('Number Detection', frame)
# 'q' 키를 누르면 종료if cv2.waitKey(1) & 0xFF == ord('q'):break
# 카메라 해제 및 창 닫기cap.release()cv2.destroyAllWindows()이 코드는 OpenCV와 Tesseract OCR을 사용하여 카메라로부터 입력된 영상에서 숫자를 탐지하고 인식하는 Python 프로그램입니다. 카메라로부터 프레임을 캡처하여 그레이스케일로 변환하고, 윤곽선(contour) 검출을 통해 특정 영역을 찾은 후, 그 영역에 대해 Tesseract를 사용해 숫자를 인식합니다. 아래는 코드의 주요 부분에 대한 분석입니다.
### 주요 기능 및 흐름
1. **Tesseract 설정**
```python
pytesseract.pytesseract.tesseract_cmd = r'e:\Tesseract\tesseract.exe'
```
- 이 줄은 Tesseract의 실행 파일 경로를 지정하는 부분으로, Tesseract의 설치 경로를 설정해야 합니다. 윈도우 시스템에서 필요합니다.
2. **로그 설정**
```python
logging.basicConfig(filename='number_detection.log', level=logging.INFO, format='%(asctime)s - %(message)s')
```
- 숫자 인식 결과를 기록하기 위해 로그 설정을 합니다. 로그 파일 이름은 `number_detection.log`이며, 각 인식된 숫자와 관련된 정보를 저장합니다.
3. **카메라 초기화**
```python
cap = cv2.VideoCapture(1)
```
- 카메라를 초기화합니다. `VideoCapture(1)`은 기본적으로 카메라 장치 ID가 `1`인 장치를 사용합니다. 대부분의 경우, 내장 카메라는 `0`으로 설정됩니다.
4. **프레임 처리 및 전처리**
```python
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
```
- 각 프레임을 그레이스케일로 변환하여 윤곽선을 검출하기 쉽게 만듭니다. 그레이스케일 변환은 이미지의 처리 속도를 빠르게 하고 불필요한 컬러 정보를 제거합니다.
```python
_, thresh = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY_INV)
```
- 임계값을 사용하여 이진화 처리를 합니다. `THRESH_BINARY_INV`를 사용하여 픽셀 값을 반전시킵니다(흰색 배경, 검은색 문자).
5. **윤곽선 검출**
```python
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
```
- `findContours`를 사용하여 이진화된 이미지에서 윤곽선을 검출합니다. 윤곽선은 이미지에서 밝기 차이가 나는 부분의 경계를 의미합니다.
6. **영역 필터링 및 OCR 수행**
```python
for contour in contours:
x, y, w, h = cv2.boundingRect(contour)
if 350 > w > 200 and 100 > h > 50:
roi = gray[y:y + h, x:x + w]
text = pytesseract.image_to_string(roi, config='--psm 8 digits').strip()
```
- 각 윤곽선에 대해 경계 사각형을 계산합니다. 사각형의 크기에 따라 유효한 영역(너무 작은 노이즈 제거)을 필터링합니다.
- ROI(Region of Interest)에서 텍스트를 추출하기 위해 `pytesseract`를 사용합니다. 여기서 `config='--psm 8 digits'`는 Tesseract가 숫자 인식만 하도록 설정합니다.
- `strip()`을 사용해 OCR 결과의 불필요한 공백을 제거합니다.
7. **중복 인식 방지 및 로그 기록**
```python
if text and text != last_recognized_text:
logging.info(f'Recognized number: {text}')
print(f'Recognized number: {text}')
last_recognized_text = text
```
- 인식된 텍스트가 이전에 인식된 텍스트와 다를 경우, 로그 파일에 기록하고 콘솔에 출력합니다. 이를 통해 중복된 인식 결과를 피합니다.
8. **결과 표시**
```python
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.putText(frame, text, (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (36, 255, 12), 2)
```
- 인식된 숫자 영역에 사각형을 그려 표시하고, 숫자 텍스트를 이미지에 출력합니다.
- `rectangle()`은 사각형을 그리고, `putText()`는 인식된 숫자를 이미지 상단에 표시하는 역할을 합니다.
9. **종료 조건**
```python
if cv2.waitKey(1) & 0xFF == ord('q'):
break
```
- 'q' 키를 누르면 루프가 종료되고 프로그램이 종료됩니다.
10. **리소스 해제**
```python
cap.release()
cv2.destroyAllWindows()
```
- 카메라 장치를 해제하고, 모든 창을 닫아 리소스를 해제합니다.
### 개선 및 주의점
1. **윤곽선 필터링 로직**:
- 현재 사각형 크기 제한 (`w`와 `h`)은 하드코딩되어 있습니다. 이 부분은 숫자의 크기와 카메라 설정에 따라 동적으로 조정될 필요가 있습니다.
- 다른 경우의 수에 대해서도 잘 동작하도록 동적인 크기 계산 또는 학습 기반 모델을 사용할 수 있습니다.
2. **OCR 설정 및 정확도**:
- OCR의 정확도를 높이기 위해 전처리 단계를 더 개선할 수 있습니다. 예를 들어, 노이즈를 제거하거나 대비를 높이는 필터링을 추가할 수 있습니다.
- 숫자 인식에 특화된 옵션이나 모델을 사용하면 더 좋은 결과를 얻을 수 있습니다.
3. **성능 최적화**:
- 실시간 인식을 위해 프레임 처리를 최적화해야 합니다. 여러 가지 전처리와 OCR 작업을 각 프레임에서 수행하므로, 성능 문제가 발생할 수 있습니다. GPU 가속을 활용하거나 Tesseract 대신 경량의 OCR 라이브러리를 사용하는 방법도 고려할 수 있습니다.
4. **안정성 및 사용자 경험**:
- 갑작스러운 종료를 방지하기 위해 예외 처리가 필요합니다. 카메라 장치가 올바르지 않을 때의 예외 처리 등 안정성 부분을 개선해야 합니다.
이와 같이, 이 코드는 기본적으로 카메라 영상에서 숫자를 검출하고 인식하는 기능을 수행하지만, 더 많은 전처리와 성능 개선이 필요할 수 있습니다. 추가적으로, 다양한 환경에서 정확도를 높이기 위해 다양한 조건을 고려해야 합니다.728x90'PYTHON(파이썬) > 파이썬 활용' 카테고리의 다른 글
특정 디렉터리에서 변경된 파일을 나스(NAS)에 FTP 프로토콜을 통해 복사(업로드)하는 프로그램 (1) 2024.11.15 특정 디렉터리 및 하위 디렉터리에서 파일을 탐색하며 조건에 따라 파일 정보를 출력 (0) 2024.11.14 첨부파일을 포함한 e-mail 보내기 (17) 2024.11.14 python으로 간단하게 e-mail 보내기 (2) 2024.11.13 네이버에서 PYTHON으로 삼성전자 주가 가져오기 (5) 2024.11.01