Contents 호환성 문제의 정의와 증상 분류 즉시 조치 체크리스트(빠른 복구) 파일 형식별 특성과 선택 기준 버전 차이로 인한 기능 손실과 대체 전략 조직 환경 차이: 32/64비트, 추가기능, 보안 정책 CSV·텍스트 파일 호환성: 인코딩·구분 기호·서식 날짜·숫자 변형 방…
글 전체 보기- 공유 링크 만들기
- X
- 이메일
- 기타 앱
Contents 호환성 문제의 정의와 증상 분류 즉시 조치 체크리스트(빠른 복구) 파일 형식별 특성과 선택 기준 버전 차이로 인한 기능 손실과 대체 전략 조직 환경 차이: 32/64비트, 추가기능, 보안 정책 CSV·텍스트 파일 호환성: 인코딩·구분 기호·서식 날짜·숫자 변형 방…
글 전체 보기이 글의 목적은 한글 문서의 스캔부터 OCR까지 전 과정을 표준화하여 실무에서 재현 가능한 높은 인식률을 달성하도록 돕는 것이다.
일반 본문 텍스트는 300 DPI가 기준이며, 소제목·각주·7pt 이하 소형 글꼴이 많다면 400~600 DPI를 권장한다. 200 DPI는 데이터 입력용 초벌 인식에는 가능하나 교정 비용이 증가하므로 권장하지 않는다. 컬러 사진이 많은 보고서는 400 DPI 컬러 모드로 스캔 후 전처리에서 배경 억제를 수행하는 것이 안정적이다.
| DPI | 권장 용도 | 장점 | 주의사항 |
|---|---|---|---|
| 300 | 일반 본문 중심 문서 | 속도·용량 균형 | 7pt 이하 텍스트는 누락 가능 |
| 400 | 작은 글씨·각주 다수 | 획 단절 감소 | 용량 증가 |
| 600 | 법령 사본·팩스 품질 저하 원본 | 재인식·후처리 여유 | 저가 스캐너는 노이즈 증가 |
텍스트 중심 문서는 그레이스케일이 최적이다. 컬러는 배경 얼룩과 하이라이터 색이 임계값을 교란할 수 있다. 도표·컬러 구분이 중요한 문서는 컬러로 보존하되 전처리에서 채널 분리 후 전용 이진화를 적용한다.
단일 페이지는 TIFF(G4/팩스) 또는 무손실 PNG를 권장한다. 다중 페이지는 PDF 컨테이너로 저장하되 내부 이미지는 무손실 또는 저손실로 유지한다. JPEG 고압축은 문자 경계가 손상되어 에러율이 상승한다.
ADF 사용 시 이중 급지 검출을 활성화한다. 샤프닝은 과도하면 가장자리에 링잉이 생기므로 스캐너 내장 샤프닝은 Low로 설정한다. 자동 크롭·빈 페이지 제거는 OCR 전 레이아웃 판단을 방해할 수 있으므로 스캐너 단계에서는 끄고 전처리에서 일괄 적용한다.
# 1) 400DPI 가정, 스큐 보정+대비 확장+적응 이진화 magick input.tif -density 400 -units PixelsPerInch ^ -deskew 40%% -trim +repage ^ -colorspace Gray -contrast-stretch 0.5%% ^ -filter Gaussian -define convolve:scale='!' ^ -adaptive-sharpen 0x1 ^ -adaptive-threshold 15x15+10% ^ -type bilevel output_clean.tif
2) 그림자 제거용 배경 추정
magick input.tif -colorspace Gray ^
( +clone -blur 0x25 ) -compose Divide -composite ^
-contrast-stretch 0.5%% output_bgfix.tif
import cv2 import numpy as np
img = cv2.imread('input.png', cv2.IMREAD_GRAYSCALE)
스큐 추정(허프 변환 기반)
edges = cv2.Canny(img, 50, 150)
lines = cv2.HoughLines(edges, 1, np.pi/180, 200)
angles = []
if lines is not None:
for rho,theta in lines[:,0]:
angle = (theta - np.pi/2) * 180/np.pi
if -20 < angle < 20: angles.append(angle)
skew = np.median(angles) if angles else 0.0
회전 보정
(h, w) = img.shape[:2]
M = cv2.getRotationMatrix2D((w//2, h//2), skew, 1.0)
rot = cv2.warpAffine(img, M, (w, h), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE)
적응형 이진화 + 노이즈 제거
thr = cv2.adaptiveThreshold(rot, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY, 31, 10)
den = cv2.medianBlur(thr, 3)
cv2.imwrite('output_clean.png', den)
명조체 얇은 세리프가 끊어지는 경우 팽창 연산을 약하게 적용한다.
# 이진 이미지에서 미세 팽창 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2,1)) fix = cv2.morphologyEx(den, cv2.MORPH_DILATE, kernel, iterations=1) HSV 채널에서 색역 마스크로 하이라이터를 분리한 뒤 V 채널 기준으로 재이진화하면 텍스트 보존율이 높다.
# 컬러 문서에서 노란 하이라이터 제거 imgc = cv2.imread('input_color.png') hsv = cv2.cvtColor(imgc, cv2.COLOR_BGR2HSV) mask = cv2.inRange(hsv, (20, 50, 50), (40, 255, 255)) # yellow range nohl = cv2.inpaint(imgc, mask, 3, cv2.INPAINT_TELEA) gray = cv2.cvtColor(nohl, cv2.COLOR_BGR2GRAY) thr = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,31,8) # 일반 문서 tesseract output_clean.png out -l kor+eng --oem 1 --psm 6
단일 열, 일정 행간 보고서
tesseract output_clean.png out -l kor+eng --oem 1 --psm 4
양식(테이블) 라인은 별도 처리 후 인식
tesseract form_clean.png out -l kor --oem 1 --psm 6
--oem 1은 LSTM 기반 엔진을 사용하여 한글 결합 규칙 처리에 유리하다.--psm은 레이아웃 가정을 의미하며, 불일치 시 오인식이 급증한다. 표 영역은 라인 제거 후 6, 단일 열 문서는 4가 안정적이다.도메인 용어가 많은 경우 wordlist를 준비하면 교정 비용이 급감한다.
# custom words 예: '유해화학물질', '용출시험', '취급자' echo -e "유해화학물질\n용출시험\n취급자" > kor.user-words
Tesseract 호출 시
tesseract input.png out -l kor --user-words kor.user-words --oem 1 --psm 6
| 상황 | 문제 | 해결 |
|---|---|---|
| 명조체(얇은 세리프) | 획 단절·점 잡음 | 미세 팽창, 400~600 DPI, 저압축 |
| 고딕체 | 문자 붙음 | 약한 침식 연산, 대비 과도 상승 주의 |
| 세로쓰기 섞임 | 레이아웃 혼동 | 영역 분리 후 별도 인식, --psm 6 |
| 낡은 사본 | 배경 얼룩·번짐 | 배경 보정→적응 이진화→형태학적 개복원 |
격자선은 OCR에 방해가 되므로 라인 검출로 분리 저장한다. 텍스트 레이어만 인식하여 CSV로 내보내고, 원본 표 이미지는 PDF에 겹쳐 둔다.
# 수평·수직선 제거(개념) lines = detect_lines(rot) # 허프변환 기반 mask_text = remove(lines, rot) # 선 제거 마스크 ocr(mask_text) # 텍스트만 OCR 차트 영역은 OCR 대상에서 제외하고 캡션만 OCR한다. 차트 데이터는 별도 추출 도구를 사용한다.
수식은 일반 OCR 정확도가 낮다. 수식 영역을 인식 제외하거나 전용 엔진으로 분리 처리한다. 보고서에서는 수식을 이미지로 보존하고 LaTeX 원문을 주석으로 관리한다.
# CLAHE 예시 clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8)) enh = clahe.apply(rot) 텍스트 행을 추적하여 곡률 모델로 펴주는 디와프 알고리즘을 적용한다. 불가피하면 페이지를 분책하여 평면화 스캔한다.
OCR 결과에 사용자 사전과 전문용어 리스트를 적용하여 치환·태깅한다. 단위(㎖, ㎍, ppm 등)는 정규식으로 보정한다.
# 간단한 단위 정규화 예시 import re text = open('out.txt', 'r', encoding='utf-8').read() text = re.sub(r'\b(mm|㎜)\b', 'mm', text) text = re.sub(r'\b(㎖|ml)\b', 'mL', text) open('out_norm.txt', 'w', encoding='utf-8').write(text) # CER 계산 예시 import editdistance gt = open('gt.txt', 'r', encoding='utf-8').read() pred = open('out_norm.txt', 'r', encoding='utf-8').read() cer = editdistance.eval(list(gt), list(pred)) / max(1, len(gt)) print(f'CER: {cer:.3%}') project/ 00_raw_scan/ # 원본 스캔 01_preproc/ # 전처리 결과 02_ocr/ # OCR 텍스트 03_review/ # 교정본 99_logs/ # 처리 로그·성능지표 YYYYMMDD_부서_문서명_p###.tif 형식을 사용하면 정렬·추적이 쉽다. 페이지 번호는 3자리 고정한다.
| 증상 | 가능 원인 | 조치 |
|---|---|---|
| 받침 오인식 | DPI 낮음, 이진화 과도 | 400 DPI 재스캔, 적응 임계값 재설정 |
| 띄어쓰기 붕괴 | 스큐·왜곡 | 디와프·스큐 보정 후 재인식 |
| 표 인식 누락 | 격자 영향 | 선 제거 후 텍스트만 인식 |
| 영문 약어 깨짐 | 언어 설정 단일 | kor+eng 병행, 사용자 단어 입력 |
| 파일 용량 과대 | 고DPI 컬러 | 그레이스케일 전환, 무손실 압축 재저장 |
| 항목 | 체크 방법 | 빈도 |
|---|---|---|
| DPI·색상 모드 | 샘플 1장 메타 확인 | 매 배치 |
| 스큐 보정 | 문단 경사 각도 < 0.5° | 매 배치 |
| 노이즈 레벨 | 빈 여백에 점 잡음 0~1개/㎠ | 매 배치 |
| OCR 옵션 | --oem, --psm 로그 저장 | 매 배치 |
| CER 샘플 | 표본 1페이지 측정 ≤ 1.0% | 주간 |
| 개인정보 마스킹 | 정규식 검출 누락 0건 | 매 배치 |
magick input.jpg -auto-level -contrast-stretch 1%% -colorspace Gray ^ -blur 0x1 -adaptive-threshold 17x17+8% out.png magick input.tif -colorspace Gray ( +clone -blur 0x35 ) -compose Divide -composite ^ -contrast-stretch 0.5%% -adaptive-threshold 15x15+10% out.tif # 선 검출 후 텍스트만 OCR, 표는 좌표로 CSV화(개념 스니펫) grid, textmask = detect_grid_and_text(img) ocr_text = ocr(textmask) cells = extract_cells(grid) export_csv(cells, ocr_text) 일반 문서는 300 DPI가 기준이다. 작은 글씨·각주가 많거나 품질이 낮은 원본은 400~600 DPI가 유리하다. 200 DPI는 교정 비용이 급증하므로 권장하지 않는다.
텍스트 중심이면 그레이스케일이 유리하다. 컬러 마커가 많다면 컬러로 보존 후 채널 분리·하이라이터 제거 전처리를 수행한다.
가능하나 배치 자동화가 어렵다. 평면화·그림자 제거·적응 이진화로 상당 부분 개선되나 대량 처리 프로젝트는 스캐너 기반 표준화를 권장한다.
엔진 언어를 한국어+영어로 병행하고 도메인 용어를 사용자 단어로 등록한다. 영문 약어가 많은 경우 --psm 6으로 단락 가정을 단순화한다.
표는 라인 제거 후 텍스트만 인식하고 셀 좌표를 CSV로 저장한다. 수식은 일반 OCR에서 오류가 많으므로 영역 제외 또는 전용 엔진으로 분리한다.
CER·WER를 사용한다. 표본 페이지를 선정해 기준문자와의 편집거리로 계산하고 주간 리포트에 추세를 기록한다.