Using Custom Array Arrays for RGB Images

I am trying to use the Eigen library for some simple image processing. I would use Array3f for the triple of RGB and Array to store the RGB image. This seems to work partially, and I can conveniently perform component addition, multiplication, and division of images. But some operations (in particular, subtraction or negation) seem to create compilation errors. Here is a minimal example:

#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 } 

The above code gives me three errors:

 ./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); ... 
+6
source share
3 answers

I think Eigen was not intended to be used that way (with vectors like "scalar" types). I donโ€™t know what causes some of the expressions to compile, but for those that donโ€™t, because Eigen sees a + operation on two Array s with the left array Array = Array3f , on the right Scalar array = float and a flag that it is incompatible.

0
source

The problem is that Eigen uses lazy evaluation and that (-Array3f(5.0f)) is actually an expression, not an array. I donโ€™t know exactly what happened, and I donโ€™t have enough time to study it right now. Before continuing, I have to say that there is no valid constructor for Array3f(float) and instead it will continue to respond with Array3f(5.0f, 4.0f, 3.1f) .

A simple quick and easy hack would be to force a negative array to be evaluated and use the + operation. Not perfect for many reasons, but

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

works. Advantage: quickly implemented. Disadvantage: there is no lazy evaluation, as eval() will create a new negative array. Also makes the code much uglier.

0
source

In case anyone is interested: the above example compiles and works fine with Eigen 3.3rc1 (most likely, everything starting with Eigen 3.3-alpha is also great).

I would still consider this function as experimental, since it is not documented, nor part of the test suite (as far as I can see).

0
source

All Articles