why are mat operators seeing wrong type? [closed]

I'm at a loss here, why does my code crash with the error:

OpenCV Error: Assertion failed (type == B.type() && (type == CV_32FC1 || type == CV_64FC1 || type == CV_32FC2 || type == CV_64FC2)) in cv::gemm, file C:\build\master_winpack-build-win64-vc14\opencv\modules\core\src\matmul.cpp, line 1530


Below is basically what I'm trying to do, some lines may be unnecessary but I've been removing all assumptions about auto-allocation and matrix depths. Note, live_image comes into my function as "const Mat" with depth CV_16U.

   ...
static Mat fused_image(live_image.rows, live_image.cols, live_image.type()); // this is my return Mat so same type
Mat gain_map(live_image.rows, live_image.cols, CV_32F); // gain_map gets the result of a blur() divided by 255.0
...
if (frame == 1) {
live_image.copyTo(fused_image); // initialize on first pass thru function, they have same type
}
// else fused_image is generated by the remaining function code and retained for the next frame iteration
...

Mat flive_image(live_image.rows, live_image.cols, CV_32F); // declare my fp arrays

Mat ffused_image(live_image.rows, live_image.cols, CV_32F);
Mat fffused_image(live_image.rows, live_image.cols, CV_32F);
Mat invgain_map(live_image.rows, live_image.cols, CV_32F);
live_image.convertTo(flive_image, CV_32F);                               // should flive_image = live_image be equivalent?
fused_image.convertTo(ffused_image, CV_32F);                         // ditto, should now have fp versions of ushort arrays

invgain_map = -1.0 * gain_map + 1.0;                                         // also tried "1.0 - gain_map;" as well as "gain_map.convertTo(invgain_map, -1, -1, 1);"
fffused_image = ffused_image * invgain_map;                            // crashes on this line, also tried C=A.mul(B) and multiply(A, B, C)
...
// note, fused_image would eventually be converted back to CV_16U from fffused_image after more matrix processing.

...


As noted it crashes on the last multiply line. When I replace * with multiply() I get a different but related error:

OpenCV Error: Bad argument (When the input arrays in add/subtract/multiply/divide functions have different types, the output array type must be explicitly specified) in cv::arithm_op, file C:\build\master_winpack-build-win64-vc14\opencv\modules\core\src\arithm.cpp, line 683


But how in the world can my types be different? I left nothing to chance. Thanks for any help.

edit retag reopen merge delete

Closed for the following reason the question is answered, right answer was accepted by berak close date 2017-02-04 01:05:07.172319

1

( 2017-02-03 11:47:17 -0500 )edit

will do next time. by the way I'm using 3.2.0 on windows 7

( 2017-02-03 12:00:30 -0500 )edit

the part, where you call blur() is missing.

also i suspect, that you're trying to set output / result Mat's to something, that is actually overwritten by the actual process. try not to do that, use empty Mat's for those. (you're only fooling yourself in belieiving wrong things about type/size in the outcome.)

( 2017-02-03 12:02:19 -0500 )edit

I left out the blur intentionally because it's not relevant to the problem. but here's the line

blur(regions, map, Size(5, 5));


where regions and map are declared simply as Mat types earlier, so they get converted to whatever is necessary by their compare and blur functions, respectively. so gain_map = map / 255.0 and should still be CV_32F type at this point, no?

my first attempts at this code actually wasn't trying to set output/result Mat's to something, so here I am now trying to make it happy by forcing everything to be CV_32F. but it's not happy.

( 2017-02-03 12:23:09 -0500 )edit

output of your blur() will be still CV_16S (same as input). might explain your problem.

( 2017-02-03 12:26:40 -0500 )edit

Even if map array is CV_16S because the blur function output it that way, why wouldn't the gain_map = map / 255.0 assignment keep gain_map as CV_32F? I don't use map again in the code, only gain_map.

So what I hear you saying is that, unlike just about every other language I've seen, in OpenCV a Matrix can actually CHANGE it's own type on the fly even when it's declared to be a specific type? If true then that's crazy!

map.convertTo(map, CV_32F);

prior to dividing by 255.0 and assigning to gain_map, but it doesn't help.

( 2017-02-03 12:37:32 -0500 )edit

By adding the following line right above the crash line I was able to see that invgain_map was being set to array type 0 despite being declared as type 5:

  cerr << ffused_image.type() << " " << invgain_map.type() << endl; // outputs 5 0 with orig code


But now riddle me this: when I add this line just above the cerr line to convert invgain_map back to type 5:

  invgain_map.convertTo(invgain_map, CV_32F);


it still crashes on the following multiply line even though the cerr output now shows 5 5, so I know types are the same. So what gives? Plus I am now getting this error:

OpenCV Error: Assertion failed (a_size.width == len) in cv::gemm, file C:\build\master_winpack-build-win64-vc14\opencv\m
odules\core\src\matmul.cpp, line 1537


How can the lengths be different?

( 2017-02-03 19:35:02 -0500 )edit
1

You should be using the multiply() function there, not the * operator. The * operator is matrix multiplication.

( 2017-02-03 21:31:51 -0500 )edit

Sort by » oldest newest most voted

Got it. I was finally able to get this to work by doing as you said, combined with simplifying my Mat declarations. Might have avoided this whole confusion if OpenCV used some other symbol for matrix multiply ("#" would make sense to me!) Anyhow, you both lead me to the solution so thanks for the numerous replies.

more