OpenCV C++ 3 维垫数据访问错误值
OpenCV C++ 3 Dimensional Mat Data Access Wrong Values
我正在使用 C++ OpenCV DNN 将结果放入垫子中。这里,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
改变
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*
来访问其数据。索引没有越界,但实际数据是越界的,因为double
是64 bit
,而float
在OpenCV中是32 bit
。
因此,在访问它时,您必须知道您是 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);
我正在使用 C++ OpenCV DNN 将结果放入垫子中。这里,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
改变
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*
来访问其数据。索引没有越界,但实际数据是越界的,因为double
是64 bit
,而float
在OpenCV中是32 bit
。
因此,在访问它时,您必须知道您是 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);