Использование собственных массивов массивов для изображений RGB

95
11

Я пытаюсь использовать библиотеку Eigen для некоторой простой обработки изображений. Я бы использовал Array3f для тройки RGB и Array для хранения 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
}


Приведенный выше код дает мне три ошибки:


./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);
...

спросил(а) 2020-03-25T21:31:05+03:00 1 неделя, 4 дня назад
1
Решение
81

Проблема в том, что 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() создаст новый отрицательный массив. Также делает код намного уродливее.

ответил(а) 2020-03-25T21:42:17.436688+03:00 1 неделя, 4 дня назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема