OpenCV 학습 노트 (05): Mat 류 상세 설명 (2)

8125 단어 OpenCV
  • 1. 머리말: Mat 류 의 깊이 있 는 해석
  • 2. 요소 데이터 주소 지정
  • 3. Mat 류 요소 접근 방법
  • 3.1 Mat 구성원 함수 at < > () 접근 요소
  • 3.2 Mat 의 구성원 함수 ptr < > () 접근 요소 사용
  • 3.3 OpenCV 교체 기 사용
  • 4. 참고 문헌
  • 1. 머리말: Mat 류 의 깊이 있 는 해석
    제 가 을 배 울 때 새로운 ADT (abstract data type, 추상 적 인 데이터 형식) 를 접 할 때마다 일반적인 방법 은 이 렇 습 니 다.
  • ADT 의 구 조 를 먼저 파악 하고 어떻게 정의 합 니까?어떤 데이터 대상 을 포함 합 니까?예 를 들 어 선형 표 는 n 개의 같은 특성 을 가 진 데이터 요소 의 유한 한 서열 이다.
  • 이 ADT 구 조 를 바탕 으로 하 는 조작 과 알고리즘 을 다시 배운다.예 를 들 어 선형 표 의 삭제 와 수정 은 순서 표 의 정렬 알고리즘 을 바탕 으로 한다.
  • 마지막 으로 이 ADT 의 저장 방식 과 실현 과정 을 배운다.예 를 들 어, 링크 가 컴퓨터 메모리 에 저장 되 어 있다.

  • 그렇다면 기본 구 조 를 이해 한 후에 OpenCV 의 가장 중요 한 ADT 인 Mat 류 로 서 계산 에서 어떻게 저장 하고 어떤 기본 적 인 조작 이 있 습 니까?
    2. 원소 데이터 주소 지정
    Mat 류 는 n 차원 단일 채널 또는 다 중 채널 의 조밀 형 수치 배열 로 실수 또는 음수 벡터 와 행렬 real or complex-valued vectors or matrices, 그 레이스 케 일과 컬러 그림 grayscale or color images, 벡터 필드 vector fields 등 을 저장 할 수 있 고 배열 M 의 데이터 분 포 는 여러 그룹의 M. step [] 에 달 려 있 기 때문에 M 배열 에서 요소 (i0,...,iM.dims−1) 의 주 소 는 다음 과 같이 계산 할 수 있다.
    addr(Mi0,...,iM.dims−1)=M.data+M.step[0]∗i0+M.step[1]∗i1+...+M.step[M.dims−1]∗iM.dims−1

    그 중
  • step [i] 는 Mat 류 에서 매우 중요 한 속성 으로 i 차원 의 총 크기, 단위 바이트
  • 를 나타 낸다.
  • M. data 는 이 열 을 저장 하 는 첫 번 째 주소 (배열 이름과 유사)
  • 를 가리킨다.
  • M. dims 는 총 차원
  • 예 를 들 어 2 차원 행렬 의 주 소 는 다음 과 같다.
    addr(Mi,j)=M.data+M.step[0]∗i+M.step[1]∗j

    주의, M. step [i] > = M. step [i + 1], 실제 M. step [i] > = M. step [i + 1] * M. size [i + 1], 그 중에서 M. size [i] 는 i 차원 에 포 함 된 개 수 를 나타 낸다. 이 는 2 차원 행렬 은 줄 에 따라 저장 (stored row - by - row) 되 고 3 차원 행렬 은 면 에 따라 저장 (stored plane - by - plane) 되 며 고 차원 은 이런 식 으로 유추 된다 는 것 을 의미한다.M. size [M. dims - 1] 는 행렬 의 최저 차원 을 나타 내 고 크기 는 M. elem Size () 와 같다.
    예 를 들 어 행렬 의 저장 방식 과 행렬 의 각 속성의 의 미 를 설명 합 니 다.
    int sizeMat[] = { 3, 4, 6 };
    Mat src(3, sizeMat, CV_32FC3, Scalar::all(0));
    cout << "src.dims = " << src.dims << endl;
    cout << "src.step[0] = " << src.step[0] << endl;
    cout << "src.step[1] = " << src.step[1] << endl;
    cout << "src.step[2] = " << src.step[2] << endl << endl;
    
    cout << "src.size[0] = " << src.size[0] << endl;
    cout << "src.size[1] = " << src.size[1] << endl;
    cout << "src.size[2] = " << src.size[2] << endl << endl;
    
    cout << "src.step1[0] = " << src.step1(0) << endl;
    cout << "src.step1[1] = " << src.step1(1) << endl;
    cout << "src.step1[2] = " << src.step1(2) << endl << endl;
    
    cout << "src.elemSize() = " << src.elemSize() << endl;
    cout << "src.elemSize1() = " << src.elemSize1() << endl;

    3 차원 행렬 을 만 듭 니 다. 사 이 즈 는 3 * 4 * 6 입 니 다. 출력 은?
    Mat 유형 차원 은 높 은 차원 에서 낮은 차원 으로 배열 되 어 있 습 니 다. 예 를 들 어 3 차원 행렬 은 얼굴, 줄, 점 의 순서에 따라 그 차원 의 크기 에 대응 합 니 다. 우리 가 위 에서 정의 한 행렬 은 3 개의 면 을 포함 하고 각 면 은 4 줄 을 포함 하 며 각 줄 은 6 개의 점 을 포함 합 니 다.
    따라서 step [0] 은 1 차원, 면 (plane), 총 요 소 를 포함 하 는 바이트 크기 를 나타 낸다.
    우리 가 정의 하 는 행렬 은 각 면 에 4 * 6 = 24 개의 점 이 있 고 각 점 은 CV 로 정의 된다.32FC 3 유형, 즉 3 채널 의 32 비트 float 형 으로 하나의 요소 가 3 개의 float, 즉 3 * 4 = 12 바이트 를 포함 하면 전체 면 의 크기 는 24 * 12 = 288 바이트 이다.
    마찬가지 로 step [1] 은 2 차원, 행 (row) 을 나타 내 고 총 요소 의 크기 를 포함한다.
    step [1] = 6 * 12 = 72 바이트
    step [2] 는 3 차원, 점 (point) 을 나타 내 고 총 요소 의 크기 를 포함한다.
    step [2] = 12 바이트
    step 1 (i) 은 i 차원 에 포 함 된 채널 수 1 차원 을 나타 내 고 4 * 6 개의 점 을 포함 하 며 모든 점 이 3 채널 이기 때문에 1 차원 은 4 * 6 * 3 = 72 개의 채널 을 포함 하고 2 차원 은 18 개의 채널 을 포함 하 며 3 차원 은 3 개의 채널 을 포함한다.
    속성 size 는 각 차원 의 크기, 즉 1 차원 크기 는 3, size (0) = 3 차원 4, size (1) = 4 차원 6, size (2) = 6 을 나타 낸다.
    속성 elemSize 는 모든 행렬 요소 의 크기 를 나타 내 는데 이 요 소 는 여러 채널 을 포함 할 수 있 습 니 다. elemSize 1 은 모든 채널 에 포 함 된 기본 유형의 크기, 즉 elemSize = channels * elemSize 1 을 나타 냅 니 다.
    마지막 으로 한 장의 그림 을 통 해 Mat 류 의 주소 지정 방식 을 표시 합 니 다.
    3. Mat 클래스 요소 접근 방법
    3.1 Mat 멤버 함수 at < > () 접근 요소
    Mat 의 구성원 함수 at () 는 템 플 릿 함수 입 니 다. 서로 다른 상황 에 따라 여러 개의 과부하 함수 가 선택 할 수 있 습 니 다. 여기 서 우 리 는 가장 흔히 볼 수 있 는 2 차원 행렬 의 at 함 수 를 사용 합 니 다.
    
    for (int r = 0; r < src.rows; r++)  
    {  
         for (int c = 0; c < src.cols; c++)  
         {     
          cout<< src.at(r,c)<

    주의, at 함 수 를 사용 할 때 행렬 요소 의 유형 과 채널 수 를 알 아야 합 니 다. 행렬 요소 의 유형 과 채널 수 에 따라 at 함수 가 전달 하 는 유형 을 확인 해 야 합 니 다. 상기 에서 우리 가 정의 한 src 행렬 은 CV 입 니 다.32FC3, 즉 3 채널 float 형 으로 Vec3f 에 대응 하여 이 유형 을 호 환 할 수 있 습 니 다.
    3.2 Mat 의 구성원 함수 ptr < > () 접근 요 소 를 사용 합 니 다.
    Vec3f*temp(NULL);
    for (int r = 0; r < src.rows; r++)  
    {  
      temp = src.ptr(r);  
      for (int c = 0; c < src.cols; c++)  
      {  
        cout<<  temp[c];  
      }  
    }  

    주의, ptr 는 행렬 을 가리 키 는 줄 입 니 다. 마찬가지 로 ptr 함 수 를 사용 해도 행렬 요소 의 유형 과 채널 수 를 알 아야 합 니 다.
    3.3 OpenCV 교체 기 사용
    MatIterator_<Vec3b> it_src;  
    MatIterator_<Vec3b> itEnd_src;
    it_src = src.begin<Vec3f>();  
    itEnd_src = src.end<Vec3f>(); 
    for (; it_src != itEnd_src; it_src++)  
    {  
      cout<< *it_src;  
    }  

    4. 참고 문헌
    [1] https://www.douban.com/note/265479171/
    [2] http://blog.csdn.net/qianqing13579/article/details/45318279
    [3] http://blog.csdn.net/bendanban/article/details/30527785

    좋은 웹페이지 즐겨찾기