이번에는 전에도 종종 기술되었던 ROI를 정리를 해보려고 한다.
Region Of Interest
이미지 내 관심 영역 지정
단어 약자에서도 볼 수 있듯이 이미지 내에서
사용자가 원하는 구간만 추출할 수 있는 기능 중 하나이다.
openCV에서 image를 load하는 경우 또는 video를 capture할때에
pixel 단위로 numpy array에 저장하기 때문에
우리는 이를 이용해서 특정 position에 접근하여서
crop과 같은 다양한 행위를 해준다고 생각하면 될 거 같다.
1. Real_Time_ROI
import cv2
#Check The Pressing Status Of Mouse
mouse_is_pressing = False
#Reset The Value
start_x, end_x, start_y, end_y = 0,0,0,0
#Check The Event Status
step = 0
temp = 0
#Swap The Position
def swap(v1, v2):
global temp
temp = v1
v1 = v2
v2 = temp
#Press The Left Button Of Mouse == Start Position Of ROI
#Release The Left Button Of Mouse == End Position Of ROI
#If Moving The Mouse And Draw Rectangle By ROI Region
def Mouse_Callback(event, x, y, flags, param):
global step, start_x, end_x, start_y, end_y, mouse_is_pressing
#Press The Left Button
if event == cv2.EVENT_LBUTTONDOWN:
step = 1
mouse_is_pressing = True
start_x = x
start_y = y
#Moving The Mouse
elif event == cv2.EVENT_MOUSEMOVE:
#If Pressing The Mouse
if mouse_is_pressing:
end_x = x
end_y = y
step = 2
#Release The Left Button
elif event == cv2.EVENT_LBUTTONUP:
mouse_is_pressing = False
end_x = x
end_y = y
step = 3
cap = cv2.VideoCapture(0)
if cap.isOpened() == False:
print("Cant Open The Camera")
exit(-1)
cv2.namedWindow("Color")
#cv2.setMouseCallback(windowName, onMouse, param = None)
#windowName = Dispose Of The Mouse Event in Window
#onMouse = Call Back Function
#param = Data of CallBack Function's Argument
cv2.setMouseCallback("Color", Mouse_Callback)
while True:
ret, img_color = cap.read()
if ret == False:
print("Cant Load The Camera")
break
#Press The Left Button
if step == 1:
cv2.circle(img_color , (start_x, start_y), 10, (0, 255, 0), -1)
#Moving The Mouse
elif step == 2:
cv2.rectangle(img_color, (start_x, start_y), (end_x, end_y), (0, 255, 0), 3)
#Release Of The Mouse
elif step == 3:
#If Start X Position Is Bigger Than End X
if start_x > end_x:
swap(start_x, end_x)
swap(start_y, end_y)
ROI = img_color[start_y : end_y, start_x : end_x]
ROI = cv2.cvtColor(ROI, cv2.COLOR_BGR2GRAY)
ROI = cv2.Canny(ROI, 150, 50)
ROI = cv2.cvtColor(ROI, cv2.COLOR_GRAY2BGR)
img_color[start_y : end_y, start_x : end_x] = ROI
cv2.imshow("Color", img_color)
key = cv2.waitKey(1)
if key == 27:
break
cap.release()
cv2.destroyAllWindows()
이 코드는 웹캠 영상에서 마우스를 이용하여서
ROI Region을 설정한 후에 해당 Region에만 Canny Edge 검출을 하는 코드이다.
2021/01/16 - [openCV] - [openCV] Graphic User Interface
Canny Edge에 대해서는 위 글에 설명이 되어있다.
코드가 전보다 길어졌지만 하나 하나 살펴보자
#Check The Pressing Status Of Mouse
mouse_is_pressing = False
#Reset The Value
start_x, end_x, start_y, end_y = 0,0,0,0
#Check The Event Status
step = 0
mouse_is_pressing은 mouse의 pressing status를 체크할 수 있는 변수이다.
start x, y / end x, y는 대충 봐도 알 수 있겠지만 Position들을 담을 변수이다.
step은 밑에 함수를 보면 이해가 갈텐데 현재 mouse의 status를 판단하여서
코드의 flow를 유동적으로 바꿔주는 역할을 한다.
#Press The Left Button
if event == cv2.EVENT_LBUTTONDOWN:
step = 1
mouse_is_pressing = True
start_x = x
start_y = y
이제 CallBack 함수의 일부분을 살펴볼건데
cv2.EVENT_LBUTTONDOWN = window에서 왼쪽 마우스 버튼이 눌릴 경우
만약 왼쪽 마우스가 눌린다면
step에 1을 대입하고
마우스가 눌렸으니 mouse_is_pressing을 True로 바꿔준다.
start x, y에는 클릭 시 (x, y) 좌표를 대입한다.
#Moving The Mouse
elif event == cv2.EVENT_MOUSEMOVE:
#If Pressing The Mouse
if mouse_is_pressing:
end_x = x
end_y = y
step = 2
cv2.EVENT_MOUSEMOVE = window에서 마우스가 움직일 경우
만약 마우스가 움직이면서, 마우스가 눌린 상태라면
end x,y에 현재 마우스 커서가 존재하는 좌표들을 넣어준다.
step에 2를 대입한다.
#Release The Left Button
elif event == cv2.EVENT_LBUTTONUP:
mouse_is_pressing = False
end_x = x
end_y = y
step = 3
cv2.EVENT_LBUTTON = window에서 왼쪽 마우스 버튼에서 Release 했을 경우
마우스에서 Release가 된 경우 mouse_is_pressing에 False를 대입해준다.
그 후 최종적으로 end x, y에 현재의 좌표를 대입한다.
#cv2.setMouseCallback(windowName, onMouse, param = None)
#windowName = Dispose Of The Mouse Event in Window
#onMouse = Call Back Function
#param = Data of CallBack Function's Argument
cv2.setMouseCallback("Color", Mouse_Callback)
cv2.setMouseCallback( windowName, onMouse(callBack Function), param )
setMouseCallBack 함수를 이용해서 미리 생성해둔 window에서
Mouse Event를 이용할 수 있도록 한다
cv2.setMouseCallback 함수의 Argument 중 param은
callBack Function에 parameter을 넘겨줄 떄 사용한다.
만약 param이 None status라면 아무런 parameter을 넘겨주지 않는다.
#Press The Left Button
if step == 1:
cv2.circle(img_color , (start_x, start_y), 10, (0, 255, 0), -1)
위에서 step이 1인 경우는 마우스의 왼쪽 버튼을 클릭하였을 때이므로
마우스가 클릭되었다는것을 시각적으로 표기하기 위해서
원을 그려줄 수 있도록 하였다.
#Moving The Mouse
elif step == 2:
cv2.rectangle(img_color, (start_x, start_y), (end_x, end_y), (0, 255, 0), 3)
step이 2인 경우는 마우스가 움직이는 상태이므로
ROI 영역을 사용자에게 표기하여 주기 위해서
rectangle 함수를 이용한다.
#Release Of The Mouse
elif step == 3:
#If Start X Position Is Bigger Than End X
if start_x > end_x:
swap(start_x, end_x)
swap(start_y, end_y)
ROI = img_color[start_y : end_y, start_x : end_x]
ROI = cv2.cvtColor(ROI, cv2.COLOR_BGR2GRAY)
ROI = cv2.Canny(ROI, 150, 50)
ROI = cv2.cvtColor(ROI, cv2.COLOR_GRAY2BGR)
img_color[start_y : end_y, start_x : end_x] = ROI
step이 3인 경우는 ROI 영역을 사용자가 지정하였다는 것이다.
여기서 예외처리를 하나 해줬다.
만약 시작 좌표가 마무리 좌표보다 큰 경우에는
swap 함수를 이용하여서 서로의 좌표를 바꿔주었다.
한마디로 드래그 방향이
위와 같지 않고
드래그의 방향이 위 그림과 같아지면
swap 함수가 실행이 되는것이다.
그 후 ROI 영역에 Canny edge를 적용해준다.
2. Operate_ROI_Average_Color
이번에는 ROI 영역에 평균 색을 추출하는 코드이다.
import cv2
import numpy as np
cap = cv2.VideoCapture(0)
while True:
ret, img_color = cap.read()
img_result = img_color.copy()
height, width = img_color.shape[:2]
center_x = int(width * 0.5)
center_y = int(height * 0.5)
cv2.rectangle(img_result, (center_x - 100, center_y - 100), (center_x + 100, center_y + 100), (0, 0, 255), 3)
img_roi = img_color[center_y - 100 : center_y + 100, center_x - 100 : center_x + 100]
m = cv2.mean(img_roi)
img_mean = np.zeros(img_roi.shape, dtype=np.uint8)
img_mean[:] = (m[0], m[1], m[2])
cv2.imshow('mean', img_mean)
cv2.imshow('color', img_result)
cv2.imshow("roi", img_roi)
key = cv2.waitKey(1)
if key == 27:
break
cap.release()
cv2.destroyAllWindows()
코드 자체는 그리 길지 않으나 처음 보는 메소드가 존재해서
하나씩 살펴보려고 한다.
height, width = img_color.shape[:2]
사진의 전체 높이와 너비 대입
center_x = int(width * 0.5)
center_y = int(height * 0.5)
Center Postion 구하기
img_roi = img_color[center_y - 100 : center_y + 100, center_x - 100 : center_x + 100]
ROI Region 지정
m = cv2.mean(img_roi)
cv2.mean(img, mask = mask)
cv2.mean()은 평균 color값을 찾을 때 사용하는 메소드이며
평균 intensity 값을 찾을 때 사용한다.
img_mean = np.zeros(img_roi.shape, dtype=np.uint8)
img_mean[:] = (m[0], m[1], m[2])
img_mean에 세로운 넘파이 배열을 만들어준다.
그리고 img_mean의 색상을 위해서 구했던 color의 average 값을
BGR에 대입을 해준다.
cv2.imshow('mean', img_mean)
cv2.imshow('color', img_result)
cv2.imshow("roi", img_roi)
각 결과 출력
흐어ㅓㅓㅓㅓ 요즘에 너무 힘들다
할 게 너무 많아졌다
오늘도 끄읕😑
'openCV' 카테고리의 다른 글
[openCV] Image Geometric Transformation (2) (0) | 2021.02.21 |
---|---|
[openCV] Image Geometric Transformation (1) (0) | 2021.02.20 |
[openCV] Draw Function (0) | 2021.02.06 |
[ openCV ] Image Operation ( Blending, Operate Image Bit, ROI ) (0) | 2021.02.02 |
[openCV] Binarization (0) | 2021.01.23 |