C++ RGB图像的特征阵列

C++ RGB图像的特征阵列,c++,arrays,image-processing,rgb,eigen,C++,Arrays,Image Processing,Rgb,Eigen,我正在尝试使用特征库进行一些简单的图像处理。我会使用Array3f作为RGB三元组,使用数组保存RGB图像。这似乎部分起作用,我可以方便地对图像进行组件式的加法、乘法和除法。但某些操作(特别是涉及减法或求反)似乎会产生编译错误。下面是一个简单的例子: #include <Eigen/Core> using namespace Eigen; int main(void) { typedef Array<Array3f, Dynamic, Dynamic> MyA

我正在尝试使用特征库进行一些简单的图像处理。我会使用Array3f作为RGB三元组,使用数组保存RGB图像。这似乎部分起作用,我可以方便地对图像进行组件式的加法、乘法和除法。但某些操作(特别是涉及减法或求反)似乎会产生编译错误。下面是一个简单的例子:

#include <Eigen/Core>

using namespace Eigen;

int main(void)
{
    typedef Array<Array3f, Dynamic, Dynamic> MyArray;
    MyArray m(2,2);

    // all of the following should have the same mathematical effect

    Array3f v = -Array3f(5.0f);             // this compiles

    MyArray a = m + v;                      // this compiles
    MyArray b = m + Array3f(-5.0f);         // this compiles
    MyArray c = m + (-Array3f(5.0f));       // this doesn't compile
    MyArray d = m - Array3f(5.0f);          // this doesn't compile
}
#包括
使用名称空间特征;
内部主(空)
{
typedef数组MyArray;
mym阵列m(2,2);
//以下所有内容应具有相同的数学效果
Array3f v=-Array3f(5.0f);//编译
MyArray a=m+v;//编译
MyArray b=m+Array3f(-5.0f);//编译
MyArray c=m+(-Array3f(5.0f));//这不会编译
MyArray d=m-Array3f(5.0f);//这不可编译
}
上面的代码给了我三个错误:

./Eigen/src/Core/CwiseBinaryOp.h:128:7: error: no member named
      'YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY' in
      'Eigen::internal::static_assertion<false>'
      EIGEN_CHECK_BINARY_COMPATIBILIY(BinaryOp,typename Lhs::Scalar,typename Rhs::Scalar);
...

./Eigen/src/Core/CwiseBinaryOp.h:187:14: error: no matching function for call to object of type 'const
      Eigen::internal::scalar_sum_op<Eigen::Array<float, 3, 1, 0, 3, 1> >'
      return derived().functor()(derived().lhs().coeff(index),
...

./Eigen/src/Core/../plugins/ArrayCwiseBinaryOps.h:208:10: error: no viable conversion from 'const
      CwiseBinaryOp<internal::scalar_sum_op<Scalar>, const Eigen::Array<Eigen::Array<float, 3, 1, 0, 3, 1>, -1, -1, 0, -1, -1>, const
      Eigen::CwiseUnaryOp<Eigen::internal::scalar_opposite_op<float>, const Eigen::Array<float, 3, 1, 0, 3, 1> > >' to 'const
      CwiseUnaryOp<internal::scalar_add_op<Scalar>, const Eigen::Array<Eigen::Array<float, 3, 1, 0, 3, 1>, -1, -1, 0, -1, -1> >'
  return *this + (-scalar);
...
/Eigen/src/Core/CwiseBinaryOp.h:128:7:错误:未指定任何成员
“您混合了不同的数值类型,您需要使用矩阵的方法来显式转换数值类型”
'Eigen::internal::static_断言'
特征检查二进制兼容性(BinaryOp,typename Lhs::Scalar,typename Rhs::Scalar);
...
./Eigen/src/Core/CwiseBinaryOp.h:187:14:错误:没有匹配函数用于调用“const”类型的对象
特征::内部::标量和'
返回派生函数().functor()(派生函数().lhs().coeff(索引),
...
./Eigen/src/Core/。/plugins/arrayWiseBinaryOps.h:208:10:错误:从“const”没有可行的转换
CwiseBinaryOp“到”常量
CwiseUnaryOp'
返回*此+(-标量);
...

我认为Eigen不应该以这种方式使用(向量是“标量”类型)。我不知道是什么原因导致一些表达式编译,但对于那些没有编译的表达式,这是因为Eigen在两个
数组上看到了
+
操作,左侧数组的标量=
数组3f
,右侧数组的标量=
浮点
,并将其标记为不兼容。

问题是Eigen使用了延迟求值而
(-Array3f(5.0f))
实际上是一个表达式,而不是一个数组。我不确定到底是什么失败了,我现在没有足够的时间来研究它。在我继续之前,我必须说
Array3f(float)
没有有效的构造函数,我将继续回答
Array3f(5.0f,4.0f,3.1f)

简单快捷的破解方法是强制求反数组的值,并使用
+
操作

MyArray c = m + (-Array3f(5.0f, 4.0f, 3.1f)).eval();

工作。优点:快速实现。缺点:没有延迟计算,因为
eval()
将创建一个新的否定数组。这也会使代码更难看。

如果有人感兴趣:上面的示例使用Eigen 3.3rc1编译并运行良好(最有可能的是,因为Eigen 3.3-alpha也很好)


我仍然认为这个特性是实验性的,因为它既不是文档化的,也不是测试套件的一部分(就我所见)。

我不明白为什么这应该是一个问题。解释使用自定义标量类型的要求,Araya3f本身似乎满足了所有这些要求。也就是说,它1)。重载标准算术运算符,2)专门处理NumTraits,3)重载有意义的数学函数。请注意,如果我使用自己的Color3f类(它不是从Array3f继承的)进行定义,则一切正常。同样值得注意的是,Array3f可以很好地进行加法、乘法和除法运算。仅减法和求反失败。请注意,对于这样小的固定大小数组,显式求值不是问题,因为值保留在寄存器中,并且没有创建实际的临时值。这似乎是一个不令人满意的解决方法(即使速度很快)。上下文:目标是使用特征数组类作为框架中颜色数据的容器,作为家庭作业的一部分分发给大学生。要求学生在各种特殊情况下调用eval()可能会导致很多混乱和令人沮丧的调试过程。