컴퓨터 영상 처리/OpenCV

OpenCV 기초

Zoo_10th 2024. 3. 19.

1. OpenCV 개요

1-1. 소개

영상처리와 컴퓨터 비전의 차이

1) 영상처리(Image Processing) 

이미지를 개선하거나 특정 정보를 추출하는 데 중점을 둔다. 이는 이미지의 노이즈 제거, 명암 대비 개선, 필터링, 이미지 변환 등을 포함할 수 있다. 영상처리의 주된 목적은 이미지 자체의 품질을 향상시키거나, 이미지로부터 유용한 정보를 추출하는 것이다.

2) 컴퓨터 비전(Computer Vision)

이미지나 비디오로부터 의미 있는 정보를 추출하고, 이를 해석하여 특정 작업을 수행하거나 결정을 내리는 과정이다. 컴퓨터 비전의 목표는 컴퓨터가 인간의 시각처럼 주변 환경을 이해하고 인식할 수 있게 하는 것이다. 이는 객체 인식, 얼굴 인식, 동작 추적, 3D 재구성 등 복잡한 작업을 포함할 수 있다.

영상처리는 컴퓨터 비전에서 중요한 초석 역할을 하며, 두 분야는 종종 함께 사용되어 보다 복잡한 문제를 해결한다.

1-2. OpenCV

1-2-1. OpenCV (Open Source Computer Vision Library)

컴퓨터 비전 및 기계 학습 소프트웨어 라이브러리다. 오픈 소스이며, C++, Python, Java 등 다양한 프로그래밍 언어로 작성된 애플리케이션을 지원한다. OpenCV는 실시간으로 동작하는 영상 처리와 컴퓨터 비전을 가능하게 하는 효율적이고 고성능의 라이브러리로 널리 인식되고 있다.

1999년에 인텔에 의해 처음 개발되었으며, 현재는 다양한 기업과 개인이 기여하는 대규모 커뮤니티 프로젝트로 성장했다. OpenCV는 2500개 이상의 최적화된 알고리즘을 포함하고 있어, 이미지 및 비디오 분석, 얼굴 인식, 객체 탐지, 특징점 추출 및 매칭, 스테레오 비전(3D 이미지 생성), 모션 추적 등 다양한 컴퓨터 비전 및 영상 처리 작업을 수행할 수 있다.

1-2-2. OpenCV의 주요 특징

1) 다양한 영상 처리 및 컴퓨터 비전 기술 지원: OpenCV는 기본적인 이미지 처리 기능(색상 변환, 필터링, 모폴로지 변환 등)부터 고급 컴퓨터 비전 기술(객체 탐지, 분류, 얼굴 인식 등)까지 광범위한 기능을 제공한다.

2) 다양한 언어 및 플랫폼 지원: OpenCV는 C++, Python, Java와 같은 여러 프로그래밍 언어를 지원하며, Windows, Linux, MacOS, Android, iOS 등 다양한 운영 체제에서 사용할 수 있다.

3) 실시간 처리 가능: OpenCV는 최적화된 알고리즘과 효율적인 내부 구조 덕분에 실시간 이미지 처리와 컴퓨터 비전 어플리케이션 개발에 적합하다.

4) 머신 러닝 및 딥러닝 모듈: OpenCV는 머신 러닝 알고리즘을 위한 인터페이스를 제공하며, 딥러닝 모델을 사용하여 이미지 분류, 객체 탐지 등의 작업을 수행할 수 있는 기능을 포함하고 있다.

5) 강력한 커뮤니티와 광범위한 문서: 전 세계적으로 활발한 커뮤니티를 보유하고 있으며, 다양한 튜토리얼, 문서, 온라인 리소스를 통해 학습과 문제 해결을 지원한다.

1-2-3. OpenCV 설치

pip install opencv-python

2. 영상처리

2-1. OpenCV로 이미지 읽기, 쓰기, 그리고 나타내기

1) 이미지 읽기: cv2.imread() 함수를 사용하여 이미지 파일을 읽어올 수 있다. 이 함수는 이미지 파일의 경로를 인자로 받아, 이미지를 numpy 배열의 형태로 로드한다.

import cv2
img = cv2.imread('image.jpg')

2) 이미지 보여주기: cv2.imshow() 함수를 사용하여 이미지를 화면에 표시한다. 첫 번째 인자는 윈도우 이름이며, 두 번째 인자는 표시할 이미지이다.

cv2.imshow('Image', img)
cv2.waitKey(0)  # 사용자가 키를 누를 때까지 대기
cv2.destroyAllWindows()

3) 이미지 쓰기: cv2.imwrite() 함수를 사용하여 이미지를 파일로 저장할 수 있다. 첫 번째 인자는 저장할 파일의 이름이며, 두 번째 인자는 저장할 이미지이다.

cv2.imwrite('output.jpg', img)

2-1-1. 이미지의 기본 속성

1) 픽셀: 이미지는 픽셀의 집합으로 구성된다. 각 픽셀은 이미지의 가장 작은 단위이며, 색상 정보를 담고 있다.

2) 이미지 사이즈: 이미지의 크기는 픽셀 단위로 측정되며, 가로와 세로의 픽셀 수로 표현된다.

3) 채널: 색상 이미지의 경우, 일반적으로 RGB (빨강, 초록, 파랑)의 3채널로 구성된다.. 흑백 이미지의 경우 1채널만을 가진다.

2-2. 동영상 파일 읽기

동영상 파일에서 영상을 읽기 위해서는 cv2.VideoCapture() 함수를 사용하여 동영상 파일을 연다. 그 다음, read() 메소드를 사용하여 동영상의 각 프레임을 순차적으로 읽는다.

2-2-1. FPS란?

FPS는 "Frames Per Second"의 약자로, 초당 프레임 수를 의미한다. 이는 비디오 또는 게임에서 이미지가 얼마나 빠르게 연속적으로 표시되는지를 나타내는 중요한 지표이다. 높은 FPS는 더 부드러운 영상 재생과 더 자연스러운 애니메이션을 의미한다. 일반적으로, 24-30 FPS는 기본적인 비디오 재생에 충분하며, 60 FPS 이상은 고화질 비디오나 게임에 사용되어 매우 부드러운 시각적 경험을 제공한다.

2-2-2. 지연 시간이란?

지연 시간(Latency)은 영상 신호가 입력되어 처리되고, 최종적으로 화면에 표시되기까지 걸리는 시간을 말한다. 낮은 지연 시간은 실시간 비디오 스트리밍이나 인터랙티브 시스템에서 중요하며, 사용자 경험에 큰 영향을 미친다. 특히, 비디오 게임이나 가상현실 애플리케이션에서 높은 지연 시간은 사용자의 몰입감을 크게 저해할 수 있다.

 

2-3. 웹캠으로부터 영상 읽기

웹캠으로부터 실시간으로 영상을 읽기 위해서는 동영상 파일을 열 때와 유사한 방식을 사용하지만, cv2.VideoCapture() 함수에 장치 인덱스(보통 0 또는 1)를 전달하여 웹캠을 연다. 장치 인덱스는 컴퓨터에 연결된 카메라의 순서를 나타낸다.

2-4. 컬러스페이스(Color Spaces)

컬러 스페이스는 색상을 표현하는 방법을 정의한 시스템이다. 이미지 처리와 컴퓨터 비전에서는 다양한 컬러 스페이스가 사용되며, 각각의 용도와 특성이 있다.

2-4-1. 바이너리 이미지 (Binary Image)

바이너리 이미지는 이미지를 흑과 백, 두 가지 색만으로 표현하는 가장 간단한 형태의 이미지다. 각 픽셀은 0(검은색) 또는 1(흰색)의 값을 가진다. 바이너리 이미지는 문서 스캐닝, 간단한 텍스트 인식, 형태학적 변환 등에 주로 사용된다.

2-4-2. 그레이 스케일 이미지 (Grayscale Image)

그레이 스케일 이미지는 다양한 명암의 회색조를 사용하여 이미지를 표현한다. 각 픽셀은 0(검은색)에서 255(흰색) 사이의 값을 가지며, 중간 값들은 다양한 그레이(회색) 톤을 나타낸다. 그레이 스케일 변환은 이미지에서 색상 정보를 제거하고, 명암 정보만을 남기는 과정이다.

2-4-3. RGB, BGR, RGBA

1) RGB: Red, Green, Blue의 약자로, 색상을 빨간색, 초록색, 파란색의 조합으로 표현한다. 각 색상 채널은 0에서 255 사이의 값을 가진다.

2) BGR: RGB와 유사하지만, 파란색과 빨간색 채널이 뒤바뀐 형태다. OpenCV에서는 이미지를 BGR 형식으로 다루는 것이 일반적이다.

3) RGBA: RGB에 알파 채널(투명도)이 추가된 형태다. 알파 채널은 이미지의 투명도를 결정하며, 0(완전 투명)에서 255(완전 불투명) 사이의 값을 가진다.

2-4-4. HSV, HSI, HSL

1) HSV (Hue, Saturation, Value): 색상(Hue), 채도(Saturation), 명도(Value)로 색상을 표현한다. HSV 컬러 스페이스는 인간의 색감 인식과 유사하기 때문에 색상 기반의 이미지 처리에 유용하다.

2) HSI (Hue, Saturation, Intensity): HSV와 유사하지만, 명도 대신 강도(Intensity)를 사용한다. HSI는 조명 변화에 덜 민감하므로, 외부 조명 조건이 변할 때 유용할 수 있다.

3) HSL (Hue, Saturation, Lightness): 색상, 채도, 밝기(Lightness)로 구성된다. HSL은 HSV와 비슷하지만, 밝기를 다르게 정의하여 좀 더 균형 잡힌 색상 표현이 가능하다.

각 컬러 스페이스는 특정 애플리케이션 또는 특정 종류의 이미지 처리 작업에 더 적합할 수 있다. 예를 들어, 색상 분류나 추적 작업에는 HSV 컬러 스페이스가 자주 사용되며, 텍스트 인식이나 형태 분석에는 바이너리 또는 그레이 스케일 이미지가 사용된다.

3. Image 변형

3-1. 직선 그리기

import cv2
import numpy as np

# 검은색 배경의 이미지 생성
image = np.zeros((512, 512, 3), np.uint8)

# 이미지에 직선 그리기: cv2.line(이미지, 시작점, 끝점, 색상, 두께)
cv2.line(image, (0, 0), (511, 511), (255, 0, 0), 5)

cv2.imshow("Line", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

3-2. 도형 그리기

1) 직사각형 그리기

# 이미지에 직사각형 그리기: cv2.rectangle(이미지, 시작점, 끝점, 색상, 두께)
cv2.rectangle(image, (100, 100), (400, 400), (0, 255, 0), 5)

2) 원 그리기

# 이미지에 원 그리기: cv2.circle(이미지, 중심, 반지름, 색상, 두께)
cv2.circle(image, (256, 256), 100, (0, 0, 255), -1)  # -1은 채우기

3-3. 글씨 쓰기

1) cv2.FONT_HERSHEY_PLAIN : 산세리프체 작은 글꼴

2) cv2.FONT_HERSHEY_SIMPLEX : 산세리프체 일반 글꼴

3) cv2.FONT_HERSHEY_DUPLEX : 산세리프체 진한 글꼴

4) cv2.FONT_HERSHEY_COMPLEX_SMALL : 세리프체 작은 글꼴

5) cv2.FONT_HERSHEY_COMPLEX : 세리프체 일반 글꼴

6) cv2.FONT_HERSHEY_TRIPLEX : 세리프체 진한 글꼴

7) cv2.FONT_HERSHEY_SCRIPT_SIMPLEX : 필기체 산세리프
8) cv2.FONT_HERSHEY_SCRIPT_COMPLEX : 필기체 세리프

9) cv2.FONT_ITALIC : 이테릭체

# 이미지에 텍스트 쓰기: cv2.putText(이미지, 텍스트, 위치, 폰트, 크기, 색상, 두께)
cv2.putText(image, 'OpenCV', (10, 500), cv2.FONT_HERSHEY_SIMPLEX, 4, (255, 255, 255), 2)

cv2.imshow("Text", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

3-4. 이벤트 처리

마우스를 클릭하면 클릭 위치에 원이 그려지게 한다.

def draw_circle(event, x, y, flags, param):
    if event == cv2.EVENT_LBUTTONDOWN:
        cv2.circle(image, (x, y), 50, (255, 0, 0), -1)

cv2.namedWindow('Event')
cv2.setMouseCallback('Event', draw_circle)

while True:
    cv2.imshow('Event', image)
    if cv2.waitKey(20) & 0xFF == 27:  # Esc 키를 누르면 종료
        break

cv2.destroyAllWindows()

3-5. 이미지 변형하기

1) 크기 조절

# 이미지 크기 조절: cv2.resize(이미지, (너비, 높이))
resized_image = cv2.resize(image, (300, 300))

cv2.imshow("Resized", resized_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

2) 이동 및 선택

# 이미지 이동: cv2.warpAffine(이미지, 변환 행렬, (열의 수, 행의 수))
rows, cols = image.shape[:2]
M = np.float32([[1, 0, 100], [0, 1, 50]])  # x축으로 100, y축으로 50 이동
translated = cv2.warpAffine(image, M, (cols, rows))

cv2.imshow("Translated", translated)
cv2.waitKey(0)
cv2.destroyAllWindows()

3) 회전

# 이미지 회전: cv2.getRotationMatrix2D(회전 중심, 각도, 스케일)
M = cv2.getRotationMatrix2D((cols / 2, rows / 2), 45, 1)
rotated = cv2.warpAffine(image, M, (cols, rows))

cv2.imshow("Rotated", rotated)
cv2.waitKey(0)
cv2.destroyAllWindows()

3-6. 그림 그리기

3-6-1. 직선 그리기

cv2.line(img, start, end, color, [thickness, lineType])

1) img : 대상 이미지

2) start : 시작점(x,y)

3) end : 끝 지점(x,y)

4) color : 선 색상 (Blue, Green, Red), 0~255

5) thicknees : 선 두께

6) lineType : 선 형태

 - cv2.LINE_4

 - cv2.LINE_8

 - cv2.LINE_AA

import cv2
import numpy as np

img = np.full((500,500,3), 255, dtype=np.uint8)
cv2.imwrite('../img/blank_500.jpg')



img = cv2.imread('../img/blank_500.jpg')

cv2.line(img, (50, 50), (150, 50), (255,0,0))   # 파란색 1픽셀 선
cv2.line(img, (200, 50), (300, 50), (0,255,0))  # 초록색 1픽셀 선
cv2.line(img, (350, 50), (450, 50), (0,0,255))  # 빨간색 1픽셀 선

# 하늘색(파랑+초록) 10픽셀 선      
cv2.line(img, (100, 100), (400, 100), (255,255,0), 10)          
# 분홍(파랑+빨강) 10픽셀 선      
cv2.line(img, (100, 150), (400, 150), (255,0,255), 10)          
# 노랑(초록+빨강) 10픽셀 선      
cv2.line(img, (100, 200), (400, 200), (0,255,255), 10)          
# 회색(파랑+초록+빨강) 10픽셀 선  
cv2.line(img, (100, 250), (400, 250), (200,200,200), 10)        
# 검정 10픽셀 선    
cv2.line(img, (100, 300), (400, 300), (0,0,0), 10)                    

# 4연결 선
cv2.line(img, (100, 350), (400, 400), (0,0,255), 20, cv2.LINE_4)   
# 8연결 선
cv2.line(img, (100, 400), (400, 450), (0,0,255), 20, cv2.LINE_8)    
# 안티에일리어싱 선 
cv2.line(img, (100, 450), (400, 500), (0,0,255), 20, cv2.LINE_AA)   
# 이미지 전체에 대각선 
cv2.line(img, (0,0), (500,500), (0,0,255))                      

cv2.imshow('lines', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

3-6-2. 도형 그리기

1) 직사각형 그리기

cv2.rectangle(img, start, end, color, [thickness, lineType])

 - img: 대상 이미지

 - start: 시작점 좌표(x, y)

 - end: 종료점 좌표(x, y)

 - color: 도형의 색상 (B, G, R), 0~255

 - thickness: 선의 두께, -1일 경우 도형 내부를 채움

 - lineType: 선의 형태

  * cv2.LINE_4

  * cv2.LINE_8

  * cv2.LINE_AA

 

2) 원 그리기

cv2.circle(img, center, radius, color, [thickness, lineType])

 - img: 대상 이미지

 - center: 중심점 좌표(x, y)

 - radius: 반지름

 - color: 도형의 색상 (B, G, R), 0~255

 - thickness: 선의 두께, -1일 경우 도형 내부를 채움

 - lineType: 선의 형태

  * cv2.LINE_4

  * cv2.LINE_8

  * cv2.LINE_AA

 

3) 다각형 그리기

cv2.polylines(img, pts, isClosed, color, [thickness, lineType])

 - img: 대상 이미지

 - pts: 다각형의 꼭짓점들. 배열의 배열 형태.

 - isClosed: 닫힌 도형 여부. True이면 닫힌 도형.

 - color: 도형의 색상 (B, G, R), 0~255

 - thickness: 선의 두께

 - lineType: 선의 형태

  * cv2.LINE_4

  * cv2.LINE_8

  * cv2.LINE_AA

3-6-3. 글씨 쓰기

cv2.putText(img, text, org, fontFace, fontScale, color, [thickness, lineType, bottomLeftOrigin])

 - img: 대상 이미지

 - text: 이미지에 표시할 문자열

 - org: 문자열이 시작되는 좌표(왼쪽 하단 기준)

 - fontFace: 글꼴 유형

  * ex) cv2.FONT_HERSHEY_SIMPLEX, cv2.FONT_HERSHEY_COMPLEX, 등

 - fontScale: 글꼴 크기에 대한 스케일 인자

 - color: 글자의 색상 (B, G, R), 0~255

 - thickness: 선의 두께

 - lineType: 선의 형태

  * cv2.LINE_4

  * cv2.LINE_8

  * cv2.LINE_AA

 - bottomLeftOrigin: True이면 이미지의 좌측 하단을 원점으로 사용. 일반적으로 False 사용

 

3-6-4. 이벤트 처리

OpenCV는 마우스 이벤트와 키보드 이벤트를 처리할 수 있는 기능을 제공한다. 이를 통해 사용자의 입력에 반응하는 대화형 애플리케이션을 개발할 수 있다.

 

1) Key 이벤트 처리

cv2.waitKey() 함수는 키보드 이벤트를 처리하는 데 사용된다. 이 함수는 지정된 시간 동안 키 입력을 대기하고, 키가 눌러지면 해당 키의 ASCII 코드를 반환한다. 특정 키 이벤트에 반응하도록 하려면, cv2.waitKey() 함수의 반환값을 사용하여 조건문을 구성할 수 있다.

import cv2

# 이미지 로드
img = cv2.imread('your_image.jpg')
cv2.imshow('Image', img)

while True:
    key = cv2.waitKey(1) & 0xFF  # 1밀리초 동안 키 입력 대기
    if key == ord('q'):  # 'q' 키를 누르면 종료
        break
    elif key == ord('s'):  # 's' 키를 누르면 이미지 저장
        cv2.imwrite('saved_image.jpg', img)
        print("Image saved")

cv2.destroyAllWindows()

 

2) Mouse 이벤트 처리

마우스 이벤트를 처리하기 위해서는 cv2.setMouseCallback() 함수를 사용하여 콜백 함수를 정의하고 등록해야 한다. 이 콜백 함수는 마우스 이벤트가 발생할 때마다 호출된다.

import cv2
import numpy as np

# 마우스 콜백 함수 정의
def draw_circle(event, x, y, flags, param):
    if event == cv2.EVENT_LBUTTONDOWN:  # 왼쪽 버튼 클릭 시
        cv2.circle(img, (x, y), 50, (255, 0, 0), -1)

# 검은색 이미지 생성
img = np.zeros((512, 512, 3), np.uint8)
cv2.namedWindow('image')
cv2.setMouseCallback('image', draw_circle)

while True:
    cv2.imshow('image', img)
    if cv2.waitKey(20) & 0xFF == 27:  # ESC 키를 누르면 종료
        break

cv2.destroyAllWindows()

3-7. 이미지 변형하기

보간법(Interpolation)은 이미지를 확대, 축소, 회전하는 과정에서 원본 이미지의 픽셀 값들을 새로운 위치에 맞게 조정하는 방법을 말한다. 이미지 처리에서 보간법은 이미지의 품질을 유지하면서 이러한 변환을 수행하는 데 중요한 역할을 한다. OpenCV에서 제공하는 주요 보간법에는 다음과 같은 것들이 있다.

3-7-1. Nearest-neighbor Interpolation (최근접 이웃 보간법)

1) 가장 간단한 보간법으로, 대상 픽셀의 색상 값을 가장 가까운 이웃 픽셀의 색상 값으로 설정한다.

2) cv2.INTER_NEAREST로 지정한다.

3) 확대 및 축소시 계단 현상이 발생하기 쉽지만, 처리 속도가 빠르다.

3-7-2. Bilinear Interpolation (양선형 보간법)

1) 대상 픽셀의 색상 값을 주변 4개의 픽셀 색상 값으로부터 선형적으로 계산하여 결정한다.

2) cv2.INTER_LINEAR로 지정한다.

3) 성능과 품질 사이에서 균형을 이루며, 일반적인 경우에 널리 사용된다.

3-7-3. Bicubic Interpolation (삼차원 보간법)

1) 대상 픽셀의 색상 값을 주변 16개의 픽셀 색상 값으로부터 삼차 함수를 사용하여 계산한다.

2) cv2.INTER_CUBIC로 지정한다.

3) 양선형 보간법보다 시각적으로 부드러운 결과를 제공하지만, 계산 비용이 더 높다.

3-7-4. Lanczos Interpolation (란초스 보간법)

1) 주변 픽셀을 사용하여 더 정교한 계산을 수행하는 고급 보간법이다.

2) cv2.INTER_LANCZOS4로 지정한다.

3) 높은 품질의 이미지 확대에 적합하지만, 계산 비용이 가장 높다.

import cv2

# 이미지 로드
img = cv2.imread('example.jpg')

# Nearest-neighbor 보간법 사용 예제
resized_nearest = cv2.resize(img, None, fx=2, fy=2, interpolation=cv2.INTER_NEAREST)

# Bilinear 보간법 사용 예제
resized_linear = cv2.resize(img, None, fx=2, fy=2, interpolation=cv2.INTER_LINEAR)

# Bicubic 보간법 사용 예제
resized_cubic = cv2.resize(img, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC)

# Area-based 보간법 사용 예제
resized_area = cv2.resize(img, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_AREA)

# Lanczos4 보간법 사용 예제
resized_lanczos = cv2.resize(img, None, fx=2, fy=2, interpolation=cv2.INTER_LANCZOS4)

# 결과 이미지 표시
cv2.imshow('Original', img)
cv2.imshow('Nearest', resized_nearest)
cv2.imshow('Linear', resized_linear)
cv2.imshow('Cubic', resized_cubic)
cv2.imshow('Area', resized_area)
cv2.imshow('Lanczos', resized_lanczos)

cv2.waitKey(0)
cv2.destroyAllWindows()

3-8. 크기 조절

이미지의 크기를 조절하는 것은 영상 처리에서 매우 중요한 작업 중 하나다. OpenCV에서는 cv2.resize() 함수를 사용하여 이미지의 크기를 쉽게 변경할 수 있다. 이 함수는 다양한 보간법을 사용하여 이미지의 크기를 조절할 수 있으며, 대표적으로 cv2.INTER_LINEAR, cv2.INTER_NEAREST, cv2.INTER_AREA, cv2.INTER_CUBIC 등이 있다.

cv2.resize(src, dsize, fx=0, fy=0, interpolation=cv2.INTER_LINEAR)

1) src: 원본 이미지

2) dsize: 출력 이미지의 크기. (너비, 높이)의 튜플 형태

3) fx (optional): 가로 축의 스케일 인자 (dsize를 지정하면 무시됨)

4) fy (optional): 세로 축의 스케일 인자 (dsize를 지정하면 무시됨)
5) interpolation: 보간법. 이미지의 크기를 변경할 때 사용하는 알고리즘

import cv2

# 이미지 로드
img = cv2.imread('example.jpg')

# 이미지 크기 조절: dsize 사용
resized_img_dsize = cv2.resize(img, dsize=(300, 200))

# 이미지 크기 조절: 스케일 인자 사용
resized_img_scale = cv2.resize(img, dsize=None, fx=0.5, fy=0.5, interpolation=cv2.INTER_LINEAR)

cv2.imshow('Original', img)
cv2.imshow('Resized with dsize', resized_img_dsize)
cv2.imshow('Resized with scale', resized_img_scale)

cv2.waitKey(0)
cv2.destroyAllWindows()

3-9. 이미지 이동

이미지를 이동시키기 위해 OpenCV에서는 Affine 변환 중 하나인 Translation(이동 변환)을 사용한다. 이를 위해 cv2.warpAffine 함수와 이동 변환 행렬을 사용한다.

[1 0 tx]
[0 1 ty]

tx는 x축으로의 이동 거리, ty는 y축으로의 이동 거리이다.

cv2.warpAffine(src, M, dsize)

1) src: 원본 이미지

2) M: 2x3 변환 행렬

3) dsize: 출력 이미지의 크기. (너비, 높이)의 튜플 형태

import cv2
import numpy as np

# 이미지 로드
img = cv2.imread('example.jpg')
rows, cols = img.shape[:2]

# 이동 변환 행렬 정의: x축으로 100, y축으로 50 이동
M = np.float32([[1, 0, 100], [0, 1, 50]])

# warpAffine 함수를 사용하여 이미지 이동
dst = cv2.warpAffine(img, M, (cols, rows))

cv2.imshow('Original', img)
cv2.imshow('Translated', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

3-10. 이미지 영역 선택 (ROI)

이미지에서 관심 있는 영역(Region of Interest, ROI)을 선택하는 것은 이미지 처리에서 자주 사용되는 기술이다. 이미지의 특정 부분을 추출하거나, 해당 부분에만 특정 작업을 수행할 수 있다.

import cv2

# 이미지 로드
img = cv2.imread('example.jpg')

# ROI 선택: 이미지의 일부분을 선택 [y1:y2, x1:x2]
roi = img[50:150, 100:200]

cv2.imshow('ROI', roi)
cv2.waitKey(0)
cv2.destroyAllWindows()

3-11. 이미지 회전

이미지를 회전시키기 위해 OpenCV에서는 cv2.getRotationMatrix2D 함수를 사용하여 회전 변환 행렬을 생성하고, cv2.warpAffine 함수를 사용하여 실제로 이미지에 회전을 적용한다.

cv2.getRotationMatrix2D(center, angle, scale)

1) center: 회전의 중심점 좌표 (x, y)

2) angle: 회전 각도(도 단위). 양수 값은 반시계 방향 회전을 의미한다.

3) scale: 추가적인 스케일링 인자 (예: 1이면 원래 크기, 0.5는 크기를 반으로 줄임)

import cv2

# 이미지 로드
img = cv2.imread('example.jpg')
rows, cols = img.shape[:2]

# 회전의 중심을 이미지의 중앙으로 설정하고, 45도 회전하며, 스케일은 1로 유지
M = cv2.getRotationMatrix2D((cols / 2, rows / 2), 45, 1)

# warpAffine 함수를 사용하여 이미지 회전
rotated_img = cv2.warpAffine(img, M, (cols, rows))

cv2.imshow('Original', img)
cv2.imshow('Rotated', rotated_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
728x90

'컴퓨터 영상 처리 > OpenCV' 카테고리의 다른 글

OpenCV_Basic (1)  (1) 2024.03.22

댓글