 # OpenCV 를 활용한 명함인식 기능 구현 강좌

(19개의 수강평)

456명의 수강생
29,700원
지식공유자 · 마이캠퍼스
19회 수업 · 총 2시간 21분 수업
평생 무제한 시청
수료증 발급 강의
수강 난이도 '중급'
마이캠퍼스의 다른 강의
연관 로드맵
아직 다른 강의가 없어요 ㅠㅠ
연관 로드맵이 없어요 ㅠㅠ

강의 마지막 예제에서 다음과 같은 에러가 발생합니다. 24일 전

```images/scannedImage.png only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices코드는 아래와 같습니다.# (참고) OpenCV - 이미지에서 텍스트 영역만 찾아내기

# 출처: http://www.danvk.org/2015/01/07/finding-blocks-of-text-in-an-image-using-python-opencv-and-numpy.html

import glob
import os
import random
import sys
import random
import math
import json
from collections import defaultdict

import cv2
from PIL import Image, ImageDraw
import numpy as np
from scipy.ndimage.filters import rank_filter

def dilate(ary, N, iterations):
"""Dilate using an NxN '+' sign shape. ary is np.uint8."""
kernel = np.zeros((N,N), dtype=np.uint8)
kernel[(N-1)/2,:] = 1
dilated_image = cv2.dilate(ary / 255, kernel, iterations=iterations)

kernel = np.zeros((N,N), dtype=np.uint8)
kernel[:,(N-1)/2] = 1
dilated_image = cv2.dilate(dilated_image, kernel, iterations=iterations)
dilated_image = cv2.convertScaleAbs(dilated_image)
return dilated_image

def props_for_contours(contours, ary):
"""Calculate bounding box & the number of set pixels for each contour."""
c_info = []
for c in contours:
x,y,w,h = cv2.boundingRect(c)
c_im = np.zeros(ary.shape)
cv2.drawContours(c_im, [c], 0, 255, -1)
c_info.append({
'x1': x,
'y1': y,
'x2': x + w - 1,
'y2': y + h - 1,
'sum': np.sum(ary * (c_im > 0))/255
})
return c_info

def union_crops(crop1, crop2):
"""Union two (x1, y1, x2, y2) rects."""
x11, y11, x21, y21 = crop1
x12, y12, x22, y22 = crop2
return min(x11, x12), min(y11, y12), max(x21, x22), max(y21, y22)

def intersect_crops(crop1, crop2):
x11, y11, x21, y21 = crop1
x12, y12, x22, y22 = crop2
return max(x11, x12), max(y11, y12), min(x21, x22), min(y21, y22)

def crop_area(crop):
x1, y1, x2, y2 = crop
return max(0, x2 - x1) * max(0, y2 - y1)

def find_border_components(contours, ary):
borders = []
area = ary.shape * ary.shape
for i, c in enumerate(contours):
x,y,w,h = cv2.boundingRect(c)
if w * h > 0.5 * area:
borders.append((i, x, y, x + w - 1, y + h - 1))
return borders

def angle_from_right(deg):
return min(deg % 90, 90 - (deg % 90))

def remove_border(contour, ary):
"""Remove everything outside a border contour."""
# Use a rotated rectangle (should be a good approximation of a border).
# If it's far from a right angle, it's probably two sides of a border and
# we should use the bounding box instead.
c_im = np.zeros(ary.shape)
r = cv2.minAreaRect(contour)
degs = r
if angle_from_right(degs) <= 10:
box = cv2.boxPoints(r)
box = np.int0(box)
cv2.drawContours(c_im, [box], 0, 255, -1)
cv2.drawContours(c_im, [box], 0, 0, 4)
else:
x1, y1, x2, y2 = cv2.boundingRect(contour)
cv2.rectangle(c_im, (x1, y1), (x2, y2), 255, -1)
cv2.rectangle(c_im, (x1, y1), (x2, y2), 0, 4)

return np.minimum(c_im, ary)

def find_components(edges, max_components=16):
"""Dilate the image until there are just a few connected components.
Returns contours for these components."""
# Perform increasingly aggressive dilation until there are just a few
# connected components.
count = 21
dilation = 5
n = 1
while count > 16:
n += 1
dilated_image = dilate(edges, N=3, iterations=n)
#_, contours, hierarchy = cv2.findContours(dilated_image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours, hierarchy = cv2.findContours(dilated_image, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
count = len(contours)
#print dilation
#Image.fromarray(edges).show()
#Image.fromarray(255 * dilated_image).show()
return contours

def find_optimal_components_subset(contours, edges):
"""Find a crop which strikes a good balance of coverage/compactness.
Returns an (x1, y1, x2, y2) tuple.
"""
c_info = props_for_contours(contours, edges)
c_info.sort(key=lambda x: -x['sum'])
total = np.sum(edges) / 255
area = edges.shape * edges.shape

c = c_info
del c_info
this_crop = c['x1'], c['y1'], c['x2'], c['y2']
crop = this_crop
covered_sum = c['sum']

while covered_sum < total:
changed = False
recall = 1 * covered_sum / total
prec = 1 - 1 * crop_area(crop) / area
f1 = 2 * (prec * recall / (prec + recall))
#print '----'
for i, c in enumerate(c_info):
this_crop = c['x1'], c['y1'], c['x2'], c['y2']
new_crop = union_crops(crop, this_crop)
new_sum = covered_sum + c['sum']
new_recall = 1 * new_sum / total
new_prec = 1 - 1 * crop_area(new_crop) / area
new_f1 = 2 * new_prec * new_recall / (new_prec + new_recall)

# Add this crop if it improves f1 score,
# _or_ it adds 25% of the remaining pixels for <15% crop expansion.
# ^^^ very ad-hoc! make this smoother
remaining_frac = c['sum'] / (total - covered_sum)
new_area_frac = 1 * crop_area(new_crop) / crop_area(crop) - 1
if new_f1 > f1 or (
remaining_frac > 0.25 and new_area_frac < 0.15):
print('%d %s -> %s / %s (%s), %s -> %s / %s (%s), %s -> %s' % (
i, covered_sum, new_sum, total, remaining_frac,
crop_area(crop), crop_area(new_crop), area, new_area_frac,
f1, new_f1))
crop = new_crop
covered_sum = new_sum
del c_info[i]
changed = True
break

if not changed:
break

return crop

"""Slightly expand the crop to get full contours.
This will expand to include any contours it currently intersects, but will
not expand past a border.
"""
bx1, by1, bx2, by2 = 0, 0, edges.shape, edges.shape
if border_contour is not None and len(border_contour) > 0:
c = props_for_contours([border_contour], edges)
bx1, by1, bx2, by2 = c['x1'] + 5, c['y1'] + 5, c['x2'] - 5, c['y2'] - 5

def crop_in_border(crop):
x1, y1, x2, y2 = crop
x1 = max(x1 - pad_px, bx1)
y1 = max(y1 - pad_px, by1)
x2 = min(x2 + pad_px, bx2)
y2 = min(y2 + pad_px, by2)
return crop

crop = crop_in_border(crop)

c_info = props_for_contours(contours, edges)
changed = False
for c in c_info:
this_crop = c['x1'], c['y1'], c['x2'], c['y2']
this_area = crop_area(this_crop)
int_area = crop_area(intersect_crops(crop, this_crop))
new_crop = crop_in_border(union_crops(crop, this_crop))
if 0 < int_area < this_area and crop != new_crop:
print('%s -> %s' % (str(crop), str(new_crop)))
changed = True
crop = new_crop

if changed:
else:
return crop

def downscale_image(im, max_dim=2048):
"""Shrink im until its longest dimension is <= max_dim.
Returns new_image, scale (where scale <= 1).
"""
a = im.shape
b = im.shape
if max(a, b) <= max_dim:
return 1, im

scale = 1 * max_dim / max(a, b)
dim = (int(a * scale), int(b * scale))
new_im = cv2.resize(im, dim, interpolation = cv2.INTER_AREA)

return scale, new_im

def process_image(path, out_path):
orig_im = Image.open(path)
scale, im = downscale_image(im)

edges = cv2.Canny(im, 100, 200)

# TODO: dilate image _before_ finding a border. This is crazy sensitive!
#_, contours, hierarchy = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
contours, hierarchy = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
borders = find_border_components(contours, edges)
borders.sort(key=lambda i_x1_y1_x2_y2: (i_x1_y1_x2_y2 - i_x1_y1_x2_y2) * (i_x1_y1_x2_y2 - i_x1_y1_x2_y2))

border_contour = None
if len(borders):
border_contour = contours[borders]
edges = remove_border(border_contour, edges)

edges = 255 * (edges > 0).astype(np.uint8)

# Remove ~1px borders using a rank filter.
maxed_rows = rank_filter(edges, -5, size=(1, 20))
maxed_cols = rank_filter(edges, -5, size=(20, 1))
debordered = np.minimum(np.minimum(edges, maxed_rows), maxed_cols)
edges = debordered

contours = find_components(edges)
if len(contours) == 0:
print('%s -> (no text!)' % path)
return

crop = find_optimal_components_subset(contours, edges)
crop = pad_crop(crop, contours, edges, border_contour)

crop = [int(x / scale) for x in crop]  # upscale to the original image size.

# draw and show cropped rectangle area in the original image
rgb_im = orig_im.convert('RGB')
draw = ImageDraw.Draw(rgb_im)
draw.rectangle(crop, outline='red')
rgb_im.show()

text_im = orig_im.crop(crop)
text_im.show()
text_im.save(out_path)
print('%s -> %s' % (path, out_path))

if __name__ == '__main__':
# path = 'images/text.jpg'
path = 'images/scannedImage.png'
out_path = 'croppedImage.png'
try:
process_image(path, out_path)
except Exception as e:
print('%s %s' % (path, e))```

0

Anaconda prompt에서 opencv설치 시 오류가 뜹니다. 8달 전

ERROR conda.core.link:_execute(507): An error occurred while uninstalling package 'defaults::conda-4.5.12-py27_0'.

WindowsError(5, '')

Attempting to roll back.

현재 파이썬이 3.6.8버전도 함께 깔려 있어서 이런 오류가 뜨는 것 같은데 어떻게 해결해야 할까요..?

1

박스 클릭하고 Ctrl + return 버튼 클릭 시 메시지 2018.11.21

박스 클릭하고 Ctrl + return 버튼 클릭 위와 같은 결과가 나오는 것을 확인을 실행했을 때 아래와 같이 실습준비설명서와 다른 메시지가 나옵니다.

File "", line 12

print "python:", sys.version

^

SyntaxError: Missing parentheses in call to 'print'. Did you mean print("python:", sys.version)?

0

라즈베리파이(라즈비안) Python2.7 OpenCV-3.4.3 환경에서 예제프로그램 사용. 2018.11.08

이미지 읽고 쓰기 (1)의 문장을 제목과 같은 환경에서 사용을 시도하였습니다. 임시로 파일의 이름은 readimage1.py로 바꾼 상태로 터미널에서 사용하였습니다.

``````   File "readimage1.py", lin 14
if__name__=='__main__':
^
SyntaxError: invalid syntax</p>``````

라는 에러가 나와 (:)를 지우면

``````   File "readimage1.py", lin 14
handle_image()
^
SyntaxError: invalid syntax</p>``````

라는 에러가 나옵니다. 또 아예 가려버리면 창이 뜨지를 않으니 굉장히 곤란한 상황입니다.

비록 강의에서 알려주신 환경은 윈도우였지만 라즈베리파이를 써야하는 상황이라 꼭 알려주시면 감사하겠습니다.

0

TesseractNotFoundError 라고 뜹니다. 2018.09.06

TesseractNotFoundError: tesseract is not installed or it's not in your path

이미지로부터 텍스트 추출인데 이렇게 뜨네요 저번에는 잘 됐는데 안됩니다 ㅜ

0

링크에러 2018.07.17

실습준비 설명서 16페이지 tesseract 링크 에러납니다.

마이크로 소프트 oxford 링크 에러납니다.

0

OCR – Tesseract 2018.07.11

안녕하세요. 지금 강의를 듣고 있는데 윗부분들은 다 잘 됐는데 tesseract가 안먹어요ㅠㅠ

TesseractNotFoundErrorTraceback (most recent call last)

in ()
13
14 if name == 'main':
---> 15 ocr_tesseract()

in ocr_tesseract()
7 image_file = 'images/scannedImage.png'
8 im = Image.open(image_file)
----> 9 text = pytesseract.image_to_string(im) #이미지로부터 텍스트를 추출해 낼 수 있다.
10 im.show()
11

C:UsersLGAnaconda2libsite-packagespytesseractpytesseract.pyc in image_to_string(image, lang, config, nice, boxes, output_type)
284 return run_and_get_output(image, 'txt', lang, config, nice, True)
285
--> 286 return run_and_get_output(image, 'txt', lang, config, nice)
287
288

C:UsersLGAnaconda2libsite-packagespytesseractpytesseract.pyc in run_and_get_output(image, extension, lang, config, nice, return_bytes)
200 except OSError:
--> 201 raise TesseractNotFoundError()
202 finally:
203 cleanup(temp_name)

TesseractNotFoundError: tesseract is not installed or it's not in your path

이렇게 뜨는데 무슨 문제가 있는 걸까요?

테스트코드에서도 경로 맞아서 테스트도 완료했는데 뭐가 문제인지 모르겠습니다ㅠㅠ
tesseract가 안돼서 project oxford로 하려고 했고 키값도 받았는데도 그것도 안먹고요...
인강에서 말씀하신 것 처럼 키값만 넣어주면 되는거 아닌가용? 도와주세여ㅠㅠㅠㅠ

1

소스코드 다운로드하여 압축해제하면 내용이 아무것도 없어요. 2018.05.16

안녕하세요.

소스코드를 다운받아서 압축해제하니 아무 것도 없네요.

빵집을 사용하는데, 압축해제하려고 더블클릭하면 폴더명이 모두 글자가 깨진채로 구성되어 있긴 합니다.

0

궁금합니다. 2017.10.02
무엇인지요? 설명에서는 없는데 if __name__ == '__main__': handel_image()

0
지식공유자 되기
많은 사람들에게 배움의 기회를 주고,
경제적 보상을 받아보세요.
기업 교육을 위한 인프런
“인프런 비즈니스” 를 통해 모든 팀원이 인프런의 강의들을
자유롭게 학습하는 환경을 제공하세요.