728x90
1. 영상(Image)
- 픽셀이 바둑판 모양의 격자로 나열되어 있는 형태(2차원 행렬)
- 픽셀: 이미지를 구성하는 가장 작은 단위
import cv2
print('현재 OpenCV 버전: ', cv2.__version__)
2. 그레이스케일 영상
- 흑백 사진처럼 색상 정보가 없는 영상
- 밝기 정보만으로 구성된 영상
- 밝기 정보는 256단계로 표현(0~255)
- 1픽셀은 8bits에 저장 = 1byte
- 가로크기 * 세로크기 = 이미지 용량
- 예) 28 * 28 = 784 bytes
img = cv2.imread('./dog.bmp', cv2.IMREAD_GRAYSCALE)
print(img)
cv2.imshow('img', img) # 창이름: 'img'
cv2.waitKey()
import cv2
import matplotlib.pyplot as plt
# cv2를 통해 그레이스케일로 불러온 후 matplotlib으로 그레이스케일 영상 출력
img = cv2.imread('./dog.bmp', cv2.IMREAD_GRAYSCALE)
plt.axis('off') # x축 y축을 숨김
plt.imshow(img, cmap='gray') # colormap을 흑백으로 설정
plt.show()
3. 트루컬러 영상
- 컬러 사진처럼 색상 정보를 가지고 있기 때문에 다양한 색상을 표현할 수 있는 영상
- red, green, blue 색 성분을 사용하고 각 256단계로 표현
- 픽셀의 표현 -> (255, 255, 255) 튜플 형태로 표현
- 1픽셀은 3bytes
- 가로크기 * 세로크기 * 3 = 이미지 용량
- 28 * 28 * 3 = 2352 bytes
img = cv2.imread('./dog.bmp') # cv2.IMREAD_COLOR 가 생략됨
print(img)
cv2.imshow('img', img)
cv2.waitKey()
✔️cv2를 통해 컬러로 불러온 후 matplotlib으로 컬러영상 출력
# OpenCV: BGR, matplotlib: RGB 때문에 색이 반전되어 출력됨
img = cv2.imread('./dog.bmp')
plt.axis('off')
plt.imshow(img)
plt.show() # 비정상적으로 출력됨
✔️cv2를 통해 컬러로 불러온 후 matplotlib으로 컬러영상 출력
img = cv2.imread('./dog.bmp')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # BGR -> RGB
plt.axis('off')
plt.imshow(img)
plt.show() # 정상적으로 출력됨
💡문제
subplot을 이용하여 왼쪽에는 그레이스케일 영상, 오른쪽에는 컬러영상을 출력하라
img_gray = cv2.imread('./dog.bmp', cv2.IMREAD_GRAYSCALE)
img_color = cv2.imread('./dog.bmp')
img_color = cv2.cvtColor(img_color, cv2.COLOR_BGR2RGB)
plt.subplot(121) # 1행 2열 첫 번째 subplot
plt.axis('off')
plt.imshow(img_gray, cmap='gray')
plt.subplot(122) # 1행 2열 두 번째 subplot
plt.axis('off')
plt.imshow(img_color)
plt.show()
4. 영상 파일 형식
- BMP
- 픽셀 데이터를 압축하지 않고 저장
- 용량이 매우 큼(픽셀의 일반적인 크기)
- 파일 구조가 단순해서 별도의 라이브러리 없이 프로그래밍이 가능
- JPG(JPEG)
- 압축률이 좋아서 파일 용량이 크게 감소
- 사진과 같은 컬러영상을 저장
- 손실 압축
- GIF
- 움직이는 영상 지원
- 256색 이하의 영상을 저장
- 무손실 압축
- PNG
- 웹 이미지용으로 권장
- 무손실, 손실 압축
- 알파 채널(투명도)을 지원
- (255, 255, 255, 1)
✔️영상 정보 알아보기
import cv2
img_gray = cv2.imread('./dog.bmp', cv2.IMREAD_GRAYSCALE)
print('img_gray type: ', type(img_gray))
print('img_gray shape: ', img_gray.shape) # (세로, 가로)
print('img_gray dtype: ', img_gray.dtype) # uint8: 0~255
img_color = cv2.imread('./dog.bmp')
print('img_color type: ', type(img_color))
print('img_color shape: ', img_color.shape) #(세로, 가로, 컬러)
print('img_color dtype: ', img_color.dtype)
💡문제1
img_color가 그레이스케일 영상인지, 컬러영상인지 구분하라
if len(img_color.shape) == 3:
print('컬러')
elif len(img_color.shape) == 2:
print('그레이스케일')
- 컬러 이미지의 경우, 'shape' 속성은 '(height, width, channels)' 형태의 튜플을 반환한다.
- 그레이스케일 이미지의 경우, '(height, width)' 형태의 튜플을 반환한다.
💡문제2
img_color에 특정 색 정보로 영상을 변경하라
# 방법1
for x in range(h):
for y in range(w):
img_color[x, y] = (255, 102, 255)
cv2.imshow('img_color', img_color)
cv2.waitKey()
# 방법2
img_color[:,:] = (255, 102, 255) # 이미지 배열의 모든 행과 모든 열
cv2.imshow('img_color', img_color)
cv2.waitKey()
✔️numpy를 사용하여 네 개의 이미지를 생성
import cv2
import numpy as np
img1 = np.zeros((240, 320), dtype=np.uint8) # 모든 값이 0인 배열 -> 검정색
img2 = np.empty((240, 320), dtype=np.uint8) # 메모리 공간만 할당하고 값을 초기화하지 않음 -> 임의의 값 포함
img3 = np.ones((240, 320), dtype=np.uint8) * 150 # 모든 값이 1인 배열 * 150 -> 회색
img4 = np.full((240, 320, 3), (155, 102, 255), dtype=np.uint8) # 주어진 값으로 배열을 채움
cv2.imshow('img1', img1)
cv2.imshow('img2', img2)
cv2.imshow('img3', img3)
cv2.imshow('img4', img4)
cv2.waitKey()
✔️copy() 함수 알아보기
import cv2
img = cv2.imread('./dog.bmp')
img_test = img.copy() # 원본 이미지를 수정하지 않고 변형할 수 있음
img_test[90:210, 120:240] = (255, 102, 255)
cv2.imshow('img', img)
cv2.imshow('img_test', img_test)
cv2.waitKey()
import cv2
img = cv2.imread('./dog.bmp')
img_test = img # 둘 다 'img'를 가리킴 -> img_test에 대한 모든 수정은 img에도 영향을 미침
img_test[90:210, 120:240] = (255, 102, 255)
cv2.imshow('img', img)
cv2.imshow('img_test', img_test)
cv2.waitKey()
✔️ 도형 그리기
import cv2
import numpy as np
img = np.full((500, 500, 3), 255, np.uint8) # 500x500 크기의 흰색(255) 3채널 이미지
cv2.line(img, (70, 70), (400, 70), (0, 0, 255), 5) # (70, 70)에서 (400, 70)까지 빨간색(0, 0, 255)의 두께 5인 선
cv2.rectangle(img, (50, 200, 150, 100), (0, 255, 0), 3) # (50, 200)에서 (150, 100) 크기의 녹색 (0, 255, 0) 직사각형
cv2.rectangle(img, (50, 350, 150, 100), (0, 255, 0), -1) # 두께가 -1로 설정되어 있어 직사각형 내부가 완전히 채워짐
cv2.circle(img, (300, 250), 50, (255, 0, 0), 4) # 중심이 (300, 250)인 반지름 50의 파란색(255, 0, 0) 원
# (300, 400) 위치에 검정색(0, 0, 0) 텍스트, 0.7크기
cv2.putText(img, 'Hello OpenCV', (300, 400), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 0))
cv2.imshow('img', img)
cv2.waitKey()
5. OpenCV-Python 모듈
- opencv
- 컴퓨터 비전과 이미지 처리를 위한 오픈소스 라이브러리
- 1999년 인텔에서 영상처리 기술을 개발하기 위한 목적으로 만듦
- 2000년 BSD 라이선스로 배포
- 2011년 이후 opencv2로 개발 시작
- opencv 설치
- pip install opencv-python
- 모듈 불러오기
- import cv2
6. 동영상 다루기
- 카메라 영상 불러오기
- cv2.VideoCapture(0)
- 동영상 불러오기
- cv2.VideoCapture('파일경로')
- 동영상 출력하기
- FourCC(Four Character Code)
- 4바이트로 된 문자열이며 데이터 형식을 구분하는 고유 글자
- 주로 AVI 파일의 영상 코덱을 구분할 때 사용(DIVX, XVID, MP4V...)
- 예) cv2.VideoWriter.fourcc(*'DIVX') cv2.VideoWriter(파일명, FourCC객체, fps, (가로, 세로))
✔️ 카메라 영상 불러오기
import cv2
import sys
cap = cv2.VideoCapture(0) # 기본 카메라 장치를 열어 cap 객체로 캡처
if not cap.isOpened(): # 카메라가 열리지 않은 경우
print('카메라를 열 수 없음')
sys.exit()
print('카메라 연결 성공') # 카메라가 열린 경우
print('가로 사이즈: ', int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)))
print('세로 사이즈: ', int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
print('FPS: ', cap.get(cv2.CAP_PROP_FPS)) # FPS(Frame Per Second)
# ret: 영상을 읽었는지 여부(True, False)
# frame: 읽어온 영상
while True:
ret, frame = cap.read() # 카메라로부터 frame을 읽어옴
if not ret:
break
cv2.imshow('frame', frame)
if cv2.waitKey(10) == 27: # ESC 키 누르면 프로그램 종료
break
cap.release() # 카메라 장치 해제
✔️ 동영상 불러오기
import cv2
import sys
cap = cv2.VideoCapture('./sea.mp4') # 파일을 불러와 cap 객체에 저장
if not cap.isOpened():
print('동영상을 불러올 수 없음')
sys.exit()
print('동영상 연결 성공')
print('가로 사이즈: ', int(cap.get(cv2.CAP_PROP_FRAME_WIdth)))
print('세로 사이즈: ', int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
print('FPS: ', cap.get(cv2.CAP_PROP_FPS))
print('프레임수: ', int(cap.get(cv2.CAP_PROP_FRAME_COUNT))) # 초당 프레임 수
while True:
ret, frame = cap.read()
if not ret:
break
cv2.imshow('frame', frame) # 읽어온 프레임을 화면에 표시
if cv2.waitKey(10) == 27:
break
cap.release()
✔️ 실시간 동영상 캡처, 출력하기
import cv2
cap = cv2.VideoCapture(0) # 기본 웹캠을 열어 객체에 저장
w = round(cap.get(cv2.CAP_PROP_FRAME_WIDTH) # 캡처한 영상의 가로 크기
h = round(cap.get(cv2.CAP_PROP_FRAME_HEIGHT) # 세로 크기
fps = cap.get(cv2.CAP_PROP_FPS)
fourcc = cv2.VideoWriter.fourcc(*'DIVX') # 'DIVX' 코덱을 사용하여 영상을 인코딩
out = cv2.VideoWriter('output.avi', fourcc, fps, (w, h)) # 영상을 파일로 저장
while True:
ret, frame = cap.read()
if not ret: # ret: 프레임을 제대로 읽었는지를 나타내는 불리언 값
break
out.write(frame) # 캡처한 프레임을 파일(output.avi)에 저장
cv2.imshow('frame', frame) # 캡처한 프레임을 화면에 실시간으로 표시
if cv2.waitKey(10) == 27:
break
cap.release()
out.release() # VideoWriter 객체를 해제하여 파일을 닫음
✔️ 두 개의 동영상 합쳐서 출력하기
import cv2
import sys
cap1 = cv2.VideoCapture('./sea1.mp4') # 동영상 파일 불러오기
cap2 = cv2.VideoCapture('./sea2.mp4')
w = round(cap1.get(cv2.CAP_PROP_FRAME_WIDTH)) # 가로
h = round(cap1.get(cv2.CAP_PROP_FRAME_HEIGHT)) # 세로
frame_cnt1 = round(cap1.get(cv2.CAP_PROP_FRAME_COUNT)) # cap1의 프레임수
frame_cnt2 = round(cap2.get(cv2.CAP_PROP_FRAME_COUNT)) # cap2의 프레임수
fps1 = cap1.get(cv2.CAP_PROP_FPS)
fps2 = cap2.get(cv2.CAP_PROP_FPS)
fourcc = cv2.VideoWriter.fourcc(*'DIVX')
out = cv2.VideoWriter('mix.avi', fourcc, fps1, (w, h)) # 합쳐진 영상을 'mix.avi'파일로 저장
for i in range(frame_cnt1): # 첫 번째 동영상 재생
ret, frame = cap1.read()
cv2.imshow('output', frame)
out.write(frame)
if cv2.waitKey(10) == 27:
break
for i in range(frame_cnt2): # 두 번째 동영상 재생
ret, frame = cap2.read()
cv2.imshow('output', frame)
out.write(frame)
if cv2.waitKey(10) == 27:
break
cap1.release()
cap2.release()
out.release()
728x90
'딥러닝' 카테고리의 다른 글
[딥러닝] 평활화, 정규화, YCrCb, HSV, CLAHE, inRange(), copyTo() (0) | 2024.08.20 |
---|---|
[딥러닝] 키이벤트, 마우스이벤트, 화소처리, 히스토그램 (2) | 2024.08.19 |
9. 전이 학습 (0) | 2024.07.31 |
8. CNN 모델 (0) | 2024.07.31 |
7. CNN (0) | 2024.07.30 |