영상의 생성과 초기화
Mat 클래스 객체의 생성과 초기화 예제 코드
void MatOp1()
{
Mat img1;
Mat img2(480, 640, CV_8UC1);
Mat img3(480, 640, CV_8UC3);
Mat img4(Size(640, 480), CV_8UC3);
Mat img5(480, 640, CV_8UC1, Scalar(128));
Mat img6(480, 640, CV_8UC3, Scalar(0, 0, 255));
Mat mat1 = Mat::zeros(3, 3, CV_32SC1);
Mat mat2 = Mat::ones(3, 3, CV_32FC1);
Mat mat3 = Mat::eye(3, 3, CV_32FC1);
float data[] = {1, 2, 3, 4, 5, 6};
Mat mat4(2, 3, CV_32FC1, data);
Mat mat5 = (Mat_<float>(2, 3) << 1, 2, 3, 4, 5, 6);
Mat mat6 = Mat_<uchar>({2, 3}, {1, 2, 3, 4, 5, 6});
mat4.create(256, 256, CV_8UC3);
mat5.create(4, 4, CV_32FC1);
mat4 = Scalar(255, 0, 0);
mat5.setTo(1.f);
}
영상의 참조와 복사
Mat 클래스 객체의 참조와 보갓
- Mat객체에 대해 = 연산자는 참조(얕은 복사)를 수행
- Mat::clone() 또는 Mat::copyTo() 함수를 이용하여 깊은 복사를 수행
void MatOp2()
{
Mat img1 = imread("dog.bmp");
Mat img2 = img1;
Mat img3;
img3 = img1;
Mat img4 = img1.clone();
Mat img5;
img1.copyTo(img5);
img1.setTo(Scalar(0, 255, 255));
imshow("img1", img1);
imshow("img2", img2);
imshow("img3", img3);
imshow("img4", img4);
imshow("img5", img5);
waitKey();
destroyAllWindows();
}
- Mat 클래스 객체의 참조와 복사
- 깊은복사의 경우 분리된 형태의 메모리 공간을 사용하기에 원본영상을 변경해도 영향을 미치지 않음
부분 영상 추출
Mat 클래스 객체에서 부분행렬 추출
- Mat 객체에 대해 ()연산자를 이용하여 부분 영상 추출 가능
- ()연산자 안에는 Rect 객체를 지정하여 부분 영상의 위치와 크기를 지정
- 참조를 활용하여 ROI(Region of interest)연산 수행 가능
영상의 픽셀 값 참조
Mat 영상의 픽셀 값 접근하기
- OpenCV에서 제공하는 기능이 아니라 자신만의 새로운 기능을 추가해야 하는 경우에 유용
- 기본적으로 Mat:data 멤버 변수가 픽셀 데이터 메모리 공간을 가리키지만, Mat 클래스 멤버 함수를 사용하는 방법을 권장
Mat::at() 함수 사용방법
template<typename _Tp> _Tp& Mat::at(int y, int x)
- y: 참조할 행 번호
- x: 참조할 열 번호
- 반환값: (_Tp& 타입으로 캐스팅 된)y행 x열 원소 값(참조).
- 사용예제:
Mat mat1 = Mat::zeros(3,4,CV_8UC1):
for (int y=0; y < mat1.cols; x++)
{
for (int x = 0; x < mat1.cols; x++)
{
mat1.at<uchar>(y, x)++;
}
}
Mat::ptr() 함수 사용방법
template<typename _Tp> _Tp* Mat::ptr(int y)
- y: 참조할 행 번호
- 반환값: (_Tp* 타입으로 캐스팅 된)y행의 시작 주소.
- 사용예제:
for (int y=0; y < mat1.rows; y++)
{
uchar* p = mat1.ptr<uchar>(y);
for (int x = 0; x < mat1.cols; x++)
{
p[x]++;
}
}
Matlterator_<T>반복자 사용 방법
- OpenCV는 Mat 클래스와 함께 사용할 수 있는 반복자 클래스 템플릿 Matlterator_ 를 제공
- Matlterator_ 는 클래스 템플릿이므로 사용할 때에는 Mat 행렬 타입에 맞는 자료형을 명시해야함
- Mat::begin() 함수는 행렬의 첫 번째 원소 위치를 반환
- Mat::end() 함수는 행렬의 마지막 원소 바로 다음 위치를 반환
for (MatIterator_<uchar> it = mat1.begin<uchar>(); it != mat1.end<uchar>(); ++it)
{
(*it)++;
}
- 성능면에서 뛰어난 것이 아니므로 앞에서 사용한 at이나 ptr을 사용하는것이 유리하다.
기초 행렬 연산
Mat 클래스 기본 행렬 연산
void MatOp5()
{
float data[] = {1, 1, 2, 3};
Mat mat1(2, 2, CV_32FC1, data);
cout << "mat1:\n" << mat1 << endl;
Mat mat2 = mat1.inv();
cout << "mat2:\n" << mat2 << endl;
cout << "mat1.t():\n" << mat1.t() << endl;
cout << "mat1 + 3:\n" << mat1 + 3 << endl;
cout << "mat1 + mat2:\n" << mat1 + mat2 << endl;
cout << "mat1 * mat2:\n" << mat1 * mat2 << endl;
}