OpenCV отображает 2-канальное изображение (оптический поток) - PullRequest
9 голосов
/ 08 октября 2011

У меня есть оптический поток, сохраненный в 2-канальной матрице 32F. Я хочу визуализировать содержимое. Какой самый простой способ сделать это?

Как мне преобразовать CV_32FC2 в RGB с пустым синим каналом, что imshow может обработать? Я использую OpenCV 2 C ++ API.

Супер бонусные баллы

В идеале я бы получил угол потока в оттенке и величину в яркости (с насыщением при постоянном 100%).

Ответы [ 2 ]

20 голосов
/ 08 октября 2011

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);
5 голосов
/ 23 марта 2015

В наборе 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 .

Example images provided by Ce Liu.

Optical flow computed using the implementation provided by Ce Liu.

...