import cv2
img = cv2.imread('snowman.png')
canny = cv2.Canny(img, 150, 200)
# (대상 이미지, minVal, maxVal)
cv2.imshow('img', img)
cv2.imshow('canny', canny)
cv2.waitKey(0)
cv2.destroyAllWindows()
minVal은 하위 임계값, maxVal은 상위 임계값이다. 변화(기울기)가 상위 임계값보다 크면 경계선으로 인식한다.
Trackbar 적용
import cv2
def empty(pos):
pass
img = cv2.imread('snowman.png')
name = "Trackbar"
cv2.namedWindow(name)
cv2.createTrackbar('threshold1', name, 0, 255, empty) # minVal
cv2.createTrackbar('threshold2', name, 0, 255, empty) # maxVal
while True:
threshold1 = cv2.getTrackbarPos('threshold1', name)
threshold2 = cv2.getTrackbarPos('threshold2', name)
canny = cv2.Canny(img, threshold1, threshold2)
# (대상 이미지, minVal, maxVal)
cv2.imshow('img', img)
cv2.imshow(name, canny)
if cv2.waitKey(1) == ord('q'):
break
cv2.destroyAllWindows()
import cv2
img = cv2.imread('card.png')
target_img = img.copy() # 사본 이미지
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, otsu = cv2.threshold(gray, -1, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
contours, hierarchy = cv2.findContours(otsu, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE) # 윤곽선 검출
# (이미지, 윤곽선 찾는 모드, 윤곽선 찾을 때 사용하는 근사치 방법)
COLOR = (0, 200, 0)
cv2.drawContours(target_img, contours, -1, COLOR, 2) # 윤곽선 그리기
# (대상 이미지, 윤곽선 정보, 인덱스 (-1이면 전체), 색깔, 두께)
cv2.imshow('img', img)
cv2.imshow('gray', gray)
cv2.imshow('otsu', otsu)
cv2.imshow('contour', target_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
윤곽선을 검출할 때는 먼저 binary 처리를 해줘야 한다
cv2.findContour는 2개의 정보(윤곽선 정보, 윤곽선 계층 구조)를 반환한다.
cv2.drawContours는 대상 이미지에 그리기 때문에 원본 이미지에 그리면 안된다. 따라서 사본을 준비해두는 것이 좋다.
- cv2.RETR_EXTERNAL : 가장 외곽의 윤곽선만 찾음
- cv2.RETR_LIST : 모든 윤곽선 찾음 (계층 정보 없음)
- cv2.RETR_TREE : 모든 윤곽선 찾음 (계층 정보를 트리 구조로 생성)
import cv2
img = cv2.imread('card.png')
target_img1 = img.copy()
target_img2 = img.copy()
target_img3 = img.copy()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, otsu = cv2.threshold(gray, -1, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
contours1, hierarchy1 = cv2.findContours(otsu, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
contours2, hierarchy2 = cv2.findContours(otsu, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
contours3, hierarchy3 = cv2.findContours(otsu, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
COLOR = (0, 200, 0)
cv2.drawContours(target_img1, contours1, -1, COLOR, 2)
cv2.drawContours(target_img2, contours2, -1, COLOR, 2)
cv2.drawContours(target_img3, contours3, -1, COLOR, 2)
cv2.imshow('img', img)
cv2.imshow('RETR_LIST', target_img1)
cv2.imshow('RETR_EXTERNAL', target_img2)
cv2.imshow('RETR_TREE', target_img3)
cv2.waitKey(0)
cv2.destroyAllWindows()
- CHAIN_APPROX_NONE : 윤곽선의 모든 좌표 반환
- CHAIN_APPROX_SIMPLE : 윤곽선의 꼭짓점 좌표만 중복을 제거하고 반환
윤곽선의 경계면을 둘러싸는 사각형
boundingRect()
import cv2
img = cv2.imread('card.png')
target_img = img.copy()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, otsu = cv2.threshold(gray, -1, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
contours, hierarchy = cv2.findContours(otsu, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
COLOR = (0, 200, 0)
for cnt in contours:
x, y, width, height = cv2.boundingRect(cnt)
cv2.rectangle(target_img, (x, y), (x + width, y + height), COLOR, 2) # 사각형 그림
cv2.imshow('img', img)
cv2.imshow('gray', gray)
cv2.imshow('otsu', otsu)
cv2.imshow('contour', target_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
boundingRect()를 사용하면 윤곽선을 둘러싸고 있는 사각형 정보를 반환한다.
contourArea() 어떤 이미지 내에서 특정 크기를 초과하는 윤곽선을 구하고 싶을 때 사용할 수 있다.
import cv2
img = cv2.imread('card.png')
target_img = img.copy()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, otsu = cv2.threshold(gray, -1, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
contours, hierarchy = cv2.findContours(otsu, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
COLOR = (0, 200, 0)
for cnt in contours:
if cv2.contourArea(cnt) > 25000: # 면적이 25000 이상인 윤곽선만 그림
x, y, width, height = cv2.boundingRect(cnt)
cv2.rectangle(target_img, (x, y), (x + width, y + height), COLOR, 2)
cv2.imshow('img', img)
cv2.imshow('contour', target_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
import cv2
img = cv2.imread('card.png')
target_img = img.copy()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, otsu = cv2.threshold(gray, -1, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
contours, hierarchy = cv2.findContours(otsu, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
COLOR = (0, 200, 0)
idx = 1
for cnt in contours:
if cv2.contourArea(cnt) > 25000:
x, y, width, height = cv2.boundingRect(cnt)
cv2.rectangle(target_img, (x, y), (x + width, y + height), COLOR, 2)
crop = img[y:y+height, x:x+width]
cv2.imshow(f'car_crop_{idx}', crop)
cv2.imwrite(f'card_crop_{idx}.png', crop) # 파일 저장
idx += 1
cv2.imshow('img', img)
cv2.imshow('contour', target_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
- 회전 : 시계 반대방향으로 90도
- 재생속도 (FPS) : 원본 x 4배
- 출력 파일명 : city_output.avi (코덱 : DIVX)
import cv2
cap = cv2.VideoCapture('city.mp4')
fourcc = cv2.VideoWriter_fourcc(*'DIVX')
width = round(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
height = round(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
fps = cap.get(cv2.CAP_PROP_FPS)
out = cv2.VideoWriter('city_output.avi', fourcc, fps * 4, (width, height))
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
rotate_270 = cv2.rotate(frame, cv2.ROTATE_90_COUNTERCLOCKWISE)
out.write(rotate_270)
cv2.imshow('video', rotate_270)
if cv2.waitKey(1) == ord('q'):
break
out.release()
cap.release()
cv2.destroyAllWindows()
- Face Detection : 얼굴은 인식하는 데 누구인지 알 필요 없을 때
- Face Recognition : 얼굴을 인식해서 누구인지까지 알아야 할 때
import cv2
import mediapipe as mp
mp_face_detection = mp.solutions.face_detection
mp_drawing = mp.solutions.drawing_utils
cap = cv2.VideoCapture('face_video.mp4')
with mp_face_detection.FaceDetection(
model_selection=0, min_detection_confidence=0.5) as face_detection:
while cap.isOpened():
success, image = cap.read()
if not success:
break
# To improve performance, optionally mark the image as not writeable to
# pass by reference.
image.flags.writeable = False
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
results = face_detection.process(image)
# Draw the face detection annotations on the image.
image.flags.writeable = True
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
if results.detections:
for detection in results.detections:
mp_drawing.draw_detection(image, detection)
cv2.imshow('MediaPipe Face Detection', cv2.resize(image, None, fx=0.5, fy=0.5))
if cv2.waitKey(1) == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
코드는 MediaPipe의 Face Detection의 예제 코드를 가져와서 일부를 수정한 것이다.
실행하면 얼굴을 인식하여 동영상에 점이 찍히는 것을 확인할 수 있다.