PDA

View Full Version : Setting ROI and increasing framerate in C#



highspeed
March 16, 2011, 07:44:16
Hi all,

Received the DMK 72BUC02 today and have started implementing it in our machine vision application.

Setting a ROI and increasing the framerate for the partial readout is crucial for our app.

I'm working in C# and Visual Studio 2008 on Win7 64-bit, target platform .Net 3.5, compiling and running as x86. Drivers and IC Imaging Control 3.2 installed.

Supplied software and demos works well. Achieving the goal is possible using the supplied configuration dialogs but none of the sample apps contains the actual code needed for setting the ROI and increasing the ROI. I've tried a couple of methods as found on the website.


First of all, stopping the device (camera=ICImagingControl)

camera.LiveStop();

I have located the FrameFilter of the ROI type and instantiate it using a delegate dispatcher:


filterROI = camera.FrameFilterCreate("ROI");

then I set the parameters from a System.Drawing.Rectangle which has been corrected for the devisable-by-four factor as follows


filterROI.SetIntParameter("Left", roi.Left);
filterROI.SetIntParameter("Top", roi.Top);
filterROI.SetIntParameter("Width", roi.Width);
filterROI.SetIntParameter("Height", roi.Height);

Finally I add the filter to the device by

camera.DeviceFrameFilters.Add(filterROI);

The ROI size is updates but it appears to be software-only, frame rate remains the same (5FPS) in a 600x200 area. When I check the

float[] camera.DeviceFrameRates
there are no new values, maximum is still full-frame-5. By what means may it change?

So then I tried creating a new Videoformat but run into trouble when trying to set the parameters and adding to the ICImagingControl. Is this the approach correct, e.g set video format and position the box? :confused:

I want the set the ROI on the sensor, do partial readouts and transfer nothing but the active pixels as fast as possible, until we hit the sensor readout or bus transfer capabilities. Besides that, a feature to set FrameRateAuto = true would be great. Another idea could be to separate the GUI stuff from the device control, hard for newbie to know whats what.

Comments and suggestion appreciated.

Thanks!

Stefan Geissler
March 16, 2011, 12:36:40
Hello,

The ROI on a 72BUC02 is set by the video format. Simply set the video format as e.g. "RGB32 (640x96)" and you have an ROI of 640 pixels width and 96 pixels height in the middle of the sensor.

You may check the available frame rates after doing so and you will see, you have more and faster ones.

highspeed
March 18, 2011, 06:02:18
Thanks for the reply Stefan. I got it working. For the sake of reference and comments I post the code I'm currently working with. Room for plenty of optimization I am sure. One problem I have is that sometimes it is not possible to set the VideoFormat, exception is NewVideoFormat not available. Perhaps the camera has not fully initialized yet, it seems to occur early on, when attempting to set ROI after first or second frame received.



public delegate void DelgateSetROI();
private bool isSettingROI = false;

public void SetROI(Rectangle newRoi)
{
// If we are not done with previous operation, return
if (isSettingROI)
return;

// Adjust ROI for sensor limitations (must be devisable by 4)
roi = AdjustToCorrectROI(newRoi);

isSettingROI = true;

if (this.camera.InvokeRequired)
this.camera.BeginInvoke(new DelgateSetROI(DoSetROI));
else
DoSetROI();
}



private void DoSetROI()
{
try
{
camera.LiveStop();

try
{
string newROIFormat = "Y800 (" + roi.Width + "x" + roi.Height + ")";
camera.VideoFormat = newROIFormat;
camera.DeviceFrameRate = camera.DeviceFrameRates[camera.DeviceFrameRates.Count() - 1];
}
catch (Exception ex)
{
isROISet = false;
isSettingROI = false;
this.Stop();
this.Start();

Console.Out.WriteLine(ex.Message);
return;
}

// Set categories
string particalScanCategoryID = "{2ced6fd6-ab4d-4c74-904c-d682e53b9cc5}";
string offsetXID = "{5E59F654-7B47-4458-B4C6-5D4F0D175FC1}";
string offsetYID = "{87FB6C02-98A8-46B0-B18D-6442D9775CD3}";

// Find catergory
VCDPropertyItem partialScan = null;
partialScan = camera.VCDPropertyItems.FindItem(particalScanCateg oryID);

// Get elements
VCDPropertyElement posX = null;
posX = partialScan.FindElement(offsetXID);

VCDPropertyElement posY = null;
posY = partialScan.FindElement(offsetYID);

if (posX == null || posY == null)
Console.Out.WriteLine("PosX/PosY is null");
else
{
// Get range properties, contains min/max and value
VCDRangeProperty XRange = (VCDRangeProperty)partialScan.Elements.FindInterfa ce(offsetXID + ":" + VCDIDs.VCDInterface_Range);
VCDRangeProperty YRange = (VCDRangeProperty)partialScan.Elements.FindInterfa ce(offsetYID + ":" + VCDIDs.VCDInterface_Range);

// Apply new values (move window to position)

if (XRange.Available == false || YRange.Available == false)
{
// occurs sometimes, think it is if the Auto is set on partial scan
isSettingROI = false;
isROISet = false;
return;
}

if(roi.X > XRange.RangeMax || roi.Y > YRange.RangeMax)
{
isSettingROI = false;
isROISet = false;
return;
}

XRange.Value = roi.X;
YRange.Value = roi.Y;

isROISet = true;
Console.Out.WriteLine("ROI Set X: " + roi.X + " Y:" + " W:" + roi.Width + " H:" + roi.Height);
}

isSettingROI = false;

camera.LiveStart();
}
catch (Exception ex)
{
Console.Out.WriteLine(ex.Message);
}
}

Stefan Geissler
March 18, 2011, 09:52:29
Thank you for posting your code!

The only situation I can imaging for not available video formats is, if the width can not be devided by 8 and the height can not be divided by 4. The VideoFormatDecsciption shows the allows steppings.

highspeed
March 18, 2011, 18:07:25
Aha! I was checking both width and height for divide by four. Works now. Thanks.

For those interested that is done with the % operator as in:


if ((number % devisable) == 0)
return true;

highspeed
April 19, 2011, 05:49:08
..even better way to adjust the roi to conform with the sensor limitations:




public Rectangle AdjustROI(Rectangle ROI)
{

Rectangle adjustedROI = new Rectangle();
adjustedROI = ROI;

int reminder = 0;

System.Math.DivRem(ROI.Width, 8, out reminder);
if (reminder != 0)
adjustedROI.Width -= reminder;

reminder = 0;

System.Math.DivRem(ROI.Height, 4, out reminder);
if (reminder != 0)
adjustedROI.Height -= reminder

return adjustedROI;
}



Note that the set roi method is async, check the size of subsequent frames to verify that the roi has been set.