【问题标题】:How to access data from cv::Mat如何从 cv::Mat 访问数据
【发布时间】:2013-06-26 06:21:21
【问题描述】:

我有一个cv::Mat,它具有以下大小480 x 640 x 32

您能告诉我如何访问此结构中的数据吗?假设我想从位置[2, 2, 2] 访问元素。我该怎么做?

编辑 1:

我曾尝试使用此template<typename T> const T& Mat::at(int i, int j, int k) const,但收到以下运行时错误:

编辑 2:

这是我使用代码的方式:

cv::Mat f(382,510,32); 
f=Utils::toMat(features); 
cout<<f.at<double>(1,1,1); 

toMat 的详细信息如下。

cv::Mat Utils::toMat( mxArray* p_)
{
mwSize ndims_= mxGetNumberOfDimensions(p_);
const mwSize* dims=mxGetDimensions(p_);
std::vector<int> d(dims, dims+ndims_);
int ndims = (d.size()>2) ? d.size()-1 : d.size();
int nchannels = (d.size()>2) ? *(d.end()-1) : 1;
int depth=CV_64F;
std::swap(d[0], d[1]);
cv::Mat mat(ndims, &d[0], CV_MAKETYPE(depth, nchannels));
// Copy each channel.
std::vector<cv::Mat> channels(nchannels);
std::vector<mwSize> si(d.size(), 0); // subscript index
int type = CV_MAKETYPE(depth, 1); // Source type
for (int i = 0; i<nchannels; ++i)
{
    si[d.size()-1] = i;
    void *pd = reinterpret_cast<void*>(
            reinterpret_cast<size_t>(mxGetData(p_))+
            mxGetElementSize(p_)*mxCalcSingleSubscript(p_, si.size(), &si[0]));
    cv::Mat m(ndims, &d[0], type, pd);
    // Read from mxArray through m
    m.convertTo(channels[i], CV_MAKETYPE(depth, 1));
}
cv::merge(channels, mat);
return  mat;
}

【问题讨论】:

  • 你为什么在其中定义/创建你的 Mat?您必须调用at 函数的方式很大程度上取决于此。另外,发布您调用at 函数的代码
  • cv::Mat f(382,510,32); f=Utils::toMat(特征); cout(1,1,1);基本上,toMat,将一个 mxArray 转换为一个 cv::mat 结构
  • 你能告诉更多关于这个Utils::toMat的信息吗?如果能贴出代码就更好了。问题 100% 出在那儿。
  • 我已经在问题正文中添加了代码
  • Hmmmmm 首先,你弄错了 cv::Mat docs.opencv.org/modules/core/doc/basic_structures.html#mat-mat 的构造函数:值 32 被用作类型!

标签: c++ opencv


【解决方案1】:
> cv::Mat f(382,510,32);

首先,你弄错了 cv::Mat http://docs.opencv.org/modules/core/doc/basic_structures.html#mat-mat 的构造函数:你的值 32 被用作类型,导致一些未定义的行为。

你必须使用这个

 Mat::Mat(int ndims, const int* sizes, int type)

 const int[] mySizes = {382,510,32}; //I hope I have written this correctly...
 cv::Mat f(3,mySizes,CV_64F). // You find CV_64 in the same documentation page.

然后,您的 Utils::toMat 函数看起来很难调试...我建议您阅读更多有关文档的内容,并可能使用 @987654328 重新实现矩阵的初始化(填充) @方法:

 f.at<double>(x,y,z) = ...

【讨论】:

  • 为什么这种方法不适用于普通图像?我正在尝试使用cv::Mat image = imread("D:\\img.jpg") 读取一个简单的图像,并尝试使用以下指令访问像素值:cout&lt;&lt;image.at&lt;double&gt;(1,1,1)&lt;&lt;endl; 为什么会崩溃?它返回的错误与问题正文的打印屏幕错误中显示的错误相同。
  • @Simon 答案很简单:当您使用 cv::Mat::at() 时,您必须能够正确指定您正在阅读的 cv::Mat 的本机类型。对于 8 位深度的彩色图像,您必须顺便使用 image.at(x,y):jpg 图像只有 2 个维度。这是 vec 的文档:docs.opencv.org/modules/core/doc/basic_structures.html#vec 关于主题“了解 cv::Mat 中的原生类型”,这可能会很有趣:stackoverflow.com/questions/10167534/…
【解决方案2】:

你可以使用.at&lt;element_type&gt;(i,j,k);

reference

template<typename T> const T& Mat::at(int i, int j, int k) const

【讨论】:

    猜你喜欢
    • 2012-11-12
    • 2018-03-26
    • 1970-01-01
    • 2021-05-23
    • 2020-04-08
    • 1970-01-01
    • 1970-01-01
    • 2014-06-21
    • 1970-01-01
    相关资源
    最近更新 更多