OpenCV C++ 3维Mat数据访问错误值

问题描述 投票:0回答:1

我是用C++ OpenCV DNN把结果放到Mat中的。在这里。dnnResult 是输出Mat。输出值是浮点数。我想提取 66 值到 3 独立的数组或 3 x 66 矩阵。

dnnResult.size[0] = 3
dnnResult.size[1] = 1
dnnResult.size[2] = 66
dnnResult.dims = 3

我试着这样循环取值,但结果是错误的。从3D Mat中访问出界数据没有错误。

for(int m = 0; m < 3; m++){
    for(int n = 0; n < 66; n++){
        myNetOutput2d[m][n] = dnnResult.at<double>(m, 0, n);    
    }
}

我也试过以下方法 如何访问三维矩阵元素?,

typedef Vec<double, 66> Vec66d;
for(int m = 0; m < 3; m++){
    for(int n = 0; n < 66; n++){
        Vec66d tmp_vec66d = dnnResult.at<double>(0, m);
        myNetOutput2d[m][n] = tmp_vec66d.val[n];

    }
}

我想用python的方法来获取大小的等价物。66 成3个独立的数组。

arr1, arr2, arr3 = dnnResult
c++ opencv mat
1个回答
1
投票

改变dnnResult.at<double>(..)dnnResult.at<float>(..)

+ 更多信息 cv::Mat::at

template<typename _Tp> inline
_Tp& Mat::at(int i0, int i1, int i2)
{
    CV_DbgAssert( elemSize() == sizeof(_Tp) );
    return *(_Tp*)ptr(i0, i1, i2);
}

inline
const uchar* Mat::ptr(int i0, int i1, int i2) const
{
    CV_DbgAssert(dims >= 3);
    CV_DbgAssert(data);
    CV_DbgAssert((unsigned)i0 < (unsigned)size.p[0]);
    CV_DbgAssert((unsigned)i1 < (unsigned)size.p[1]);
    CV_DbgAssert((unsigned)i2 < (unsigned)size.p[2]);
    return data + i0 * step.p[0] + i1 * step.p[1] + i2 * step.p[2];
}

cv::Mat 用一个原始指针保存数据,而 cv::Mat::at<_Tp> 访问它的数据,并将指针投向 _Tp*. 指数没有出界,但实际数据是从出界中得到的,因为 double64 bitfloat32 bit 在OpenCV中。

所以,你必须在 知道cv::Mat的正确类型。

如果你想把数据投向 double,你必须在得到正确的数据后再投。

myNetOutput2d[m][n] = (double)dnnResult.at<float>(m, 0, n);

或者,将 dnnResult的类型为 double 在访问它之前,。

dnnResult.convertTo(dnnResult, CV_64F); 
...
myNetOutput2d[m][n] = dnnResult.at<double>(m, 0, n);
© www.soinside.com 2019 - 2024. All rights reserved.