4

Executing this:

std::vector<cv::Point2f> pts; // contains 4 elements
cv::Mat ptsMat = ((cv::InputArray)pts).getMat();

On one machine I get a 4-by-1 cv::Mat with 2 channels. Each element represents a 2D point. On another machine, I get a 2090-by-1 cv::Mat with 2 channels with weird data. This is wrong and this is a problem, since the vector contained only 4 items.

On both machines using OpenCV 3.1 built from source using CMake on Windows 10.

EDIT

I started experiencing similar problem on a different machine. In Visual Studio in Debug mode the following snippet works fine:

std::vector<cv::Point2f> points = { cv::Point2f(2, 1), cv::Point2f(2, 1), cv::Point2f(1, 3) };
cv::InputArray arr = points;
cv::Mat ma = arr.getMat();
std::cout << ma.ptr<float>(0)[1];

But when I compile it in Release, it crashes on the last line with Access violation reading location...

Further investigation revealed that the key flag that makes a difference is:

Runtime library: Multithreaded DLL (/MD) --------> crash

Runtime library: Multithreaded DLL Debug (/MDd) --------> works

EDIT 2

Based on the comment of Mateen Ulhaq, I checked the

std::vector<cv::Point2f> points;
cv::Mat image(points);

and this works fine. The problem is that some of OpenCV larger functions (e.g. undistortPoints) internally use the getMat() conversion. And if I run that on release, the app crashes.

EDIT 3

Just checked, same problem occurs on OpenCV 3.2

AndroC
  • 4,758
  • 2
  • 46
  • 69
  • 2
    The same code works when built on different machine? Which compilers are used and were the same ones used to build OpenCV? – slawekwin May 10 '17 at 14:16
  • I use the same version of Visual Studio and its compiler for building both this code and OpenCV on both computers. – AndroC May 11 '17 at 06:37
  • 1
    Have you looked at [this](https://stackoverflow.com/questions/23585158/create-mat-from-vectorpoint2f?rq=1)? Or is your question to figure out why this happens? – Mateen Ulhaq Jun 16 '17 at 09:22
  • will check it out. tnx . btw i added more info to the question – AndroC Jun 16 '17 at 09:36
  • Mateen Ulhaq, my goal is to make the function `undistortPoints()` work. This function internally uses `getMat()` which does not work on Release. It worked up to now and I dont know why it stopped working. If I cannot make it work, I would at least like to know the reason... – AndroC Jun 16 '17 at 11:44
  • 2
    I don't know if it helps solving your problem but I spotted two things which I find a bit strange. 1. You are you using a **c-style** cast to cast an vector containing points to an Mat. 2. Why do you use InputArray? As far as I know it's an internally used class and when a function expects it you can just pass mats, or vector to it. – TruckerCat Jun 16 '17 at 15:40
  • Tnx for comment. I am using InputArray so that I can call function `getMat()`. This is just so I can demostrate the problem. std::vector does not have this function. Yes. It is internally used. And wherever it is internally used, I cannot send std::vectors there... because internal call to `getMat()` will crash the application... – AndroC Jun 16 '17 at 16:07
  • 1
    You need to use the same Runtime library across the entire program if you use types like `std::vector` on interfaces. In general it is very bad to expose types like `std::vector` on interfaces since their internal representation depend on whether it is release or debug – Jens Munk Jun 17 '17 at 20:36
  • You want to say that both OpenCV and my program that is using it both need to be built either in Debug or Release? Problems arise when OpenCV is built with Release and the dependent program is built with Debug? – AndroC Jun 19 '17 at 09:15

1 Answers1

0

This is not exactly an answer I was looking for but here goes.

It seems every time this has occurred, it was immediately after a Windows Update.

I completely deleted and re-built the following libraries: VTK, OpenCV, Eigen and finally, my project.

This fixed it for me.

AndroC
  • 4,758
  • 2
  • 46
  • 69