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.
Please use 101010 button to edit your code
will do next time. by the way I'm using 3.2.0 on windows 7
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.)
I left out the blur intentionally because it's not relevant to the problem. but here's the line
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.
output of your blur() will be still CV_16S (same as input). might explain your problem.
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!
I tried adding this line:
map.convertTo(map, CV_32F);
prior to dividing by 255.0 and assigning to gain_map, but it doesn't help.
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:
But now riddle me this: when I add this line just above the cerr line to convert invgain_map back to type 5:
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:
How can the lengths be different?
You should be using the multiply() function there, not the * operator. The * operator is matrix multiplication.