PDA

View Full Version : DShowLibException with Y16 in Grab mode



Ben Lyon
August 8, 2014, 15:35:07
Hi,

I am having trouble in making my B&W USB camera to work in Y16 mode. It works fine in RGB24 and Y800 modes, but in Y16 it throws the following DShowLibException at LiveStart().

I am currently using IC Imaging Control.NET Version 3.3.4.1916:

---------------------------
---------------------------
Unknown error occurred
Base Library Error : An unexpected DShowLibException occured: Error = startLive failed.
VideoCaptureDevice = DMK 23U445
VideoFormat = Y16 (1280x960)
In file : "GrabberPImpl.cpp" at line : 599


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

This is what I am doing:


icImgControl.LiveStop();

oldSink = icImgControl.Sink;

fhs = new TIS.Imaging.FrameHandlerSink();
fhs.SnapMode = false; // Set to Grab Mode
fhs.FrameTypes.Add(new TIS.Imaging.FrameType(colorFormat)); // colorFormat for Y16
icImgControl.Sink = fhs;

icImgControl.LiveCaptureContinuous = true;
icImgControl.LiveDisplay = false;
icImgControl.DeviceTrigger = true;

icImgControl.Sink.SinkModeRunning = true;

icImgControl.LiveStart(); // This is where the exception occurs.

Any idea?

Ben

Stefan Geissler
August 8, 2014, 15:46:25
Hi Ben,

For using Y16 in the sink, the OverlayBitmap object must be removed.


var sink = new FrameHandlerSink(false, 5, new FrameType(MediaSubtypes.Y16));

icImagingControl1.Sink = sink;

// No overlay possible with this.
icImagingControl1.OverlayBitmapPosition = PathPositions.None;


What is the content of "colorFormat"?

Ben Lyon
August 8, 2014, 16:43:59
Stefan,

Thank you for your quick reply. The content of "colorFormat" is the same as yours, MediaSubtypes.Y16.

As I have to dash home now, I will try your suggestion tomorrow and tell you about the outcome.

Cheers,
Ben

Ben Lyon
August 9, 2014, 10:36:09
Stefan,

Removing the OverlayBitmap object solved the StartLive() exception problem with Y16, I am happy to report.

However, there still remains a problem with Y16 format. In the grab mode, as mentioned above, I am using ImageAvailable() event and DisplayImageBuffer() to display images. Again this scheme works well in RGB24 and Y800, but in Y16 DisplayImageBuffer() seems broken: No refresh on the screen ;-(

Any suggestion?

Ben

Stefan Geissler
August 11, 2014, 08:04:14
Hello

The question is: How to display a 16 bit format on screen, while it is 8 bit only?

If you want to handle 16/12 bit formats, then most other components of your computer, like your graphics board, is incompatible. You have to convert it to an 8 bit format first.
Therefore, you can not display the Y16 image buffer on screen.

You may create an 8bit System.Drawing.Bitmap and copy the wanted bytes from the image buffer into the bitmap and display the bitmap in a picturebox.

I must admit, I never tried to display an Y16 image buffer in IC Imaging Control on my own. I simply had not the idea of doing this.

Ben Lyon
August 11, 2014, 17:03:54
Stefan,

In my project, Y16 images are saved in files for later analysis, while on-screen images are monitored.

I was about to try your scheme of converting a Y16 image to a 8-bit bitmap for the display. Then I had a second thought and changed LiveDisplay to true, and voila, now it works the way I want. With LiveDisplay turned on, I don't even need DisplayImageBuffer() to do this.

Maybe it was my misunderstanding that going to "grab" mode disrupts the display path...

Thanks for your help,
Ben

Stefan Geissler
August 12, 2014, 08:04:43
Ben

Good to read, the issue is solved. I thought, you wanted to display the may be processed images from within the ImageAvailable event. Therefore, I was on the wrong track. Sorry for this.

Stanislaw
June 10, 2015, 13:16:18
Hi,

I am dealing with the same problem as Ben and unfortunately I can't get past the exception that is thrown when the LiveStart method is called. I am using a Skyris 274M camera. With IC Capture, the Y16 mode i available and works fine. Can you have a look at my code:



ic.LiveStop();
ic.DeviceFrameRate = ic.DeviceFrameRates[ic.DeviceFrameRates.Length - 1];

sink = new FrameHandlerSink(false, 5, new FrameType(MediaSubtypes.Y16));
ic.Sink = sink;

ic.OverlayBitmapPosition = PathPositions.None;

ic.LiveCaptureContinuous = true;
ic.LiveDisplay = false;
ic.Sink.SinkModeRunning = true;

ic.LiveStart();


Thanks in advance,
Stanislaw

Stanislaw
June 10, 2015, 13:26:44
Hi,

I am dealing with the same problem as Ben and unfortunately I can't get past the exception that is thrown when the LiveStart method is called. I am using a Skyris 274M camera. With IC Capture, the Y16 mode i available and works fine. Can you have a look at my code:



ic.LiveStop();
ic.DeviceFrameRate = ic.DeviceFrameRates[ic.DeviceFrameRates.Length - 1];

sink = new FrameHandlerSink(false, 5, new FrameType(MediaSubtypes.Y16));
ic.Sink = sink;

ic.OverlayBitmapPosition = PathPositions.None;

ic.LiveCaptureContinuous = true;
ic.LiveDisplay = false;
ic.Sink.SinkModeRunning = true;

ic.LiveStart();


Thank you in advance,
Stanislaw

Stefan Geissler
June 10, 2015, 16:05:54
Stanislaw

Your code looks fine, so I wonder, whether you set Y16 as video format in your camera. If not, please do so.

Stanislaw
June 10, 2015, 17:43:53
Dear Stefan,

Thank you for your quick response and the hint. With the proper video format set, the exception is gone and I can access 16-bit data easily.

When in the Y16 video mode and with the setup as in the code above, can I somehow access a 24bpp bitmap from the current buffer or do I need to create a bitmap from the ushort array myself (it works but is not very fast)?

Kind regards,
Stanislaw

Stanislaw
June 10, 2015, 17:44:33
Dear Stefan,

Thank you for your quick response and the hint. With the proper video format set, the exception is gone and I can access 16-bit data easily.

When in the Y16 video mode and with the setup as in the code above, can I somehow access a 24bpp bitmap from the current buffer or do I need to create a bitmap from the ushort array myself (it works but is not very fast)?

Kind regards,
Stanislaw

Stefan Geissler
June 12, 2015, 13:53:52
If the buffer is not 24bit, you can not access it as 24 bit. You must create you own one.

Stanislaw
June 15, 2015, 14:02:44
Dear Stefan,

I have been able to achieve good speeds by using pointers in unsafe context for byte manipulation and casting.

Just to be sure, the 12-bit output of the camera should have "real" 4096 discrete values from 0 to 4095, which is what I get. Alternatively, reading 2 bytes per pixel from the Y16 sink buffer and casting them to e.g. a ushort will give 65536 values, which is not the actual depth of the pixels.

Kind regards,
Stan

Stefan Geissler
June 15, 2015, 15:23:50
Hi Stan


You are right, the unsafe context makes the pixel access much faster.

The pixel format is described here:

http://www.theimagingsource.com/en_US/support/documentation/icimagingcontrol-class/PixelformatY16.htm

So it is
0000000 0000nnnn

the "nnnn" are random and you can discard them

Stanislaw
June 18, 2015, 12:49:49
Dear Stefan,

I have one more issue. Sometimes, the MemorySnapImage method throws a timeout exception. I set the timeout to double the exposure time plus some overhead (e.g. for 1 sec. exposures, I set a timeout of 3 sec.). It seems to work well for a few calls of the method and then suddenly stops. After this happens, calling this method always throws a timeout exception. Usually to recover I need to shut down the application and run ICCapture. After that (maybe the camera's settings are reset...?), it works again for some time.

What can be the reasons for this exception what can I do to avoid it?

Kind regards,
Stan

Stefan Geissler
June 18, 2015, 14:59:07
Stan

is it possible you lock the images buffers, but do not unlock them?

Also, if the live video continues, it not a problem of data transfer inside the computer.

Stanislaw
June 18, 2015, 16:03:53
Dear Stefan,

I am not explicitely using any locks. Does the GetIntPtr() method lock items? Maybe I should use locks?i

I've noticed that this issue with timeouts happens in snap mode but it is also apparent in grab mode with liveCaptureContinuous set to true. In the second case, the image pixels do not refresh, some old frame is stuck in the memory. So the problem is the same, just there is no timeout.

The same behaviour is on the SKYRIS 274M camera and DMK21AU04.AS.

Below is my init code (for grab mode):



ic.Device = dev;
var vf = ic.VideoFormats;

ic.LiveStop();

// Set lowest frame rate
ic.DeviceFrameRate = ic.DeviceFrameRates[ic.DeviceFrameRates.Length - 1];

// Set video mode
if (videoMode == TISVideoMode.TIS_12bit)
{
var foundFormat = Array.Find(vf, a => (a.BitsPerPixel == 16 && a.Name.Contains("Y16")));
if (foundFormat == null)
throw new InvalidOperationException("Format not supported by camera");
this.videoMode = videoMode;
ic.VideoFormat = foundFormat.Name;
ic.MemoryCurrentGrabberColorformat = ICImagingControlColorformats.ICY16;
}
else if (videoMode == TISVideoMode.TIS_8bit)
{
var foundFormat = Array.Find(vf, a => (a.BitsPerPixel == 8 && a.Name.Contains("Y800")));
if (foundFormat == null)
throw new InvalidOperationException("Format not supported by camera");
this.videoMode = videoMode;
ic.VideoFormat = foundFormat.Name;
ic.MemoryCurrentGrabberColorformat = ICImagingControlColorformats.ICY800;
}
else
{
throw new InvalidOperationException("Unknown video format");
}

// Create sink
if (this.videoMode == TISVideoMode.TIS_12bit)
{
sink = new FrameHandlerSink(false, 5, new FrameType(MediaSubtypes.Y16));
}
else if(this.videoMode == TISVideoMode.TIS_8bit)
{
sink = new FrameHandlerSink(false, 5, new FrameType(MediaSubtypes.Y800));
}
else
{
throw new InvalidOperationException("Unknown video format to sink");
}

// Finalize setup
ic.OverlayBitmapPosition = PathPositions.None;
ic.Sink.SinkModeRunning = true;
ic.LiveCaptureContinuous = true;
ic.LiveDisplay = false;
ic.Sink = sink;
ic.LiveStart();


I read pixels this way (example for Y800):


private ushort[] ReadY800PixelsAsUshort(TIS.Imaging.ImageBuffer buf)
{
ushort[] pixels = new ushort[buf.Size.Height * buf.Size.Width];
unsafe
{
var sourcePtr = (byte*)sink.LastAcquiredBuffer.GetIntPtr();
for (int i = 0; i < pixels.Length; ++i)
{
pixels[i] = (ushort)((*sourcePtr++));
}
}
return pixels;
}

Thanks for you help!

Kind regards,
Stan

Stefan Geissler
June 18, 2015, 16:14:06
Stan

I do not see, where you access the image buffer from the image buffers collection. I only see the function, where you pass a buffer too.

Also, finding the lowest frame rate can be done as:



using System.Linq;

ic.DeviceFrameRate = ic.DeviceFrameRates.Min();

So you wont get problems if the frame rates are sorted upside down.

Stanislaw
June 18, 2015, 16:25:39
Dear Stefan,

LatestImage is the method that is used to get the image for further processing:


public ushort[] LatestImage()
{
if (videoMode == TISVideoMode.TIS_12bit)
{
return ReadY16PixelsAsUshort(sink.LastAcquiredBuffer);
}
else if(videoMode == TISVideoMode.TIS_8bit)
{
return ReadY800PixelsAsUshort(sink.LastAcquiredBuffer);
}
else
{
throw new InvalidOperationException("Unknown video format");
}
}

sink is a global variable, the same one used in the init code.

Maybe I should be using ic.ImageActiveBuffer instead of sink.LastAcquiredBuffer?

Good point with the frame rates, thanks!

Kind regards,
Stan

Stefan Geissler
June 22, 2015, 08:43:20
Hi

If you use a sink explicitly, then sink.LastAcquiredBuffer is the recommended function.

BTW: Which timeout do you use? does it fit to the framerate? e.g. Timeout is 1 second and frame rate is also 1 second or below, then it can last more than one second for receiving an image and you receive an time out.

Stanislaw
June 22, 2015, 12:27:28
Dear Stefan,

The configured frame rate is the slowest one, 3.75 fps. Exposure time (T) is set manually, then timeout = T * 2 + 1000 ms. This should work for any exposure time.

As I have mentioned before, also in grab mode the camera stops streaming images sometimes.

Maybe the exposure setting method is causing problems:


public void SetAbsoluteExposure(double Value)
{
if(isConnected)
{
VCDAbsoluteValueProperty ExposureAbs;
ExposureAbs = (VCDAbsoluteValueProperty)ic.VCDPropertyItems.Find Interface(
VCDIDs.VCDID_Exposure + ":" +
VCDIDs.VCDElement_Value + ":" +
VCDIDs.VCDInterface_AbsoluteValue);

if (ExposureAbs != null)
{
ExposureAbs.Value = Value;
WriteToLog("[TIS] New exposure time is " + GetAbsoluteExposure().ToString("F5") + " sec.");
}
}
}


Kind regards,
Stan

Stefan Geissler
June 22, 2015, 14:41:12
Hi

Did I already ask for the computer model you use?

Stanislaw
June 22, 2015, 15:03:39
Computer 1: Windows Server 2008 R2 Standard 64-bit, 12 GB, i7 950 @ 3.07 GHz
Computer 2: iMac via Parallels, Windows 7 64-bit, 8 GB, i7 3770 @ 3.4 GHz

Computer 2 is used for development, both for testing. Both have no problems running IC Capture.

Regards,
Stan

Stefan Geissler
June 23, 2015, 13:29:18
Hi Stan,


Computer 1: Windows Server 2008 R2 Standard 64-bit, 12 GB, i7 950 @ 3.07 GHz

I never used Windows Server, because the installation of DirectShow usually is incomplete.


Computer 2: iMac via Parallels, Windows 7 64-bit, 8 GB, i7 3770 @ 3.4 GHz

No experiences with iMac and Parallels. Therefore I am not able to comment this.

Do you encounter the same problems with IC Capture?

Stanislaw
June 23, 2015, 14:27:54
Hi Stefan,

Well, I was thinking that maybe the computer hardware is the cause of the problems but since IC Capture works without any problems on both systems, I ruled this out.

How does the init procedure with IC Capture look like? After I get this "hang" and the camera stops producing images, I need to either reconnect the camera physically or run IC Capture for the problem to disappear. If I could reproduce this software procedure, maybe I could "reset" the camera in my own code.

Also, I have noticed that the problem is more frequent when I set the exposure time manually.

Kind regards,
Stan

Stefan Geissler
June 23, 2015, 14:56:50
Hi Stan

for analyzing this, I need a complete, very small project, that reproduces the issue.

Stanislaw
June 25, 2015, 16:37:03
Dear Stefan,

Ok, I will extract a small project.

Stan