본문 바로가기
코딩/OpenCV

[C++ opencv] 이미지에 텍스트 넣기

by DIYver 2020. 10. 17.

 

본문 목표

OpenCV를 다루다보면 결과창(LCD)에 원하는 정보를 표현해야 할 때가 있다.

printf( ) 또는 cout 을 이용해서 콘솔창에 정보를 띄워도 되지만, 

이런 경우 이미지 화면과 콘솔 화면을 둘 다 봐야 하기에 시선이 분산 된다.

 

따라서 결과창에 텍스트를 넣어서 확인할 수 있다면 굳이 콘솔창을 띄우지 않아도 될 것이다.

 

오늘은 결과 이미지에 원하는 텍스트를 출력하는 것을 다뤄보도록 하겠다.

 

 

키워드 : putText

 

 

 

 

 

알아볼 함수 원형

- 텍스트 삽입하기( putText )

	Mat img;
	img = imread("text_test_1.jpg", 1);

	Mat img_out;
	img.copyTo(img_out);

	char mystr[30];
	sprintf_s(mystr, "Bird");

	putText(img_out, mystr, Point(500, 200), 1, 2, Scalar(255, 255, 0), 1, 8);

 

putText( img, string, Point(x,y), font face, font scale, color, thickness, line type, bottom left origin )

  ○ img: 입력할 이미지, 입력한 이미지에 텍스트를 삽입하게 된다.

 

  ○ string : 입력하고 싶은 텍스트, char 자료형이면 된다.

 

  ○ Point(x, y) : 텍스트를 삽입할 위치, xy좌표계로 입력해야 한다.

 

  ○ font face : 글꼴

- 여러 글꼴이 존재, 사용자 글꼴을 사용 불가

- 옵션은 아래에서 선택하여 사용하면 됨

참고)

  세리프(Serif)는 획 끝이 낚시바늘처럼 날카롭게 튀어나온 폰트를 뜻함. 명조체가 이에 해당

  산 세리프(San-Serif)는 세리프의 반대로, 튀어나온 부분이 없음. 고딕체가 이에 해당

 

Option Value  /  Explain
FONT_HERSHEY_SIMPLEX / 0 / 중간 크기 산세리프 폰트
FONT_HERSHEY_PLAIN / 1 / 작은 크기 산세리프 폰트
FONT_HERSHEY_DUPLEX / 2 / 2줄 산세리프 폰트
FONT_HERSHEY_COMPLEX / 3 / 중간 크기 세리프 폰트
FONT_HERSHEY_TRIPLEX / 4 / 3줄 세리프 폰트
FONT_HERSHEY_COMPLEX_SMALL / 5 / COMPLEX 보다 작은 크기
FONT_HERSHEY_SCRIPT_SIMPLEX / 6 / 필기체 스타일 폰트
FONT_HERSHEY_SCRIPT_COMPLEX / 7 / 복잡한 필기체 스타일
FONT_ITALIC / 16 / 이탈릭체를 위한 플래그

 

  ○ font scale : 폰트 크기

 

  ○ color : scalar 값의 색상 정보 입력

- scalar( Blue, Green, Red)

- scalar::all(255) : 흰색

- scalar::all(0) : 검정색

 

  ○ thickness : 폰트 굵기

 

  ○ line type : 글자 선의 형태

 

  ○ bottom left origin : 영상의 원점 좌표를 좌측 하단으로 설정함

- 원래 영상의 원점 좌표는 좌상단인데, 평소 xy좌표계와 헷갈리는 사람들을 위한 옵션임

 

 

 

 

 

 

코드 테스트 결과

- CODE

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main(int, char**)
{
	Mat img;
	img = imread("text_test_1.jpg", 1);

	Mat img_out;
	img.copyTo(img_out);

	char mystr[30];
	sprintf_s(mystr, "Bird");

	putText(img_out, mystr, Point(500, 200), 0, 2, Scalar(255, 255, 0), 1, 8);
	putText(img_out, mystr, Point(650, 200), 1, 2, Scalar(0 , 0, 255), 1, 8);
	putText(img_out, mystr, Point(800, 200), 3, 2, Scalar(0, 255, 0), 1, 8);
	putText(img_out, mystr, Point(800, 400), 6, 2, Scalar(0, 255, 255), 1, 8);
	
	imshow("origin", img);
	imshow("test", img_out);
	waitKey(0);
	return 0;
}

 

- RESULT

원본 이미지

 

 

텍스트 삽입한 이미지

 

우리가 흔히 문서작업에서 사용하는 폰트 개념을 사용하면 안 된다.

일단 폰트 스케일을 똑같이 두고 했음에도, font face 자체에 크기 정보가 다르게 설정되어 있기 때문이다.

따라서 글자를 넣을 때에는 여러번 시행착오를 감수해야 한다.

 

그리고 위에서 설명한대로 명조체와 고딕체가 분명하게 나뉘는 것을 확인할 수 있다.

필기체도 있긴 하지만 정보 확인 목적으로는 잘 사용하지 않는다.

 

 

 

 

 

 

 

 

이번에는 정해져있는 문구가 아닌, 변수값을 출력하는 것을 다뤄보도록 하자.

제일 간단하게 하기 위해서 이미지의 크기를 텍스트로해서 이미지에 삽입하는 코드를 작성해보았다.

- CODE

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;


void WARP(Mat input_img, Mat& output_img);
void inRange_white(Mat input_img, Mat& output_img);
void inRange_yellow(Mat input_img, Mat& output_img);

void user_function(Mat input_image, Mat* img_out);


int main(int, char**)
{
	Mat img;
	img = imread("text_test_2.jpg", 1);

	resize(img, img, Size(640, 480));
	Mat img_out;
	img.copyTo(img_out);

	char mystr_1[30];
	char mystr_2[30];

	sprintf_s(mystr_1, "width : %d", img.cols);
	sprintf_s(mystr_2, "Height : %d", img.rows);

	putText(img_out, mystr_1, Point(20, 20), 5, 1, Scalar(0, 0, 255), 1);
	putText(img_out, mystr_2, Point(20, 40), 5, 1, Scalar(0, 0, 255), 1);

	imshow("origin", img);
	imshow("test", img_out);
	waitKey(0);
	return 0;
}

 

- RESULT

원본이미지를 resize 함수를 이용해서 640 * 480 이미지로 만들어 주었다.

 

결과 이미지에 원하던 대로 이미지의 폭과 높이가 출력되었다.

 

여기서 핵심은 sprintf_s( ) 함수가 마치 printf( ) 함수와 비슷한 역할을 한다는 것이다.

원래는 int 자료형을 char 자료형으로 바꿔주는 itoa 같은 함수를 이용했어햐 하는데,

 

c++에서는 편하게 sprintf_s( ) 함수를 이용해서 가능하다는 것이다.

 

scanf_s 와 마찬가지로 윈도우 상에서만 마지막에 _s 가 붙는다.

다른 운영체제를 사용중이라면 그냥 sprintf( ) 로 사용하면 된다.

 

 

 

 

 

결론.

1. OpenCV 기능을 이용하여 이미지에 텍스트를 넣을 수 있다.

2. OpenCV에서 제공하는 폰트밖에 사용할 수 없다.

3. 변수 출력부터 원하는 텍스트 출력이 가능하다.

4. 정상적인 방법으로는 한글 출력은 불가능 하다.

5. 많은 시행착오를 거쳐야 원하는 위치에 출력할 수 있다.

 

 

 

 

 

 

 

 

도움이 되었거나, 문제가 있는 경우 댓글로 알려주세요~!

감사의 댓글은 작성자에게 큰 힘이 됩니다 ^^

댓글