본문 목표
이미지를 처리함에 있어서 사용자가 확인할 수 있어야 쉽게 코드를 개발할 수 있다.
원을 표현해야하는 경우 어떻게 원을 이미지에 그려넣을 수 있는지 알아보자.
키워드 : circle( )
알아볼 함수 원형
- 원 그리기 ( circle )
Mat img = imread("lane.png", 1);
Mat img_circle;
img.copyTo(img_circle);
circle(img_circle, Point(500, 100), 50, Scalar(255, 0, 255), 1, 8, 0);
circle(img_circle, Point(100, 100), 100, Scalar(255,0,0), 1, 4, 0);
circle(img_circle, Point(200, 300), 70, Scalar::all(255), 3, 8, 0);
circle(img_circle, Point(400, 300), 60, Scalar::all(0), -1, 8, 0);
circle( img, Point(x, y), radius, Scalar(b,g,r), thickness, lineType, shift )
○ img : 원을 그려넣을 이미지 입력
○ Point(x, y) : 원의 중심 위치
○ radius : 원의 반지름, 숫자로만 입력
○ scalar(b, g, r) : 선의 색상을 b, g, r 순으로 입력
- 하얀색의 경우 (255,255,255) 를 써도 되고
간편하게 Scalar::all(255) 를 사용하면 됨
○ thickness : 선의 굵기를 설정할 수 있음
○ lineType : 선의 타입을 설정 가능,
■ FILLED : 안을 채워 넣음 , -1
■ LINE_4 : 4 connected line , 4
■ LINE_8 : 8 connected line , 8
■ LINE_AA : 안티앨리어싱 , 16
○ shift : 사용될 일 없으니 그냥 0을 사용하면 된다.
lineType 에 대해서 부연설명을 해보자면,
FILLED는 내부를 채우는 방식인데,
사용법이 살짝 다르다.
thickness 를 입력하는 자리에 CV_FILLED 또는 FILLED 또는 -1 을 입력하면 된다.
위와 같이 사용해야 오류가 나지 않으며, 정상적으로 실행된다.
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
둘 중에 하나를 입력하면 된다.
LINE_AA 는 안티앨리어싱으로
왼쪽 이미지가 원본 직선이라면
확대 시킨 것이 오른쪽 이미지이다.
이때 오른쪽 이미지에 회색의 픽셀들이 다수 관찰되는데
이렇게 생긴 것들이 안티앨리어싱의 결과이다.
부드럽게 선을 표현하고자할 때 사용한다.
코드 테스트 결과
- 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_circle;
img.copyTo(img_circle);
circle(img_circle, Point(500, 100), 50, Scalar(255, 0, 255), 1, 8, 0);
circle(img_circle, Point(100, 100), 100, Scalar(255,0,0), 1, 4, 0);
circle(img_circle, Point(200, 300), 70, Scalar::all(255), 3, 8, 0);
circle(img_circle, Point(400, 300), 60, Scalar::all(0), -1, 8, 0);
imshow("img_line", img_circle);
waitKey(0);
return 0;
}
- RESULT
자신이 갖고 있는 아무 이미지를 불러와도 좋다.
그리고 원을 그려넣어줄 이미지 변수를 새로 만들고,
.copyTo( ) 함수를 이용해서 데이터를 복사해준다.
원을 총 4개 그리는데,
첫 번째로 그리는 원은 중심 좌표가 (500, 100) 이고, 반지름 50 이며, 색은 보라색, 두께는 1 로 한다.
방향성은 대각선을 포함한다.
두 번째로 그리는 원은 중심 좌표가 (100, 100) 이고, 반지름 100 이며, 색은 파란색, 두께는 1로 한다.
방향성은 대각선을 포함하지 않는다.
세 번째로 그리는 원은 중심 좌표가 (200, 300) 이고, 반지름 70 이며, 색은 하얀색, 두께는 3으로 한다.
네 번째로 그리는 원은 중심 좌표가 (400, 300) 이고, 반지름 60 이며, 색은 검은색, 내부채움으로 한다.
결과는 위와 같다.
확대해서 방향성에 대각선을 포함하는 것과 포함하지 않는 경우를 비교해보자.
파란색 원은 4 connected 로
대각선 방향을 포함하지 않는다.
결과 이미지 역시 가로 세로로 연속되어 있는 것을 확인할 수 있다.
보라색 원은 8 connected 로
대각선 방향을 포함한다.
따라서 결과 이미지를 보면, 대각선으로 연속되는 것을 볼 수 있다.
위에서 다루지 않은 것이 있는데,
바로 grayscale 이미지에는 직선을 흑백으로 표현할 수밖에 없다.
grayscale 은 8UC1 (8 bit, Unsigned, Channel, 1(one)) 이므로, 컬러를 표현할 수 없다.
따라서 흑백이미지에 색을 갖는 직선을 그려넣으려면 복잡한 과정이 필요하다.
결론.
이미지에 그림판에서 하는 것처럼 원을 그려넣을 수 있다.
원의 중심 좌표와, 반지름, 선의 색, 선의 두께, 내부채움 여부와 연결 방향성을 사용자가 조절할 수 있다.
도움이 되었거나, 문제가 있는 경우 댓글로 알려주세요~!
감사의 댓글은 작성자에게 큰 힘이 됩니다 ^^
'코딩 > OpenCV' 카테고리의 다른 글
[C++ opencv] HSV 색상 검출하기 (7) | 2020.07.27 |
---|---|
[C++ opencv] 관심영역 Region of Interest (RoI) 사용 방법 (0) | 2020.07.21 |
[C++ opencv] 이미지에 사각형 그리기, rectangle( ) (0) | 2020.07.21 |
[C++ opencv] 이미지에 선, 직선 그리기 (0) | 2020.07.21 |
[C++ opencv] "이미지 복사" 개념 이해하기 .copyTo (0) | 2020.07.21 |
댓글