DevelopmentTool/OpenCV

[OpenCV] Vec 클래스

유제필 2022. 11. 17. 08:52

Vec 클래스란

Vec 클래스란? 작은 개수의 원소로 구성된 벡터를 표현하는 템플릿 클래스이다.

Vec 클래스는 OpenCV 프로그래밍에서 유용하게 사용되고 있다.

Vec 클래스는 Matx 클래스의 상속을 받는다.

하나의 행으로만 이루어진 행렬을 행 벡터라고 부르고,

하나의 열로만 구성된 행렬은 열 벡터라고 부른다.

즉, 벡터는 같은 자료형을 가진 원소 몇 개로 구성된 데이터 형식이라고 볼 수 있다.

template<typename _Tp, int m, int n> class Matx
{
public:
   ...
   _Tp val[m*n];
}

template<typename _Tp, int cn> class Vec : public Matx<_Tp, cn, 1>
{
public:
   ...
   _Tp& operator[](int i);
};

tmplate<typename _Tp, int n> static inline
std::ostream& operator << (std::ostrean& out, const Vec<_Tp, n>& vec);

Matx 클래스는 작은 크기의 행렬을 표현하기 위해 만들어진 템플릿 클래스이다. 이 행렬 클래스는 원소 데이터를

val 이라는 이름의 배열에 저장한다. (_Tp val[m * n])

_Tp는 행렬 원소 자료형이고, m 은 행의 개수, n은 열의 개수를 의미한다.

Vec 클래스는 Matx 클래스를 상속받아 만들어지며, 열 개수가 1개로 특화된 벡터 표현 클래스이다.

템플릿을 사용하기 때문에 실제 코드에서 사용할 때 < >괄호 사이에 데이터가 자료형과 데이터 개수를 명시해야 한다.

예를 들어 정수형 데이터 4개를 가지고 있는 벡터라면, Vec<int, 4> 형식을 사용하고

uchar 자료형 3개를 가지고 있는 벡터라면 Vec<uchar, 3> 형식의 변수를 사용한다.

그런데 매번 Vec<uchar, 3> 과 같은 형태로 작성하는 것은 불편하여,

OpenCV는 자주 사용되는 자료형과 개수에 대한 Vec 클래스 템플릿의 이름 재정의를 제공한다.

Vec<number>{b|s|w|i|f|d}

number : 2, 3, 4 등 데이터 개수. 작은 숫자를 지정한다.
{ } : b, s, w, i, f, d 문자 중 하나를 지정한다.
      b : uchar(unsigned char)
      s : short
      w : ushort(unsigned short)
      i : int
      f : float
      d : double

 

 

OpenCV 라이브러리에 정의된 Vec 클래스 이름 재정의

typedef Vec<uchar, 2> Vec2b;
typedef Vec<uchar, 3> Vec3b;
typedef Vec<uchar, 4> Vec4b;

typedef Vec<short, 2> Vec2s;
typedef Vec<short, 3> Vec3s;
typedef Vec<short, 4> Vec4s;

typedef Vec<ushort, 2> Vec2w;
typedef Vec<ushort, 3> Vec3w;
typedef Vec<ushort, 4> Vec4w;

typedef Vec<int, 2> Vec2i;
typedef Vec<int, 3> Vec3i;
typedef Vec<int, 4> Vec4i;
typedef Vec<int, 6> Vec6i;
typedef Vec<int, 8> Vec8i;

typedef Vec<float, 2> Vec2f;
typedef Vec<float, 3> Vec3f;
typedef Vec<float, 4> Vec4f;
typedef Vec<float, 6> Vec6f;

typedef Vec<double, 2> Vec2d;
typedef Vec<double, 3> Vec3d;
typedef Vec<double, 4> Vec4d;
typedef Vec<double, 6> Vec6d;

예를 들어 컬러 영상의 픽셀 값을 표현하고 싶을 경우 Vec<uchar, 3> 형식 대신 간단하게 나타낼 수 있다.

 

Ve3b p1, p2(0, 0, 255);

 

Vec3b(uchar, 3) 의 변수 p1 과 p2를 선언할 수 있다.

이렇게 변수를 선언하면 p1, p2 각각 내부에 uchar val[3]; 형식의 멤버 변수를 가진다.

 

p1의 경우 p1.val 배열 원소가 모두 0으로 초기화되고,

p2의 경우 p2.val[0] = 0, p2.val[1] = 0, p2.val[2] = 255 으로 초기화된다.

p1.val[0] = 255;

 

위 코드는 p1 변수의 첫 번째 원소 값을 기존 0에서 255로 바꾸는 코드이다.

기존 배열과 같이 원소의 값을 변경할 수 있다.

Vec 클래스도 C/C++ 표준 입출력을 지원하므로,

std::cout과 std::endl 을 이용하여 벡터의 원소를 간단한게 출력할 수 있다.

 

std::cout << "p1 : " << p1 << std::endl;
std::cout << "p2 : " << p2 << std::endl;

p1 : [255, 0, 0]
p2 : [0, 0, 255]