[python]OpenCV 공부노트 Mat
앞서 Matx와 Size, Range 등의 기본적인 클래스를 사용해보고 Mat클래스부터 TIL을 남기고자 한다.
#pragma warning(disable: 4819)
#include "opencv.hpp"
using namespace cv;
using namespace std;
int main()
{
Mat A(2, 3, CV_8UC1);
Mat B(2, 3, CV_8UC1, Scalar(0));
Mat C(2, 3, CV_8UC3, Scalar(1, 2, 3,4)); // 채널이 3이기때문에(C3) Scalar(,4)는 포함되지 않음.
Mat E(2, 3, CV_8UC4, Scalar(1, 2, 3, 4)); // (1,2,3,4),(1,2,3,4),(1,2,3,4),
// (1,2,3,4),(1,2,3,4),(1,2,3,4) 의 2,3가 나옴
float data[] = { 1,2,3,4,5,6 };
Mat D(2, 3, CV_32FC1, data);
cout << A << endl << endl;
cout << B << endl << endl;
cout << C << endl << endl;
cout << D << endl << endl;
cout << E << endl << endl;
//cout << F << endl << endl;
// Mat 생성자 이용시
// Size를 이용해서 (col, row)를 파라미터로 주는방법과
// row, col을 하드로 작성하는 방법. 결과는 같다.
Mat A1(Size(3, 2), CV_8UC1);
Mat B1(Size(3, 2), CV_8UC1, Scalar(0));
Mat C1(Size(3, 2), CV_8UC3, Scalar(1,2,3));
Mat D1(Size(3, 2), CV_8UC3, data);
cout << A1 << endl << endl;
cout << B1 << endl << endl;
cout << C1 << endl << endl;
cout << D1 << endl << endl;
return 0;
}

#pragma warning(disable: 4819)
#include "opencv.hpp"
using namespace cv;
using namespace std;
int main()
{
Vec<float, 3> V(1, 0, 0);
Mat V1(V);
Mat V2(Vec<float, 3>(0, 1, 0));
cout << V1 << endl << endl;
cout << V2 << endl << endl;
cout << endl << "=======================" << endl << endl;
Matx<float, 3, 3> A(1, 2, 3, 4, 5, 6, 7, 8, 9);
Mat A1(A); // Matx를 이용해 Mat 생성자로 초기화
Mat A2(A1, Range(1, 2), Range::all()); // [1,2)행, 모든칼럼 -> (4,5,6)
Mat A3(A1, Rect(1, 1, 2, 2)); // x,y, width, height -> (5,6), (8,9)
CvMat mat = cvMat(3, 3, CV_32FC1, A.val);
Mat A4 = cvarrToMat(&mat); // copyData = false
Mat A5 = cvarrToMat(&mat, true); // copyData = true. (= deepCopy)
A.val[0] = 200;
cout << A1 << endl << endl;
cout << A2 << endl << endl;
cout << A3 << endl << endl;
cout << endl << "==========deep copy test===========" << endl << endl;
cout << A4 << endl << endl;
cout << A5 << endl << endl;
return 0;
}

V1과 V2는 3×1행렬이 생성되었음. ( 1*3 예상했었음 )
A4의 경우 A[0]이 200으로 바뀌자 A를 참고하고있었기 떄문에 A4[0]도 200이 된다.
A5는 deepcopy라 영향받지않음.
중요한건 Range(int r1, int r2),Range(int c1, int c2) 는 각 행, 열 범위를 의미하고 (ex. Range(0,1), Range(1,2) 면 0행, 1열 범위)
해당하는 범위가 [r1,r2), [c1,c2) 라는 것이다.
다음으로는 3차원 행렬을 다루어 본다.
#pragma warning(disable: 4819)
#include "opencv.hpp"
using namespace cv;
using namespace std;
int main()
{
int sizes[] = { 2,3,4 };
Mat A(3, sizes, CV_32FC1);
Mat B(3, sizes, CV_32FC1, Scalar(0));
cout << "B.dims = " << B.dims << endl;
cout << "B.rows = " << B.rows << endl;
cout << "B.cols = " << B.cols << endl;
cout << "B.size[0] = " << B.size[0] << endl;
cout << "B.size[1] = " << B.size[1] << endl;
cout << "B.size[2] = " << B.size[2] << endl;
return 0;
}

dims가 >2 이기때문에 rows와 cols는 -1로 출력된다.
B 각 원소의 size가 2,3,4인 것으로 보아 2x3x4 공간의 Matrix인것을 알 수 있다.
#pragma warning(disable: 4819)
#include "opencv.hpp"
using namespace cv;
using namespace std;
int main()
{
int sizes[] = { 2,3,4 };
Mat A(3, sizes, CV_32FC1);
Mat B(3, sizes, CV_32FC1, Scalar(0));
for (int i = 0; i < B.size[0]; i++) {
cout << "B[" << i << "]" << endl;
for (int j = 0; j < B.size[1]; j++) {
for (int k = 0; k < B.size[2]; k++) {
cout << B.at<float>(i, j, k); // 32FC1이므로 float템플릿을 이용하여 접근
if (k != B.size[2] - 1) {
cout << ", ";
}
else {
cout << ";";
}
}
cout << endl;
}
}
return 0;
}

3×4의 배열이 2개가 존재하여 2x3x4 공간을 이룬다. (z*y*x)
#pragma warning(disable: 4819)
#include "opencv.hpp"
using namespace cv;
using namespace std;
int main()
{
Ptr<IplImage> oldImage(cvLoadImage("lena.jpg", IMREAD_GRAYSCALE));
if (oldImage.empty()) {
cout << "file not found." << endl;
return -1;
}
Mat newImage = cvarrToMat(oldImage);
imshow("newImage", newImage);
waitKey();
return 0;
}
IplImage와 cvLoadImage에 의해 행렬을 생성하는 방법.

Mat::create() 행렬 생성은 이어서..
51개의 댓글