2017-05-01 6 views
0

をコピーせずにベクトル私は、この関数ました:変換品種::マットはstdする::

void foo(cv::Mat &mat){ 
    float *p = mat.ptr<float>(0); 
    //modify mat values through p 
} 

をそして、私は関数を呼び出す、このコードがあります。しかし

void bar(std::vector<unsigned char> &vec){ 
    //... 
    cv::Mat res(m, n, CV_32FC1, (void *)&workspace.front()); 
} 

、上記のコードをパフォーマンスの問題があります。vecはおそらく整列していません。実際には、インテルコンパイラはreference *out has unaligned accessと言っています。これが理由だと思う。

Btw、私がthisで見つけたように、cv::Matが整列しようとしています。だから、簡単な回避策がすることです:あなたが想像できるようにcv::Mat res(m,n)

  • コールfoo(m);
  • m.ptr<float>(0)
  • vecポインタを割り当て

    1. を作成し、ここでのパフォーマンスは非常に重要なので、ディープコピーです質問から外れています。

      私はthis問題のコードを試みた:

      vec = res.data; 
      

      をしかし、私は、コンパイラのエラーを取得します。さらに、私は上記のコードが(非効率な)コピーを行うかどうかわからない、または指示されたデータをvecで変更するだけです。

      これをどのようにスムーズに行うことができますか?そうしないと、別の回避策が理解できます。

    答えて

    0

    は一見にあなたの答えのためのhere

    std::vector<uchar> array; 
    if (mat.isContinuous()) { 
        array.assign(mat.datastart, mat.dataend); 
    } else { 
        for (int i = 0; i < mat.rows; ++i) { 
        array.insert(array.end(), mat.ptr<uchar>(i), mat.ptr<uchar>(i)+mat.cols); 
        } 
    } 
    
    //p.s.: For cv::Mats of other types, like CV_32F, you should do like this: 
    
    std::vector<float> array; 
    if (mat.isContinuous()) { 
        array.assign((float*)mat.datastart, (float*)mat.dataend); 
    } else { 
        for (int i = 0; i < mat.rows; ++i) { 
        array.insert(array.end(), (float*)mat.ptr<uchar>(i), (float*)mat.ptr<uchar>(i)+mat.cols); 
        } 
    } 
    
    +0

    感謝を取る、私はこれは要素のではなく、参照の深いコピーを実行するために起こっている(そしてそれは非効率的になる)ことを恐れています、右?言い換えると、これは線形になります。 – cplusplusuberalles

    +0

    申し訳ありませんが、私は注意を払っていませんでした。多分プレーンなポインタ配列かもしれません。私は友人にもオープンCVで働いている人に尋ねました。彼は同じ方向を指していました。 – BlooB

    関連する問題