OpenCV displaying a 2-channel image (optical flow)

前端 未结 2 1304
小蘑菇
小蘑菇 2021-02-05 22:11

I have optical flow stored in a 2-channel 32F matrix. I want to visualize the contents, what\'s the easiest way to do this?

How do I convert a CV_32FC2 to R

相关标签:
2条回答
  • 2021-02-05 22:36

    imshow can handle only 1-channel gray-scale and 3-4 channel BRG/BGRA images. So you need do a conversion yourself.

    I think you can do something similar to:

    //extraxt x and y channels
    cv::Mat xy[2]; //X,Y
    cv::split(flow, xy);
    
    //calculate angle and magnitude
    cv::Mat magnitude, angle;
    cv::cartToPolar(xy[0], xy[1], magnitude, angle, true);
    
    //translate magnitude to range [0;1]
    double mag_max;
    cv::minMaxLoc(magnitude, 0, &mag_max);
    magnitude.convertTo(magnitude, -1, 1.0 / mag_max);
    
    //build hsv image
    cv::Mat _hsv[3], hsv;
    _hsv[0] = angle;
    _hsv[1] = cv::Mat::ones(angle.size(), CV_32F);
    _hsv[2] = magnitude;
    cv::merge(_hsv, 3, hsv);
    
    //convert to BGR and show
    cv::Mat bgr;//CV_32FC3 matrix
    cv::cvtColor(hsv, bgr, cv::COLOR_HSV2BGR);
    cv::imshow("optical flow", bgr);
    
    cv::waitKey(0);
    
    0 讨论(0)
  • 2021-02-05 22:43

    The MPI Sintel Dataset provides C and MatLab code for visualizing computed flow. Download the ground truth optical flow of the training set from here. The archive contains a folder flow_code containing the mentioned source code.

    You can port the code to OpenCV, however, I wrote a simple OpenCV wrapper to easily use the provided code. Note that the method MotionToColor is taken from the color_flow.cpp file. Note the comments in the listing below.

    // Important to include this before flowIO.h!
    #include "imageLib.h"
    #include "flowIO.h"
    #include "colorcode.h"
    // I moved the MotionToColor method in a separate header file.
    #include "motiontocolor.h"
    
    cv::Mat flow;
    // Compute optical flow (e.g. using OpenCV); result should be
    // 2-channel float matrix.
    
    assert(flow.channels() == 2);
    // assert(flow.type() == CV_32F);
    
    int rows = flow.rows;
    int cols = flow.cols;
    
    CFloatImage cFlow(cols, rows, 2);
    
    // Convert flow to CFLoatImage:
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            cFlow.Pixel(j, i, 0) = flow.at<cv::Vec2f>(i, j)[0];
            cFlow.Pixel(j, i, 1) = flow.at<cv::Vec2f>(i, j)[1];
        }
    }
    
    CByteImage cImage;
    MotionToColor(cFlow, cImage, max);
    
    cv::Mat image(rows, cols, CV_8UC3, cv::Scalar(0, 0, 0));
    
    // Compute back to cv::Mat with 3 channels in BGR:
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            image.at<cv::Vec3b>(i, j)[0] = cImage.Pixel(j, i, 0);
            image.at<cv::Vec3b>(i, j)[1] = cImage.Pixel(j, i, 1);
            image.at<cv::Vec3b>(i, j)[2] = cImage.Pixel(j, i, 2);
        }
    }
    
    // Display or output the image ...
    

    Below is the result when using the Optical Flow code and example images provided by Ce Liu.

    Example images provided by Ce Liu.

    Optical flow computed using the implementation provided by Ce Liu.

    0 讨论(0)
提交回复
热议问题