Jump to content

LabVIEW crashes when calling OpenCV dll


Recommended Posts

Hi everyone. 
I wrote wrapper in Visual Studio for OpenCV calibrateCamera() function. Every operation like converting 1D array of points to vector<vector<Point2f>>  etc, works ok, except most important thing.
When function ()calibrateCamera is called, LabVIEW crashes. When this line is commented out, dll works ok (at least labview is still alive). Im out of ideas. I suspect that this is problem with memory management but i dont have an idea where it cames from. Function do not operate directly on data passed from LabVIEW.

Ultimately I can compile code as exe and call it via cmd, but I'm curious why such a thing appears.

 

Thanks for your precious time!
Zyga


dll source (if you need i can enclose some sample input data):

 

#include <opencv2/core/core.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <extcode.h>

using namespace cv;
using namespace std;


static void calcBoardCornerPositions(Size boardSize, float squareSize, vector<Point3f> &corners);
static void arr2vect(float *APoints,int *Asize, vector<vector<Point2f>> &imagePoints);

extern "C"
{
    float __declspec(dllexport)

Calibrate(float *APoints, int *Asize, int width, int height, float squareSize)
{
    //initialize variables
    vector<vector<Point2f>> imagePoints;
    Size boardSize;
    boardSize.height = height; boardSize.width = width;
    Mat cameraMatrix = Mat::eye(3, 3, CV_64F), distCoeffs = Mat::zeros(1, 1, CV_64F);
    cameraMatrix.at<double>(0,0) = 1.0;
    vector<Mat> rvecs, tvecs;
    vector<vector<Point3f>> objectPoints(1);
    Size imageSize; imageSize.width = 2040; imageSize.height = 2040;

arr2vect(APoints, Asize, imagePoints); // prepare imagePoints
calcBoardCornerPositions(boardSize, squareSize, objectPoints[0]); //prepare objectPoints
objectPoints.resize(imagePoints.size(),objectPoints[0]);

//calibrate
double rms = calibrateCamera(objectPoints, imagePoints, imageSize, cameraMatrix, distCoeffs, rvecs, tvecs);
return rms;
}
}

 

 

//definitions
static void arr2vect(float *APoints,int *Asize, vector<vector<Point2f>> &imagePoints)
{
    int page = *(Asize); int row = *(Asize+1); int col = *(Asize +2);
    Point2f pointBuf;
    vector<Point2f> vectBuf;

    for (int i = 0; i<page; i++)
    {
        for (int j = 0; j<row; j++)
        {
            pointBuf.x = *(APoints + (i*(row*col))+j*2);
            pointBuf.y = *(APoints + (i*(row*col))+j*2+1);
            vectBuf.push_back(pointBuf);
        }
        imagePoints.push_back(vectBuf);
        vectBuf.clear();
    }
    vectBuf.clear();
}

static void calcBoardCornerPositions(Size boardSize, float squareSize, vector<Point3f> &corners)
                                    
{
    corners.clear();
            for( int i = 0; i < boardSize.height; ++i )
                 for( int j = 0; j < boardSize.width; ++j )
                     corners.push_back(Point3f(float( j*squareSize ), float( i*squareSize ), 0));   

}

Edited by Zyga
Link to post

How is the call library node configured in LabVIEW when you call this function? What are the inputs to it? Make sure all arrays (ASize and APoints here) are preallocated to the correct length in LabVIEW before passing them to the DLL.

Link to post

Thanks for repty.
my function ptotype:
float Calibrate(float *APoints, int32_t *Asize, int32_t width, int32_t height, float squareSize);
And LabVIEW call:
post-27557-0-19450500-1422400009.png
If I remove:
double rms = calibrateCamera(objectPoints, imagePoints, imageSize, cameraMatrix, distCoeffs, rvecs, tvecs);
from compiled code, functions works. Non of from LabVIEW data is used to call this function.
objectPoints is a vector created from Apoints  by arr2vect() while Asize is used to properly place elements in mentioned vector.

Link to post

  1. Have you made sure you pass the arrays as Array Data Pointers, and not any other format? http://zone.ni.com/reference/en-XX/help/371361L-01/lvexcodeconcepts/array_and_string_options/
  2. What happens if you call this DLL from another C++ program?

 

double rms = calibrateCamera(objectPoints, imagePoints, imageSize, cameraMatrix, distCoeffs, rvecs, tvecs);

from compiled code, functions works. Non of from LabVIEW data is used to call this function.

objectPoints is a vector created from Apoints  by arr2vect() while Asize is used to properly place elements in mentioned vector.

 

Well, you are using LabVIEW data to create objectPoints.

 

Crashes caused by memory errors don't always happen immediately. For example, the error could have happened in arr2vect(), but program only crashes when you call calibrateCamera(). Or, by removing calibrateCamera(), you changed the memory layout of your program in a way such that the error doesn't cause a crash anymore.

Edited by JKSH
Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Similar Content

    • By LogMAN
      I discovered a potential memory corruption when using Variant To Flattened String and Flattened String To Variant functions on Sets. Here is the test code:

      In this example, the set is serialized and de-serialized without changing any data. The code runs in a loop to increase the chance of crashing LabVIEW.
      Here is the type descriptor. If you are familiar with type descriptors, you'll notice that something is off:

      Here is the translation:
      0x0008 - Length of the type descriptor in bytes, including the length word (8 bytes) => OK 0x0073 - Data type (Set) => OK 0x0001 - Number of dimensions (a set is essentially an array with dimension size 1) => OK 0x0004 - Length of the type descriptor for the internal type in bytes, including the length word (4 bytes) => OK ???? - Type descriptor for the internal data type (should be 0x0008 for U64) => What is going on? It turns out that the last two bytes are truncated. The Flatten String To Variant function actually reports error 116, which makes sense because the type descriptor is incomplete, BUT it does not always return an error! In fact, half of the time, no error is reported and LabVIEW eventually crashes (most often after adding a label to the numeric type in the set constant). I believe that this corrupts memory, which eventually crashes LabVIEW. Here is a video that illustrates the behavior:

      2021-02-06_13-43-58.mp4 Can somebody please confirm this issue?
      LV2019SP1f3 (32-bit) Potential Memory Corruption when (de-)serializing Sets.vi
    • By Billy_G
      Hello, I wrote a LabVIEW program to communicate with a hardware sensor using vendor-provided LLB and a DLL files. The program runs fine on my workstation both from LabVIEW IDE and from a compiled executable. The problem starts when I copy the entire executable folder to a target host without a LabVIEW IDE (only with a runtime engine). The application opens with a broken Run arrow and a "missing external function" error message appears for every function call I made to the DLL (see attached).
      I have tested my application on 5 completely different Windows 10 computers managed by different people. On three of them with various versions of LabVIEW IDE my executable opened with a whole Run arrow and no error message. Two other machines previously had no LabVIEW, so I installed a Runtime Engine 2017f2 32-bit with default settings to match the version of my IDE. Both gave an identical error message.
      The DLL is always included in the application build. I have tried placing the DLL in every conceivable location on the target host: in the executable folder, in the /data folder, in the c:\Windows and system32 folders... I even created a full folder tree matching the location of the project on the developer workstation. Same error. When I intentionally hide the DLL, my executable prompts me to point to it upon being opened, and when I do, I get all the same error messages.
      Vendor documentation only asks to put the two files in the same folder. From programmer's manual: " The driver was written in LabWindows/CVI, version 4.0.1 and is contained in a dynamic link library which can be linked with a variety of programming languages." There is no vendor-provided support.
      One way I actually got rid of the error message was by editing every Call Library Function Node in every VI in the LLB to use relative path to DLL together with the Application Directory VI. However, I feel that there has got to be a better way to compile than by editing a vendor-provided library, especially since it works as-is on some computers. Can anyone suggest what it is?
      Thank you for your time!
       

    • By LogMAN
      Here is another bug I discovered in LV2019+ which reliably crashes LV. Simply connect a set to the map input of the Map Get / Replace Value node on the IPE:

      This VI is executable in LV2019 SP1 f3, which means that you can actually build that into an executable without noticing.
      I have reported this, but there is no CAR yet.
    • By torekp
      DLL functions or shared variables?  Or something else?
      I have a Labview 2014-64 executable (or I can build a DLL) that runs one piece of equipment, the X-ray.  The other engineer has a large CVI Labwindows 2015 + MS Visual Studio 2012 (C++) executable that runs everything else.  I want the Labview code to be a slave of the CVI code, accepting commands to turn X-ray On or Off, reporting failures, and the like.  Translating the X-ray code into C++ would be possible in principle, but not fun.
      Shared variables look easy, but I'm kinda scared of them.  I would define all the shared variables in my LV code, since I'm more familiar with LV, then use them in both.  There's a thread in here called "Shared Variable Woes" so maybe I should be scared.  In the alternative, I tried building a proof-of-concept DLL in Labview, and calling its functions in CVI/C++, and it works, but it's kinda clunky.  (I'm attaching it below in case you want to play, or advise.)
      Your advice would be appreciated.
      XrayDLL.zip
    • By hutha
      New Toolkit : OpenCV wrapper for Raspberry Pi (LinuxRT) for LabVIEW
      Great ! learning platform student and maker for learning machine vision application with LabVIEW.
      It's working with LabVIEW Home 2014 edition and  required LINX 3.0 toolkit.
      You can run NI-VISION toolkit with Raspberry Pi board too.
      1.QwaveCameraCV is a LabVIEW Camera Driver library for Raspberry Pi 3B/3B+ (LinuxRT)
      https://github.com/QWaveSystems/QwaveCameraCV


      2.QwaveOpenCV is OpenCV wrapper functions for LabVIEW for Raspberry Pi 3B/3B+ (LinuxRT)
      https://github.com/QWaveSystems/QwaveOpenCV


      3.QwaveOpenCV Examples using OpenCV (C/C++) and NI-VISION for Raspberry Pi 3B/3B+ (LinuxRT)
      https://github.com/QWaveSystems/QwaveOpenCV-Examples


       
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.