2012-10-02 15 views
6

OpenCVで画像を読み込み、サイズを取得してサーバに送信して画像を処理し、それを元に戻す必要があります特徴。サーバにデータを転送するためにバイト配列にcv :: Matを格納する

私はvector<byte>を使用することを考えていましたが、データをcv :: Matにコピーする方法はわかりません。私はそれが速いので、ポインターでデータにアクセスしようとしているwan'tしかし、私は実行時例外があります。私はこのようなものを持っています。このタスクのための最善のアプローチである

Mat image = imread((path + "name.jpg"), 0); 
vector<byte> v_char; 
for(int i = 0; i < image.rows; i++) 
    { 
     for(int j = 0; j < image.cols; j++) 
     { 
      v_char.push_back(*(uchar*)(image.data+ i + j));    

     }   
    } 
  • ?それはOpenCVのための最速であるよう

答えて

7

直接アクセスは良いアイデアですが、あなたはステップが欠落しているし、それはおそらく、なぜあなたのプログラムの中断の理由です。次の行が間違っている:あなたはをインクリメントする必要はありません

v_char.push_back(*(uchar*)(image.data+ i + j)); 

、あなたは私がimage.stepを+ をインクリメントする必要があります。それはこのようになります:

Mat image = imread((path + "name.jpg"), 0); 
vector<byte> v_char; 
for(int i = 0; i < image.rows; i++) 
    { 
     for(int j = 0; j < image.cols; j++) 
     { 
      v_char.push_back(*(uchar*)(image.data+ i*image.step + j));    

     }   
    } 
1

あなたは、ベクターを使用する必要がなぜ私は完全に理解していないが、それは本当に必要だ場合、私はあなたが簡単なのmemcpyを行うことをお勧めします。

vector<byte> v_char(image.width * image.height); //Allocating the vector with the same size of the matrix 
memcpy(v_char.data(), image.data, v_char.size() * sizeof(byte)); 
5

が上の改善しますJav_Rockの答えはここで私がそれをやる方法です。

Mat image = ...; 
vector<byte> v_char(image.rows * image.cols); 

for (int i = 0; i < image.rows; i++) 
    memcpy(&v_char[i * image.cols], image.data + i * image.step, image.cols); 

EDIT:コンストラクタによる初期化は、余分な再割り当てを避けるために十分なスペースが割り当てられますが、それはまたデフォルト値にベクトル内のすべての項目を設定します(0)。次のコードは、この余分な初期化を避けています。

Mat image = ...; 
vector<byte> v_char; 
v_char.reserve(image.rows * image.cols); 

for (int i = 0; i < image.rows; i++) 
{ 
    int segment_start = image.data + i * image.step; 
    v_char.insert(v_char.end(), segment_start, segment_start + image.cols); 
} 
+1

確かに、私はこの方法がより好きです –

+0

なぜあなたはmemcpyをするために必要ですか?なぜすべてのメモリをコピーしないのですか? –

+3

一般的に、Mat :: stepはMat :: colsとは異なるためです。これにより、実際にバイトを再構成することなく、行列をトリミングすることができます。データをコピーせずに、ウィンドウを参照するサブマトリックスを別のマトリックスにすることができます。サブマトリクス内のセルを変更すると、元のマトリクス内のセルが実際に変更されます。サブマトリクスは参照するだけです。 – Dialecticus

4

これまでのところ大きな回答がありましたが、これはあなたの主な問題ではありません。 に送信する前に、サーバーに画像を送信することは、です。

したがって、圧縮方法についてはcv::imencode()を、サーバのOpenCVマトリックスに戻すにはcv::imdecode()を変換してみてください。 imencode ouptutをソケットに押し込むだけで完了です。

関連する問題