2017-08-25 3 views
0

座標生成し、次の形式の2次元マトリクスを生成するためにいくつかの方法がある:指数表記でグリッド

(0, 0) (1, 0) (2, 0) (3, 0) 
(0, 1) (1, 1) (2, 1) (3, 1) 
(0, 2) (1, 2) (2, 2) (3, 2) 
(0, 3) (1, 3) (2, 3) (3, 3) 

は、このマトリックスは、grid[j, i] = (i, j)として表すことができます。このグリッドを生成するための

些細な方法は、次のようになります。

auto grid = cv::Mat(height, width, CV_32FC2); 

for (auto j = 0; j < height; j++) { 
    for (auto i = 0; i < width; i++) { 
     grid.at<cv::Vec2f>(j, i) = cv::Point2f(i, j); 
    } 
} 

しかし、これは遅く、「手動」である、と少し醜いです。

Pythonで

は、一つは、これを行うことができます。

grid = np.dstack(np.meshgrid(np.arange(width), np.arange(height))) 

何C++でのタイプcv::Matのこのグリッドを生成するための良い方法だろうか?

+0

あなたは、このようなグリッドを必要とするのはなぜ?ループを避けるためにMATLABやPythonで通常使用されるもの。私のC++ループは速く動作します。このようなグリッドは必要ありません。そして、あなたが本当にそれを必要とするなら、あなたがCPPで表示する方法は大丈夫です。私はこのグリッドが必要 –

+0

@AndreySmorodov理由は、それが終わる場所を確認するために各点にアフィン変換を適用することです。大まかに、 'transform.dot(grid.reshape(width * height、2).transpose())'は、各点が変換のもとで終わる位置のリストを私に提供します。 –

+1

あなたが不足している '{}'ループのためのあなたの内なるために私はmisstakenないです場合。 '{}'がなければ最初の次の文だけがネストされたループから実行されます –

答えて

2

C++ループが速く、ハードウェアが可能にするように思われます。暗黙的なstatic_cast<float>(j)がオプティマイザによって内側のループの外側に移動されたと仮定します。

C++はstd::iotaを持っているが、それは唯一の1Dコンテ​​ナ上で動作します。

OpenCVのアプローチは、画素ごとにint position[2]を渡して関数を呼び出しますされ、cv::Mat::forEachだろう。 OpenCVのドキュメントは3D exampleを持っているが、それはほとんどあなたがやろうとしているものと同じです。

1

at()メソッドを使用しないと、個々の値に最も遅くアクセスする方法がより速くなります(docs for Matを参照)。代わりにptr()を使用してください:

for (auto j = 0; j < height; j++) { 

    cv::Vec2f* row = grid.ptr<cv::Vec2f>(j); 

    for (auto i = 0; i < width; i++) { 
     row[i] = cv::Point2f(i, j); 
    } 
} 

またはポインタdataメンバーに:

cv::Vec2f* arr = (cv::Vec2f*) grid.data; 

for (auto j = 0; j < width; j++) { 
    for (auto i = 0; i < height; i++) { 
     arr[grid.cols*i + j] = cv::Point2f(i, j); 
    } 
}