Ask Your Question
0

why are mat operators seeing wrong type? [closed]

asked 2017-02-03 11:34:55 -0600

jp2112 gravatar image

updated 2017-02-03 11:46:11 -0600

LBerger gravatar image

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 flag offensive 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

Comments

1

Please use 101010 button to edit your code

LBerger gravatar imageLBerger ( 2017-02-03 11:47:17 -0600 )edit

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

jp2112 gravatar imagejp2112 ( 2017-02-03 12:00:30 -0600 )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.)

berak gravatar imageberak ( 2017-02-03 12:02:19 -0600 )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.

jp2112 gravatar imagejp2112 ( 2017-02-03 12:23:09 -0600 )edit

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

berak gravatar imageberak ( 2017-02-03 12:26:40 -0600 )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!

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.

jp2112 gravatar imagejp2112 ( 2017-02-03 12:37:32 -0600 )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?

jp2112 gravatar imagejp2112 ( 2017-02-03 19:35:02 -0600 )edit
1

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

Tetragramm gravatar imageTetragramm ( 2017-02-03 21:31:51 -0600 )edit

1 answer

Sort by » oldest newest most voted
0

answered 2017-02-03 23:17:21 -0600

jp2112 gravatar image

updated 2017-02-03 23:17:58 -0600

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.

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2017-02-03 11:34:55 -0600

Seen: 1,887 times

Last updated: Feb 03 '17