이미지와 동영상에 주석을 달면 여러 가지 목적을 달성할 수 있으며, OpenCV를 사용하면 프로세스가 간단하고 쉬워집니다. 사용 방법을 확인하세요:
- 데모에 정보 추가
- 객체 감지 시 객체 주위에 경계 상자 그리기
- 이미지 분할을 위해 다양한 색상으로 픽셀 강조 표시
이미지에 주석을 다는 방법을 배우면 비디오 프레임에 주석을 다는 것도 마찬가지로 쉬워 보일 것입니다. 비디오의 각 프레임이 이미지로 표현되기 때문입니다. 여기서는 기하학적 모양과 텍스트로 이미지에 주석을 다는 방법을 보여드리겠습니다.
여기의 모든 예제에서 사용할 이미지입니다.
먼저, 이미지에 주석을 달기 위해 이 코드를 잠깐 살펴보세요. 코드의 각 줄은 여러분이 완전히 이해할 수 있도록 자세히 설명될 것입니다.
파이썬:
# Import dependencies
import cv2
# Read Images
img = cv2.imread('sample.jpg')
# Display Image
cv2.imshow('Original Image',img)
cv2.waitKey(0)
# Print error message if image is null
if img is None:
print('Could not read image')
# Draw line on image from point A to B
imageLine = img.copy()
pointA = (200,80)
pointB = (450,80)
cv2.line(imageLine, pointA, pointB, (255, 255, 0), thickness=3, lineType=cv2.LINE_AA)
cv2.imshow('Image Line', imageLine)
cv2.waitKey(0)
C++
// Import dependencies
#include <opencv2/opencv.hpp>
#include <iostream>
// Using namespaces to nullify use of c::function(); syntax and std::function(); syntax
using namespace std;
using namespace cv;
int main()
{
// Read Images
Mat img = imread("sample.jpg");
// Display Image
imshow("Original Image", img);
waitKey();
// Print Error message if image is null
if (img.empty())
{
cout << "Could not read image" << endl;
}
// Draw line on image
Mat imageLine = img.clone();
Point pointA(200,80);
Point pointB(450,80);
line(imageLine, pointA, pointB, Scalar(255, 255, 0), 3, 8, 0);
imshow("Lined Image", imageLine);
waitKey();
}
시스템에 이미 OpenCV가 있다고 가정합니다. OpenCV를 설치해야 하는 경우 아래의 관련 링크를 방문하세요.
아래에 표시된 대로 OpenCV를 가져오는 것으로 시작합니다.
참고: C++의 경우 일반적으로 cv::function()을 사용합니다. cv 네임스페이스(namespace cv 사용)를 사용하기로 했기 때문에 OpenCV 함수에 직접 액세스할 수 있습니다. 함수 이름 앞에 cv::를 붙일 필요가 없습니다. 코드 다운로드는 원문 참고.
파이썬:
# Import dependencies
import cv2
C++
// Import dependencies
#include <opencv2/opencv.hpp>
#include <iostream>
// Using namespaces to nullify use of c::function(); syntax and std::function(); syntax
using namespace std;
using namespace cv;
아래 코드에서 imread()를 사용하여 이미지를 읽고 imshow()를 사용하여 표시합니다. C++ 코드에는 몇 가지 추가 단계가 필요합니다. imread() 함수를 사용하여 이미지를 읽기 전에 main 함수를 만들고 이미지에 대한 행렬을 정의합니다.
이미지를 표시하려면 imshow() 함수를 사용합니다.
파이썬:
# Read the image
img = cv2.imread('sample.jpg')
#Display the input image
cv2.imshow('Original Image',img)
cv2.waitKey(0)
C++:
int main()
{
// Read Image
Mat img = imread("sample.jpg");
// Display the Image
imshow("Original Image", img);
waitKey();
// Print Error message if image is null
if (img.empty())
{
cout << "Could not read image" << endl;
}
다음으로 OpenCV의 다양한 그리기 함수를 사용하여 이미지에 주석을 다는 방법을 설명합니다. 각 함수에는 여러 가지 선택적 인수가 제공됩니다. 자세히 알아보려면 OpenCV 설명서 페이지를 참조하세요.
선 그리기
이 첫 번째 예에서는 OpenCV의 line() 함수를 사용하여 이미지에 색상 선으로 주석을 달겠습니다. line() 함수를 호출하기 전에 다음을 사용하여 원본 이미지의 복사본을 만듭니다:
- Python의 copy() 함수
- C++의 clone() 함수
복사본은 이미지에 대한 변경 사항이 원본 이미지에 영향을 미치지 않도록 합니다. C++에서는 먼저 원본 이미지의 사본에 대한 행렬을 만듭니다.
line() 함수의 구문은 다음과 같습니다:
line(image, start_point, end_point, color, thickness)
- 첫 번째 인수는 이미지입니다.
- 다음 두 인수는 선의 시작점과 끝점입니다.
A(x1, y1) 지점에서 B(x2, y2) 지점까지 선을 그립니다. 여기서 A와 B는 이미지의 두 점을 나타냅니다. 이미지의 왼쪽 상단 모서리를 보면 xy 좌표계의 원점이 있습니다.
- x축은 수평 방향 또는 이미지의 열을 나타냅니다.
- y축은 수직 방향 또는 이미지의 행을 나타냅니다.
아래 코드에서 볼 수 있듯이:
- 시작점과 끝점을 지정하여 이미지에 수평으로 250픽셀 길이의 선을 그립니다.
- 색상을 파란색과 녹색의 혼합으로 정하고 두께를 3으로 지정합니다.
다른 선택적 인수를 알아보려면 여기에서 OpenCV 설명서 페이지를 방문하세요.
파이썬:
#Make copy of the image
imageLine = img.copy()
# Draw the image from point A to B
pointA = (200,80)
pointB = (450,80)
cv2.line(imageLine, pointA, pointB, (255, 255, 0), thickness=3))
cv2.imshow('Image Line', imageLine)
cv2.waitKey(0)
C++:
// Make copy of the image
Mat imageLine = img.clone();
// Draw the image from point A to B
Point pointA(200,80);
Point pointB(450,80);
line(imageLine, PointA, PointB, Scalar(255, 255, 0), 3, 8, 0);
imshow("Lined Image", line_image);
waitKey();
아래 이미지에서 결과를 확인하세요.
원 그리기
다음으로 OpenCV의 circle() 함수를 사용하여 이미지에 원으로 주석을 달아 보겠습니다. 구문을 살펴보세요:
circle(image, center_coordinates, radius, color, thickness)
- OpenCV의 모든 그리기 함수와 마찬가지로 첫 번째 인수는 이미지입니다.
- 다음 두 인수는 원의 중심과 반지름에 대한 좌표를 정의합니다.
- 마지막 두 인수는 선의 색상과 두께를 지정합니다.
이 예에서 개 얼굴 주위에 빨간색 원으로 이미지에 주석을 달았습니다. 그런 다음 imshow() 함수를 사용하여 주석이 달린 이미지를 표시합니다.
파이썬:
# Make a copy of image
imageCircle = img.copy()
# define the center of circle
circle_center = (415,190)
# define the radius of the circle
radius =100
# Draw a circle using the circle() Function
cv2.circle(imageCircle, circle_center, radius, (0, 0, 255), thickness=3, lineType=cv2.LINE_AA)
# Display the result
cv2.imshow("Image Circle",imageCircle)
cv2.waitKey(0)
C++:
// Make a copy of image
Mat circle_image = img.clone();
// define the center of circle
Point circle_center(415,190);
// define the radius of circle
int radius = 100;
// Draw a circle using the circle() Function
circle(circle_image, circle_center, radius, Scalar(0, 0, 255), 3, 8, 0);
// Display the result
imshow("Circle on Image", circle_image);
waitKey();
채워진 원 그리기
방금 이미지에 빨간색 원으로 주석을 달았습니다. 지금 이 원을 단색으로 채우고 싶다면 어떨까요? 간단합니다. 아래 코드에 표시된 대로 두께 인수를 -1로 변경하기만 하면 됩니다.
파이썬:
# make a copy of the original image
imageFilledCircle = img.copy()
# define center of the circle
circle_center = (415,190)
# define the radius of the circle
radius =100
# draw the filled circle on input image
cv2.circle(imageFilledCircle, circle_center, radius, (255, 0, 0), thickness=-1, lineType=cv2.LINE_AA)
# display the output image
cv2.imshow('Image with Filled Circle',imageFilledCircle)
cv2.waitKey(0)
C++:
// make a copy of the original image
Mat Filled_circle_image = img.clone();
// define the center of circle
Point circle_center(415,190);
// define the radius of the circle
int radius = 100;
//Draw a Filled Circle using the circle() Function
circle(Filled_circle_image, circle_center, radius, Scalar(255, 0, 0), -1, 8, 0);
// display the output image
imshow("Circle on Image", circle_image);
waitKey();
사각형 그리기
이제 OpenCV의 rectangle() 함수를 사용하여 이미지에 사각형을 그립니다. 구문을 확인하세요.
rectangle(image, start_point, end_point, color, thickness)
rectangle() 함수에서 직사각형 모서리의 시작점(좌측 상단)과 끝점(우측 하단)을 제공합니다.
지금 이 예제 코드를 살펴보고 강아지 얼굴에 빨간색 직사각형으로 이미지에 주석을 달아보세요.
파이썬:
# make a copy of the original image
imageRectangle = img.copy()
# define the starting and end points of the rectangle
start_point =(300,115)
end_point =(475,225)
# draw the rectangle
cv2.rectangle(imageRectangle, start_point, end_point, (0, 0, 255), thickness= 3, lineType=cv2.LINE_8)
# display the output
cv2.imshow('imageRectangle', imageRectangle)
cv2.waitKey(0)
C++:
// make a copy of the original image
Mat rect_image = image.clone();
// Define the starting and end points for the rectangle
Point start_point(300,115);
Point end_point(475,225);
// Draw a rectangle using the rectangle() function
rectangle(rect_image, start_point, end_point, Scalar(0,0,255), 3, 8, 0);
imshow("Rectangle on Image", rect_image);
waitKey();
타원 그리기
OpenCV의 ellipse() 함수를 사용하여 이미지에 타원을 그릴 수도 있습니다. ellipse() 함수의 구문은 원의 구문과 매우 유사합니다. 다만 반지름 대신 다음을 지정해야 합니다:
- 타원의 장축과 단축 길이
- 회전 각도
- 타원의 시작 및 종료 각도
- - 이러한 각도를 사용하면 호의 일부만 그릴 수 있습니다.
ellipse(image, centerCoordinates, axesLength, angle, startAngle, endAngle, color, thickness)
아래 예제 코드에서 이미지에 주석을 달 수 있습니다:
- 수평 파란색 타원
- 수직 빨간색 타원
다시 볼 수 있듯이 OpenCV의 그리기 함수는 매우 유사하여 마스터하기 쉽습니다. 또한, 많은 기본 기하학적 모양의 위치와 방향을 자유롭게 정의할 수 있도록 선택적 인수를 제공합니다.
파이썬:
# make a copy of the original image
imageEllipse = img.copy()
# define the center point of ellipse
ellipse_center = (415,190)
# define the major and minor axes of the ellipse
axis1 = (100,50)
axis2 = (125,50)
# draw the ellipse
#Horizontal
cv2.ellipse(imageEllipse, center, axis1, 0, 0, 360, (255, 0, 0), thickness=3)
#Vertical
cv2.ellipse(imageEllipse, center, axis2, 90, 0, 360, (0, 0, 255), thickness=3)
# display the output
cv2.imshow('ellipse Image',imageEllipse)
cv2.waitKey(0)
C++:
// make a copy of the original image
Mat imageEllipse = img.clone();
// define the center point of ellipse
Point ellipse_center(415,190);
// define the major and minor axes of the ellipse
Point axis1(100, 50);
Point axis2(125, 50);
// Draw an ellipse using the ellipse() function
//Horizontal
ellipse(imageEllipse, ellipse_center, axis1, 0, 0, 360, Scalar(255, 0, 0), 3, 8, 0);
// Vertical
ellipse(imageEllipse, ellipse_center, axis2, 90, 0, 360, Scalar(0, 0, 255), 3, 8, 0);
// display the output
imshow("Ellipses on Image", imageEllipse);
waitKey();
반타원 그리기
이 예제에서는 이전 코드를 수정하여 다음을 수행합니다:
- 파란색 타원의 절반만 그리기
- 수직 빨간색 타원을 반만 채워진 수평 빨간색 타원으로 변경
이를 위해 다음과 같이 변경합니다:
- 파란색 타원의 endAngle을 180도로 설정
- 빨간색 타원의 방향을 90에서 0으로 변경
- 빨간색 타원의 시작 및 종료 각도를 각각 0과 180으로 지정
- 빨간색 타원의 두께를 음수로 지정
파이썬:
# make a copy of the original image
halfEllipse = img.copy()
# define the center of half ellipse
ellipse_center = (415,190)
# define the axis point
axis1 = (100,50)
# draw the Incomplete/Open ellipse, just a outline
cv2.ellipse(halfEllipse, ellipse_center, axis1, 0, 180, 360, (255, 0, 0), thickness=3)
# if you want to draw a Filled ellipse, use this line of code
cv2.ellipse(halfEllipse, ellipse_center, axis1, 0, 0, 180, (0, 0, 255), thickness=-2)
# display the output
cv2.imshow('halfEllipse',halfEllipse)
cv2.waitKey(0)
C++:
//make a copy of the original image
Mat halfEllipse = image.clone();
// define the center of half ellipse
Point ellipse_center(415,190);
//define the axis point
Point axis1(100, 50);
// draw the Half Ellipse, just the outline
ellipse(halfEllipse, ellipse_center, axis1, 0, 180, 360, Scalar(255, 0, 0), 3, 8, 0);
// if you want to draw a Filled ellipse, use this line of code
ellipse(halfEllipse, ellipse_center, axis1, 0, 0, 180, Scalar(0, 0, 255), -2, 8, 0);
// display the output
imshow("Half-Ellipses on Image", halfEllipse);
waitKey();
아래의 결과를 확인하세요:
텍스트 추가
마지막으로 이미지에 텍스트 주석을 달아 보겠습니다. 이를 위해 OpenCV의 putText() 함수를 사용합니다. 구문과 인수를 살펴보겠습니다.
putText(image, text, org, font, fontScale, color)
- 평소처럼 첫 번째 인수는 입력 이미지입니다.
- 다음 인수는 이미지에 주석을 달 실제 텍스트 문자열입니다.
- 세 번째 인수는 텍스트 문자열의 왼쪽 상단 모서리에 대한 시작 위치를 지정합니다.
- 다음 두 인수는 글꼴 스타일과 크기를 지정합니다.
- OpenCV는 Hershey 글꼴 컬렉션의 여러 글꼴 스타일과 기울임꼴 글꼴도 지원합니다. 다음 목록을 확인하세요.
- FONT_HERSHEY_SIMPLEX = 0,
- FONT_HERSHEY_PLAIN = 1,
- FONT_HERSHEY_DUPLEX = 2,
- FONT_HERSHEY_COMPLEX = 3,
- FONT_HERSHEY_TRIPLEX = 4,
- FONT_HERSHEY_COMPLEX_SMALL = 5,
- FONT_HERSHEY_SCRIPT_SIMPLEX = 6,
- FONT_HERSHEY_SCRIPT_COMPLEX = 7,
- FONT_ITALIC = 16
- 글꼴 크기는 글꼴의 기본 크기를 늘리거나 줄이는 데 사용되는 부동 소수점 값입니다. 이미지의 해상도에 따라 적절한 글꼴 크기를 선택하세요.
- 마지막 필수 인수는 BGR 트리플릿으로 지정된 색상입니다.
이 코드를 살펴보면 이러한 인수가 이미지에 텍스트 문자열을 표시하는 데 어떻게 구현되는지 알 수 있습니다.
파이썬:
# make a copy of the original image
imageText = img.copy()
#let's write the text you want to put on the image
text = 'I am a Happy dog!'
#org: Where you want to put the text
org = (50,350)
# write the text on the input image
cv2.putText(imageText, text, org, fontFace = cv2.FONT_HERSHEY_COMPLEX, fontScale = 1.5, color = (250,225,100))))
# display the output image with text over it
cv2.imshow("Image Text",imageText)
cv2.waitKey(0)
cv2.destroyAllWindows()
C++:
// make a copy of the original image
Mat imageText = img.clone();
// Write text using putText() function
putText(imageText, "I am a Happy dog!", Point(50,350), FONT_HERSHEY_COMPLEX, 1.5, Scalar(250,225,100));
imshow("Text on Image", imageText);
waitKey(0);
최종 결과가 나왔습니다!
Streamlit을 사용한 웹 애플리케이션
OpenCV를 사용하여 이미지에 주석을 달 수 있는 간단한 웹 애플리케이션을 만들었습니다. 여기에서 탐색할 수 있습니다.
요약
기하학적 모양과 텍스트로 이미지에 주석을 달면 강력한 커뮤니케이션 방법이 됩니다. 이미지에 대한 정보를 확대하는 데 도움이 됩니다. 이미지는 다양한 컴퓨터 비전 알고리즘으로 처리된 후 거의 항상 오버레이 결과에 주석이 달립니다(예: 경계 상자는 객체 감지 모델에서 감지한 객체 주위에 그려짐).
여기에서 기하학적 모양과 텍스트로 이미지에 주석을 달기가 얼마나 쉬운지 확인했습니다. 그리기 함수도 입력 인수가 비슷합니다. 주석의 위치와 크기를 지정하는 방법만 약간 다를 수 있습니다.
또한 원하는 색상으로 모양을 채우는 방법도 배웠습니다. 특정 방향과 길이의 타원과 호를 그렸습니다.
마지막으로 텍스트로 이미지에 주석을 다는 방법을 확인했습니다.
이 게시물에서 논의한 모든 코드는 이 링크에서 찾을 수 있습니다 → OpenCV Colab Notebook을 사용한 이미지 주석달기.
- Introduction To OpenCV
- Read, Display and Write an Image using OpenCV
- Reading and Writing Videos using OpenCV
- Image Resizing with OpenCV
- Cropping an Image using OpenCV
- Image Rotation and Translation Using OpenCV
- Annotating Images Using OpenCV
- Color spaces in OpenCV (C++ / Python)
- Image Filtering Using Convolution in OpenCV
- Image Thresholding in OpenCV
- Blob Detection Using OpenCV ( Python, C++ )
- Edge Detection Using OpenCV
- Mouse and Trackbar using OpenCV GUI
- Contour Detection using OpenCV
- Simple Background Estimation in Videos using OpenCV (C++/Python)
- Deep Learning with OpenCV DNN Module: A Definitive Guide
'OpenCV' 카테고리의 다른 글
OpenCV 이미지 크기 조정 (0) | 2025.09.09 |
---|---|
OpenCV 초보자는 여기서 시작하세요. (0) | 2025.09.08 |
OpenCV를 사용하여 비디오 읽기 및 쓰기 (0) | 2025.09.08 |
OpenCV를 사용하여 이미지 읽기, 표시 및 쓰기 - 시리즈 (2) | 2025.09.04 |
OpenCV 주피터 노트북에서 No module named'CV2' 에러 (0) | 2025.04.15 |
이미지 처리(Image Processing) - 이수안컴퓨터연구소 (9강, 동영상) (1) | 2024.06.28 |
컴퓨터 비전(Computer Vision) - 이수안컴퓨터연구소 (14강, 동영상) (1) | 2024.06.28 |
OpenCV Example 36강 (0) | 2024.06.27 |
더욱 좋은 정보를 제공하겠습니다.~ ^^