이미지의 특정 영역을 지정하는 것에 대해 ROI(Region Of Interest)라고 한다. OpenCV가 Python언어에 대해서는 관심영역을 지정하도록 지원하는 별도의 API는 없지만, NumPy의 slicing을 통해서 이와 관련된 작업을 할 수 있다. img라는 이미지의 관심 영역의 시작 좌표가 (x, y)이고 해당 영역의 폭이 w, 높이가 h라고 하면 관심 영역을 지정하는 코드는
ROI = img[y:y+h, x:x+w]
와 같이 작성할 수 있다. 이는 img의 y행에서 y+h행까지, x열에서 x+w열까지 slicing한 것을 의미한다.
1. 좌표 지정
import cv2
import numpy as np
img = cv2.imread('image.jpg')
x = 350; y = 125
w = 260; h = 260
roi = img[y:y+h, x:x+w]
cv2.rectangle(roi,(0,0), (h-1, w-1), (0,255,0),5)
cv2.imshow("IMAGE", img)
cv2.waitKey()
cv2.destroyAllWindows()
2. 마우스 이벤트
위와 같이 관심영역의 크기를 직접 지정해서 도출할 수도 있지만, 일일이 관심영역을 지정하는 것은 번거롭다. 이는 마우스 마우스 이벤트 처리를 통해 쉽게 정할 수 있다.
import cv2
import numpy as np
img = cv2.imread('image.jpg')
cv2.imshow('img', img)
drag = False # drag 상태
defalut_x, default_y, w, h = -1,-1,-1,-1 # 좌표
blue = (255,0,0)
def Mouse(event, x, y, flag, param):
global drag, default_x, default_y, img # global variance
if event == cv2.EVENT_LBUTTONDOWN: # 왼쪽 버튼 누름
drag = True
default_x = x
default_y = y
elif event == cv2.EVENT_MOUSEMOVE: # 마우스 이동
if drag:
draw = img.copy() # img 복제
cv2.rectangle(draw, (default_x, default_y), (x,y), blue, 3)
cv2.imshow("img", draw)
elif event == cv2.EVENT_LBUTTONUP: # 왼쪽 버튼 뗌
if drag:
drag = False
w = x - default_x
h = y - default_y
if w > 0 and h > 0:
draw = img.copy()
cv2.rectangle(draw, (default_x, default_y), (x,y), blue, 3)
cv2.imshow("img", draw)
roi = img[default_y:default_y+h, default_x:default_x+w]
cv2.imshow("drag", roi) # drag 한 창 생성
cv2.imwrite('drag.jpg', roi) # drag 내용 저장
else:
cv2.imshow('img',img)
cv2.setMouseCallback('img', Mouse)
cv2.waitKey()
cv2.destroyAllWindows()
Mouse 함수는 마우스 왼쪽 버튼이 클릭되고 우측 아래로 드래그를 할 때만 관심 영역을 지정하도록 작동한다. 왼쪽 버튼이 눌리면 drag를 시작하는 좌표가 default_x, default_y에 저장되고 drag 상태는 True로 바뀐다. 마우스가 이동해서 사각형을 그리기 전에 draw라는 변수에 새롭게 이미지를 복제한다. 복제하지 않고 기존 상태에서 그리면 마우스가 이동하는 위치에 따라 색이 덮이는 현상이 발생하게 된다. 마우스 이동을 마친 후, 버튼을 떼면 이동한 폭과 높이를 계산해서 드래그 한 이미지를 출력하고 저장한다.
3. cv2.selectROI()
cv2.selectROI()를 통해 위 코드를 더욱 간결하게 작성할 수 있다.
import cv2
import numpy as np
img = cv2.imread('image.jpg')
x,y,w,h = cv2.selectROI('image', img, False)
if w and h:
roi = img[y:y+h, x:x+w]
cv2.imshow('drag', roi)
cv2.imwrite('drag.jpg', roi)
cv2.imshow('image', img)
cv2.waitKey()
cv2.destroyAllWindows()
방향에 관계없이 드래그를 해서 관심 영역을 지정할 수 있다는 점에서 위 코드와 차이를 가지며, 작동하는 방식은 동일하다.
'데이터 분석 & 시각화 > OpenCV' 카테고리의 다른 글
[OpenCV Programming] 필터 처리 1 - 블러링 (0) | 2020.07.17 |
---|---|
[OpenCV Programming] 이미지 변환 2 (1) | 2020.07.15 |
[OpenCV Programming] 이벤트 처리 (0) | 2020.07.10 |
[OpenCV Programming] 이미지에 그림 그리기 (2) | 2020.07.08 |
[OpenCV Programming] Webcam (0) | 2020.07.06 |
최근댓글