OpenCV 사용법1

InSung-Na·2023년 5월 3일
0

Part 11. OpenCV

목록 보기
3/6
post-thumbnail

해당 글은 제로베이스데이터스쿨 학습자료를 참고하여 작성되었습니다

1. 영상 데이터 속성과 픽셀값 참조

영상 데이터 속성

  • OpenCV는 영상데이터를 numpy.ndarray로 표현

  • numpy.ndarray

    • ndim : 차원 수
    • shape : 차원 크기 (h,w) or (h,w,3)
    • size : 전체 원소 갯수
    • dtype : 데이터타입. 영상데이터는 uint8
  • OpenCV 영상 데이터 자료형과 Numpy 자료형

  • 그레이스케일 : cv2.CV_8UC1 -> numpy.uint8

    • shape=(h,w)
  • 컬러영상 : cv2.CV_8UC3 -> numpy.uint8

    • shape=(h,w,3)

영상 데이터 속성(Python)

import cv2
import sys

# 영상 불러오기
img1 = cv2.imread('./data/cat.bmp', cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread('./data/cat.bmp', cv2.IMREAD_COLOR)

# 영상 속성
print('type(img1):', type(img1)) # type(img1): <class 'numpy.ndarray'>
print('img1.shape:', img1.shape) # img1.shape: (h, w)
print('img2.shape:', img2.shape) # img2.shape: (h, w, 3)
print('img2.dtype:', img2.dtype) # img2.dtype: uint8
h, w = img2.shape[:2]

print('img2 size: {} x {}'.format(w, h))

# 색상 속성
if len(img1.shape) == 2:
    print('img1 is a grayscale image')
elif len(img1.shape) == 3:
    print('img1 is a truecolor image')
------------------------------------------------------------
type(img1): <class 'numpy.ndarray'>
img1.shape: (480, 640)
img2.shape: (480, 640, 3)
img2.dtype: uint8
img2 size: 640 x 480
img1 is a grayscale image

영상의 픽셀 값 참조

영상의 픽셀 값 참조(Python)

  • for문 대신 슬라이싱을 사용할 것
img1 = cv2.imread('./data/cat.bmp', cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread('./data/cat.bmp', cv2.IMREAD_COLOR)
# for y in range(h):
#     for x in range(w):
#         img1[y, x] = 255
#         img2[y, x] = [0, 0, 255]
img1[:, :]=255
img2[:, :]=[0, 0, 255]  # (B, G, R)

cv2.imshow("img1", img1)
cv2.imshow("img2", img2)
cv2.waitKey()
cv2.destroyAllWindows()

2. 영상의 생성과 복사

새 영상 생성하기

  • empty로 생성하는 경우, 임의의 값이 들어가므로 주의
numpy.empty(shape, dtype=float, ...) -> arr
numpy.zeros(shape, dtype=float, ...) -> arr
numpy.ones(shape, dtype=None, ...) -> arr
numpy.full(shape, fill_value, dtype=None, ...) -> arr
  • shape: 각 차원의 크기. (h, w) 또는 (h, w, 3)
  • dtype: 원소의 데이터 타입. Default=numpy.uint8
  • arr: 생성된 영상(numpy.ndarray)
  • 참고사항:
    • numpy.empty() : 임의의 값으로 초기화된 배열을 생성
    • numpy.zeros() : 0으로 초기화된 배열을 생성
    • numpy.ones() : 1로 초기화된 배열을 생성
    • numpy.full() : fill_value로 초기화된 배열을 생성

새 영상 생성하기(Python)

import numpy as np
import cv2

# 새 영상 생성하기
img1 = np.empty((240, 320), dtype=np.uint8)       # grayscale image
img2 = np.zeros((240, 320, 3), dtype=np.uint8)    # color image
img3 = np.ones((240, 320), dtype=np.uint8) * 255  # white
img4 = np.full((240, 320, 3), (0, 255, 255), dtype=np.uint8)  # yellow

cv2.imshow('img1', img1)
cv2.imshow('img2', img2)
cv2.imshow('img3', img3)
cv2.imshow('img4', img4)
cv2.waitKey()
cv2.destroyAllWindows()

영상 참조 및 복사

영상 참조 및 복사(Python)

img1 = cv2.imread('./data/HappyFish.jpg')

img2 = img1         # img1을 참조
img3 = img1.copy()  # img1을 복사

img1[:, :, :] = 255

cv2.imshow('img1', img1)
cv2.imshow('img2', img2)
cv2.imshow('img3', img3)
cv2.waitKey()
cv2.destroyAllWindows()

3. 부분 영상 다루기

부분 영상 추출

부분 영상 추출(Python)

import numpy as np
import cv2

img1 = cv2.imread('./data/HappyFish.jpg')

# img.shape = (h, w)
img2 = img1[40:120, 30:150]  # numpy.ndarray의 슬라이싱
img3 = img1[40:120, 30:150].copy()

img2.fill(0)

cv2.imshow('img1', img1)
cv2.imshow('img2', img2)
cv2.imshow('img3', img3)
cv2.waitKey()
cv2.destroyAllWindows()

부분 영상처리

부분 영상처리(Python)

img = cv2.imread('./data/lenna.bmp', cv2.IMREAD_GRAYSCALE)

img_face = img[200:400, 200:400]  # 얼굴 영역(관심영역, ROI)

# cv2.add(input, add_num, output)
cv2.add(img_face, 50, img_face)   # 밝기 조절
cv2.circle(img_face, (100, 100), 80, 0, 2)	# 원 그리기
cv2.imshow('img', img)
cv2.waitKey()
cv2.destroyAllWindows()

4. 마스크 영상과 ROI

ROI와 마스크 연산

  • 관심 영역(ROI)
    - Region of Interest
    • 영상에서 특정 연산을 수행하고자 하는 영역
  • 마스크 연산
    • OpenCV에서는 이미지합성을 할 때, 마스크 영상의 0이 아닌 부분을 입력영상에서 추출해서 출력영상과 합성을 한다.
    • 배경과 대상을 구분하는 마스크 영상을 활용
    • 마스크 영상은 cv2.CV_8UC1타입이어야 한다
    • 픽셀 값이 0이 아닌 위치에서만 연산이 수행됨

마스크 연산 함수

  • cv2.copyTo(src, mask, dst=None) -> dst
    • src : 입력영상, cv2.CV_8UC3
    • mask : 마스크 영상, cv2.CV_8U
      • 0이 아닌 픽셀에 대해서만 복사연산 수행
    • dst : 출력영상, cv2.CV_8UC3
    • 연산 수행 시 각 인자의 크기가 동일해야 함

마스크 영상을 이용한 영상 합성(Python)

import sys
import cv2


# 마스크 영상을 이용한 영상 합성
src = cv2.imread('./data/airplane.bmp', cv2.IMREAD_COLOR)
mask = cv2.imread('./data/mask_plane.bmp', cv2.IMREAD_GRAYSCALE)
dst = cv2.imread('./data/field.bmp', cv2.IMREAD_COLOR)

if src is None or mask is None or dst is None:
    print('Image load failed!')
    sys.exit()
    
# mask에서 값이 0이 아닌 부분을 src에서 복사해서 dst에 합성
# cv2.copyTo() 실행 시에 모든 요소의 크기가 같아야 함
cv2.copyTo(src, mask, dst)
# dst[mask > 0] = src[mask > 0]

cv2.imshow('src', src)
cv2.imshow('mask', mask)
cv2.imshow('dst', dst)
cv2.waitKey()
cv2.destroyAllWindows()

5. 투명한 PNG파일 합성하기

알파 채널 활용

알파 채널 활용(Python)

import sys
import cv2

# 알파 채널을 마스크 영상으로 이용
src = cv2.imread('./data/cat.bmp', cv2.IMREAD_COLOR)
logo = cv2.imread('./data/opencv-logo-white.png', cv2.IMREAD_UNCHANGED)

if src is None or logo is None:
    print('Image load failed!')
    sys.exit()

mask = logo[:, :, 3]    # mask는 알파 채널로 만든 마스크 영상
logo = logo[:, :, 0:3]  # logo는 b, g, r 3채널로 구성된 컬러 영상
h, w = mask.shape[:2]
crop = src[10:10+h, 10:10+w]  # logo, mask와 같은 크기의 부분 영상 추출

cv2.copyTo(logo, mask, crop)  # logo를 crop에 합성 -> crop은 src의 참조이므로 src의 수정됨
#crop[mask > 0] = logo[mask > 0]

cv2.imshow('src', src)
cv2.imshow('logo', logo)
cv2.imshow('mask', mask)
cv2.waitKey()
cv2.destroyAllWindows()

0개의 댓글