728x90
  • 강의 수강하면서 실습한 내용을 업로드합니다.
  • 필기 내용은 코드와 함께 주석으로 입력했습니다.
  • 한 실습 당 여러 방법이 섞여 있어서 주석처리를 예의주시 필요
  • 실습 날짜: 2021-02-17, OpenCV 첫시작

영상 기본 조작 

import cv2
import sys

#특정 키를 가지고 창을 끌때

print('Hellow, opencv', cv2.__version__)

# img= cv2.imread('cat.bmp') #img: image를 뜻함
img = cv2.imread('cat.bmp', cv2.IMREAD_GRAYSCALE) #BGR이미지를 gray로 열고 싶을때는 cv2.IMREAD_GRAYSCALE 삽입하기

#예외처리
if img is None: #영상 파일 불러오지 못했을때 실행되는 코드,
    print('Image load failed!')
    sys.exit() 
cv2.imwrite('cat_gray.png', img) #컬러 이미지를 gray로 저장하기 

cv2.namedWindow('image') #창을 하나 생성해주는 함수, 창 이름을 image 지정 
                        #띄울 이미지가 크다면 이 함수를 적고 flags를 normal로 지정해서 창사이즈 변경가능하도록 설정
                        #이미지가 작으면 생략해도 cv2.imread가 알아서 창을 만들어준다(auto창, 사이즈 변경 불가)

cv2.imshow('image',img) #창에 영상을 보여주는 함수, 첫번째 인자는 띄울 창 이름, 두번째 인자는 띄울 이미지 , 그리고 키보드 입력 있을때 까지 대기

#특정 키를 눌렀을때 종료하도록 하는 코드, 아스킷을 이용
# while True:
#     if cv2.waitKey()==27: #esc키의 아스킷 숫자 27
#         break


#아스킷이 아닌 키보드알파벳을 이용할때
while True:
    if cv2.waitKey()==ord('q'): #특정 알파벳을 눌러서 종료하고 싶을때는 ord() 안에 해당 알파벳 넣기
        break

# key=cv2.waitKey(2000) #영상이 실제로 나올수 있게끔 하는 함수, 2000-> 2초
# print(key)

cv2.destroyAllWindows() #기존에 띄운 창을 모두 닫은 함수

 

여러 이미지로 슬라이드 쇼 생성하기

#슬라이드 쇼 만들기

import sys, os
import glob
import cv2

#문자열의 리스트 형태로 저장
img_files= glob.glob('.\\images\\*.jpg') #images안에 .jpg파일을 문자열로 모두 가져온다

for f in img_files:
    print(f) #.\images\autumn_forest_park_128379_1920x1080.jpg  형태

#전체창 만들기setWindowProperty(), window normal로 만들어야 전체화면이 가능하다
cv2.namedWindow('image',cv2.WINDOW_NORMAL) #WINDOW_NORMAL속성의 창을 생성 후
cv2.setWindowProperty('image', cv2.WND_PROP_FULLSCREEN,  #setWindowProperty를 통해 전체화면 속성으로 변경
                                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)==27: #ESC
        break

    # if cv2.waitKey(1000)==0: #키보드 아무 값을 쳐도 0보다는 큼 즉 아무키 눌렀을때 꺼진다
                              #아무것도 안누르면 -1을 리턴
    #     break

    idx +=1

    if idx>=cnt: 
        idx=0

cv2.destroyAllWindows()






 

Matplot으로 영상 load

import matplotlib.pyplot as plt
import cv2


# 컬러 영상 출력
imgBGR = cv2.imread('cat.bmp')

#matplotlib은 RGB순서를 기대하기 때문에 
#opencv BGR을 cvtColor통해서 RGB로 순서 변경 후 matplotlib에 적용 
imgRGB = cv2.cvtColor(imgBGR, cv2.COLOR_BGR2RGB)

plt.axis('off') #눈금 제거
plt.imshow(imgRGB)
plt.show()

# 그레이스케일 영상 출력
#2차원 형태로 되어 있다고 보면된다. 밝기 값만 있다
imgGray = cv2.imread('cat.bmp', cv2.IMREAD_GRAYSCALE)

plt.axis('off')
plt.imshow(imgGray, cmap='gray')
plt.show()

# 두 개의 영상을 함께 출력
plt.subplot(121), plt.axis('off'), plt.imshow(imgRGB) #컬러버전 
plt.subplot(122), plt.axis('off'), plt.imshow(imgGray, cmap='gray') #gray버전
plt.show()

 

영상불러오기 & 픽셀 값 변경 

import sys
import cv2


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

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

#영상의 크기를 참조하는 방법

#그레이스케일
h,w = img1.shape
print('w x h= {} x {}'.format(w,h)) 

#컬러-> 에러뜸  왜? (w,h) 크기의 3개 이미지를 두개 변수로 받을려고 했기 때문에
# h,w = img2.shape
# print('w x h= {} x {}'.format(w,h))

#해결방법-> (w,h,c) 에서 w,h만 가져오도록 [:2] 적용
h,w = img2.shape[:2] #그레이스케일에 사용해도 무방
print('w x h= {} x {}'.format(w,h))


#영상의 픽셀 값을 참조하는 방법
#영상의 (20,10)좌표의 픽셀 값을 알고 싶을때
x=20
y=10 
p1= img1[y,x]
print(p1) #grayscale 픽셀값이 238(밝은 편)

p2= img2[y,x]
print(p2) # [237 242 232] 블루,그린,레드 순

#이를 이용해서 특정 픽셀값에 내가 원하는 값을 대입 할수있다
'''
for y in range(h):  #각 픽셀을 for문으로 돌아다니면서 아래 조건으로 픽셀값을 바꾸는 코드-> 느림
    for x in range(w):
        img1[y,x]=0 #검정색
        img2[y,x]=(0,255,255) #노란색
'''
#위코드는 사용 지양(느림),아래코드 추천
img1[:, :] = 0
img2[:, :] = (0,255,255)

cv2.imshow('img1', img1)
cv2.imshow('img2', img2)
# cv2.waitKey()

cv2.destroyAllWindows()

 

부분영상 추출 & 복사

import numpy as np
import cv2

# 새 영상 생성하기
img1 = cv2.imread('HappyFish.jpg') #물고기 그림
img2=img1[50:160, 150:300]
img3=img1[50:160, 150:300].copy()

#(105,225) 좌표에, 반지름 20, 컬러는 (0,0,255), 두께2
                 #(x, y) 
#이미지를 짜른 순간 좌표는 짤려진 이미지 좌측 상단이 0,0으로 초기화                               
cv2.circle(img2, (50,50), 20, (0,0,255),2) 

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

 

마스크 연산 & ROI

import sys
import cv2

# 마스크 영상을 이용한 영상 합성
# src = cv2.imread('airplane.bmp', cv2.IMREAD_COLOR)
# mask = cv2.imread('mask_plane.bmp', cv2.IMREAD_GRAYSCALE)
src =cv2.imread('opencv-logo-white.png', cv2.IMREAD_UNCHANGED)

#알파와 BGR 구성
mask =src[:, :, -1] #투명한 알파 채널
src= src[:, :, 0:3] #BGR만 따로
dst = cv2.imread('field.bmp', cv2.IMREAD_COLOR)

h,w = src.shape[:2]
crob= dst[0:h,0:w] #직접 dst 사진의 좌표를 지정해서 위치를 알려줘야 한다

#CV2를 이용한 방법
# cv2.copyTo(src, mask,dst) #crob을 넣지않고 왼쪽 코드처럼 실행하면 로고와 dst 크기가 맞지 않아서 합성이 안됨
cv2.copyTo(src, mask,crob)

#numpy로 이용한 방법
# dst[mask>0] = src[mask>0] #마스크가 0이상인 부분에 True값이 반환 될것이고 그 반환된 
                            #그 자리 그대로 src자리에 대입되면, 비행기가 싹뚝 뽑혀서 dst의 True위치에 비행기를 넣는다   

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


그리기 함수

import numpy as np
import cv2

img = np.full((400, 400, 3), 255, np.uint8)

            #(가로,세로)(가로,세로)
cv2.line(img, (50, 50), (200, 50), (0, 0, 255), 5)
cv2.line(img, (50, 60), (150, 160), (0, 0, 128))

#직사각형은 두가지 방법으로 그릴수 있다

                #50,200 좌측상단 좌표, 150:가로, 100:세로
cv2.rectangle(img, (50,200,150,100), (0,0,225),2)

                #좌측상단좌표,우측하단좌표,color지정,두께
cv2.rectangle(img, (70,220),(180,280),(0,128,0),-1) #두께 음수는 내부를 채운다

#cv2.LINE_8로 원을 그리면 거친 느낌의 원을 만든다
#cv2.LINE_AA를 넣어주면 반듯한 원이 만들어진다 
#사각형은 cv2.LINE_AA 사용 안해도 되지만 원이나, 문자열 같은걸 이용할때는 애용하는게 좋다. 거친면이 사라진다                                               
cv2.circle(img, (300,100), 30,(255,255,0), -1, cv2.LINE_AA)
cv2.circle(img, (300,100),60,(255,0,0), 3, cv2.LINE_AA)

#다각형의 꼭지점을 넘파이 array로 만든다
pts = np.array([[250,200],[300,200],[350,300],[250,300]]) #이걸 넣을때 리스트 형태로 감싸서 넣어야한다

                        #True를 주면 시작점과 끝점을 이어준다(폐곡선)
cv2.polylines(img, [pts], True, (250,0,255),2)

#문자열 넣기
text= 'Hello? OpenCV'+cv2.__version__

                      #(x,y)인데 좌측하단 기준임
cv2.putText(img, text, (50,350), cv2.FONT_HERSHEY_SIMPLEX,0.8, #폰트설정
(0,0,255), 1, cv2.LINE_AA)

cv2.imshow("img", img)
cv2.waitKey()
cv2.destroyAllWindows()

 

카메라와 동영상 처리1

==================카메라 실습=========================
cap = cv2.VideoCapture()
# cap.open(0) #기본 카메라를 open하겠다는 의미
# cap = cv2.VideoCapture(0) #위와 같은 결과

# if not cap.isOpened(): #카메라 제대로 열렸는지 확인
#     print('camera open failed')
#     sys.exit()

# #카메라의 가로,세로를 가져오는 방법
# w= int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
# h= int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# print(w, h)

# # #카메라 크기를 변경하는 방법- 내 컴퓨터에는 지원 안되는듯
# # cap.set(cv2.CAP_PROP_FRAME_WIDTH),320)
# # cap.set(cv2.CAP_PROP_FRAME_HEIGHT),240)
# # print(w, h)


# #한 프레임씩 계속 받아오는 코드 생성
# while True:
#     #프레임을 받아오는 함수 는 cap.read()
#     #read()가 리턴하는 것이 두가지 : ret(불리언), image
#     #불리언의 True: 사진이 제대로 받은경우
#     #즉 read()는 불리언과 ndarray(이미지) 두가지를 준다
#     ret, frame = cap.read() #현재 열려 있는 카메라 디바이스에서 한 프레임씩 받아오는 작업을 한다

#     if not ret: #True가 아니면
#         break

#     #이 부분에는 가져온 정지 영상을 처리하는 코드를 작성 할수 있다
#     #윤곽선 추출
#     edge= cv2.Canny(frame,50,150)

#     cv2.imshow('edge',edge)
#     cv2.imshow('frame',frame) #'frame'의 창은 굳이 만들지 않아도 알아서 만든다(특이 경우는 예외)
#     if cv2.waitKey(20)==27: #20ms를 기다리고 꺼진다 하지만 여기에 ESC를 누르면 while문을 빠져나온다
#         break

# cap.release() #open했던 cap을 해체 시킨다
# cv2.destroyAllWindows()


# ======================동영상 실습==============================
import sys
import cv2


# 카메라 열기
cap = cv2.VideoCapture('video1.mp4')

if not cap.isOpened():
    print("video open failed!")
    sys.exit()

# 카메라 프레임 크기 출력
print('Frame width:', int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)))
print('Frame height:', int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))

# 카메라 프레임 처리
while True:
    ret, frame = cap.read()

    if not ret:
        break
    edge= cv2.Canny(frame,50,150)


    # inversed = ~frame  # 반전
    cv2.imshow('edge',edge)
    cv2.imshow('frame', frame)
    # cv2.imshow('inversed', inversed)

    if cv2.waitKey(20) == 27:
        break

cap.release()
cv2.destroyAllWindows()

 

카메라와 동영상 처리2

import sys
import cv2


cap = cv2.VideoCapture(0)

if not cap.isOpened():
    print("Camera open failed!")
    sys.exit()

w = round(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) #float형태로 나오기 때문에 정수로 만들기 위해서 
h = round(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fps = cap.get(cv2.CAP_PROP_FPS) 

#DIVX를 이용해서 정수값을 리턴해준다 fourcc : 압축 방식
fourcc = cv2.VideoWriter_fourcc(*'DIVX') # *'DIVX' == 'D', 'I', 'V', 'X'
delay = round(1000 / fps) #프레임간의 시간간격

out = cv2.VideoWriter('output.avi', fourcc, fps, (w, h)) #컬러영상 저장

if not out.isOpened():
    print('File open failed!')
    cap.release()
    sys.exit()

while True:
    ret, frame = cap.read()

    if not ret:
        break

    # inversed = ~frame
    edge= cv2.Canny(frame, 50,150) #edge는 그레이라서 컬러로 바꾼다음에 저장해야 19번 코드와 호환됨
    edge_color= cv2.cvtColor(edge, cv2.COLOR_GRAY2BGR)
    
    #out.write(frame) #소리는 x, 영상만 저장됨
    out.write(edge_color)

    cv2.imshow('frame', frame)
    cv2.imshow('edge', edge)
    cv2.imshow('edge_color', edge_color)
    # cv2.imshow('inversed', inversed)

    if cv2.waitKey(delay) == 27:
        break

cap.release()
out.release()
cv2.destroyAllWindows()

 

728x90

+ Recent posts