Machine Vision

cancel
Showing results for 
Search instead for 
Did you mean: 

Frame Acquisition Freezing when Changing Video Data Width

Hello,

 

We are currently using the Mikrotron MC1310 camera and NI PCIe-1429 frame grabber.

 

We are running into an issue where the acquisition is freezing whenever we change the video data size from 8x8 to 10x8.  I wrote a sample app that reproduces the issue. I first use the Mikrotron control application to change from 8x8 to 10x8.  Then when the application is launched and the background acquisition is started using errChk(imgSessionAcquire(Sid, TRUE, NULL)), the errChk(imgGetAttribute (Sid, IMG_ATTR_LAST_VALID_FRAME, &currBufNum)) call never returns a valid frame number.

 

The code, which is very much like the LLGrab example, is below:

 

-------------------------------

#include "mainwindow.h"
#include "niimaq.h"

static SESSION_ID   Sid = 0;
static BUFLIST_ID   Bid = 0;
static INTERFACE_ID Iid = 0;
static Int32        AcqWinWidth = 1280;
static Int32        AcqWinHeight = 1024;
#define NUM_GRAB_BUFFERS 3000
static Int8         *ImaqBuffers[NUM_GRAB_BUFFERS];

// error checking macro
#define errChk(fCall) if (error = (fCall), error < 0) {goto Error;} else

MainWindow::MainWindow(QWidget *parent, Qt::WFlags flags)
    : QMainWindow(parent, flags)
{
    ui.setupUi(this);
    
    bool bReturn = connect(ui.pushButton_StartRecording, SIGNAL(clicked()),
                      this, SLOT(Start()));
}

MainWindow::~MainWindow(void)
{
}

void MainWindow::Start(void)
{
    int error = 0;
    int bufferCommand = 0;
    int currBufNum = -1;
    char    intfName[]    = {"img0"};
    unsigned int bytesPerPixel;
    unsigned int bufSize;

    // Open an interface and a session
    errChk(imgInterfaceOpen (intfName, &Iid));
    errChk(imgSessionOpen (Iid, &Sid));

    errChk(imgSetAttribute2 (Sid, IMG_ATTR_ROI_WIDTH, AcqWinWidth));
    errChk(imgSetAttribute2 (Sid, IMG_ATTR_ROI_HEIGHT, AcqWinHeight));
    errChk(imgSetAttribute2 (Sid, IMG_ATTR_ROWPIXELS, AcqWinWidth));

    // create a buffer list with totalFrames elements
    //this->m_pImaqBufferArray = new Int8*[this->m_totalAcquisionFrames];
    errChk(imgCreateBufList(NUM_GRAB_BUFFERS, &Bid));
    
    
    // compute the size of the required buffer
    errChk(imgGetAttribute (Sid, IMG_ATTR_BYTESPERPIXEL, &bytesPerPixel));
    bufSize = AcqWinWidth * AcqWinHeight * bytesPerPixel;

    for (unsigned int i = 0; i < NUM_GRAB_BUFFERS; i++)
    {
        errChk(imgCreateBuffer(Sid, FALSE, bufSize, (void**)&ImaqBuffers[i])); //(void**)&(this->m_pImaqBufferArray[i])));
        errChk(imgSetBufferElement2(Bid, i, IMG_BUFF_ADDRESS, ImaqBuffers[i]));
        errChk(imgSetBufferElement2(Bid, i, IMG_BUFF_SIZE, bufSize));
        bufferCommand = (i == (NUM_GRAB_BUFFERS - 1)) ? IMG_CMD_STOP : IMG_CMD_NEXT;
        errChk(imgSetBufferElement2(Bid, i, IMG_BUFF_COMMAND, bufferCommand));
    }

    // lock down the buffers contained in the buffer list
    errChk(imgMemLock(Bid));

    // configure the session to use this buffer list
    errChk(imgSessionConfigure(Sid, Bid));

    // start the acquisition, asynchronous
    errChk(imgSessionAcquire(Sid, TRUE, NULL));

    ui.label_CurrentFrameValue->setText(QString(""));
    QCoreApplication::processEvents();

    while(currBufNum < 0)
    {
        errChk(imgGetAttribute (Sid, IMG_ATTR_LAST_VALID_FRAME, &currBufNum));
    }
    while(currBufNum < NUM_GRAB_BUFFERS)
    {
        ui.label_CurrentFrameValue->setText(QString::number(currBufNum+1));
        QCoreApplication::processEvents();
        errChk(imgGetAttribute (Sid, IMG_ATTR_LAST_VALID_FRAME, &currBufNum));
    }

    if (Bid != 0)
        imgMemUnlock(Bid);

    // dispose of the buffers
    for (int i = 0; i < NUM_GRAB_BUFFERS; i++)
        if (ImaqBuffers[i] != NULL)
            imgDisposeBuffer(ImaqBuffers[i]);

    // close this buffer list
    if (Bid != 0)
        imgDisposeBufList(Bid, FALSE);

    // Close the interface and the session
    if(Sid != 0)
        imgClose (Sid, TRUE);
    if(Iid != 0)
        imgClose (Iid, TRUE);

Error:
    if(error < 0)
    {
        static Int8 ErrorMessage[256];
        std::string messageStr;

        memset(ErrorMessage, 0x00, sizeof(ErrorMessage));

        // converts error code to a message
        imgShowError(error, ErrorMessage);

        messageStr.assign(ErrorMessage);
    }
}

0 Kudos
Message 1 of 13
(5,053 Views)

Hello Brian,

 

Are there any other acquisition modes that are causing this error, or does it only appear when the video data size is changed to 10x8?  Are you able to obtain any information from the errChk(imgGetAttribute (Sid, IMG_ATTR_BYTESPERPIXEL, &bytesPerPixel));

 

We can consider using another image attribute to diagnose what may be occuring, such as using the last valid buffer, or frame count attributes as they are always readable. 

 

Cheers,

 

Joel

0 Kudos
Message 2 of 13
(5,037 Views)

Hello Joel,

 

I determined that this problems happens when I change any of the camera parameters using the Mikrotron MC Control application before attempting an acquisition.  ! was able to simplify the example even more by taking out Qt and writing to the console window.  See the attached file for the new code.

 

Here are the results of executing the code:

 

Acquisition width: 1280
Acquisition height: 1024
Total acquisition frames: 30
Bytes per pixel: 1
Acquisition In Progress: 1
Waiting for first frame
Cur Frame: -1
Cur Frame Count: 0
Cur Buffer: -1
Cur Frame: -1
Cur Frame Count: 0
Cur Buffer: -1
Cur Frame: -1
Cur Frame Count: 0
Cur Buffer: -1
Cur Frame: -1
Cur Frame Count: 0
Cur Buffer: -1
Cur Frame: -1
Cur Frame Count: 0
Cur Buffer: -1
Cur Frame: -1
Cur Frame Count: 0
Cur Buffer: -1

.......

 

I had to stop the execution of the application because it wasn't getting any frames at all.  As you can see I was able to get the bytes per pixel and also see that the acquisition in progress was true.  However there are no frames or buffers being captured.  What else can I try for a test?  The strange thing is that the LLGrab sample application still works after I modify camera parameters.  I can't see any differences in the function calls or order of functions or compile and build settings.

 

Thanks,

 

-brian

0 Kudos
Message 3 of 13
(5,034 Views)

Hello Joel,

 

I was wrong about the LLGrab sample running OK after the camera parameters are changed.

 

When I run it after any parameters have been changed, I am getting the following error:

 

A timeout error occurred while waiting for the specified event.  If waiting for an image,

verify that all video data is acquired within the timeout period.  If waiting for a signal,

verify that the signal assertion occurs within the timeout period.

 

-brian

0 Kudos
Message 4 of 13
(5,033 Views)

Brian,

 

Are you able to adjust the necessary attribute in Measurement & Automation Explorer?  If the error occurs when you use the Mikrotronic Control Application, the Mikrotronic driver may be interfering the NI-IMAQ driver for the framegrabber.  As long as the National Instruments software has the correct camera file, you should be able to use Measurement & Automation Explorer to adjust the Camera & Acquisition attributes.  Perhaps try adjusting the attribute there and running the example.  If the attributes aren't located there, you may need to edit the camera file.  Also, if possible you might want to test the LLGrab example on a PC that does not have the third party Mikrotronic driver.

 

What is a Camera File, Do I Need One, and How Can I Obtain One?

Regards,
Isaac S.
Applications Engineer
National Instruments
0 Kudos
Message 5 of 13
(5,021 Views)

Hello,

 

That would be great if all the parameters I needed to change were accessible via MAX.  However, they are not.  The most important one for us to change is the frame rate.  Not only is this attribute not in MAX it is also not in the camera parameters file.

 

 

0 Kudos
Message 6 of 13
(5,018 Views)

Hello,

 

I found out that when I set the acquisition width to 1280 and the acquistion height to 1024 in the llgrab example and change the video data width to 10x8 it is always causing the timeout issue.  However the timeout issue is actually being thrown from the imgSessionCopyBufferByNumber() method and not from the imgGetAttribute(Sid, IMG_ATTR_LAST_VALID_FRAME, &currBufNum) method.  The IMG_ATTR_LAST_VALID_FRAME attribute is always being returned as -1.  How can I alleviate that issue?  Can I change the acquisition timeout for each frame to make it larger so that valid frames are returned with the larger acquistion size?

0 Kudos
Message 7 of 13
(5,009 Views)

Hello,

 

I tried setting the IMG_ATTR_FRAMEWAIT_MSEC attribute to a very high number.  However, the IMG_ATTR_LAST_VALID_FRAME call is not waiting and is still returning -1.

0 Kudos
Message 8 of 13
(5,008 Views)

Hello,

 

 

After setting the parameters in the MC control application, are you saving them then exiting out of the application?  After discussing this issue with an R&D engineer, he stated that changing some parameters can slow down the camera which could explain the timeout error.  Also you may try adjusting the timeout in Measurement & Automation Explorer under acquisition attributes, the default is 5 sec.  How often are you changing the parameters in the control application?  Is the end goal to have all the acquired images to have a 10x8 data size?

Regards,
Isaac S.
Applications Engineer
National Instruments
0 Kudos
Message 9 of 13
(5,003 Views)

Hello,

 

My final goal is to be able to allow our custom application to change the parameters of the camera via the serial write commands.  I wanted to do a quick tests of changing them via the camera control application first to see what would happen.  We do not plan on using the camera control application or MAX while our custom application is running.  Instead we want to give users the ability to change all parameters via our application and to give them the ability to capture frames at the fastest rate which is achieved via the 10x8 video data size. 

 

I still don't understand why the IMG_ATTR_LAST_FRAME attribute is constantly returning -1.  Are you saying that if I increase the acquistion timeout in MAX that the IMG_ATTR_LAST_FRAME will return a valid frame number for the 10x8 video data size and 1280x1024 image size?  Also by increasing the acquistion timeout in MAX does that in turn modify the camera data file?

0 Kudos
Message 10 of 13
(4,998 Views)