Generate Opticalflow on images using OpenCV

asked 2019-11-25 15:09:11 -0500

updated 2019-11-26 02:24:06 -0500

berak gravatar image

I am trying run OpenCV broxopticalflow function. Here is my code

int main(int argc, const char* argv[]){

        //use GPU 0
        setDevice(0);

        //source and target dirs
        string sourceDir = "source";
        string targetDir = "output";

        vector<string> filesInDir=getFileNamesFromDirAsVector(sourceDir.c_str());

        Ptr<BroxOpticalFlow> ptr = cv::cuda::BroxOpticalFlow::create(0.197f, 50.0f, 0.8f, 5, 150, 10);//(alpha ,gamma ,scale ,inner_iterations ,outer_iterations ,solver_iterations);   

        cout<<"Calculate flow for dir "<<sourceDir.c_str()<<endl;
        for (vector<string>::size_type i = 0; i <(filesInDir.size()-1); ++i){



            string frame0Name=sourceDir+"/"+filesInDir[i] ;
            string frame1Name=sourceDir+"/"+filesInDir[i+1];
            Mat frame0Color = imread(frame0Name,0);
            Mat frame1Color = imread(frame1Name,0);



            //frame0Color.convertTo(frame0Color, CV_32FC1, 1.0 / 255.0);
            //frame1Color.convertTo(frame1Color, CV_32FC1, 1.0 / 255.0);

            Mat frame0Gray, frame1Gray;
            //cv::cvtColor(frame0Color, frame0Gray, cv::COLOR_BGR2GRAY);
            //cv::cvtColor(frame1Color, frame1Gray, cv::COLOR_BGR2GRAY);
            frame0Color.convertTo(frame0Gray,CV_32FC1, 1.0 / 255.0);
            frame1Color.convertTo(frame1Gray,CV_32FC1, 1.0 / 255.0);
            cuda::GpuMat d_frame0;
            cuda::GpuMat d_frame1;
            d_frame0.download(frame0Gray);
            d_frame1.download(frame1Gray);
            cuda::GpuMat d_fu;
            ptr->calc(d_frame0, d_frame1, d_fu);
}

}

Most of this code is copied from github. When i run this code, i run into follwing error:

OpenCV(4.1.0) /src/opencv_contrib-4.1.0/modules/cudaoptflow/src/brox.cpp:132: error: (-215:Assertion failed) frame0.type() == CV_32FC1 in function 'calc'

calc function checks if the first argument is of type CV_32FC1.This is where the code fails. Basically my question is how to convert the gpu_mat to the required type. I tried different ways as you can see the commented lines in the code. How do i convert the type of matrices to CV_32FC1? Why is the conversion i used in the code did not work although it worked for lot of implementation on github?

edit retag flag offensive close merge delete

Comments

although it worked for lot of implementation on github?

link ?

berak gravatar imageberak ( 2019-11-26 01:41:10 -0500 )edit

d_frame0.download(frame0Gray);

you're confusing gpu upload / download ? (and thus pass empty gpuMat to the optflow)

berak gravatar imageberak ( 2019-11-26 02:20:48 -0500 )edit

Are you saying i should do

d_frame0.upload(frame0Gray);

d_frame1.upload(frame1Gray);

When i changed the code to above i got the following error:

OpenCV(4.1.0) /src/opencv-4.1.0/modules/core/src/matrix_wrap.cpp:118: error: (-213:The function/feature is not implemented) You should explicitly call download method for cuda::GpuMat object in function 'getMat_'

bananapen gravatar imagebananapen ( 2019-11-26 15:15:39 -0500 )edit

i copied code from this file on github. Its not exactly same.

bananapen gravatar imagebananapen ( 2019-11-26 15:17:21 -0500 )edit