2

オプティカル フローの水平成分と垂直成分の両方を実際に計算するオプティカル フロー画像を描画する方法はocl::PyrLKOpticalFlow::dense()? だから私はそれらを描く方法がわかりません。私は opencv が初めてです。誰でも私を助けることができますか?

構文 :

ocl::PyrLKOpticalFlow::dense(oclMat &prevImg, oclMat& nextImg, oclMat& u, oclMat &v,oclMat &err)
4

3 に答える 3

9

オプティカル フロー コミュニティで使用されている確立された方法は、さまざまなデータ セットの 1 つで確認できるように、動きベクトル フィールドを色分けされたイメージとして表示することです。たとえば、 MPI データセットまたはMiddlebury データセットです。

したがって、モーション ベクトルの長さと角度を推定します。また、HSV から RGB 色空間への変換 (OpenCV の cvtColor 関数を参照) を使用して、色分けされた画像を作成します。モーション ベクトルの角度を H (色相) チャネルとして使用し、正規化された長さを S (彩度) チャネルとして使用し、V (値) を 1 に設定します。画像の色はモーションの方向を示し、彩度 長さ (速度)。

コードは次のようになります ( use_value == true の場合、彩度は 1 に設定され、値チャネルはモーション ベクトルの長さに関連することに注意してください)。

    void FlowToRGB(const cv::Mat & inpFlow,
                cv::Mat & rgbFlow,
                const float & max_size ,
                bool use_value)
{
    if(inpFlow.empty()) return;
    if( inpFlow.depth() != CV_32F)
        throw(std::exception("FlowToRGB: error inpFlow wrong data type ( has be CV_32FC2"));
    const float grad2deg = (float)(90/3.141);
    cv::Mat pol(inpFlow.size(), CV_32FC2);

    float mean_val = 0, min_val = 1000, max_val = 0;
    float _dx, _dy;

    for(int r = 0; r < inpFlow.rows; r++)
    {
        for(int c = 0; c < inpFlow.cols; c++)
        {
            cv::Point2f polar = cvmath::toPolar(inpFlow.at<cv::Point2f>(r,c));
            polar.y *= grad2deg;
            mean_val +=polar.x;
            max_val = MAX(max_val, polar.x);
            min_val = MIN(min_val, polar.x);
            pol.at<cv::Point2f>(r,c) = cv::Point2f(polar.y,polar.x);
        }
    }
    mean_val /= inpFlow.size().area();
    float scale = max_val - min_val;
    float shift = -min_val;//-mean_val + scale;
    scale = 255.f/scale;
    if( max_size > 0)
    {
        scale = 255.f/max_size;
        shift = 0;
    }

    //calculate the angle, motion value 
    cv::Mat hsv(inpFlow.size(), CV_8UC3);
    uchar * ptrHSV = hsv.ptr<uchar>();
    int idx_val  = (use_value) ? 2:1;
    int idx_sat  = (use_value) ? 1:2;


    for(int r = 0; r < inpFlow.rows; r++, ptrHSV += hsv.step1())
    {
        uchar * _ptrHSV = ptrHSV;
        for(int c = 0; c < inpFlow.cols; c++, _ptrHSV+=3)
        {
            cv::Point2f vpol = pol.at<cv::Point2f>(r,c);

            _ptrHSV[0] = cv::saturate_cast<uchar>(vpol.x);
            _ptrHSV[idx_val] = cv::saturate_cast<uchar>( (vpol.y + shift) * scale);  
            _ptrHSV[idx_sat] = 255;
        }
    }   
    cv::Mat rgbFlow32F;
    cv::cvtColor(hsv, rgbFlow32F, CV_HSV2BGR);
    rgbFlow32F.convertTo(rgbFlow, CV_8UC3);}
 }
于 2013-11-26T14:46:21.100 に答える
1

少し前に、コードで次のようなことをしました。

        calcOpticalFlowPyrLK(frame_prec,frame_cur,v_corners_prec[i],corners_cur,status, err);


        for(int j=0; j<corners_cur.size(); j++){
                if(status[j]){

                    line(frame_cur,v_corners_prec[i][j],corners_cur[j],colors[i]);
                }
        }

基本的に、この繰り返しで OF によって追跡されたポイントと前のポイントの間に線を引きます。これは、画像上のフローを表すオプティカル フロー ラインを引きます。

お役に立てれば..

于 2013-11-19T12:18:48.040 に答える