1

我目前正在从事一个涉及运动补偿的项目。

此时我在 cv::Mat 输入中有输入图像;

cv::resize( input, input_resized, cvSize(64,48), 12, 12, CV_INTER_AREA);
input_resized.convertTo(input_float, CV_32F); //this might be redundant while cv::rezise dst should be 32F.

现在运动矢量存储在 2 通道 cv::Mat 运动中,它的存储方式如下:

// w -image.width , h-image.height
    X0  Y0  X1   Y1   X2   Y2   ...  Xw-1  Yw-1      
    Xw  Yw  Xw+1 Yw+1 Xw+2 Yw+2 ...  X2w-1 Y2w-1
    ...
    X(h-1)w Y(h-1)w   ............. X(h-1)(w-1)Y(h-1)(w-1)

所以如果我使用:

std::vector<cv::Mat> motionvect(2);
cv::split(motion, motionvect);

我将在motionvect(0) 中获得X,在motionvect2(1) 中获得Y。

此外,我尝试过:

std::vector<cv::Mat> rgbChannels(3);
cv::split(input_float, rgbChannels);
cv::remap(rgbChannels[0], outChannels[0], motionvect[0], motionvect[1], CV_INTER_LINEAR, IPL_BORDER_CONSTANT, cvScalar(0,0, 0));
cv::remap(rgbChannels[1], outChannels[1], motionvect[0], motionvect[1], CV_INTER_LINEAR, IPL_BORDER_CONSTANT, cvScalar(0,0, 0));
cv::remap(rgbChannels[2], outChannels[2], motionvect[0], motionvect[1], CV_INTER_LINEAR, IPL_BORDER_CONSTANT, cvScalar(0,0, 0));

cv::merge(outChannels, input_with_motion);

我得到的结果很奇怪,有人告诉我这是因为 Y 向量。显然,如果 X 是这样的:

1  2  3  4  5
6  7  8  9  10
11 12 13 14 15

那么 Y 应该是:

1  6  11  
2  7  12  
3  8  13
4  9  14
5  10 15

那是对的吗?转置矩阵的排序。如果是真的,是否有任何功能可以将 motiovect[2] 更改为这样,或者我应该为每个单独的组件执行此操作?

此外,对于最后一步,我需要在我的流程中的不同时间应用重新映射。像这样的东西:

Function1 ( (float*) input_float.data , (float*) motion.data, (unsigned char*) out.data );
   Function2 ( float* input, float* R, float* G, float* B);
   Function3 ( float* R, float* G, float* B, float* W, float* Z);

其中 R、G、B、W、Z 是 float* 类型,它们分配有

 R = (float*) malloc (frame_size * sizeof(float) );

我需要对 float* A 和 float* B 应用运动补偿,但这些输入不允许重新映射。它们必须是 InputArray,我找不到任何方法将 float* 转换为任何可接受的 InputArray 类型。

我知道我的想法不是很有条理,但我希望你至少能理解我的一个问题。1. 如果我将运动矢量存储在 cv::Mat 中,例如 x0 y0 x1 y1 ..,如何应用重映射?2. 我可以将 float* 转换为 cv::remap 的可接受输入吗?

4

2 回答 2

2

我发现本教程http://docs.opencv.org/doc/tutorials/imgproc/imgtrans/remap/remap.html对于了解如何设置 map1、map2 参数非常有用。最后是这样的:

for(int i=0; i< rows; i++){
        for(int j=0; j<col; j++)
            { 
             map_x.at<float>(i,j) = j + motion_vect.ptr<float>(i)[2*j+0];
             map_y.at<float>(i,j) = i + motion_vect.ptr<float>(i)[2*j+1];;
        }}

要将输出图像作为原始图像:

map_x.at<float>(i,j) = j ;
map_y.at<float>(i,j) = i ;
于 2013-12-06T10:25:38.143 回答
0

对于您的#2,您可以这样做以将浮点值从指针获取到某个 Mat 中:

cv::Mat testMat = cv::Mat::zeros(2, 3, CV_32F);
std::cout << "(1, 2) elem = " << testMat.at<float>(1, 2) << std::endl;

float* pTestVal = new float;
*pTestVal = 3.14F;
testMat.at<float>(1, 2) = *pTestVal;
delete pTestVal;

std::cout << "(1, 2) elem = " << testMat.at<float>(1, 2) << std::endl;
于 2013-12-05T02:17:11.997 回答