Impact Acquire SDK .NET
ContinuousCapture.cs

The ContinuousCapture program is a simple example for a continuous acquisition.

Program location
The source file ContinuousCapture.cs can be found under:
%INSTALLDIR%\apps\CSharp\ContinuousCapture\
Note
If you have installed the package without example applications, this file will not be available. On Windows® the sample application can be installed or removed from the target system at any time by simply restarting the installation package.
ContinuousCapture example:
  1. Opens a Balluff device.
  2. Snaps images continuously (without display using Linux).
Console Output
[0]: BF000306 (mvBlueFOX-202C, Family: mvBlueFOX, interface layout: DeviceSpecific)

Please enter the number in front of the listed device followed by [ENTER] to open it: 0
Using device number 0.
Press [ENTER] to end the application
Initialising the device. This might take some time...
Info from BF000306: FramesPerSecond: 28.655660, ErrorCount: 0, CaptureTime_s: 0.104195
Info from BF000306: FramesPerSecond: 28.655636, ErrorCount: 0, CaptureTime_s: 0.104017
Info from BF000306: FramesPerSecond: 28.655659, ErrorCount: 0, CaptureTime_s: 0.104153
Info from BF000306: FramesPerSecond: 28.655636, ErrorCount: 0, CaptureTime_s: 0.104072
Info from BF000306: FramesPerSecond: 28.655660, ErrorCount: 0, CaptureTime_s: 0.104234
How it works

The continuous acquisition is similar to the single capture. There is only one difference, this capture is implemented inside a thread.

Device pDev = DeviceManager.getDevice(devNr);
pDev.open();
A small helper class to administer various library search path related variables and paths.
Definition LibraryPath.cs:14
static void init()
Calling this method will add the folders containing unmanaged libraries to the systems library search...
Definition LibraryPath.cs:251
This namespace contains classes and functions belonging to the image acquisition module of this SDK.
Definition Enumerations.cs:2
Definition Enumerations.cs:2
Definition Enumerations.cs:2

Then you have to send a request to the request queue:

FunctionInterface fi = new FunctionInterface(pDev);
TDMR_ERROR result = TDMR_ERROR.DMR_NO_ERROR;
while ((result = (TDMR_ERROR)fi.imageRequestSingle()) == TDMR_ERROR.DMR_NO_ERROR) { };
if (result != TDMR_ERROR.DEV_NO_FREE_REQUEST_AVAILABLE)
{
Console.WriteLine("'FunctionInterface.imageRequestSingle' returned with an unexpected result: {0}({1})", result, ImpactAcquireException.getErrorCodeAsString(result));
}

Accessing the mv.impact.acquire.Request object can be done after it has been checked using the mvIMPACT.acquire.Request.isOK property. The image attached to the request can then be processed and/or displayed if the request does not report an error.

requestNr = fi.imageRequestWaitFor(timeout_ms);
pRequest = fi.isRequestNrValid(requestNr) ? fi.getRequest(requestNr) : null;
if (pRequest != null)
{
if (pRequest.isOK)
{

Now you have the image and e.g. you can display it.

After the image handle you have to unlock the image buffer:

pPreviousRequest.unlock();
Source code
using System;
using System.Threading;
#if USE_DISPLAY
#endif // #if USE_DISPLAY
using mv.impact.acquire.examples.helper;
namespace mv.impact.acquire.examples
{
class ContinuousCapture
{
static void Main(string[] args)
{
mv.impact.acquire.LibraryPath.init(); // this will add the folders containing unmanaged libraries to the PATH variable.
Device pDev = DeviceAccess.getDeviceFromUserInput();
if (pDev == null)
{
Console.WriteLine("Unable to continue! Press any key to end the program.");
Console.Read();
Environment.Exit(1);
}
Console.WriteLine("Initialising the device. This might take some time...");
try
{
pDev.open();
}
{
// this e.g. might happen if the same device is already opened in another process...
Console.WriteLine("An error occurred while opening device " + pDev.serial +
"(error code: " + e.Message + "). Press any key to end the application...");
Console.ReadLine();
Environment.Exit(1);
}
#if USE_DISPLAY
ImageDisplayWindow window = new ImageDisplayWindow(String.Format("mvIMPACT_acquire sample, Device {0}", pDev.serial.read()));
#endif // #if USE_DISPLAY
bool terminated = false;
Console.WriteLine("Press [ENTER] to end the application");
Thread thread = new Thread(delegate ()
{
// establish access to the statistic properties
Statistics statistics = new Statistics(pDev);
// create an interface to the device found
// Send all requests to the capture queue. There can be more than 1 queue for some devices, but for this sample
// we will work with the default capture queue. If a device supports more than one capture or result
// queue, this will be stated in the manual. If nothing is mentioned about it, the device supports one
// queue only. This loop will send all requests currently available to the driver. To modify the number of requests
// use the property mv.impact.acquire.SystemSettings.requestCount at runtime (note that some devices will
// only allow to modify this parameter while NOT streaming data!) or the property
// mv.impact.acquire.Device.defaultRequestCount BEFORE opening the device.
TDMR_ERROR result = TDMR_ERROR.DMR_NO_ERROR;
while ((result = (TDMR_ERROR)fi.imageRequestSingle()) == TDMR_ERROR.DMR_NO_ERROR) { };
if (result != TDMR_ERROR.DEV_NO_FREE_REQUEST_AVAILABLE)
{
Console.WriteLine("'FunctionInterface.imageRequestSingle' returned with an unexpected result: {0}({1})", result, ImpactAcquireException.getErrorCodeAsString(result));
}
DeviceAccess.manuallyStartAcquisitionIfNeeded(pDev, fi);
// run thread loop
Request pRequest = null;
// we always have to keep at least 2 images as the display module might want to repaint the image, thus we
// cannot free it unless we have a assigned the display to a new buffer.
Request pPreviousRequest = null;
int timeout_ms = 500;
int cnt = 0;
int requestNr = Device.INVALID_ID;
while (!terminated)
{
// wait for results from the default capture queue
requestNr = fi.imageRequestWaitFor(timeout_ms);
pRequest = fi.isRequestNrValid(requestNr) ? fi.getRequest(requestNr) : null;
if (pRequest != null)
{
if (pRequest.isOK)
{
++cnt;
// here we can display some statistical information every 100th image
if (cnt % 100 == 0)
{
Console.WriteLine("Info from {0}: {1}: {2}, {3}: {4}, {5}: {6}", pDev.serial.read(),
statistics.framesPerSecond.name, statistics.framesPerSecond.readS(),
statistics.errorCount.name, statistics.errorCount.readS(),
statistics.captureTime_s.name, statistics.captureTime_s.readS());
}
#if USE_DISPLAY
# if CLR_AT_LEAST_3_DOT_5
// Extension methods are not supported by CLR versions smaller than 3.5 and this next function
// is therefore not available then.
window.imageDisplay.SetImage(pRequest);
# else
// If extension methods are not available, the following function can be used instead. It is
// not as convenient and will only work for some pixel formats. For more complex pixel formats
// use other overloads of this method
window.imageDisplay.SetImage(pRequest.imageData.read(), pRequest.imageWidth.read(), pRequest.imageHeight.read(), pRequest.imageBytesPerPixel.read() * 8, pRequest.imageLinePitch.read());
# endif
window.imageDisplay.Update();
#endif // #if USE_DISPLAY
}
else
{
Console.WriteLine("Error: {0}", pRequest.requestResult.readS());
}
if (pPreviousRequest != null)
{
// this image has been displayed thus the buffer is no longer needed...
pPreviousRequest.unlock();
}
pPreviousRequest = pRequest;
// send a new image request into the capture queue
}
//else
//{
// Please note that slow systems or interface technologies in combination with high resolution sensors
// might need more time to transmit an image than the timeout value which has been passed to imageRequestWaitFor().
// If this is the case simply wait multiple times OR increase the timeout(not recommended as usually not necessary
// and potentially makes the capture thread less responsive) and rebuild this application.
// Once the device is configured for triggered image acquisition and the timeout elapsed before
// the device has been triggered this might happen as well.
// The return code would be -2119(DEV_WAIT_FOR_REQUEST_FAILED) in that case, the documentation will provide
// additional information under TDMR_ERROR in the interface reference.
// If waiting with an infinite timeout(-1) it will be necessary to call 'imageRequestReset' from another thread
// to force 'imageRequestWaitFor' to return when no data is coming from the device/can be captured.
// Console.WriteLine("imageRequestWaitFor failed ({0}, {1}), timeout value too small?", requestNr, ImpactAcquireException.getErrorCodeAsString(requestNr));
//}
}
DeviceAccess.manuallyStopAcquisitionIfNeeded(pDev, fi);
#if USE_DISPLAY
// stop the display from showing freed memory
#endif // #if USE_DISPLAY
// In this sample all the next lines are redundant as the device driver will be
// closed now, but in a real world application a thread like this might be started
// several times an then it becomes crucial to clean up correctly.
// free the last potentially locked request
if (pRequest != null)
{
pRequest.unlock();
}
// clear all queues
});
thread.Start();
Console.ReadLine();
terminated = true;
thread.Join();
#if USE_DISPLAY
window.Dispose();
#endif // #if USE_DISPLAY
}
}
}
This class and its functions represent an actual device detected by this interface in the current sys...
Definition Device.cs:91
const int INVALID_ID
A symbolic constant to define an invalid handle.
Definition Device.cs:178
void open()
Opens a device.
Definition Device.cs:209
readonly PropertyS serial
A string property (read-only) containing the serial number of this device.
Definition Device.cs:516
T read()
Reads a value from a property.
Definition EnumPropertyI.cs:342
The function interface to devices supported by this interface.
Definition FunctionInterface.cs:21
int imageRequestSingle()
Sends an image request to the mv.impact.acquire.Device driver.
Definition FunctionInterface.cs:656
Request getRequest(int nr)
Returns a const pointer to the desired mv.impact.acquire.Request.
Definition FunctionInterface.cs:452
int imageRequestWaitFor(int timeout_ms)
Waits for a request object to become ready.
Definition FunctionInterface.cs:1021
int imageRequestReset(int requestCtrlNr)
Deletes all requests currently queued for the specified mv.impact.acquire.ImageRequestControl.
Definition FunctionInterface.cs:575
bool isRequestNrValid(int nr)
Check if nr specifies a valid mv.impact.acquire.Request.
Definition FunctionInterface.cs:1098
An base class for exceptions generated by Impact Acquire.
Definition Exceptions.cs:9
static String getErrorCodeAsString(int errorCode)
Returns a string representation of a error.
Definition Exceptions.cs:48
IntPtr read()
Reads a value from a property.
Definition PropertyPtr.cs:49
String read()
Reads a value from a property.
Definition PropertyS.cs:144
Contains information about a captured buffer.
Definition Request.cs:77
readonly PropertyPtr imageData
A pointer property (read-only) containing the start address of the image data.
Definition Request.cs:1579
readonly PropertyI imageLinePitch
An integer property (read-only) containing the offset (in bytes) to the next line of each channel bel...
Definition Request.cs:1655
readonly EnumPropertyI< TRequestResult > requestResult
An enumerated integer property (read-only) defining the result of this request.
Definition Request.cs:1211
readonly PropertyI imageWidth
An integer property (read-only) containing the width of the image in pixels.
Definition Request.cs:1693
readonly PropertyI imageBytesPerPixel
An integer property (read-only) containing the number of bytes per pixel in this image.
Definition Request.cs:1679
bool isOK
Convenience function to check if a request has been processed successfully.
Definition Request.cs:1173
readonly PropertyI imageHeight
An integer property (read-only) containing the height of the image in pixels.
Definition Request.cs:1704
int unlock()
Unlocks the request for the driver again.
Definition Request.cs:619
Contains statistical information.
Definition Statistics.cs:10
readonly PropertyI errorCount
An integer property (read-only) containing the overall count of image requests which returned with an...
Definition Statistics.cs:82
readonly PropertyF framesPerSecond
A float property (read-only) containing the current number of frames captured per second.
Definition Statistics.cs:98
readonly PropertyF captureTime_s
A float property (read-only) containing the average time needed to capture an image.
Definition Statistics.cs:75
A class that can be used to display images in a window.
Definition ImageDisplayWindow.cs:15
readonly ImageDisplay imageDisplay
Returns a reference to the actual display object associated with this window.
Definition ImageDisplayWindow.cs:108
void Dispose()
Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resourc...
Definition ImageDisplayWindow.cs:85
void RemoveImage()
Removes the current image from the display.
Definition ImageDisplay.cs:327
void SetImage(IntPtr pData, int width, int height, int bipp, int pitch)
Sets the next image to display.
Definition ImageDisplay.cs:282
void Update()
Immediately redraws the current image.
Definition ImageDisplay.cs:333
TDMR_ERROR
Errors reported by the device manager.
Definition mvDriverBaseEnums.cs:2375
This namespace contains classes and functions that can be used to display images.
Definition Enumerations.cs:2