オプティカル フローの水平成分と垂直成分の両方を実際に計算するオプティカル フロー画像を描画する方法はocl::PyrLKOpticalFlow::dense()
? だから私はそれらを描く方法がわかりません。私は opencv が初めてです。誰でも私を助けることができますか?
構文 :
ocl::PyrLKOpticalFlow::dense(oclMat &prevImg, oclMat& nextImg, oclMat& u, oclMat &v,oclMat &err)
オプティカル フローの水平成分と垂直成分の両方を実際に計算するオプティカル フロー画像を描画する方法はocl::PyrLKOpticalFlow::dense()
? だから私はそれらを描く方法がわかりません。私は opencv が初めてです。誰でも私を助けることができますか?
構文 :
ocl::PyrLKOpticalFlow::dense(oclMat &prevImg, oclMat& nextImg, oclMat& u, oclMat &v,oclMat &err)
オプティカル フロー コミュニティで使用されている確立された方法は、さまざまなデータ セットの 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);}
}
少し前に、コードで次のようなことをしました。
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 によって追跡されたポイントと前のポイントの間に線を引きます。これは、画像上のフローを表すオプティカル フロー ラインを引きます。
お役に立てれば..