문제

OpenCV의 새로운 C ++ 인터페이스를 사용하는 방법을 배우려고 노력하고 있습니다.

멀티 채널 매트릭스의 요소에 액세스하려면 어떻게해야합니까? 예를 들어:

Mat myMat(size(3, 3), CV_32FC2);

for (int i = 0; i < 3; ++i)
{
    for (int j = 0; j < 3; ++j)
    {
        //myMat_at_(i,j) = (i,j);
    }
}

이것을하는 가장 쉬운 방법은 무엇입니까? 이전 인터페이스의 CVSET2D와 같은 것
가장 효과적인 방법은 무엇입니까? 이전 인터페이스에서 직접 포인터를 사용하는 것과 유사합니다.

고맙습니다

도움이 되었습니까?

해결책

typedef struct elem_ {
        float f1;
        float f2;
} elem;
elem data[9] = { 0.0f };
CvMat mat = cvMat(3, 3, CV_32FC2, data );

float f1 = CV_MAT_ELEM(mat, elem, row, col).f1;
float f2 = CV_MAT_ELEM(mat, elem, row, col).f2;

CV_MAT_ELEM(mat, elem, row, col).f1 = 1212.0f;
CV_MAT_ELEM(mat, elem, row, col).f2 = 326.0f;

업데이트 : OpenCV2.0 용

1. 요소를 나타내려면 하나의 유형을 선택하십시오

MAT (또는 CVMAT)에는 행, COL, 채널의 3 가지 차원이 있습니다.
행과 col을 지정하여 행렬에서 하나의 요소 (또는 픽셀)에 액세스 할 수 있습니다.

CV_32FC2 요소가 2 개의 채널이있는 32 비트 플로팅 포인트 값임을 의미합니다.
따라서 위의 코드의 Elem은 허용 가능한 하나의 표현입니다. CV_32FC2.

좋아하는 다른 표현을 사용할 수 있습니다. 예를 들어 :

typedef struct elem_ { float val[2];    } elem;
typedef struct elem_ { float x;float y; } elem;

opencv2.0은 다음과 같은 행렬의 요소를 나타내는 몇 가지 새로운 유형을 추가합니다.

template<typename _Tp, int cn> class CV_EXPORTS Vec // cxcore.hpp (208)

그래서 우리는 사용할 수 있습니다 Vec<float,2> 대표합니다 CV_32FC2, 또는 사용 :

typedef Vec<float, 2> Vec2f; // cxcore.hpp (254)

요소를 나타낼 수있는 더 많은 유형을 얻으려면 소스 코드를 참조하십시오.
여기서 우리는 사용합니다 Vec2f

2. 요소에 액세스하십시오

매트 클래스에서 요소에 액세스하는 가장 쉽고 효율적인 방법은 mat :: at입니다.
4 개의 과부하가 있습니다.

template<typename _Tp> _Tp& at(int y, int x);                // cxcore.hpp (868)
template<typename _Tp> const _Tp& at(int y, int x) const;    // cxcore.hpp (870)
template<typename _Tp> _Tp& at(Point pt);                    // cxcore.hpp (869)
template<typename _Tp> const _Tp& at(Point pt) const;        // cxcore.hpp (871)
// defineded in cxmat.hpp (454-468)

// we can access the element like this :
Mat m( Size(3,3) , CV_32FC2 );
Vec2f& elem = m.at<Vec2f>( row , col ); // or m.at<Vec2f>( Point(col,row) );
elem[0] = 1212.0f;
elem[1] = 326.0f;
float c1 = m.at<Vec2f>( row , col )[0]; // or m.at<Vec2f>( Point(col,row) );
float c2 = m.at<Vec2f>( row , col )[1];
m.at<Vec2f>( row, col )[0] = 1986.0f;
m.at<Vec2f>( row, col )[1] = 326.0f;

3. 오래된 인터페이스와 상호 작용합니다

MAT는 2 개의 변환 기능을 제공합니다.

// converts header to CvMat; no data is copied     // cxcore.hpp (829)
operator CvMat() const;                            // defined in cxmat.hpp
// converts header to IplImage; no data is copied
operator IplImage() const;

// we can interact a Mat object with old interface :
Mat new_matrix( ... );
CvMat old_matrix = new_matrix;  // be careful about its lifetime
CV_MAT_ELEM(old_mat, elem, row, col).f1 = 1212.0f;

다른 팁

VEC3I 대신 VEC3B를 사용해야합니다.

for (int i=0; i<image.rows; i++)
{
    for (int j=0; j<image.cols; j++)
    {
        if (someArray[i][j] == 0)
        {
            image.at<Vec3b>(i,j)[0] = 0;
            image.at<Vec3b>(i,j)[1] = 0;
            image.at<Vec3b>(i,j)[2] = 0;
        }
    }
}

기본 데이터 배열에 직접 액세스 할 수 있습니다.

Mat myMat(size(3, 3), CV_32FC2);

myMat.ptr<float>(y)[2*x]; // first channel
myMat.ptr<float>(y)[2*x+1]; // second channel

사용중인 매트의 데이터 유형에 따라 다릅니다. CV_32FC1과 같은 숫자 인 경우 다음을 사용할 수 있습니다.

myMat.at<float>(i, j)

UCHAR 유형 인 경우 사용 요소에 액세스 할 수 있습니다.

(symb.at<Vec3b>(i, j)).val[k]

여기서 k는 채널이고, 그레이 스케일 이미지의 경우 0, 컬러는 3입니다.

C ++ API로 멀티 채널 배열에 액세스하는 가장 좋은 방법은 PTR 방법을 사용하여 특정 행에 대한 포인터를 만드는 것입니다.

예를 들어;

type elem = matrix.ptr<type>(i)[N~c~*j+c]

어디

  • 유형: 데이터 유형 (float, int, char ect ..)
  • : 당신이 관심이있는 행
  • 체크 안함: 채널 수
  • 제이: 관심있는 열
  • : 관심있는 열 (0-3)

다른 C-> C ++ 변환에 대한 정보는이 링크를 확인하십시오. 원천

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top