Opencv Mat 의 세 가지 상용 유형 소개

13355 단어 OpenCV
이 시리즈
@YhL_Leo
출품, 전재 출처 를 밝 혀 주세요.
글 링크:
http://blog.csdn.net/yhl_leo/article/details/47683127
본 고 는 주로 Opencv 에서 자주 사용 하 는 세 가지 Mat 유형 을 소개 한다. Mat, Mat_, Matx.
1. Mat
1.1 생 성 및 초기 화
int rows = 3, cols = 1;
cv::Size size(cols, rows);

/* first method */
cv::Mat myMat( rows, cols, CV_8UC1, cv::Scalar(0) );
cv::Mat myMat = cv::Mat( rows, cols, CV_8UC1, cv::Scalar(0) );

cv::Mat myMat( size, CV_8UC1, cv::Scalar(0) );
cv::Mat myMat( cv::Size(cols, rows), CV_8UC1, cv::Scalar(0) );

/* second method */
cv::Mat myMat2;
myMat = cv::Mat( rows, cols, CV_8UC1 );
// initial with other mat or data
myMat.copyTo(myMat2);         // initial with mat

cv::Point3i pts( 1, 2, 3 );   
myMat2 = cv::Mat(pts, true);  // initial with other data

주의:
  • Mat::Mat(int rows, int cols, int type, const Scalar& s)Mat::Mat(Size size, int type, const Scalar& s) 함 수 를 사용 하여 Mat 을 초기 화 할 때 Size 행렬 의 보관 순 서 는 (col, row) 또는 (width, height) 임 을 주의해 야 한다.
  • Mattype 종류 가 매우 많 기 때문에 일반적인 CV_8UC1, ... , CV_64FC4 1 - 4 채널 의 행렬 을 만 들 수도 있 고 더 높 은 채널 의 행렬 CV_8UC(n), ... , CV_64FC(n) 을 만 들 수도 있다. 그 중에서 최대 CV_CN_MAX 채널, Opencv 2.4.11 버 전에 서 #define CV_CN_MAX 512 에 달 할 수 있다.
  • 다 중 채널 Mat 을 만 들 때 예 를 들 어 CV_8UC3cv::Scalar(0, 0,0) 또는 myMat.setTo(cv::Scalar(0)) 을 사용 하 는데 그 중에서 후 자 는 임 의 채널 에 통용 된다.
  • 다른 Mat 복사 본 을 사용 하여 초기 화 할 때 void Mat::copyTo(OutputArray m) const 함수 가 먼저 m.create(this->size(), this->type()) 을 호출 하기 때문에 입력 한 m 을 재 구축 (sizetype 포함) 한 다음 에 데 이 터 를 복사 합 니 다.m.copyTo(m) 도 허용 되 며 아무런 문제 가 없다.

  • 1.2 데이터 접근
    여기 서 자주 사용 하 는 세 가지 방법 만 열거 합 니 다.
    1. 포인터 배열 방식
    cv::Mat image = cv::imread( "E:\\test.JPG", CV_LOAD_IMAGE_GRAYSCALE );
    const int rows = image.rows;
    const int cols = image.cols; 
    
    uchar* data = (uchar*)image.data;
    for ( int i=0; ifor ( int j=0; jint index = i*cols + j;
            data[index] = 0;
            /*
                if color one: 
                data[index * 3 + 0] = 0;
                data[index * 3 + 1] = 0;
                data[index * 3 + 2] = 0;
            */ 
        }
    }
    /*
        // also can be used as follow:
        for ( int i=0; i
    // cv::imwrite( "E:\\test2.JPG", image );

    2. .ptr 방식
    /* .ptr with [] */
    for ( int i=0; idata = image.ptr( i );
        for ( int j=0; jdata[j] = 0;
            /*
                if color one:
                data[j*3 + 0] = 0;
                data[j*3 + 1] = 0;
                data[j*3 + 2] = 0;
            */
        }
    }
    
    /* .ptr with pointer */
    for ( int i=0; idata = image.ptr( i );
        for ( int j=0; jdata++ = 0;
        }
    }

    3. .at 방식
    for ( int i=0; i<rows; i++ )
    {
        for ( int j=0; j<cols; j++ )
        {
             image.at<uchar>(i, j)= 0; // also can be: image.at<uchar>( cv::Point(j, i) ) = 0;
             /*
                 if color one:
                 image.at<uchar>( i, j*3 + 0 ) = 0;
                 image.at<uchar>( i, j*3 + 1 ) = 0;
                 image.at<uchar>( i, j*3 + 2 ) = 0;
             */
        }
    }

    세 가지 방법 은 속도 에 차이 가 있 으 니 관심 있 는 것 은 스스로 테스트 해 보 세 요 ~
    2. Mat_ Mat_Mat 에 계승 되 었 고 Mat 에 비해 데이터 세그먼트 가 증가 하지 않 았 으 나 더욱 편리 한 기능 을 추가 하여 표현 도 더욱 간소화 되 었 다.
    2.1 생 성 및 초기 화
    /* first method */
    cv::Mat_<double> myMat_ = ( cv::Mat_<double>(3, 3) << 
        1.0, 2.0, 3.0,
        4.0, 5.0, 6.0,
        7.0, 8.0, 9.0);
    
    cv::Mat_<double> myMat_ = cv::Mat_<double>::zeros(3, 3); // others: eyes, diag, ones
    
    /* second method */
    cv::Mat_<double> myMat_(3, 1, 0.0); 
    // -> cv::Mat image(3, 1, CV_64FC1, cv::Scalar(0.0));
    
    // create a 100x100 color image and fill it with green(in RGB space)
    cv::Mat_<cv::Vec3b> image( 100, 100, cv::Vec3b(0, 255, 0) );
    
    /* third method */
    cv::Mat myMat( 100, 100, CV_64F1, cv::Scalar(0) );
    cv::Mat_<double>& myMat_ = (cv::Mat_<double>&)myMat; 

    주의:
  • 에서 ( cv::Mat_(row, col) << ...) ) 형식 으로 만 들 고 초기 화 할 때 가장 바깥 에 있 는 ( ) 은 생략 할 수 없습니다.
  • 두 번 째 는 Mat 포인터 나 인용 방식 으로 Mat_ 을 만 들 거나 초기 화 할 때 이들 의 데이터 형식 이 일치 해 야 합 니 다. 그렇지 않 으 면 프로그램 컴 파일 에 문제 가 없 지만 실행 하면 BUG ~
  • 2.2 데이터 액세스
    /* 
        Note that Mat::at<_tp>(int y, int x) and 
        Mat_<_tp>::operator ()(int y, int x) do 
        absolutely the same and run at the same speed
    */ 
    int rows = myMat_.rows;
    int cols = myMat_.cols;
    
    /* first method */ 
    for ( int i=0; ifor ( int j=0; jstd::cout << myMat_(i, j) << std::endl;
        }
    }
    
    // for multi-channel images/matrices:
    for ( int i = 0; i < rows; i++ )
    {
        for( int j = 0; j < cols; j++ )
        {
            // scramble the 2nd (red) channel of each pixel
            image(i, j)[2] ^= (uchar)(i ^ j); // ^: exclusive or operation
        }
    }
    
    /* second method */
    int matCount = rows * cols;
    for ( int idx=0; idx < matCount; idx++ )
    {
        std::cout << myMat_(idx) <<std::endl;
    }

    3. Matx Matx 은 주로 크기, 데이터 유형 (부동 소수점 형) 이 알 고 있 는 작은 행렬 (최대 6x6 을 초과 하지 않 음) 에 사용 되 는데 Matx12f, ... , Matx66fMatx12d, ... , Matx66d 을 포함한다.
    생 성과 초기 화 는 간단 합 니 다. 소 개 를 많이 하지 않 습 니 다.
    cv::Matx31d myMatx( 1.0, 2.0, 3.0 );
    
    cv::Matx33d myMatx2 = cv::Matx33d( 0.0, 0.0, 0.0 );

    마지막 으로 Mat 의 연산 (더하기, 빼 기, 곱 하기, 역, 전환, 평균 값, 표준 차이...) 세 가지 유형 에 대한 기본 적 인 차이 가 크 지 않 고 문서 에서 도 쉽게 찾 을 수 있 습 니 다 ~
    참고 문서:http://www.docs.opencv.org/modules/core/doc/basic_structures.html?highlight=mat

    좋은 웹페이지 즐겨찾기