4. 이미지 연산

 

4.1 이미지 더하기


4.1.1 modulo 연산


img = img1 + img2

두개의 이미지를 각각의 픽셀 단위로 덧셈을 하여 255보다 큰 경우 256으로 나눈 나머지를 픽셀 값으로 설정 합니다. ( 250 + 7 = 257/256 -> 1)

더하는 이미지는 사이즈가 동일해야 하며 사이즈가 같지 않으면 아래와 같은 오류가 발생 합니다.


 ValueError: operands could not be broadcast together with shapes (277,350,3) (213,350,3) 


4.1.2 Saturation 연산


cv2.add() 함수를 이용하여 두개의 이미지를 각각의 픽셀 단위로 덧셈을 한 후 255보다 큰 경우 255를 픽셀 값으로 설정 합니다. (250 + 7 = 257 -> 255)

 

cv2.add(src1, src2[, dst[, mask[, dtype]]]) → dst

 

parameter

내용

src1

이미지 파일

src2

이미지 파일

dst

결과 파일

mask

영역 지정

dtype

output depth

 

이미지를 더하는 예제


import numpy as np

import cv2

 

img1 = 'F:/Python/images/image001.png'

img2 = 'F:/Python/images/image002.png'

 

# image read

imread1 = cv2.imread(img1, cv2.IMREAD_COLOR)

imread2 = cv2.imread(img2, cv2.IMREAD_COLOR)

 

# image add

img_plus = imread1 + imread2

img_add = cv2.add(imread1, imread2)

 

# image show

cv2.imshow('image + ', img_plus)

cv2.imshow('image add', img_add)

 

cv2.waitKey(0)

cv2.destroyAllWindows()



두개의 이미지를 이용하여 연산을 진행 합니다.


image001.png

opencv_bit_add


image002.png

opencv_bit_add


- modulo 연산


메뚜기 사진의 배경이 거의 없어서 배경을 제외 하고는 물체 확인이 어렵습니다.


opencv_bit_add


- Saturation 연산


이것도 원본 사진을 보지 않은 경우에는 예측이 어렵습니다.


opencv_bit_add


4.3 이미지 Blending

 

cv2.addWeighted()

두개의 이미지에 각각의 가중치를 조절하여 덧셈하는 방법입니다가중치의 값이 큰 이미지가 좀더 선명하게 나타 납니다.

 

cv2.addWeighted(src1, alpha, src2, beta, gamma[, dst[, dtype]]) → dst


parameter

내용

src1

이미지1

alpha

이미지1 가중치

src2

이미지2

beta

이미지2 가중치

gamma

각 덧셈에 추가하는 값

dst

결과 이미지

dtype

depth

 

dst[i] = saturate(src1[i]*alpha + src2[i]*beta + gamma)


import numpy as np

import cv2

 

img1 = 'F:/Python/images/image001.png'

img2 = 'F:/Python/images/image002.png'

 

# image read

imread1 = cv2.imread(img1, cv2.IMREAD_COLOR)

imread2 = cv2.imread(img2, cv2.IMREAD_COLOR)

 

def weight (x):

    pass

 

cv2.namedWindow('image')

cv2.createTrackbar('Weight', 'image', 0, 100, weight)

 

while True:

    weight = cv2.getTrackbarPos('Weight','image')

    addWeight = cv2.addWeighted(imread1,float(100-weight) * 0.01, imread2,float(weight) * 0.01,0)

    cv2.imshow('image', addWeight)

 

    if cv2.waitKey(1) &0xFF == 27:

        break;

 

cv2.waitKey(0)

cv2.destroyAllWindows()


가중치가 높은 이미지가 선명하게 보이게 됩니다우리가 흔하게 볼 수 있는 은은한 장면 전환과 같습니다.


opencv_bit_add




3. 비디오 입력 출력

 

3.1 VideoCapture

 

opencv에서 동영상 입력 부분을 관리하는 함수 입니다모든 디바이스의 입출력은 파일 처리와 비슷하기 때문에 파일 처리를 해보았다면 사용되는 method등이 좀 다를 뿐 작업 방식도 비슷합니다.

cv2.VideoCapture() → <VideoCapture object>

VideoCapture() 함수를 사용 했을 때 리턴되는 오브젝트 인데 양이 너무 많아 지면 낭비이니 심심하실 때 ‘VideoCapture class’로 검색하면 자료를 찾을 수 있습니다.

 

cv2.VideoCapture(filename) → <VideoCapture object>


cv2.VideoCapture(device) → <VideoCapture object>


parameter

 내용

 filename

 동영상 파일 명 또는 이미지 파일명

 device

 연결된 영산 장치 index (하나만 있는 경우 0)


VideoCapture() 함수에 파일 명을 넣으면 저장된 비디오를 불러오고  0, 1 등을 넣으면 입력 디바이스 순서(한개인 경우 0)에 따라 실시간 촬영 frame을 받아 올 수 있습니다.

 

- 비디오 파일 읽기


기존 동영상 파일을 읽어와 창을 생성하고 frame이 끝날 때 까지 보여주는 예제 입니다.


import cv2

 

videoFile1 = 'F:/Python/images/video001.mp4

cap = cv2.VideoCapture(videoFile1)

 

while(cap.isOpened()):

    ret, frame = cap.read()

   

    if ret:

        cv2.imshow('video', frame)

 

        if cv2.waitKey(1) & 0xFF == ord('q'):

                break

    else:

        break

 

cap.release()

cv2.destroyAllWindows()


opencv_video


- 디바이스 읽기


디바이스 장치로 부터 frame을 하나씩 읽어와 생성된 창에 보여줍니다디바이스로 부터 읽은 영상은 화면 크기를 조절할 수 있습니다.


import cv2

 

cap = cv2.VideoCapture(0)

 

# 화면 크기 설정

cap.set(3,320)

cap.set(4,240)

 

while True:

   

    ret, frame = cap.read()

   

    if ret:

        cv2.imshow('video', frame)

 

        if cv2.waitKey(1) & 0xFF == ord('q'):

                break

    else:

        break

 

cap.release()

out.release()

cv2.destroyAllWindows()


opencv_video



3.2 VideoCapture Method

 

cv2.VideoCapture.open(filename) → retval

비디오 파일을 불러오는 경우 파일명을 사용하여 오픈 합니다.

 

cv2.VideoCapture.open(device) → retval

영상 장치를 이용하는 경우 디바이스 index 값으로 오픈 합니다.

 

cv2.VideoCapture.isOpened() → retval

파일이 정상적으로 open 되었는가 여부를 알아보는 것으로 사용 가능 하면 True를 리턴합니다.

 

cv2.VideoCapture.release() → None

open된 비디오 파일이나 영상 장치를 닫습니다.

 

cv2.VideoCapture.grab() → retval

비디오 파일이나 영상 장치로 부터 다름 frame을 가져옵니다. 성공 시 True를 리턴 합니다.

 

cv2.VideoCapture.retrieve([image[, flag]]) → retval, image

grabframedecode해서 돌려 줍니다.  frame이 없을 경우 False를 리턴 합니다.

 

cv2.VideoCapture.read([image]) → retval, image

grab()retrieve() 함수와 같이 사용되며 decode frame을 읽어 옵니다.  frame이 없을 경우 False를 리턴 합니다.

 

cv2.VideoCapture.get(propId) → retval

캡처한 영상의 속성을 리턴 합니다.

 

parameter

내용

cv2.CAP_PROP_POS_MSEC

Current position of the video file in milliseconds or video capture timestamp

cv2.CAP_PROP_POS_FRAMES

0-based index of the frame to be decoded/captured next

cv2.CAP_PROP_POS_AVI_RATIO

Relative position of the video file: 0 - start of the film, 1 - end of the film

cv2.CAP_PROP_FRAME_WIDTH

Width of the frames in the video stream

cv2.CAP_PROP_FRAME_HEIGHT

Height of the frames in the video stream

cv2.CAP_PROP_FPS

Frame rate

cv2.CAP_PROP_FOURCC

4-character code of codec

cv2.CAP_PROP_FRAME_COUNT

Number of frames in the video file

cv2.CAP_PROP_FORMAT

Format of the Mat objects returned by retrieve()

cv2.CAP_PROP_MODE

Backend-specific value indicating the current capture mode

cv2.CAP_PROP_BRIGHTNESS

Brightness of the image (only for cameras)

cv2.CAP_PROP_CONTRAST

Contrast of the image (only for cameras)

cv2.CAP_PROP_SATURATION

Saturation of the image (only for cameras)

cv2.CAP_PROP_HUE

Hue of the image (only for cameras)

cv2.CAP_PROP_GAIN

Gain of the image (only for cameras)

cv2.CAP_PROP_EXPOSURE

Exposure (only for cameras)

cv2.CAP_PROP_CONVERT_RGB

Boolean flags indicating whether images should be converted to RGB

cv2.CAP_PROP_WHITE_BALANCE

Currently not supported

cv2.CAP_PROP_RECTIFICATION

Rectification flag for stereo cameras (note: only supported by DC1394 v 2.x backend currently)

 

cv2.VideoCapture.set(propId, value) → retval

캡처한 영상의 속성값을 설정 합니다.


parameter

 내용

 propId

 get() 속성 값과 같음

 value

 속성 값


- method 사용 예


import cv2

 

videoFile1 = 'F:/Python/images/video001.avi'

 

cap = cv2.VideoCapture(videoFile1)

 

# get()

frame_width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)

frame_height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)

print(frame_width, frame_height, end=',')

 

# grab(), retrieve(), read()

if cap.grab():

    flg, frame = cap.retrieve()

    if flg:

        cv2.imshow('video', frame)

 

    flg2, frame2 = cap.read()

    if flg2:

        cv2.imshow('video2', frame2)

       

       

cap.release()

cv2.waitKey(0)

cv2.destroyAllWindows()


- cv2.VideoCapture.get() 실습 해보기


cv2 VideoCapture get opencv


cv2.VideoCapture.get()cap = cv2.VideoCapture(videoFile1) 이렇게 해서 cap 변수에 File을 받아오고 cap.get()으로 파일에 대한 설정 값을 얻어 옵니다하단에 print문을 이용하여 cap.get()으로 받아온 동영상의 size 852, 480을 출력해 보았습니다 아래는 video 출력 결과입니다.


cv2 VideoCapture get opencv



3.3 VideoWriter

 

VideoWriter() 함수를 이용하여 frame을 파일에 출력 합니다.

 

cv2.VideoWriter([filename, fourcc, fps, frameSize[, isColor]]) → <VideoWriter object>


parameter

내용

filename

저장할 동영상 파일명

fourcc

frame 압축 관련 4자리 code

fps

초당 저장할 frame

frameSize

frame size (가로, 세로)

isColor

컬러 저장 여부.


 

cv2.VideoWriter.open(filename, fourcc, fps, frameSize[, isColor]) → retval

VideoWriter() 함수를 초기화 하거내 재 초기화를 진행 합니다.

 

cv2.VideoWriter.isOpened() → retval

비디오 저장의 초기화 유무를 리턴 합니다. (True, False)

 

cv2.VideoWriter.write(image) → None

저장 파일에 다음 frame을 기록 합니다.

 

cv2.VideoWriter_fourcc(c1, c2, c3, c4) → retval

fourcc code를 리턴 합니다.

 

- Device frame 저장


import cv2

 

videoFile1 = 'F:/Python/images/video001.avi'

 

cap = cv2.VideoCapture(0)

 

# 화면 크기 설정

cap.set(3,320)

cap.set(4,240)

 

# 파일 쓰기

fourcc = cv2.VideoWriter_fourcc(*'DIVX')

out = cv2.VideoWriter(videoFile1, fourcc, 25.0, (320,240))

 

while True:

   

    ret, frame = cap.read()

   

    if ret:

   

        out.write(frame)

 

        cv2.imshow('video', frame)

 

        if cv2.waitKey(1) & 0xFF == ord('q'):

                break

    else:

        break

 

cap.release()

out.release()

cv2.destroyAllWindows()


- 도형 그리기 저장


꼭 동영상이나 디바이스 입력을 출력하는건 아닙니다.  frame을 생성할 수 있는 것이면 출력이 가능 합니다도형을 회전시키면서 저장을 해보겠습니다.


import numpy as np

import cv2

import time

 

 

videoFile1 = 'F:/Python/images/video003.avi'

 

fourcc = cv2.VideoWriter_fourcc(*'DIVX')

out = cv2.VideoWriter(videoFile1, fourcc, 25.0, (384,384))

#cv2.VideoWriter.open(filename, fourcc, fps, frameSize[, isColor])

 

# color 설정

blue_color = (255, 0, 0)

green_color = (0, 255, 0)

red_color = (0, 0, 255)

white_color = (255, 255, 255)

 

# 모두 0으로 되어 있는 빈 Canvas(검정색)

img = np.zeros((384, 384, 3), np.uint8)

for i in range(0, 90):

   

    pt1 = cv2.ellipse2Poly((200, 200), (100, 160), i, 0, 360, 50)

    img = cv2.ellipse(img, (200, 200), (100, 160), 0, 0, 360, white_color, 2)

    img = cv2.polylines(img, [pt1], False, green_color, 2)

   

    out.write(img)

    time.sleep(0.5)  # 너무 빨리 진행되지 않도록

 

print('end')  

out.release()

cv2.waitKey(0)

cv2.destroyAllWindows()


opencv_video


2. 이미지 입력 출력


도형 그리기는 빈 공간에 무엇인가를 새로 그리고 보여주는 기능이지만 이미지 입출력은 기존에 존재하는 이미지 파일을 작업하는 부분이라 간단하게 테스트 할 수 있습니다.

 

2.1 이미지 입력

 

imread() 함수를 이용하여 저장된 이미지를 읽어 옵니다.

 

cv2.imread(filename[, flags]) → retval


parameter

 내용

 filename

 읽어올 파일 명

 flags

 cv2.IMREAD_COLOR : Color로 읽음(1)

cv2.IMREAD_GRAYSCALE : Grayscale로 읽음(0)

cv2.IMREAD_UNCHAGED : alpha channel 까지 포함해 읽음(-1)


2.2 이미지 출력

 

imwrite() 함수를 이용하여 이미지를 파일로 출력 합니다.


cv2.imwrite(filename, img[, params]) → retval


parameter

 내용

 filename

 저장할 파일 명

 img 이미지 파일

 params

 IMWRITE_JPEG_QUALITY

 IMWRITE_WEBP_QUALITY

 IMWRITE_PNG_COMPRESSION

 IMWRITE_PXM_BINARY


2.3 이미지 화면 출력

 

imshow() 함수를 이용하여 이미지를 모니터에 보여줍니다.


cv2.imshow(winname, filename) → None


parameter

 내용

 winname 이미지 창 이름

 filename

 파일 명


예제)


이미지 파일을 읽어와 회색으로 저장하고 화면에 보여주는 예제 입니다.


import cv2

 

fname = 'F:/Python/images/image001.png'

fwname = 'F:/Python/images/image001_save.png'

 

# image read

color = cv2.imread(fname, cv2.IMREAD_COLOR)

gray = cv2.imread(fname, cv2.IMREAD_GRAYSCALE)

unchange = cv2.imread(fname, cv2.IMREAD_UNCHANGED)

 

# image show

cv2.imshow('Color', color)

cv2.imshow('Gray', gray)

cv2.imshow('Unchange', unchange)

 

# gray image write

cv2.imwrite(fwname, gray)

 

cv2.waitKey(0)

cv2.destroyAllWindows()


- 원본 이미지


opencv_image


- 칼라 이미지 창


opencv_image


- 회색 이미지 창


opencv_image


- 무 변경 이미지 창


opencv_image


- 파일로 저장된 이미지


opencv_image



2.4 이미지 창 생성

 

cv2.namedWindow() 함수를 이용하여 이미지 창을 생성 합니다.


cv2.namedWindow(winname[, flags]) → None


parameter

 내용

 winname

 window caption name

 flags

 WINDOW_NORMAL

 WINDOW_AUTOSIZE


2.5 이미지 창 이동

 

MoveWindow() 함수를 이용하여 모니터에서의 위치를 설정하면 창을 이동 합니다.


cv2.moveWindow(winname, x, y) → None


parameter

 내용

 winname

 이미지 창 이름

 x 윈도우 전체 화면의 x 좌표
 y 윈도우 전체 화면의 y 좌표


이미지 파일을 읽어와 모니터 화면의 좌표를 이용하여 창을 이동 합니다.


import cv2

 

fname = 'F:/Python/images/image001.png'

 

# image read

img = cv2.imread(fname, cv2.IMREAD_COLOR)

 

# image show

cv2.imshow('Move', img)

 

# window move

cv2.moveWindow('Move', 50, 0)

 

cv2.waitKey(0)

cv2.destroyAllWindows()



opencv_image


모니터 상단 휴지통 옆에 딱 붙어 있습니다.


2.6 이미지 창 크기 조절

 

ResizeWindow() 함수를 이용하여 창 크기 조절이 가능 합니다이미지도 창의 비율에 맞추어 수정 됩니다.

 

cv2.resizeWindow(winname, width, height) → None


parameter

 내용

 winname

 이미지 창 이름

 width 이미지 폭
 height 이미지 높이


신규 이미지 창을 만들어 이미지를 대입 합니다.


import cv2

 

fname = 'F:/Python/images/image001.png'

 

# image read

img = cv2.imread(fname, cv2.IMREAD_COLOR)

 

# image resize

cv2.namedWindow('Resized Window', cv2.WINDOW_NORMAL)

cv2.resizeWindow('Resized Window', 250, 100)

 

# image show

cv2.imshow('Resized Window', img)

 

cv2.waitKey(0)

cv2.destroyAllWindows()


opencv_image



1.6 문자


org 좌표를 글자의 우측 하단을 시작점으로 하여 주어진 텍스트를 출력 합니다.


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


parameter

 내용

 img

 이미지 파일

 text

 출력 문자

 org

 출력 문자 시작 위치 좌표 (좌측 하단)

 fontFace

cv2.FONT_HERSHEY_SIMPLEX : 0

cv2.FONT_HERSHEY_PLAIN : 1

cv2.FONT_HERSHEY_DUPLEX : 2

cv2.FONT_HERSHEY_COMPLEX : 3

cv2.FONT_HERSHEY_TRIPLEX : 4

cv2.FONT_HERSHEY_COMPLEX_SMALL : 5

cv2.FONT_HERSHEY_SCRIPT_SIMPLEX : 6

cv2.FONT_HERSHEY_SCRIPT_COMPLEX : 7

cv2.FONT_ITALIC : 16

 fontScale

 폰트 크기

 color

 폰트 색상

 thickness

 폰트 두꼐

 lineType

 선 종류 (default cv.Line_8)

 - LINE_8 : 8-connected line

 - LINE_4 : 4-connecterd line

 - LINE_AA : antialiased line

 bottomLeftOrigin

 org 사용 옵션. True : 좌측 하단. False : 좌측 상단


import numpy as np

import cv2

 

# color 설정

blue_color = (255, 0, 0)

green_color = (0, 255, 0)

red_color = (0, 0, 255)

white_color = (255, 255, 255)

 

# Font 종류

fonts = [cv2.FONT_HERSHEY_SIMPLEX,

cv2.FONT_HERSHEY_PLAIN,

cv2.FONT_HERSHEY_DUPLEX,

cv2.FONT_HERSHEY_COMPLEX,

cv2.FONT_HERSHEY_TRIPLEX,

cv2.FONT_HERSHEY_COMPLEX_SMALL,

cv2.FONT_HERSHEY_SCRIPT_SIMPLEX,

cv2.FONT_HERSHEY_SCRIPT_COMPLEX,

cv2.FONT_ITALIC]

 

# 모두 0으로 되어 있는 빈 Canvas(검정색)

img = np.zeros((384, 384, 3), np.uint8)

 

# Font 그리기

for i in range(0, len(fonts)):

    point = 30, 30 + (i * 40)

    cv2.putText(img, 'PYTHON', point, fonts[i], 1, white_color, 2, cv2.LINE_AA)

 

cv2.imshow('polylines',img)

cv2.waitKey(0)

cv2.destroyAllWindows()


opencv_font



12345

+ Recent posts