본문 바로가기
강의 (Lecture)/OpenCV 마스터 with Python (초급)

OpenCV + Python 각도 측정기 (실습)

by codingwalks 2024. 9. 30.
728x90
반응형

안녕하세요. 코딩산책입니다.

이번 글에서는 이전에 학습했던 내용을 기반으로 파이썬과 OpenCV 라이브러리를 활용하여 이미지 상에서 두 선이 이루는 각도를 측정하는 프로그램을 만들어볼 예정입니다. 마우스 클릭을 통해 두 선을 정의하고, 간단한 수학적 계산을 통해 각도를 구하는 과정을 자세히 설명하고, 실제 코드와 함께 예시를 제공합니다.
 

1. 프로젝트 준비

1.1 필요한 라이브러리

import cv2
import math
cv2: OpenCV 라이브러리로 이미지 처리를 담당
math: 삼각함수 등 수학적 계산을 위한 표준 라이브러리

1.2 이미지 불러오기

image = cv2.imread('test.jpg')

cv2.imread() 함수를 이용해 측정할 이미지를 불러옵니다. 'test.jpg'는 테스트 이미지 파일이므로 실제 사용할 이미지 경로로 수정해야 합니다.
자세한 내용은 아래의 글을 참조해 주세요.

 

OpenCV + Python 이미지, 비디오, 웹캠(Webcam), RTSP 및 RTMP 스트림 처리

안녕하세요. 코딩산책입니다.이 글은 OpenCV를 사용하여 이미지, 비디오, 웹캠, 그리고 RTSP/RTMP 같은 스트리밍 URL을 처리하는 방법을 설명합니다. 이미지 파일을 읽고 화면에 출력하는 기본적인

codingwalks.com

 
 

2. 마우스 클릭 이벤트 처리

이제 마우스를 클릭하여 두 선을 정의할 좌표를 저장하는 기능을 구현합니다.

2.1 마우스 콜백 함수 정의

마우스를 클릭할 때마다 해당 좌표에 빨간색 원을 그려 표시하고, 좌표를 points_list에 저장합니다.

def mouse_points(event, x, y, flags, params):
    if event == cv2.EVENT_LBUTTONDOWN:
        cv2.circle(image, (x, y), 5, (0, 0, 255), -1)
        points_list.append((x, y))

2.2 마우스 이벤트 설정

마우스 클릭 이벤트를 정의한 함수와 OpenCV 윈도우를 연결합니다.

cv2.setMouseCallback('Image', mouse_points)

 
자세한 내용은 아래의 글을 참조해 주세요.

 

OpenCV + Python 마우스 및 키보드 이벤트 처리와 트랙바 활용하기

안녕하세요. 코딩산책입니다.이벤트 처리는 사용자와 프로그램 간의 상호작용을 가능하게 해주는 중요한 요소입니다. OpenCV에서도 이러한 이벤트 처리 기능을 통해 이미지와 비디오를 보다 직

codingwalks.com

 

3. 각도 계산하기

세 개의 점 좌표가 필요하며, 클릭한 세 점을 이용해 두 선의 기울기를 구한 후 각도를 계산합니다.

3.1 각도 계산 공식

tan(θ) = (m2 - m1) / (1 + m1 * m2) 공식을 사용하여 두 직선이 이루는 각도를 계산합니다. 이때, math.atan2() 함수는 각도를 -π에서 π까지 구해주며, 이를 도 단위로 변환합니다.

각도 계산

3.2 충분한 점 개수 확인

세 개의 점이 클릭되면 각도를 계산할 준비가 된 것입니다.

if len(points_list) % 3 == 0 and len(points_list) != 0:
	# 각도 계산

3.3 좌표 추출

마지막으로 클릭한 세 개의 점을 각각 첫 번째, 두 번째, 세 번째 점으로 저장합니다.

points_1 = points_list[-3]
points_2 = points_list[-2]
points_3 = points_list[-1]

3.4 기울기 계산

두 선의 기울기를 계산합니다.

m1 = (points_2[1] - points_1[1]) / (points_2[0] - points_1[0])
m2 = (points_3[1] - points_2[1]) / (points_3[0] - points_2[0])

3.5 각도 계산

기울기를 이용해 두 직선이 이루는 각도를 라디안으로 구한 후, 이를 도(degree) 단위로 변환합니다.

angle_radians = math.atan2(m2 - m1, 1 + m1 * m2)
angle_degrees = round(math.degrees(angle_radians))

 

4. 전체 소스코드

4.1 마우스 클릭 방법

마우스를 세 번 클릭하여 첫 번째 선의 시작점, 두 선의 교차점, 그리고 두 번째 선의 끝점을 지정합니다.

4.2 오차

이미지 해상도와 클릭의 정확도에 따라 약간의 오차가 발생할 수 있지만, 간단한 실습용으로는 충분한 정확도를 제공합니다. 더 정확한 측정을 위해서는 보다 복잡한 알고리즘 사용을 권고드립니다.

4.3 소스코드

import cv2
import math

points_list = []

def mouse_points(event, x, y, flags, params):
    if event == cv2.EVENT_LBUTTONDOWN:
        cv2.circle(image, (x, y), 5, (0, 0, 255), -1)
        points_list.append((x, y))

image = cv2.imread('angle_finder.jpg')
cv2.imshow('Image', image)
cv2.setMouseCallback('Image', mouse_points)

while True:
    if len(points_list) % 3 == 0 and len(points_list) != 0:
        points_1 = points_list[-3]
        points_2 = points_list[-2]
        points_3 = points_list[-1]

        m1 = (points_2[1] - points_1[1]) / (points_2[0] - points_1[0])
        m2 = (points_3[1] - points_2[1]) / (points_3[0] - points_2[0])

        angle_radians = math.atan2(m2 - m1, 1 + m1 * m2)
        angle_degrees = round(math.degrees(angle_radians))

        cv2.line(image, points_1, points_2, (0, 0, 255), 2)
        cv2.line(image, points_2, points_3, (0, 0, 255), 2)
        cv2.putText(image, f"Angle: {angle_degrees} degrees", (points_2[0] - 40, points_1[1] - 20), cv2.FONT_HERSHEY_SIMPLEX, 1.5, (0, 0, 255), 2)

    cv2.imshow('Image', image)
    if cv2.waitKey(1) == ord('q'):
        break

cv2.destroyAllWindows()

결과 이미지

 

5. 결론

이번 글에서는 파이썬과 OpenCV를 활용하여 이미지 상에서 두 선이 이루는 각도를 측정하는 프로그램을 구현했습니다. 이를 통해 이미지 처리와 수학적 계산을 결합한 실용적인 프로그램을 개발하는 방법을 이해할 수 있습니다.
 

해당 포스트가 유용하셨다면 하단의 좋아요와 구독하기 부탁드립니다. ^^

Buy me a coffee

 

[Codingwalks]에게 송금하기 - AQR

[Codingwalks]에게 송금하기 - AQR

aq.gy

728x90
반응형