3

私は次のコードを書きました:

int _tmain(int argc, _TCHAR* argv[])
{

int vals[]={1,2,3,4,5,6,7,8,9};

CvMat mat = cvMat(3,3,CV_8UC1,vals);

for(int i=0;i<mat.rows;i++)
{
    int* ptr = (int*) (mat.data.ptr + i* mat.step);

    for(int j=0;j<mat.cols;j++)
    {
                printf("%d\t",*ptr++);

    }
    printf("\n");
}

return 0;
}

私が得た出力は次のとおりです。

1              2               3
512            768             1024
196608         262144          327680

マトリックスが正しく初期化されていません。ポインタptrは各行の先頭を指し、それをインクリメントすると、対応する列の要素が得られます。私の仮定は正しいですか?使用したcvMatコンストラクターや要素のアクセス方法に間違いはありませんか?

4

4 に答える 4

1

間違い。mat.data.ptrは、 http: //www.cs.iit.edu/~agam/cs512/lect-notes/opencv-intro/opencv-intro.htmlの符号なし文字用です。

uchar*  ptr;     // data pointer for an unsigned char matrix

あなたが使用する必要があります

mat.data.i

整数の場合

行列を適切に初期化しますが、データ構造の間違ったポインターを使用しているため、間違って出力します。

CvMat                      // 2D array
  |-- int   type;          // elements type (uchar,short,int,float,double) and flags
  |-- int   step;          // full row length in bytes
  |-- int   rows, cols;    // dimensions
  |-- int   height, width; // alternative dimensions reference
  |-- union data;
      |-- uchar*  ptr;     // data pointer for an unsigned char matrix
      |-- short*  s;       // data pointer for a short matrix
      |-- int*    i;       // data pointer for an integer matrix
      |-- float*  fl;      // data pointer for a float matrix
      |-- double* db;      // data pointer for a double matrix

見る?これは役に立ちましたか?

于 2012-08-12T14:56:57.450 に答える
1

なぜあなたはcv::Matクラスを使わないのですか?

それはメモリをよりよく処理するいくつかの便利な機能を持っています。

あなたのケースで宣言して初期化cv::Matするためのコードは次のようになります:

int main()
{
   int vals[] = {1,2,3,4,5,6,7,8,9};

    Mat mat = cv::Mat(3, 3, CV_8UC1, vals).clone();

    for(int i = 0; i < mat.rows; i++)
    {
        for(int j = 0; j < mat.cols; j++)
        {
             cout << mat.at<uchar>(j,i) << " ";
        }
        cout << endl;
    }
    return 0;
}
于 2012-08-12T19:15:44.140 に答える
0

コードにいくつかの奇妙な問題があります。そして残念ながら、tuğrulbüyükışıkの答えは半分しか正しくありません。これらの行を見てください:

// you reserve 9 integers on the stack (9*4=36bytes)
int vals[]={1,2,3,4,5,6,7,8,9}; 

// declare a matrix of uchars. 3*3*1 byte = 9 bytes
// Now, the matrix thinks it has only 9 bytes allocated.
CvMat mat = cvMat(3,3,CV_8UC1,vals); 

// Now you read the values from the matrix. 
// You actually access all the 36 bytes, but if they weren't wrongly allocated 
// at first, you would have a out-of-bounds access. 
for(int i=0;i<mat.rows;i++)
{
    int* ptr = (int*) (mat.data.ptr + i* mat.step);
}

すべてのデータを同じ形式に変換する必要があります:int(4バイト)またはuchar(1バイト)のいずれか

int vals[]={1,2,3,4,5,6,7,8,9}; 
CvMat mat = cvMat(3,3,CV_32SC1,vals); // 32SC1 means signed integer, 32 bits

また

unsigned char vals[]={1,2,3,4,5,6,7,8,9};
CvMat mat = cvMat(3,3,CV_8UC1,vals); // 8UC1 means unsigned char, 8 bits
于 2012-08-13T06:36:14.607 に答える
0

間違った使用法(huseyin tugrul Buyukisikによって説明されています)に加えて、あなたの間違いは、マトリックスを作成したときに間違ったタイプを使用したことです

int vals[] = {1,2,3,4,5,6,7,8,9};
CvMat mat = cvMat(3,3,CV_8UC1,vals); // WRONG TYPE!

マトリックスを作成するときは、CV_32SC1(signed intの場合)を使用する必要があります。

また、マトリックスにアクセスするときは、を使用する必要がありますmat.ptr<int>(row)。完全な例:

int vals[] = {1,2,3,4,5,6,7,8,9};

// Fill matrix content without allocating new memory 
// Beware: changing the content of vals changes the content of mat and vice versa
// Use correct type CV_32SC1 or let OpenCV find the correct one by using
// CV_MAKETYPE(cv::DataDepth<int>::value, 1) instead
cv::Mat mat = cv::Mat(3, 3, CV_32SC1, vals);  

// Print content
for(int row = 0; row < mat.rows; row++)
{
    int* rowPtr = mat.ptr<int>(row);

    for(int col = 0; col < mat.cols; col++)
        std::cout << rowPtr[col] << " ";

    std::cout << std::endl;
}
于 2013-08-13T19:27:39.563 に答える