✍️ 작성 목적: OpenCV 마우스 이벤트를 활용해 직사각형 그리기, 텍스트 쓰기, 붓으로 그리기 등의 실습을 정리했습니다. 단순히 코드 실행이 아닌 코드의 흐름과 원리, 그리고 제가 느낀 부족했던 점과 개선 방향까지 담았습니다.
📌 학습 내용 요약
- OpenCV로 이미지 불러오기
- 마우스 클릭 이벤트 감지
- 마우스 위치에 도형 및 글씨 그리기
- 드래그로 사각형 그리기
- 좌클릭/우클릭에 따라 색상 변경하기
📁 예제 1 – [2-6] 이미지에 도형과 글씨 그리기
🔧 사용 기능:
- cv.rectangle(): 사각형 그리기
- cv.putText(): 글씨 쓰기
💡 코드:
import cv2 as cv
import sys
img = cv.imread('girl_laughing.jpg') # 이미지 불러오기
if img is None:
sys.exit('파일을 찾을 수 없습니다.')
# 직사각형 그리기 (좌측 상단 830,30 ~ 우측 하단 1000,200), 빨간색
cv.rectangle(img, (830, 30), (1000, 200), (0, 0, 255), 2)
# 텍스트 추가 (위치: 830,24), 파란색
cv.putText(img, 'laugh', (830, 24), cv.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2)
cv.imshow('Draw', img)
cv.waitKey()
cv.destroyAllWindows()
🧠 배운 점:
- 단순한 이미지 출력만 하는 게 아니라, 그 위에 원하는 위치에 그림과 글씨를 그릴 수 있음
- 텍스트와 도형이 겹치지 않게 위치 조절이 중요함
📁 예제 2 – [2-7] 마우스로 클릭한 곳에 사각형 그리기
import cv2 as cv
import sys
img = cv.imread('girl_laughing.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, 0, 255), 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
🧠 배운 점:
- 마우스 버튼 종류에 따라 동작을 달리하는 이벤트 처리
- 직사각형 크기 조절도 가능함
📁 예제 3 – [2-8] 드래그로 사각형 그리기
import cv2 as cv
import sys
img = cv.imread('girl_laughing.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, 0, 255), 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
🧠 배운 점:
- 마우스 눌렀을 때 시작 좌표, 뗐을 때 끝 좌표로 사각형 생성
- 마치 그림판처럼 드래그로 영역 지정 가능
📁 예제 4 – [2-9] 좌클릭은 파란 붓, 우클릭은 빨간 붓
import cv2 as cv
import sys
img = cv.imread('soccer.jpg')
if img is None:
sys.exit('파일을 찾을 수 없습니다.')
BrushSiz = 5
LColor, RColor = (255, 0, 0), (0, 0, 255) # 파란색, 빨간색
def painting(event, x, y, flags, param):
if event == cv.EVENT_LBUTTONDOWN:
cv.circle(img, (x, y), BrushSiz, LColor, -1)
elif event == cv.EVENT_RBUTTONDOWN:
cv.circle(img, (x, y), BrushSiz, RColor, -1)
elif event == cv.EVENT_MOUSEMOVE and flags == cv.EVENT_FLAG_LBUTTON:
cv.circle(img, (x, y), BrushSiz, LColor, -1)
elif event == cv.EVENT_MOUSEMOVE and flags == cv.EVENT_FLAG_RBUTTON:
cv.circle(img, (x, y), BrushSiz, RColor, -1)
cv.imshow('Painting', img)
cv.namedWindow('Painting')
cv.imshow('Painting', img)
cv.setMouseCallback('Painting', painting)
while True:
if cv.waitKey(1) == ord('q'):
cv.destroyAllWindows()
break
🧠 배운 점:
- 마우스를 움직이면서 색칠하는 기능까지 가능
- 클릭 여부와 움직임을 동시에 판단해야 함 (flags 사용)
😓 부족했던 점
- 처음엔 setMouseCallback()의 사용법이 어려웠습니다.
- 마우스 이벤트 종류가 많아 혼동이 있었고, 좌표 설정도 헷갈렸습니다.
🔧 개선할 부분
- 사각형 그릴 때, 실시간으로 미리보기 형태로 보이게 구현하고 싶었습니다.
- 브러시 색상이나 크기를 키보드로 바꿀 수 있도록 확장해보면 실전 그림판과 가까워질 것 같습니다.
- 코드 재사용성을 높이기 위해 콜백 함수 안에 너무 많은 동작을 넣지 않고, 함수 분리도 고민하고 있습니다.
✅ 마무리 정리
오늘 배운 OpenCV 마우스 이벤트 실습은 단순한 이미지 출력에서 벗어나, 인터랙티브한 프로그램을 만드는 데 필수적인 기능이었습니다.
마우스 클릭 → 도형 → 색칠 → 글씨까지 직접 반응하는 프로그램을 만든다는 재미가 컸고,
무엇보다 사용자 이벤트 처리에 대한 감각을 익히는 데 큰 도움이 되었습니다.
'이미지와 영상처리' 카테고리의 다른 글
| 📚 OpenCV 실습: 이미지 자르기, 사각형 표시, 다양한 확대 방법 비교 (2025-04-28) (0) | 2025.04.29 |
|---|---|
| 🎓 FastText 활용 영화 리뷰 감성 분석 (2024-04-16) (0) | 2025.04.16 |
| 머신러닝 기초 실습 - SVM, 로지스틱 회귀, KNN 분류 모델 비교 (with OpenCV)📅 작성일: 2025년 4월 8일 (0) | 2025.04.08 |
| 📅 2025년 4월 7일 - 머신러닝 모델 비교와 OpenCV 이미지 처리 실습 (0) | 2025.04.07 |