我可以以任何方式从 OpenCV 对象取消引用中将数据分配给双重函数返回检索吗?

Posted

技术标签:

【中文标题】我可以以任何方式从 OpenCV 对象取消引用中将数据分配给双重函数返回检索吗?【英文标题】:Can I assign data to a double function return retrievd from an OpenCV object dereference in ANY way? 【发布时间】:2014-03-14 09:57:08 【问题描述】:

这可能看起来很愚蠢?但我刚刚发现我认为用另一种语言不可能的事情是可能的,所以我必须尝试。

double cv_Mat_at_double(Mat* self, int i, int j) 
  return self->at<double>(i, j);

是我所指的函数。在 opencv 中,您可以通过调用 'M.at(i, j) = 1' 将数据分配给矩阵 M。在我上面的函数中,我想知道是否有任何方法可以进入双重返回并获取它刚刚来自的对象以为其设置数据。无论如何,我并不反对骇客或打破常规。但它必须使用 .at 对象包装器。我试过了:

函数调用为:

  double cv_Mat_at_double(Mat* self, int i, int j) 
     return self->at<double>();
  

 //Imagine a 2x2 Matrix filled with data,  (a 1 at element 0x0) here
 double i = cv_Mat_at_double(H, 0, 0);
 cout << i; (output> 1)
 i = 2;
 cout << i; (output> 2)
 cout << cv_Mat_at_double(H, 0, 0); (output> 1)

改成

double cv_Mat_at_double(Mat* self, int i, int j) 
  return self->at();


Error = .at expects an argument

Mat* cv_Mat_at_double(Mat* self, int i, int j) 
  return self->at<double>();

Error = can't return double as pointer

我知道我能做到这一点

double cv_Mat_at_double_Val(Mat* self, int i, int j, double val) 
   return  self->at<double>(i,j)=val;

但我希望上面的函数 cv_Mat_at_double 仅返回 Mat 对象的 i,j 元素的值能够设置矩阵元素的值,而不会使上述 3 个函数变得更重。就像我可以采用我在顶部发布的第一个函数......并且只需破解双重返回的想法并使用它来设置矩阵元素。但至少我会很高兴我能得到一个 Mat::at 的包装器,它既可以读写矩阵元素,又不比 cv_Mat_at_double 重(cpu 使用率)。这篇文章是关于打破惯例并让它发生的,所以我强调黑客的想法,因为我还没有读到你可以做到这一点,但也许我没有问正确的问题。 提前感谢您对此提供的任何帮助。

编辑:

我想知道是否有办法编写您发布的函数,如下所示...将 Mat 对象参数更改为 Mat*。很抱歉,我之前忽略了作为要求之一 =) 我以后会更加小心。

我所有的 Mat 类包装器都使用 Mat* 返回并接受 Mat* 参数,并且有大约 2000 行代码......这实际上是 C++ OpenCV 函数 Mat::at 的 C 包装器。如下包装,我收到一条错误消息,而不是在编译器中,它编译得很好,但我实际上是用第三种语言包装的,这得到了一个未处理的内存错误错误,并在 ubuntu 上使用 g++ 在 emacs 中按原样(如下)编译包装器值得信赖,我遇到了很多错误...没有发布它们,因为它会很长。

不知道为什么在终端中使用 g++ 编译有效,但 emacs 和我的其他语言无法编译...感谢您提供更多帮助

 double &cv_Mat_at_double(Mat* &M, int i, int j)  
    return M->at<double>(i,j); 

【问题讨论】:

@edward monney ?那一定是你;) 这里是什么意思? “但我希望返回 0x0 处的值的函数也能够设置值” @berak,对此感到抱歉...为了清楚起见,我进行了编辑。 他的意思是可以为 cv::Mat 做一个数组运算符 []。 【参考方案1】:

您可以返回对双精度的引用而不是值:

double &cv_Mat_at_double(cv::Mat &M, int i, int j) 
    return M.at<double>(i,j);

然后您可以将 cv_Mat_at_double 用作左值或右值:

cv::Mat M = (cv::Mat_<double>(2,2) << 1, 0, 0, 0);
std:: cout << cv_Mat_at_double(M, 0, 0) << std::endl; // prints 1
cv_Mat_at_double(M, 0, 0) = 2;
std:: cout << cv_Mat_at_double(M, 0, 0) << std::endl; // prints 2

编辑:带有指向 cv::Mat: 的指针的版本:

double &cv_Mat_at_double(cv::Mat* M, int i, int j)  
    return M->at<double>(i,j); 

(您只需删除 '&')。

EDIT2:仅引用 Mat 对象。

cv::Mat M = (cv::Mat_<double>(2,2) << 1, 0, 0, 0);
std:: cout << cv_Mat_at_double(&M, 0, 0) << std::endl; // prints 1
cv_Mat_at_double(&M, 0, 0) = 2;
std:: cout << cv_Mat_at_double(&M, 0, 0) << std::endl; // prints 2

【讨论】:

在忘记提及与代码有关的必要性之前,我接受了您的回答,您是否可以查看我的最新编辑,到目前为止,我非常感谢您的帮助。 非常感谢 marol,你真的帮了我很多。我什至对你的代码进行了基准测试,十亿次迭代大约需要 40 秒。所以你的想法很快,它教会了我很多东西。 .感谢您帮助我进行所有这些编辑...祝您有美好的一天。

以上是关于我可以以任何方式从 OpenCV 对象取消引用中将数据分配给双重函数返回检索吗?的主要内容,如果未能解决你的问题,请参考以下文章

在YUV_420_888中将图像从Android发送到OpenCV Mat中的JNI的最有效方式

删除通过取消引用新对象初始化的对象

如何以编程方式取消从 InputStream 中读取?

在 Opencv 中将数据放入 Mat 对象中

从 GDB 中的列表中打印取消引用的值

从Powerpoint添加对Excel对象库的引用