所以我有这段代码:
if(channels == 3)
type = CV_32FC3;
else
type = CV_32FC1;
cv::Mat M(rows,cols,type);
std::cout<<"Cols:"<<cols<<" ColsMat:"<<M.cols<<std::endl;
float * source_data = (float*) M.data;
// copying the data into the corresponding pixel
for (int r = 0; r < rows; r++)
{
float* source_row = source_data + (r * rows * channels);
for (int c = 0; c < cols ; c++)
{
float* source_pixel = source_row + (c * channels);
for (int ch = 0; ch < channels; ch++)
{
std::cout<<"Row:"<<r<<" Col:"<<c<<" Channel:"<<ch<<std::endl;
std::cout<<"Type check: "<<typeid(T_M(0,r,c,ch)).name()<<std::endl;
float* source_value = source_pixel + ch;
*source_value = T_M(0, r, c, ch);
}
}
}
T_M是Eigen :: Tensor
我首先想到的是我从T_M那里得到了错误,但事实并非如此。
我尝试访问* source_value,我很确定这是错误的来源。
有趣的是,我不会在最后或开始时得到错误。我在中间得到了seg故障。 例如,行:915,cols:793,以及通道:1
我在Row收到错误:829 Col:729频道:0。
我无法弄清楚这个错误的来源。
答案 0 :(得分:2)
您计算的行指针错误,应该是cols
而不是rows
:
float* source_row = source_data + (r * cols * channels);
一般来说,当你使用矩阵的平面表示时,你必须非常小心,它确实容易出错。
答案 1 :(得分:2)
如果矩阵是连续的,Jean-FrançoisFabre的答案将起作用。如果您无法确定(例如,如果矩阵由其他人提供,如果您使用子矩阵等),则应使用widthstep功能来计算行指针:
float* source_row = (float*)(M.data + r*M.step);
这会自动使用正确数量的通道,填充等
更简单的是直接使用row-ptr函数:
float* source_row = (float*)(M.ptr(r));