OpenCV 기본 자료형 클래스

이영준·2022년 4월 25일
0
post-thumbnail

자료형 클래스 종류
Point_ : 픽셀의 좌표를 표현
Size_: 사각형 영역의 크기를 표현
Vec, Scalar: 벡터 값을 저장
Rect_: 사각형의 위치와 크기 정보를 표현
RotatedRect: 회전된 사각형을 표현

🔑Point_ 클래스

2차원 평면 위에 있는 점의 좌표를 표현하는 템플릿 클래스로 x,y값 멤버 변수를 가지고 있음

다양한 타입을 넣을 수 있으며 int형을 넣는 Point2i는 Point로 재정의됨

Point간의 연산

#include "/opencv/build/include/opencv2/opencv.hpp"
#include <iostream>

using namespace std;
using namespace cv;



int main()
{
	cv::Point_<float> pt1(0.1f, 0.1f);
	cv::Point_<float> pt2(0.2f, 0.2f);
	cv::Point_<float> pt3(0.3f, 0.3f);
	cv::Point_<float> pt4(0.4f, 0.4f);
	cv::Point_<float> pt5(0.5f, 0.5f);
    
	cv::Point_<float> ptA1 = pt1 + pt1;
	cv::Point ptA2 = pt2 + pt2;
	cv::Point ptA3 = pt3 + pt3;
	cv::Point ptA4 = pt4 + pt4;
	cv::Point ptA5 = pt5 + pt5;
    
	std::cout << "ptA1 = " << ptA1 << std::endl;
	std::cout << "ptA2 = " << ptA2 << std::endl;
	std::cout << "ptA3 = " << ptA3 << std::endl;
	std::cout << "ptA4 = " << ptA4 << std::endl;
	std::cout << "ptA5 = " << ptA5 << std::endl;
}

결과:
ptA1 = [0.2, 0.2]
ptA2 = [0, 0]
ptA3 = [1, 1]
ptA4 = [1, 1]
ptA5 = [1, 1]
Point로 선언한 Point객체는 int형이므로 float이 int로 들어가게 됨


직관적으로 우리가 생각하는대로 좌표끼리 사칙연산이 되며

📌dot()

pt1.dot(pt2)함수는 좌표값끼리의 곱을 합하는 연산을 한다.

Point 출력

앞선 코드 결괏값처럼 [x좌표, y좌표]형태로 출력이 된다

🔑Size_ 클래스

직사각형의 width, height를 표현

#include "./opencv2/opencv.hpp"
#include <iostream>
#include <string>

using namespace cv;
using namespace std;

int main() {

	Size sz1, sz2(10, 50);
	Size sz3 = sz2 * 2;

	cout << sz3 << endl;

	sz3.width = 5; sz3.height = 10;

	cout << sz3 << endl;

}

결과:
[20 x 100]
[5 x 10]
표준출력을 지원하며, 정의가 되어있어 [가로 * 세로] 형태로 출력이 된다

📌size.area()

사각형의 넓이를 구해주는 함수이다.

🔑Rect_ 클래스

사각형이 그려지는 시작점(왼쪽 위) x,y와 width, height의 4개 멤버 변수를 가지는 클래스

Rect에 Size를 더하여 사각형의 크기를 바꾸거나,
Point를 더하여 시작점 좌표를 바꿀 수 있다

#include "./opencv2/opencv.hpp"
#include <iostream>

using namespace std;
using namespace cv;

int main() {

	Mat A(100, 200, CV_8UC1, Scalar(0));//100행 200열짜리 검정 캔버스창
	Rect R(90, 40, 20, 20);
	Rect R1, R2;
	R1 = R + Size(20, 20) + Point(-60, -10);
	R2 = R + Size(20, 20) + Point(40, -10);

	cout << R1 << endl;
	cout << R2 << endl;

	rectangle(A, R1, Scalar(255));//R1을 A안에 255(흰색)으로 그려라
	rectangle(A, R2, Scalar(255));//R2을 A안에 255(흰색)으로 그려라

	namedWindow("test", WINDOW_NORMAL);
	imshow("test", A);
	waitKey(0);
} 

rectangle(Mat, Rect, color)은 Mat에다가 Rect를 color테두리로 그려주는 함수이다.

결과:

위와 같이 [width x height from (x,y)]형태로 출력이 되며 test 캔버스에 해당 색으로 그려준다.

📌Rect의 & 와 | 연산

rect1 & rect2는 두 직사각형의 겹치는 영역,
rect1 | rect2는 두 직사각형이 모두 들어가는 큰 직사각형의 영역을 의미한다.

🔑Vec 클래스

같은 자료형을 가진 원소 몇 개로 구성된 데이터 형식
하나의 행으로만 이루어진 행렬은 행 벡터, 하나의 열로만 구성되면 열 벡터라고 부름
행 벡터와 열 벡터를 합쳐서 벡터 또는 벡터 행렬이라고 함
Matx 클래스를 상속받아 만들어짐

벡터에 들어가는 타입과, 채널 수를 명시하여 정의한다.

b: uchar
s: short
w: ushort
int : i
float: f

벡터의 값은 val멤버로 접근하거나 배열을 접근하듯이 접근, 수정이 가능하다
p1.val[0] = 100 or p1[0] = 100


#include "./opencv2/opencv.hpp"
#include <iostream>

using namespace std;
using namespace cv;

void main() {


	//자료형이 안맞는 경우에는
	//그냥 에러가 남
	Vec2i a(1, 2), aa;
	Vec2d b(4.0, 3.0), bb;

	//aa = a + b;
	//bb = a - b;

	aa = a + (Vec2i)b;
	bb = (Vec2d)a - (Vec2d)b;


	cout << aa << endl;
	cout << bb << endl;
}

결과:
[5, 5]
[-3, -1]
Vec 은 출력하면 배열처럼 출력된다.

주의할 점은 벡터끼리의 연산은 무조건 형이 맞는 상태에서 해야한다는 점이다. 안맞으면 오류가 출력된다. 확인결과 point나 size연산도 동일하게 적용되는 듯 보인다.
float을 int형으로 출력할 수는 있으나, float 과 int를 더해주는 것은 자동변환이 안되는듯.

🔑Scalar 클래스

4채널 이하의 영상에서 픽셀 값을 표현하기 위해 사용된다.

Vec클래스를 상속받았으며, 4개의 원소를 가지고 있는 클래스이다.
그 중 Scalar로 재정의된 scalar클래스는 크기가 4인 double형 배열 val을 멤버 변수로 가지고 있다.

Scalar(밝기)
Scalar(B,G,R)
Scalar(B,G,R, 투명도)로 사용할 수 있다.

ex)

#include "./opencv2/opencv.hpp"
#include <iostream>

using namespace std;
using namespace cv;

void ScalarOp() {
	Scalar gray = 128;
	cout << "gray : " << gray << endl;

	Scalar yellow(0, 255, 255);
	cout << "yellow : " << yellow << endl;

	Mat img1(256, 256, CV_8UC3, yellow);

	for (int i = 0; i < 4; i++)
		cout << yellow[i] << endl;
}

int main() {

	ScalarOp();
}

결과:
gray : [128, 0, 0, 0]
yellow : [0, 255, 255, 0]
0
255
255
0

실습: 직접 scalar값 주고 그려보기

#include "./opencv2/opencv.hpp"
#include <iostream>
#include <string>

using namespace cv;
using namespace std;

int main() {
	Mat A(100, 200, CV_8UC3, Scalar(255, 255, 255));
	Rect R(90, 40, 20, 20);
	Rect R1, R2, R3;
	Point P(50, 0);

	R1 = R - P;
	R2 = R;
	R3 = R + P;

	
	Scalar Blue = Scalar(255, 0, 0);
	Scalar Green = Scalar(0, 255, 0);
	Scalar Red = Scalar(0, 0, 255);

	rectangle(A, R1, Red);
	rectangle(A, R2, Blue);
	rectangle(A, R3, Green);

	imshow("test", A);

	waitKey();

	destroyAllWindows();


}

🔑RotatedRect 클래스

회전된 사각형을 표현하는 클래스로
중심좌표 center, 가로세로 크기인 size, 회전 각도인 angle을 멤버 변수로 가짐
모든 정보를 float를 이용해서 표현함

📌points 함수

Point2f pts[4];
rr1.points(pts);

RotatedRect의 네 꼭짓점의 좌표를 가져오기 위해서 사용한다. 좌측 하단 꼭짓점부터 시계방향으로 꼭짓점 좌표를 추출한다.

📌BoundingRect() 함수

r1 = rr1.boundingRect();

회전된 사각형을 둘러싸는 수평상태의 직사각형 정보를 추출하여 Rect로 반환함.

profile
컴퓨터와 교육 그사이 어딘가

0개의 댓글