【问题标题】:conversion between c++ class and OpenCV matrix operationc++类与OpenCV矩阵运算之间的转换
【发布时间】:2012-09-23 12:41:28
【问题描述】:

我正在尝试将以下 c++ 行转换为 OpenCV 矩阵运算(也是 c++):

double myCode::calculate ( int i, int au )
{
    double k;
    for ( int j = 0; i < N; i ++ );
    {
         k += fabs(data[i][j] - means[au][j]);            
    }
}

我想将“data”和“means”定义为openCV矩阵类型,比如:

cv::Mat data ( NUMBER_OF_OBSERVATIONS, N, CV_8UC3 );
cv::Mat means = cv::Mat.zeros ( 5, N, CV_8UC3 );

然后为这个 cvMat 类型“数据”和“手段”重复上面的类。我怎样才能做到这一点?特别是我不知道该怎么做:

k += fabs(data[i][j] - means[au][j]); 

非常感谢。

【问题讨论】:

  • 删除for 循环开始处的; 可能是有意义的。此外,cv::Mat.zeros 实际上应该是 cv::Mat::zeros
  • 我误写了“;”在这里,但在我的代码中没有“;”在for循环行中,除了我用“cv::Mat::zeros”替换了“cv::Mat.zeros”,但“fabs”功能仍然无法工作。

标签: c++ opencv for-loop matrix type-conversion


【解决方案1】:

你可以简单地写

double myCode::calculate ( int i, int au )
{
    cv::Scalar res = sum(avg(data(RowRange(i)) - means(RowRange(au))));
    return res[0] + res[1] + res[2]; // sum all the channels together
}

请注意,RowRange() 实际上不是正确的语法 - 请查看 OpenCV 文档以了解 Range() 的正确用法,但这就是想法。

【讨论】:

  • 感谢您的回答,但它说“总和”未定义。但我已经包含了“math.h”和“stdio.h”。这可能是太低级别的错误,但我仍然无法修复它。你有什么建议吗?
  • sum 来自 opencv 核心 try cv::sum(cv::abs(...))
  • 再次感谢您。我用“cv::sum(cv::abs(...))”替换了“sum(avg(...))”,但现在它说“不存在从 cv::Scalar 到 double 的合适转换函数” .我认为 cv::sum 返回一个 cv::Scalar,但我的类是 double 类型。我再次需要你的帮助,谢谢。
  • 稍微看一下文档会对您有所帮助...但无论如何,我会更正该功能。预计会出现其他一些错误 - 请检查文档以了解 Range() 的正确用法
  • 我已经检查并用作“cv::Mat.rowRange”,并将类类型从“double”更改为“cvScalar”,并且它有效。非常感谢。
【解决方案2】:

在 OpenCV Mat 对象中访问像素的简单方法是使用 at() 运算符。 如果您的数据类型是 1 通道无符号字符 (CV_8UC1),您可以这样做:

k += fabs(data.at<uchar>(i,j) - means.at<uchar>(i,j)); //works for CV_8UC1 type

但是,您有 3 个通道(R、G、B),由 CV_8UC3 数据类型中的 C3 指定。因此,以下是您在每个频道上的 k += fabs(...) 分别如何操作:

//for CV_8UC3 type
k += fabs(data.at<cv::Vec3b>(i,j)[0] - means.at<cv::Vec3b>(i,j)[0]); // Blue Channel
k += fabs(data.at<cv::Vec3b>(i,j)[1] - means.at<cv::Vec3b>(i,j)[1]); // Green Channel
k += fabs(data.at<cv::Vec3b>(i,j)[2] - means.at<cv::Vec3b>(i,j)[2]); // Red Channel

This post 提供有关像素访问的进一步说明。

【讨论】:

  • 我试过你的代码,但它说:“Vec3b”没有定义。你有什么主意吗?谢谢。
  • 尝试在.cpp 文件的顶部声明using namespace cv;,或者将Vec3b 替换为cv::Vec3b
  • 我在上面的代码中用cv::Vec3b 替换了Vec3b。让我知道这是否有效。
  • 我试过了,那个错误似乎已经解决了,但不是它不能识别“fabs”。它说:多个重载函数“fabs”实例与参数列表匹配。
  • 啊哈,我想我明白了。 fabs() 喜欢浮点(float 或 double)数据类型。我认为编译器在抱怨,因为 fabs 并没有真正为 char 数据定义。我认为转换为 double 应该可以解决它:fabs((double)data.at&lt;cv::Vec3b&gt;(i,j)[0] - (double)means.at&lt;cv::Vec3b&gt;(i,j)[0]);
猜你喜欢
  • 2012-09-18
  • 1970-01-01
  • 1970-01-01
  • 2016-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-02
  • 1970-01-01
相关资源
最近更新 更多