DevelopmentTool/OpenCV

[OpenCV] Mat 클래스의 크기 및 타입 변환 함수

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

Mat 클래스의 크기나 타입을 변환시키는 멤버 함수가 있다.

Mat::convertTo()

void Mat::convertTo(OutputArray m, int rtype, doule alpha=1, double beta=0) const;

m : 출력 행렬이다. 만약 m 행렬이 적절한 크기와 타입이 아닌 경우 행렬 원소 데이터를 새로 할당한다.
rtype : 원하는 출력 행렬의 타입이다. 만약 rtype이 음수이면 출력 행렬은 입력 행렬과 같은 타입을 갖는다.
alpha : 추가적으로 곱할 값
beta : 추가적으로 더할 값

Mat::convertTo() 함수는 행렬의 타입을 변경하는 함수이다.

행렬 원소의 타입을 다른 타입으로 변경하고, 추가적으로 모든 원소에 일정한 값을 더하거나 곱할 수 있다.

출력 행렬 m의 원소 값은 수식에 의해 결정된다.

m(x, y) = saturate_cast<rtype>(alpha x (*this)(x,y)+beta)

Mat::convertTo() 함수를 사용할 때 : 일련의 복잡한 연산을 수행해야 할 경우, 연산의 정확도를 높이기 위하여 픽셀 값을 정수형이 아닌

실수형으로 변환하여 내부 연산을 수행할 때, CV_8UC1 타입의 행렬을 3V_32FC1 타입으로 변경할 때, 사용한다.

Mat img1 = imread("lenna.bmp", IMGREAD_GRAYSCALE);

Mat img1f;
img1.converTo(img1f, CV_32FC1);

레나 파일을 그레이스케일 영상 img1로 불러온 후, uchar 자료형 대신 float 자료형을 생성하는 행렬 img1f를 생성하는 예제 코드이다.

Mat::reshape()

Mat Mat::reshape(int cn, int rows=0) const;

cn : 새로운 채널 수. 만약 이 값이 0이면 채널 수를 변경하지 않는다.
rows : 새로운 행의 수. 만약 이 값이 0이면 행의 개수를 변경하지 않는다.
반환값 : 모양이 변경된 행렬을 반환한다.

Mat::reshape() 함수는 주어진 행렬의 크기 또는 채널 수를 변경하는 함수이다.

행렬 원소 데이터를 복사하여 새로운 행렬을 만드는 것이 아니라 하나의 행렬 원소 데이터를 같이 참조하는 행렬을 반환한다.

그러므로 반환된 행렬 원소 값을 변경함녀 원본 행렬의 원소 값도 함께 바뀌게 된다.

uchar data1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
Mat mat1(3, 4, CV_8UC1, data1);
Mat mat2 = mat1.reshape(0, 1);

std::cout << "mat1 : \n" << mat1 << std::endl;
std::cout << "mat2 : \n" << mat2 << std::endl;

Mat::reshape() 함수를 이용하여 3 x 4 크기의 행렬을 1 x 12 크기의 행렬로 변환하는 예제 코드이다.

mat1 : 
[ 1, 2, 3, 4;
  5, 6, 7, 8;
  9, 10, 11, 12]
mat 2 : 
[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

위 코드의 출력 결과로, 3 x 4 크기의 행렬 mat1이 1행으로 구성된 1 x 12 크기의 행렬 mat2로 변환됐다.

Mat::resize();

void Mat::resize(size_t sz);
void Mat::resize(size_t sz, const Scalar& s);

sz : 새로운 행 개수
s : 새로 추가되는 행 원소의 초깃값

Mat::resize() 함수는 행렬의 모양을 변경시키는 것이 아닌, 단순히 행렬의 행 크기를 변경하고 싶을 때 사용한다.

 

행렬의 행 개수를 sz 변환하는데, sz가 기존 행렬의 행 개수보다 작으면 아래쪽 행을 제거하고,

기존 행렬의 행 개수보다 크면 아래쪽에 행을 추가한다.

 

이때 추가하는 행 원소의 초깃값으로 s를 지정할 수 있다.

Mat mat1(3, 4, CV_8UC1, data1);

mat1.resize(5, 100);

mat1의 행렬이 3 x 4 크기였지만 resize(5, 100) 코드에 의해 크기가 5 x 4 크기의 행렬로 변경되고,

새로 추가된 행의 원소는 모두 100으로 설정된다.

[ 1, 2, 3, 4;
  5, 6, 7, 8;
  9, 10, 11, 12;
100, 100, 100, 100;
100, 100, 100, 100]

새로 추가된 원소가 모두 100으로 변경되었다.

Mat::push_back()

template<typename _Tp> void Mat::push_back(const _Tp& elem);
template<typename _Tp> void Mat::push_back(const Mat_<_Tp>& elem);
template<typename _Tp> void Mat::push_back(const std::vector<_Tp>& elem);
void Mat::push_back(const Mat& m);

elem : 행렬의 맨 마지막 행에 추가할 원소 데이터
m : 행렬의 맨 마지막 행에 추가할 행렬. *this와 타입과 열 개수가 같아야 한다.

Mat::push_back() 함수는 이미 존재하는 행렬에 원소 데이터를 추가하고 싶을 때 사용한다.

함수 인자로 _Tp& 또는 std::vdctor<_Tp>& 타입을 사용할 경우, *this 행렬은 1열짜리 행렬이어야 한다.

만약 Mat_<_Tp>& 또는 Mat& 타입을 인자로 사용할 경우, *this 행렬과 인자로 전달된 m 행렬의 열 개수가 같아야 한다.

Mat mat1(3, 4, CV_8UC1, data1);
mat1.resize(5, 100);
Mat mat2 = Mat::ones(1, 4, CV_8UC1) * 255;
mat1.push_back(mat2);
Mat::push_back() 함수를 이용하여 3 x 4 크기의 행렬 mat1에 1 x 4 크기의 행렬 mat3을 맨 마지막 행으로 추가하는 코드이다.
[ 1, 2, 3, 4;
  5, 6, 7, 8;
  9, 10, 11, 12;
100, 100, 100, 100;
100, 100, 100, 100;
255, 255, 255, 255]

 

Mat::pop_back()

void Mat::pop_back(size_t nelems=1);
nelems : 제거할 행 개수. *this 행렬의 행 개수보다 크면 안된다.

추가하는 코드들과 반대로, 맨 아래에 있는 행을 제거하는 함수이다.

'DevelopmentTool > OpenCV' 카테고리의 다른 글

[OpenCV] Scalar 클래스  (0) 2022.11.17
[OpenCV] Vec 클래스  (0) 2022.11.17
[OpenCV] Mat 클래스의 픽셀 접근 방법  (0) 2022.11.17
[OpenCV] Mat 클래스 ROI 추출 함수  (0) 2022.11.17
[OpenCV] Mat 클래스의 행렬 복사  (0) 2022.11.17