juuuding

[Computer Vision & Deep Learning] OpenCV - 그래픽 기능과 사용자 인터페이스 만들기 본문

인공지능/cs231n

[Computer Vision & Deep Learning] OpenCV - 그래픽 기능과 사용자 인터페이스 만들기

jiuuu 2023. 10. 31. 00:50

 저장되어 있는 이미지 파일에 도형을 그리고 글을 써서 표시해보겠다. openCV에서는 line, rectangle, polylines, circle, ellipse를 이용하여 순서대로 선, 직사각형, 다각형, 원, 타원을 그릴 수 있고, purText로 문자열을 작성할 수 있다. 

 

[영상에 도형 그리고 글 쓰기]

 우선 영상 파일을 읽어준 후 retangle을 이용하여 직사각형을 그려준다. 인수 값으로는 도형을 그릴 파일 객체, 도형 시작 위치, 끝 위치, BGR 값, 선의 두께를 입력해주면 된다. 그 다음 purText로 글을 작성해주는데, 마찬가지로 파일 객체, 글 작성 위치, 폰트, 글자 크기, BGR 값, 글자 두께를 차례대로 인수 값에 전달하면 된다. 

 

[Code]

'''
영상에 도형 그리고 글씨 쓰기
''' 

import cv2 as cv
import sys

img=cv.imread("resource/soccer.jpg")

if img is None:
    sys.exit("파일을 찾을 수 없습니다.")


cv.rectangle(img,(451,185),(620,378),(0,255,0),2)
cv.putText(img,"KangIn",(451,175),cv.FONT_HERSHEY_SIMPLEX,1,(255,255,255),2)

cv.imwrite("kangin_rectangle.jpg",img)

cv.imshow("Draw", img)

cv.waitKey()
cv.destroyAllWindows()

 

[마우스를 통한 상호작용]

 위의 코드는 rectangle에 지정해준 위치에 직사각형을 그리는 반면, 이번에는 마우스를 이용해 직사각형을 그릴 수 있게 해볼 것이다. 우선 마우스를 다루기 위해서는 콜백 함수라는 프로그래밍 방식을 이용해야한다. 보통 프로그램은 코드가 작성된 순서대로 실행되지만, 마우스를 다루는 프로그램에서는 클릭이나 커서 이동과 같은 이벤트가 언제 발생할지 알 수 없기 때문이다. 우선 Drawing 이라는 이름을 가진 파일을 윈도우에 띄워준 후, setMouseCallback 함수를 이용하여 콜백 함수를 호출한다. 아래의 코드는 EVENT_LBUTTONDOWN을 이용하여 마우스 왼쪽 버튼을 눌렀을 때 초록색 (200,200) 사이즈의 사각형이 그려지도록 설정하고, EVENT_RBUTTONDOWN을 이용하여 마우스 오른쪽 버튼을 눌렀을 때 파란색 (100,100) 사이즈의 사각형이 그려지도록 설정했다. 

 draw 함수의 매개 변수에서 event는 발생한 이벤트의 종류, x와 y는 이벤트가 일어난 순간의 커서 위치를 나타낸다. 여기서 사용하진 않았지만 flags는 마우스 이벤트가 발생할 때의 특정 조건을 말한다. 예를 들면 ctrl, shift, alt 등의 키 조합을 생성하는 조건이라고 할 수 있다. param은 이미지, 특정 변수와 같이 파라미터로 전송될 값을 말한다.

 

※ EVENT

 - EVENT_MOUSEMOVE : 마우스 움직였을 때

 - EVENT_LBUTTONDOWN : 마우스 왼쪽 버튼을 눌렀을 때

 - EVENT_RBUTTONDOWN : 마우스 오른쪽 버튼을 눌렀을 때

 - EVENT_MBUTTONDOWN : 마우스 가운데 버튼을 눌렀을 때

 - EVENT_LBUTTONUP : 마우스 왼쪽 버튼을 올렸을 때

 - EVENT_RBUTTONUP : 마우스 오른쪽 버튼을 올렸을 때

 - EVENT_MBUTTONUP : 마우스 가운데 버튼을 올렸을 때

 - EVENT_LBUTTONDBCLICK : 마우스 왼쪽 버튼을 두 번 눌렀을 때

 - EVENT_RBUTTONDBCLICK : 마우스 오른쪽 버튼을 두 번 눌렀을 때

 - EVENT_MBUTTONDBCLICK : 마우스 가운데 버튼을 두 번 눌렀을 때

 - EVENT_MOUSEWHEEL : 마우스 상하 스크롤 사용할 때

 - EVENT_MOUSEHWHEEL : 마우스 좌우 스크롤 사용할 때

 

※ FLAGS

 - EVENT_FLAG_LBUTTON : 마우스 왼쪽 버튼이 눌러져 있음

 - EVENT_FLAG_MBUTTON : 마우스 가운데 버튼이 눌러져 있음

 - EVENT_FLAG_RBUTTON : 마우스 오른쪽 버튼이 눌러져 있음

 - EVENT_FLAG_CTRLKEY : 컨트롤 키가 눌러져 있음

 - EVENT_FLAG_SHIFTKEY : 쉬프트 키가 눌러져 있음

 - EVENT_FLAG_ALTKEY : 알트 키가 눌러져 있음

 - flags > 0 : 마우스 스크롤 이벤트의 윗 방향 또는 오른쪽 방향

 - flags < 0 : 마우스 스크롤 이벤트의 아랫 방향 또는 왼쪽 방향

 

[Code]

'''
마우스를 통한 상호작용
''' 

import cv2 as cv
import sys

img=cv.imread("resource/son.jpg")

if img is None:
    sys.exit("파일을 찾을 수 없습니다.")


def draw(event,x,y,flags,param):
    if event==cv.EVENT_LBUTTONDOWN:
        cv.rectangle(img,(x,y),(x+200,y+200),(0,255,0),2)
    elif event==cv.EVENT_RBUTTONDOWN:
        cv.rectangle(img,(x,y),(x+100,y+100),(255,0,0),2)

    cv.imshow("Drawing",img)

cv.namedWindow("Drawing")
cv.imshow("Drawing",img)

cv.setMouseCallback("Drawing", draw)

while(True):
    if cv.waitKey(1)==ord('q'):
        cv.destroyAllWindows()
        break

 

[마우스 드래그로 도형 크기 조절하기]

 위의 코드에서는 사각형 크기가 정해져있다. 사각형 크기를 마음대로 조절하려면 마우스 클릭과 드래그를 함께 이용하면 된다. 마우스를 누르는 위치를 사각형의 시작 위치로 지정하고, 마우스를 떼는 위치를 사각형의 오른쪽 아래 부분으로 지정하면 원하는 크기대로 사각형을 만들 수 있다. 여기서 주의해야할 점은 버튼을 클릭한 순간의 좌표 값 ix, iy를 전역 변수로 설정해야한다는 것인데, 그렇게 하지 않으면 드래그하는 동안 발생하는 여러 번의 함수 호출에서 좌표가 생성과 소멸을 반복하므로 원래의 좌표 값을 유지하지 못하게 된다.

 

[Code]

import cv2 as cv
import sys 

img=cv.imread("resource/son.jpg")

if img is None:
    sys.exit("파일을 찾을 수 없습니다.")

def draw(event,x,y,flags,param):
    global ix,iy
    if event == cv.EVENT_LBUTTONDOWN:
        ix,iy=x,y
    elif event == cv.EVENT_LBUTTONUP:
        cv.rectangle(img,(ix,iy),(x,y),(0,255,0),2)

    cv.imshow("Drawing",img)

cv.imshow("Drawing",img)
cv.setMouseCallback("Drawing",draw)

while(True):
    if cv.waitKey(1)==ord('q'):
        cv.destroyAllWindows()
        break