앞으로 나올 수학적 개념과 연산… 들이 많이 걱정되긴 하지만
결국은 배워야 늘고 해야 느는것이기 때문에 마인드컨트롤하며 무너지지않고 잘 진행할 수 있도록 노력해야겠다.
이번에는 수학적 개념에 앞서 Mat클래스내에서 연산(API의 상위 레벨)하는것을 목표로 한다.
#include <opencv2\opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
#define WIN_NAME "winSrcImage"
#define FILE_LENA_JPG "lena.jpg"
int main(void) {
IplImage* image = cvLoadImage("lena.jpg", CV_LOAD_IMAGE_GRAYSCALE); // Intel Processing Library
Mat matrixA1 = cvarrToMat(image); // 데이터 공유
Mat matrixA2 = cvarrToMat(image).clone(); // 데이터까지 복사
Mat matrixB, matrixC;
flip(matrixA1, matrixB, 0); // 상하
imshow("matB", matrixB);
imshow("origin1", matrixA1);
flip(matrixA1, matrixC, 1); // 좌우
imshow("matC", matrixC);
imshow("origin2", matrixA1);
// flip을 해도 원본데이터에는 당연히 영향이 가지않음 -> clone:데이터복사
waitKey(0);
destroyAllWindows();
return 0;
}
flip함수는 이름과 같이 직관적이다.
기억해야할 것은 마지막 flipCode인자에 0을 넣으면 상하(x축을 기준으로), 1을 넣으면 좌우(y축을 기준으로)에 대하여 대칭이 된다.
위에 주석에도 적었듯이 flip을 적용한다고 원본 매트릭스에 영향이 가지는 않는다.
flip을 한 후에 다시 원본데이터를 imshow했을 때 기존 원본가 같음을 확인할 수 있다.
#include <opencv2\opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
#define WIN_NAME "winSrcImage"
#define FILE_LENA_JPG "lena.jpg"
int main(void) {
Mat srcImage = imread("lena.jpg", IMREAD_GRAYSCALE);
if (srcImage.empty()) {
return -1;
}
Rect rectROI(0, 0, 256, 256);
Mat extractROI = srcImage(rectROI);
for (int i = 0; i < 64; i++) {
for (int j = 0; j < 64; j++) {
extractROI.at<uchar>(i, j) = 0;
}
}
imshow("ROI", extractROI);
imshow("src", srcImage);
waitKey(0);
Mat repeatedMat = repeat(extractROI, 2, 2);
imshow("repeatedMat", repeatedMat);
waitKey(0);
return 0;
}
ROI는 관심영역일 뿐 데이터를 클로닝하여 저장하는 것이 아니다.
ROI를 지정한 Mat객체의 값을 인위적으로 손실시킨 다음 원본 Mat객체를 확인해보자.
위처럼 원본 srcImage 객체의 데이터에 반영된 것을 볼 수 있다.
repeat함수는 주어진 Mat객체의 데이터를 바탕으로 n * m형태의 바둑판식 패턴처럼 이어붙여준다.
물론 주어진 Mat객체의 데이터는 우리가 64*64만큼을 손실시켜놨으므로 위와같은 결과가 나오게 된다.
모자이크 함수를 쓰는것은 아니고, ROI를 이용해 모자이크 효과를 내는것이 목표이다.
TYPE값이 왜 0인가… 설마 CV_8UC1의 상수값이 0이던가~~했는데
역시나. 이왕이면 좀 알아두는게 좋을 것 같아 아래 링크를 참고하였다.
(더 보기…)