[OpenCV] 컴퓨터비전의 시작

메르센고수·2023년 12월 24일
0

OpenCV

목록 보기
1/9

들어가기 앞서..

오랜만에 Posting이다 학기 생활하느라 바빠서 글을 못썼는데 벌써 크리스마스 이브가 되었다니 시간이 참 빠르다... 지금껏 백준에 대한 글만 올렸었는데, 이제부터는 내가 관심있는 분야에 대한 글을 써보고자 한다.
글을 쓰기 전 이번 2학기 근황을 간단히 말해보면, 기계학습이론과 인공지능, 시스템프로그래밍, 컴파일러설계, 알고리즘 5전공을 들었는데 무지하게 힘들었다... 5전공은 다음생에서는 하지 말아야겠다고 다시 한번 느끼게 해준 3개월이였다.

사실 2학기를 들어가면서 인공지능 관련 Lab실에서 학부연구생을 해보면서 경험을 쌓고 싶다는 생각은 있었는데, 막연히 인공지능에 대해 연구하고 싶다는 생각만 있었을 뿐, 자연어처리, 컴퓨터비전과 같은 세부적인 분야에 대해서는 정하지 못하여서 지원을 하지 않았었다. 그러다가 컴퓨터비전에 대한 유튜브 동영상을 보게 되었는데 너무 인상적이여서 이 분야에 대해 배우고 싶다는 생각이 들었다. 이것저것 알아보다 보니 지금껏 자주 써왔던 문서 스캔 프로그램이 컴퓨터비전 기술로 만들어진 어플리케이션이라는 것을 알게 되었고 나 역시 컴퓨터비전을 연구해서 실생활에 사용될 수 있는 어플을 개발하고 싶다는 생각이 들어서 무작정 컴퓨터비전에 대한 인터넷강의를 끊어서 보기 시작했다.

앞으로 Posting할 OpenCV 관련 글들은 인터넷 강의를 수강하고 내용에 대한 정리글과 배운 내용을 바탕으로 방학 기간에 혼자서 간단한 프로젝트를 진행한 과정에 대한 글이 될 것이다.
프로젝트를 어떤 것을 할지는 아직 정하지 못하였지만, 이제 막 배우는 입장이기 때문에 간단한 프로젝트가 될 것 같다.

참고로 지금부터 올리는 OpenCV 관련 글은 배우는 입장으로 배운 내용에 대해 정리하는 글들이고, 출처는 패스트캠퍼스에서 황선규 박사님의 온라인 강의
'OpenCV를 활용한 컴퓨터비전과 딥러닝'이다.


OpenCV의 시작

OpenCV란?

: Open Source Computer Vision의 약자로 영상 처리에 사용할 수 있는 Python 오픈 소스 라이브러리 이다.

OpenCV
https://github.com/opencv

한가지 예시 코드를 보면, 아래의 코드에서는 cv2 (OpenCV)의 version과 cat.bmp 사진 파일을 불러와서 새 창에 고양이 사진을 띄우는 간단한 코드이다.

import sys
import cv2

print('Hello OpenCV',cv2.__version__)

img=cv2.imread('cat.bmp') # cat.bmp를 불러와 img 변수에 저장

if img is None: # 영상 불러오기가 실패하면 에러 메시지를 출력하고 종료
    print('Image load failed!')
    sys.exit()
    
cv2.namedWindow('image') # 'image'라는 이름의 새창을 만듦
cv2.imshow('image',img) # 이 창에 img 출력
cv2.waitKey() # 키보드 입력이 있을 때까지 wait 

cv2.destroyAllWindows() # 생성된 모든 창을 닫음

>>> Hello OpenCV 4.8.1


이렇게 영상을 불러와서 라이브러리에 있는 다양한 기능들로 이미지를 처리하는 것이 OpenCV를 배우는 목적이라고 생각한다.
흔히 볼 수 있는 크로마키 합성, 사후 보정 등이 예시에 해당한다.

함수 예시

이번엔 위의 예시 코드에서 쓰인 함수에 대해 설명하고자 한다.

영상 파일 불러오기

cv2.imread(filename, flags=None) -> retval
  • filename : 불러올 파일명
  • flags : 영상 파일 불러오기 옵션 플래그
cv2.IMREAD_COLORcv2.IMREAD_GRAYSCALEcv2.IMREAD_UNCHANGED
BGR 컬러 영상으로 읽기 (기본값)그레이 스케일 영상으로 읽기영상 파일 속성 그대로 읽기
shape=(rows, cols, 3)shape=(rows, cols)shape=(rows, cols, 4)
  • retval : 불러온 영상 데이터 (numpy.ndarray)

영상 파일 저장하기

cv2.imwrite(filename, img, params=None) -> retval

1) filename : 저장할 영상 파일 이름 (문자열)
2) img : 저장할 영상 데이터 (numpy.ndarray)
3) params : 파일 저장 옵션 지정 (속성 & 값의 정수 쌍)
→ [cv2.IMWRITE_JPEG_QUALITY,90] : JPG 파일 압축률을 90%로 지정
4) retval : 정상적으로 저장하면 True, 실패하면 False

새 창 띄우기

cv2.namedWindow(winname, flags=None) -> None

1) winname : 창 고유 이름 (문자열)
2) flags : 창 속성 지정 플래그

cv2.WINDOW_NORMALcv2.WIDOW_AUTOSIZE
영상 크기를 창 크기에 맞게 지정창 크기를 영상 크기에 맞게 변경 (기본값)

창 닫기

cv2.destroyWindow(winname) -> None
cv2.destroyAllWindows() -> None

1) winname : 닫고자 하는 창 이름
2) 참고사항
- cv2.destroyWindow() 함수는 지정한 창 하나만 닫는다.
- cv2.destroyAllWindows()는 열려있는 모든 창을 닫는다.
- 일반적인 경우 프로그램 종료시 OS에 의해 열려 있는 모든 창이 자동으로 닫힌다.

창 위치 이동

cv2.moveWindow(winname, x, y) -> None

1) winname : 창 이름
2) x, y : 이동할 위치 좌표

창 크기 변경

cv2.resizeWindow(winname, width, height) -> None

1) winname : 창 이름
2) width : 변경할 창의 가로 크기
3) height : 변경할 창의 세로 크기
4) 참고 사항
- 창 생성시 cv2.WINDOW_NORMAL 속성으로 생성되어야 동작
- 영상 출력 부분의 크기 만을 고려함 (제목 표시줄, 창 경계는 고려 X)

영상 출력하기

cv2.imshow(winname, mat) -> None

1) winname : 영상을 출력할 대상 창 이름
2) mat : 출력할 영상 데이터 (numpy.ndarray)
3) 참고 사항

  • uint16, int32 자료형 행렬의 경우, 행렬 원소값을 255로 나눠서 출력
  • float32, float64 자료형 행렬의 경우, 행렬 원소 값에 255를 곱해서 출력
    ⇒ 가급적 uint8 type를 지정해주는게 좋음
  • 만약 winname에 해당하는 창이 없으면 창을 새로 만들어서 영상을 출력함
  • Windows OS에서는 Ctrl+C, Ctrl+S 지원
  • 실제로는 cv2.waitKey() 함수를 호출해야 화면에 영상이 나타남

키보드 입력 대기

cv2.waitKey(delay=None) -> retval

1) delay : 밀리초 단위 대기 시간. delay≤0 이면 무한히 기다림. 기본값은 0
2) retval : 눌린 키 값 (ASCII code). 키가 눌리지 않으면 -1
3) 참고 사항

  • cv2.waitKey() 함수는 OpenCV 창이 하나라도 있을 때 동작함
  • 특정 키 입력을 확인하려면 ord() 함수를 이용
    while True:
    	if cv2.waitKey()==ord('q'): # q를 누르면 종료
        	break
     while True:
    	if cv2.waitKey()==27: # esc를 누르면 창이 닫힘
        	break
  • 주요 특수키 코드 : 27(ESC), 13(ENTER), 9(TAB)

import sys
import cv2

print('Hello OpenCV',cv2.__version__)

img=cv2.imread('cat.bmp',cv2.IMREAD_GRAYSCALE) # cat.bmp를 불러와 img 변수에 저장

if img is None: # 영상 불러오기가 실패하면 에러 메시지를 출력하고 종료
    print('Image load failed!')
    sys.exit()
    
cv2.imwrite('cat_gray.png',img,params=None)
    
cv2.namedWindow('image') # 'image'라는 이름의 새창을 만듦
cv2.imshow('image',img) # 이 창에 img 출력
cv2.waitKey() # 키보드 입력이 있을 때까지 wait => imshow랑 set라고 봐도 무방

cv2.destroyAllWindows() # 생성된 모든 창을 닫음

이번엔 한가지 달라진 부분이 있다. 두 번째 줄을 보면, image를 불러오는데 flag가 cv2.IMREAD_GRAYSCALE인 것을 확인할 수 있다. 이 의미는 cat.bmp 파일을 흑백영상으로 가져온다는 의미이다.
출력 영상을 확인해보면 다음과 같다.

이 두 image를 OpenCV가 아닌 matplotlib으로도 출력할 수 있다.

import matplotlib.pyplot as plt
import cv2


# 컬러 영상 출력
imgBGR = cv2.imread('cat.bmp')
imgRGB = cv2.cvtColor(imgBGR, cv2.COLOR_BGR2RGB) # BGR을 RGB 순서로 변경

plt.axis('off')
plt.imshow(imgRGB)
plt.show()

# 그레이스케일 영상 출력
imgGray = cv2.imread('cat.bmp', cv2.IMREAD_GRAYSCALE)

plt.axis('off') # off를 안하면 영상 가로 세로에 축이 생김
plt.imshow(imgGray, cmap='gray')
plt.show()

# 두 개의 영상을 함께 출력
plt.subplot(121), plt.axis('off'), plt.imshow(imgRGB) # 1행 2열 1번째
plt.subplot(122), plt.axis('off'), plt.imshow(imgGray, cmap='gray') # 1행 2열 2번째
plt.show()

실습

휴대폰을 보면 슬라이드쇼 기능이 있다. 여러장의 사진을 일정한 주기에 맞춰서 자동으로 보여주는 기능인데, OpenCV로 간단하게 구현을 해보았다.

import os
import sys
import glob
import cv2


# 이미지 파일을 모두 img_files 리스트에 추가

# os.listdir() 사용 방법
#file_list=os.listdir('.\\images')
#img_files=[os.path.join('.\\images',file)for file in file_list if file.endswith('.jpg')]

# glob.glob() 사용 방법
img_files = glob.glob('.\\images\\*.jpg')

if not img_files:
    print("There are no jpg files in 'images' folder")
    sys.exit()

# 전체 화면으로 'image' 창 생성
cv2.namedWindow('image', cv2.WINDOW_NORMAL)
cv2.setWindowProperty('image', cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)

# 무한 루프
cnt = len(img_files)
idx = 0

while True:
    img = cv2.imread(img_files[idx])

    if img is None:
        print('Image load failed!')
        break

    cv2.imshow('image', img)
    if cv2.waitKey(1000) >= 0: # 아무 키나 누르면 종료됨
        break

    idx += 1
    if idx >= cnt:
        idx = 0

cv2.destroyAllWindows()

images 폴더에 있는 .jpg 파일들을 fullscreen으로 슬라이드쇼

오늘은 여기까지 이고 OpenCV Series는 앞으로 계속될 예정입니다ㅎㅎ

profile
블로그 이전했습니다 (https://phj6724.tistory.com/)

0개의 댓글

관련 채용 정보