[opencv] Mat_ 클래스와 InputArray, OutputArray
정말 간만에 하는 것 같다. 얼른 기본클래스를 끝내고, 실질적인 영상처리에 돌입해야함.
텐서플로우도 조금씩 시작하고있고 처리할게 한 두개 밀려있다보니 계속 opencv를 미루다 하는 중..
나의 나중기억은 항상 보장할 수 없으므로 코드와 주석을 통한 로그를 남기도록 한다.
#pragma warning(disable: 4819) #include "opencv.hpp" #include <iomanip> using namespace cv; using namespace std; void toThreshold(InputArray _src, OutputArray _dst, uchar threshVal); int main() { Mat dstImage(2, 3, CV_32F); for (int i = 0; i < dstImage.rows; i++) { for (int j = 0; j < dstImage.cols; j++) { dstImage.at<float>(i, j) = (float)(i* dstImage.cols + j); } } Mat_<double> B = (Mat_<double>)dstImage; //Mat_<float> B = (Mat_<float>)dstImage; Mat_<float>& C = (Mat_<float>&)dstImage; B(0, 0) = 10.0f; // C가 dstImage의 레퍼런스를 참고하기때문에 B에 변형을 가해서 확인. // 하지만 dstImage와 B, C 모두 float으로 자료형이 설정돼있고, 타입캐스팅의 템플릿 역시 float이므로 동일한 메모리를 참고한다. // B에서 Mat_<float> B 대신 Mat_<double> B를 하면 템플릿의 자료형 이 달라지므로 새로운 메모리를 할당하도록 한다. cout << dstImage << endl; cout << "------------------------" << endl; cout << B << endl; cout << "------------------------" << endl; cout << C << endl; cout << "------------------------" << endl; //imshow("dstImage", dstImage); //waitKey(); system("cls"); Mat_<Vec3b> image(400, 400, Vec3b(255, 255, 255)); for (int i = 0; i < 400; i++) { image(i, i) = Vec3b(0, 0, 0); // 흰바탕에 검은 대각선 예상합니다. } for (int i = 0; i < 400; i++) { for (int j = 0; j < 400; j++) { image(i, j)[0] = 0; // 3채널이기 때문에. image(i, j)[1] = 60; image(i, j)[2] = 180; // 모든 채널을 건드려서 대각선도 덮어버림. } } //imshow("image", image); //waitKey(0); system("cls"); Mat_<uchar> srcImage = imread("lena.jpg", IMREAD_GRAYSCALE); float sum = 0; for (int i = 0; i < srcImage.rows; i++) { for (int j = 0; j < srcImage.cols; j++) { sum += srcImage(i, j); } } // Mat::total() : Returns the total number of array elements. // 총 byte(uchar)를 더한 값을 225*225(가로 세로)로 나누면 평균 값이 나옴. imshow("test", srcImage); cout << sum << endl << srcImage.total() << endl; cout << "Avg = sum / total = " << sum / srcImage.total() << endl; cout << srcImage.dims << endl; system("cls"); Mat_<float> AA(10, 10); for (int i = 0; i < AA.rows; i++) { for (int j = 0; j < AA.cols; j++) { AA(i, j) = (float)(i*AA.cols + j); } } cout << AA << endl; cout << "sum(A) = " << cv::sum(AA) << endl; float sum2 = 0; Mat_<float>::iterator it = AA.begin(); // AA의 첫 포지션을 이터레이터로 지정 for (; it != AA.end(); it++) { // 횟수 제한없이 이터레이터가 AA의 끝을 만날 때까지 실행. it++는 일반적인 it.next()와 동일. sum2 += *it; // 이터레이터가 가르키는 주소의 값은 float } cout << setw(10) << sum2 << endl; Mat_<float> BB(10, 10); Mat_<float>::const_iterator itAA = AA.begin(); Mat_<float>::iterator itBB = BB.begin(); for (; itAA != AA.end(); itAA++, itBB++) { *itBB = *itAA; } cout << BB << endl; // const한 iterator를 통해 BB로 AA값을 복사. // InputArray, OutputArray /* InputArray는 벡터나 행렬을 인수로 전달할때 유용. R/O로 Mat을 인수로 전달하는 대신 InputArray로 인수를 전달 OutputArray는 벡터나 행렬을 출력으로 사용할 인수를 전달할 때 사용됌. R/W가능. 그렇다면 굳이 InputOutputArray가 존재하는 이유는?.... 일단 InputArray < OutputArray < InputOutputArray 순으로 상속임. */ Mat srcImage2 = imread("lena.jpg", IMREAD_GRAYSCALE); if (srcImage2.empty()) { return -1; } Mat dstImage2; float threshRatio = 0.8; // 값이 1에 가까울수록 밝은 픽셀만 0처리, 나머지는 255처리라 점점 어두워짐 if (threshRatio > 1.0 || threshRatio < 0.0) { // 올바르지않은 스레숄드 비율값이 들어왔을 때 return -1; } int ratioToVal = UCHAR_MAX * threshRatio; toThreshold(srcImage2, dstImage2, ratioToVal); imshow("test", dstImage2); waitKey(0); system("cls"); return 0; } void toThreshold(InputArray _src, OutputArray _dst, uchar threshVal) { Mat src = _src.getMat(); // InputArray로 받아온 입력값은 getMat으로 Mat 객체를 받아올 수 있음 _dst.create(src.size(), src.type()); Mat dst = _dst.getMat(); for (int i = 0; i < src.rows; i++) { for (int j = 0; j < src.cols; j++) { if (src.at<uchar>(i, j) < threshVal) { dst.at<uchar>(i, j) = 0; } else { dst.at<uchar>(i, j) = 255; } } } }
카테고리: 개발노트
2개의 댓글
구농공 · 2019-03-01 10:48:22
앗! 제가 아는 묘아님이 맞으시려나…
예전 리에님블로그에서…
myoatm · 2019-03-01 15:13:56
안녕하세요, 반갑습니다!
개인서버로 이사하여 이쪽에만 일지를 남기고 있습니다.