Maecky
Maecky

Reputation: 2038

OpenCv use exp with Mat

I want to perform a Matrix calculation in OpenCV according to this formula:

newMat = 1 / ( 1 + exp( scalar * ( otherScalar - Matrix ) ) )

Is there an easy way to do this in OpenCV or do I have to calculate this in a for loop? The main problem for me is the exp( Matrix ).

Regards

Upvotes: 0

Views: 6112

Answers (3)

Barney Szabolcs
Barney Szabolcs

Reputation: 12544

@Maecky the chances are you just wrote a bug in your answer.

1+A usually means I+A and 1/A means inversion (that is A^{-1}) where I is the identity matrix -- called eye in matlab and in opencv. (Moreover F/A === F*A^{-1})

In your solution you are adding an all-one matrix to newMat (called ones in matlab and in opencv), not eye.

Correctly (that is calculating (I + exp(scalar*(otherScalar*I-Matrix)))^{-1} ):

using namespace cv;
Size s = Matrix.size();
int t = Matrix.type();
Mat newMat;
Mat I = Mat::eye(s,t);

exp( scalar * ( otherScalar*I - Matrix ), newMat );
newMat = (I + newMat).inv();

Upvotes: 0

Sam
Sam

Reputation: 20056

Maecky's answer is perfectly fine - for 1-channel images.

The fun starts if your image has more than one channel. For some reasons,

float(scalar) - _3ChannelMat

applies the operation only on the first channel, while multiplication

float(scalar2) * _3channelMat

is done on all the channels of the image. Funny, isn't it?

The solution is to use cv::Scalars:

newMat = cv::Scalar(0.4, 0.4, 0.4) * ( cv::Scalar(255, 255, 255) - _3channelMat);

I have filed a bug a while ago on this strange behaviour, but no answer yet.

Upvotes: 3

Maecky
Maecky

Reputation: 2038

Ok, i found the answer myself, here the code if someone has the same problem:

newMat = float(scalar) * ( float(otherScalar) - newMat);
cv::exp( newMat, newMat );
newMat= 1.0f / ( 1.0f + newMat);

Upvotes: 3

Related Questions