[opencv] Mat_ 클래스와 InputArray, OutputArray

글쓴이 Engineer Myoa 날짜

정말 간만에 하는 것 같다. 얼른 기본클래스를 끝내고, 실질적인 영상처리에 돌입해야함.

텐서플로우도 조금씩 시작하고있고 처리할게 한 두개 밀려있다보니 계속 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

    안녕하세요, 반갑습니다!
    개인서버로 이사하여 이쪽에만 일지를 남기고 있습니다.

답글 남기기

Avatar placeholder

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다