OpenCV 显示 2 通道图像(光流)

发布于 2024-12-08 21:28:22 字数 208 浏览 0 评论 0原文

我将光流存储在 2 通道 32F 矩阵中。我想可视化内容,最简单的方法是什么?

如何将 CV_32FC2 转换为带有空蓝色通道的 RGB(imshow 可以处理)?我正在使用 OpenCV 2 C++ API。

超级奖励点

理想情况下,我会得到色调的流动角度和亮度的大小(饱和度恒定为 100%)。

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 RGB with an empty blue channel, something imshow can handle? I am using OpenCV 2 C++ API.

Super Bonus Points

Ideally I would get the angle of flow in hue and the magnitude in brightness (with saturation at a constant 100%).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

飞烟轻若梦 2024-12-15 21:28:22

imshow 只能处理 1 通道灰度和 3-4 通道 BRG/BGRA 图像。所以你需要自己做一个转换。

我认为你可以做类似的事情:

//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);

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);
黑色毁心梦 2024-12-15 21:28:22

MPI Sintel 数据集 提供用于可视化计算流的 C 和 MatLab 代码。从此处下载训练集的地面真实光流。该存档包含一个文件夹flow_code,其中包含上述源代码。

您可以将代码移植到 OpenCV,但是,我编写了一个简单的 OpenCV 包装器来轻松使用提供的代码。请注意,MotionToColor 方法取自 color_flow.cpp 文件。请注意下面列表中的注释。

// 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 ...

下面是使用 Ce Liu 提供的光流代码和示例图像时的结果。

示例图像由刘策提供。

使用刘策提供的实现计算光流。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文