openCv page Dewarp 분석 -1

개요

이번에는 openCV를 이용해서 북스캔을 구현하는 오픈소스를 분석해 보겠습니다. 해당 프로젝트의 기능은 기존에 구부려져 있는 책의 이미지를 피는 북스캔을 목적으로 하고 있습니다.

해당 정보는 아래를 참고 부탁드립니다.

이미지 파일 로딩

이 프로젝트는 page_dewarp.py 파일 하나로 이루어져 있습니다.
이 프로젝트를 구동하기 위해서는 아래와 같은 커맨드를 입력합니다.

python page_dewarp.py IMAGE1 [IMAGE2 ...]

기본적으로 python과 openCV 모듈이 PC에 탑재되어야 합니다. IMAGE1 IMAGE2는 파일 이름입니다. 여러개의 파일을 한꺼번에 처리할 수 있습니다.

프로젝트의 시작은 main()에서 시작합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def main():

# ① 파라미터 값은 이미지 파일 하나 이상이 들어와야 함
if len(sys.argv) < 2:
print 'usage:', sys.argv[0], 'IMAGE1 [IMAGE2 ...]'
sys.exit(0)

# ② 결과를 파일이 아닌 스크린으로 보여줄때 윈도우 창 이름 설정
if DEBUG_LEVEL > 0 and DEBUG_OUTPUT != 'file':
cv2.namedWindow(WINDOW_NAME)

outfiles = [] # 아웃풋 파일을 List로 설정
# ③ input 파일 개수만큼 for문을 돌림 (한개일땐 한번만...)
for imgfile in sys.argv[1:]:
# ④ 파일 이름으로 openCV에서 파일을 읽음
img = cv2.imread(imgfile)
...
  • ①은 파라미터의 길이로 이미지 파일 이름이 설정되어 있지 않으면 안내 문구를 돌려줍니다.
  • ② 는프로젝트에는 DEBUG_LEVEL이 있어 설정에 따라 중간 결과물들을 볼 수 있습니다. 중간 결과물을 file이 아닌 screen으로 보고 싶으면 openCV에서 생성할 window 창의 이름을 설정해 줍니다.
  • ③은 이미지 파일이 여러개가 로드되었을때 for문을 통해 모듈을 반복해서 돌립니다. 이미지가 하나라면 한번만 실행됩니다.
  • ④는 cv.imread()를 통해서 입력된 이미지 파일을 openCV에서 처리할 numpy배열(img)로 변환합니다.

이미지 resize

1
small = resize_to_screen(img)

resize_to_screen() 함수를 통해서 이미지 resize를 실행합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def resize_to_screen(src, maxw=1280, maxh=700, copy=False):

height, width = src.shape[:2]

scl_x = float(width)/maxw
scl_y = float(height)/maxh

scl = int(np.ceil(max(scl_x, scl_y)))

if scl > 1.0:
inv_scl = 1.0/scl
img = cv2.resize(src, (0, 0), None, inv_scl, inv_scl, cv2.INTER_AREA)
elif copy:
img = src.copy()
else:
img = src

return img

해당 함수의 기능은 입력 받은 이미지의 높이와 폭을 원본 비율을 유지시키는 선에서 기준크기1280x700과 비교해서 더 작게 resize하는 것입니다.

기본적으로 함수를 사용할 때 파라미터로 src만 입력했기 때문에 maxw=1280, maxh=700, copy=False값은 유지됩니다.

처음으로 scl_x = float(width)/maxw, scl_y = float(height)/maxh 을 통해서 폭과 높이에 대해서 기준 크기와의 차이를 비교합니다.

scl = int(np.ceil(max(scl_x, scl_y))) 에서는 비교된 스케일 중 큰 값을 기준으로 올림 처리를 해서 최종 스케일을 취득합니다.

if scl > 1.0: 만약 스케일이 기준크기보다 크다면 resize를 통해 원본 이미지를 줄여줍니다.

기준크기 이하로 만들기 위한 스케일 비율을 구하기 위해 inv_scl = 1.0/scl을 실행합니다.

img = cv2.resize(src, (0, 0), None, inv_scl, inv_scl, cv2.INTER_AREA)를 통해서 이미지 resize를 실행합니다.

cv2.resize의 기본형은 resize(src, dsize, dst=None, fx=None, fy=None, interpolation=None)입니다.

  • src : input 이미지 입니다.
  • dsize : resize를 위한 절대 크기가 입력됩니다. 여기서는 절대가 아닌 상대 크기로 변환하기 때문에 (0,0)을 입력하였습니다.
  • dst : 리턴으로 img를 받기때문에 dst값을 따로 입력하지 않습니다.
  • fx, fy : 폭과 높이를 resize 하기 위한 상대 비율을 입력합니다.
  • interpolation : 이미지 크기를 조절할때 사용할 보간법을 지정합니다.
    • cv2.INTER_NEAREST : 이웃 보간법
    • cv2.INTER_LINEAR : 쌍 선형 보간법
    • cv2.INTER_LINEAR_EXACT : 비트 쌍 선형 보간법
    • cv2.INTER_CUBIC : 바이큐빅 보간법
    • cv2.INTER_AREA : 영역 보간법
    • cv2.INTER_LANCZOS4 : Lanczos 보간법

여기서는 cv2.INTER_AREA를 사용해 영역 보간법을 사용하습니다.

기본적으로 쌍 선형 보간법이 가장 많이 사용됩니다.

이미지를 확대하는 경우, 바이큐빅 보간법이나 쌍 선형 보간법을 가장 많이 사용합니다.

이미지를 축소하는 경우, 영역 보간법을 가장 많이 사용합니다.

영역 보간법에서 이미지를 확대하는 경우, 이웃 보간법과 비슷한 결과를 반환합니다.

resize된 이미지

공유하기