본문 목표
이미지를 처리함에 있어서 사용자가 확인할 수 있어야 쉽게 코드를 개발할 수 있다.
직선을 표현해야하는 경우 어떻게 직선을 이미지에 그려넣을 수 있는지 알아보자.
키워드 : line()
알아볼 함수 원형
- 함수 기능 ( Function Name )
Mat img = imread("lane.png", 0);
Mat img_line;
img.copyTo(img_line);
line(img_line, Point(200, 200), Point(200, 300), Scalar::all(255), 1, 8, 0);
line(img_line, Point(200, 200), Point(200, 100), Scalar(105,200,100), 1, 8, 0);
line( Input Output Array, pt1, pt2, scalar(b,g,r), thickness, lineType, shift )
○ Input Output Array : 직선을 그려넣을 이미지 입력
○ pt1, pt2 : 직선의 양 끝 좌표을 입력, Point(x, y)
○ scalar(b, g, r) : 직선의 색상을 b, g, r 순으로 입력
- 하얀색의 경우 (255,255,255) 를 써도 되고
간편하게 Scalar::all(255) 를 사용하면 됨
○ thickness : 직선의 굵기를 설정할 수 있음
○ lineType : 직선의 타입을 설정 가능,
- FILLED : 안을 채워 넣음
- LINE_4 : 4 connected line , 4
- LINE_8 : 8 connected line , 8
- LINE_AA : 안티앨리어싱 , 16
○ shift : 사용될 일 없으니 그냥 0을 사용하면 된다.
○ lineType 에 대해서 부연 설명해보겠다.
직선을 그려넣는 경우에 FILLED 는 사용될 일이 없을 것이고;
LINE_4 와 LINE_8 의 차이를 살펴보자.
LINE_4 는 4방향을 뜻하고,
LINE_8 은 8방향을 뜻한다.
즉, LINE_4 옵션을 사용한다면 4 방향으로만 선이 연결이 된다.
LINE_8 옵션은 8방향으로 되므로, 대각선으로 표현이 가능하다.
왼쪽의 직선을 보면 픽셀이 다 세로와 가로로 연결이 되어있음을 알 수 있다.
왼쪽의 방법이 LINE_4 의 경우이다.
오른쪽의 직선을 보면 픽셀이 대각선으로 연결되어 있음을 알 수 있다.
LINE_8 방법으로 대각선으로도 연속성을 인정한 경우이다.
OpenCV 에서는 LINE_8 을 기본값으로 사용하고 있다.
LINE_8 또는 8
둘 중에 하나를 입력하면 된다.
안티 앨리어싱은 게임에서 많이 볼 수 있는 옵션 중 하나인데,
부자연스러운 직선을 자연스럽게 보이게 할 때 사용한다.
연산처리에서는 잘 사용하지 않으며, 사용자에게 부드러운 직선을 결과 값으로 보여줄 때 사용한다.
포토샵에서 위와같이 직선을 하나 그었을 때,
확대를 해보면
이렇게 검은색 뿐만이 아니라 회색의 픽셀들이 눈에 띄게 되는데,
이 픽셀들이 안티앨리어싱의 결과라고 할 수 있다.
축소해서 보면 보다 자연스러운 직선으로 보이게 해준다.
코드 테스트 결과
- CODE
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main(int ac, char** av)
{
Mat img = imread("lane.png", 1);
Mat img_line;
img.copyTo(img_line);
line(img_line, Point(200, 200), Point(300, 400), Scalar::all(255), 1, 8, 0);
line(img_line, Point(200, 200), Point(100, 100), Scalar(0,250,0), 1, LINE_4, 0); //녹색으로 표현
line(img_line, Point(200, 200), Point(300, 100), Scalar(0, 0, 255), 2, 4, 0); //적색으로 표현
imshow("img", img);
imshow("img_line", img_line);
waitKey(0);
return 0;
}
- RESULT
이런 컬러 이미지를 원본으로 사용하였다.
기본적으로 직선을 그려넣는 함수 line( ) 은
input 과 output 이 같은 이미지이기 때문에 미리 사용할 이미지를 복사해서 사용하는 것이 좋다.
이전 포스트에서 Mat 은 포인터처럼 사용된다고 해서, 특별히 .copyTo( ) 라는 함수를 사용한다고 했었으므로
처음 듣는다면 참고하시길 바란다.
직선을 총 3개 그려넣으라고 명령을 하였다.
첫 번째 직선에서는 직선의 색을 Scalar::all(255) 를 사용하여 하얀색을 명령했다.
두 번째 직선에서는 직선의 색을 Scalar 에서 (0, 255, 0) 을 사용하여 녹색으로 명령하였고,
특별히 LINE_4 라고 하여 대각선 연결을 허용하지 않았다.
세 번째 직선에서는 직선의 색을 Scalar 에서 (0, 0, 255) 를 사용하여 적색으로 명령하였고,
LINE_4 와 같은 값인 4를 넣어서 방향성을 부여해주었다.
그리고 직선의 두께를 1이 아닌 2를 부여하였다.
결과는 위와 같이 나왔다.
여기서 확인해봐야 하는 부분은 방향성과 직선의 두께이다.
첫 번째로 명령한 하얀색 선은 8 connected 방식이므로,
대각선으로도 연속성을 보여준다.
두 번째로 명령한 녹색 선은 4 connected 방식으로,
가로와 세로로 계속 연속된 직선을 보여준다.
세 번째로 명령한 적색 선은 4 connected 이면서도 직선 두께가 2 이다.
확실히 두껍게 그려진 것을 볼 수 있다.
두께가 2 이상이 되면 connected 방식은 큰 의미가 없어지는 것 같다.
그리고 4connected 보다는 8connected 가 연산속도가 더 빠를 것으로 보인다.
위에서 다루지 않은 것이 있는데,
바로 grayscale 이미지에는 직선을 흑백으로 표현할 수밖에 없다.
grayscale 은 8UC1 (8 bit, Unsigned, Channel, 1(one)) 이므로, 컬러를 표현할 수 없다.
따라서 흑백이미지에 색을 갖는 직선을 그려넣으려면 복잡한 과정이 필요하다.
결론.
이미지에 그림판에서 하는 것처럼 직선을 그려넣을 수 있다.
직선의 색과 연결 방향성, 두께를 사용자가 조절할 수 있다.
방향성은 보통 8 connected 를 사용하고, 두께도 보통은 1을 사용한다.
도움이 되었거나, 문제가 있는 경우 댓글로 알려주세요~!
감사의 댓글은 작성자에게 큰 힘이 됩니다 ^^
'코딩 > OpenCV' 카테고리의 다른 글
[C++ opencv] 이미지에 원 그리기, circle( ) (0) | 2020.07.21 |
---|---|
[C++ opencv] 이미지에 사각형 그리기, rectangle( ) (0) | 2020.07.21 |
[C++ opencv] "이미지 복사" 개념 이해하기 .copyTo (0) | 2020.07.21 |
[C++ opencv] High pass filter (HPF)로 윤곽선 검출, edge detection (1) | 2020.07.15 |
[C++ opencv] low pass filters (LPF)로 노이즈 제거하기 (0) | 2020.07.15 |
댓글