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
'실습 note' 카테고리의 다른 글
KBO 타자 OPS 예측 실습(데이콘 경진대회 1등 솔루션) (0) | 2021.02.20 |
---|---|
OpenCV_3(필터링) (0) | 2021.02.19 |
OpenCV_2(기본 영상처리) (0) | 2021.02.18 |
캐글 신용카드 사기 검출 실습( lightGBM,Smote 실습) (0) | 2021.01.27 |
앙상블 실습(랜덤포레스트,GBM,XGBoost,LightBoost) (0) | 2021.01.23 |