Programing/OpenCV
#OpenCV 4로 배우는 컴퓨터 비전과 머신 러닝 - 3
CouqueD'asse
2022. 5. 19. 16:29
3.2.2 행렬의 생성과 초기화
// 생성과 동시에 원소 값 저장을 위한 메모리 공간 할당에 대한 생성자
Mat::Mat(int rows, int cols, int type);
// 행렬의 크기 지정
Mat::Mat(Size size, int type);
// 생성과 동시에 모든 원소 값을 특정 값으로 초기화
Mat::Mat(int rows, int cols, int type, const Scalar& s);
Mat::Mat(Size size, int type, cpnst Scalar& s);
// Scalar 영상의 픽셀 값을 표현
Mat img1(480, 640, CV_8UC1, Scalar(128);
Mat img2(480, 640, CV_8UC3, Scalar(0, 0, 128);
// 모든 원소가 0으로 초기화된 행렬
static MatExpr Mat::zeros(int rows, int cols, int type);
static MatExpr Mat::zeros(Size size, int type);
// 0으로 초기화된 3x3 정수형 행렬
Mat mat1 = Mat::zeros(3,3, CV_32SC1);
// 비어 있는 Mat 객체 또는 이미 생성된 Mat 객체에 새로운 행렬을 할당
void Mat::create(int rows, int cols, int type);
void Mat::create(Size size, int type);
mat3.create(4,4 CV_32FC1);
mat4.cerate(256,256, CV_8UC3);
// 원소 값을 초기화
mat3.setTo(1.f);
mat4 = Scalar(255, 0, 0);
// 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, 225));
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);
}
3.2.3 헹렬의 복사
얕은 복사 : 픽셀 데이터 공유
깊은 복사 : 메모리 공간을 새로 할당하여 픽셀 데이터 전체를 복사
// 깊은 복사
Mat Mat::clone() const;
void Mat::copyTo(OutputArray m) const;
void Mat::copyTo(OutputArraym, InputArray mask) const;
void MatOp2()
{
Mat img1 = imread("char.png");
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();
}
3.2.4 부분 행렬 추출
// 괄호 연산자 재정의 함수의 원형
Mat Mat::operator()(const Rect& roi) const;
Mat Mat::operator()(Range rowRange, Range colRange) const;
// 영상의 부분 영상 반전
void MatOp3()
{
Mat img1 = imread("char.png");
if (img1.empty())
{
cerr << "Img load Failed!" << endl;
return;
}
Mat img2 = img1(Rect(120, 20, 50, 50));
Mat img3 = img1(Rect(120, 20, 50, 50)).clone();
img2 = ~img2;
imshow("img1", img1);
imshow("img2", img2);
imshow("img3", img3);
waitKey();
destroyAllWindows();
}
3.2.5 행렬의 원소 값 참조
// 직관적인 행렬 원소 접근 방법
template<typename _Tp> _Tp& Mat::at(imt y, imt x);
// 특정 행의 첫번째 원소 주소를 반환
template<typename _Tp> _Tp* Mat::ptr(int y);
// 행렬의 원소 값 참조 방법을 이용하여 원소 값 증가
void MatOp4()
{
Mat mat1 = Mat::zeros(3, 4, CV_8UC1);
for (int j = 0; j < mat1.rows; j++)
{
for (int i = 0; i < mat1.cols; i++)
{
mat1.at<uchar>(j, i)++;
}
}
for (int j = 0; j < mat1.rows; j++)
{
uchar* p = mat1.ptr<uchar>(j);
for (int i = 0; i < mat1.cols; i++)
{
p[i]++;
}
}
for (MatIterator_<uchar> it = mat1.begin<uchar>(); it != mat1.end<uchar>(); ++it)
{
(*it)++;
}
cout << "mat1:\n" << mat1 << endl;
}
3.2.6 행렬 정보 참조하기
void MatOp5()
{
Mat img1 = imread("char.png");
cout << "Width : " << img1.cols << endl;
cout << "Height : " << img1.rows << endl;
cout << "Channels : " << img1.channels() << endl;
if (img1.type() == CV_8UC1)
{
cout << "img1 is grayscale img." << endl;
}
else if (img1.type() == CV_8UC3)
{
cout << "img1 is a truecolor img." << endl;
}
float data[] = { 2.f, 1.1414f, 3.f, 1.732f };
Mat mat1(2, 2, CV_32FC1, data);
cout << "mat1 : \n" << mat1 << endl;
}
3.2.7 행렬 연산
void MatOp6()
{
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;
}
3.2.8 크기 및 타입 변환 함수
// 타입 변환
void Mat::comvertTo(OutputArray m, int rtype, double alpha=1, double beta=0) const;
// 주어진 행렬의 크기 또는 채널 수 변경
Mat Mat::reshape(int cn, int rows=0) const;
// 행렬의 행 크기 변경
void Mat::resize(size_t sz);
void Mat::resize(size_t sz, const Scalar& s);
void MatOp7()
{
Mat img1 = imread("C:\\Users\\jinse\\Pictures\\char.png", IMREAD_GRAYSCALE);
Mat img1f;
img1.convertTo(img1f, CV_32FC1);
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);
cout << "mat1:\n" << mat1 << endl;
cout << "mat2:\n" << mat2 << endl;
Mat mat3 = Mat::ones(1, 4, CV_8UC1) * 255;
mat1.push_back(mat3);
cout << "mat1:\n" << mat1 << endl;
mat1.resize(6, 100);
cout << "mat1:\n" << mat1 << endl;
}