PanoramicMappedImage

Hello
I’m new to CVB. I’m developing in VB.NET using the ringbuffer control to cache frames from a line scan camera. I need to create images of rectangular objects coming down a conveyor belt that will consist of multiple frames stitched together.
I understand that I need to stitch 2 buffer frames together so that I can use the edge control to see if I have a beginning frame of an object, then keep checking subsequent frame pairs for the ending edge.
It was suggested that I use the PanoramicMappedImage to do the stitching, but I’m having difficulties finding VB reference examples on this. I saw the C# example, but it seems to use pointers to expressions and I’m not sure how to convert that to VB.
I’m also having difficulty finding the best way to convert from stemmer.cvb.image’s to system.drawing.images (in memory)
Can anyone give me some guidance on doing what I’m trying to accomplish? Is there a better way than what I layed out above?

Any help would be appreciated

Maurice

Hello @MoDiver,

when you say ringbuffer control do you mean the ActiveX control? You also seem to use the object oriented wrappers. Then you don’t need the ActiveX controls. We don’t have many VB.Net users, this is why we don’t have examples. Sorry. Still I recommend reading:

https://forum.commonvisionblox.com/t/getting-started-with-cvb-net/246?u=parsd

The C# in there is easily translated to VB.Net as the objects are the same. There also the ring buffer is explained.

PanoramicImage

I start with the code:

Sub AcquisitionLoop(device As Device)
  Dim stream = device.Stream

  stream.RingBuffer.LockMode = RingBufferLockMode.On
  stream.RingBuffer.ChangeCount(6, DeviceUpdateMode.UpdateDeviceImage)

  stream.Start()
  Dim lastImage As StreamImage = Nothing
  Try
    While True
      Dim newImage = stream.Wait()
      If lastImage IsNot Nothing Then
        ProcessImages(lastImage, newImage) 
      End If

      If lastImage IsNot Nothing
        lastImage.Dispose()
      End If
      lastImage = newImage
    End While
  Finally
    If lastImage IsNot Nothing
      lastImage.Dispose()
    End If
    stream.Abort()
  End Try
End Sub

Sub ProcessImages(imageTop As Image, imageBottom As Image)
  Dim combinedImage = PanoramicMappedImage.CreateVertical(imageTop, imageBottom)
  
  YourSearch(combinedImage)
End Sub

You store your previous image and process then two at once without copying any data. To be able to do that you need to increase the ring buffer size and change the lock mode to manual (LockMode.On). The size increase is necessary to prevent loosing frames. And you now need to explicitly unlock your unused images via .Dispose(). If you don’t do that your ring buffer runs out of usable memory and your application blocks in the .Wait call.

Image to Bitmap

Just add the reference to Stemmer.Cvb.Extensions.dll to your project and make sure that you import the namespace Stemmer.Cvb.Extensions. Then you can simply call .ToBitmap() on a Stemmer.Cvb.Image.

I hope that helps.

2 Likes

Thank you!
That helped a lot.

I’ve been pulling my hair out trying to overcome another hurdle…
I’m currently trying to set the PixelFormat to RGB8. I see C# code in tutorials that uses an OCX AxCVIMAGELib.AxCVimage to get the nodemap

Is there a way to do it using Stemmer.Cvb.DeviceFactory.OpenPort(“GenICam.vin”, 0).Stream ?

Thank you for your guidance
Mo

I was able to get the Pixel format node with GenApi.NMGetNode()
and I made it equal to the enumerated RGB8 node
but it doesn’t set

How do I set/write the node back to the video device?

Thanks

Nevermind, I figured it out.

        videoDevice = Stemmer.Cvb.DeviceFactory.OpenPort("GenICam.vin", 0)
        deviceNodeMap = videoDevice.NodeMaps(NodeMapNames.Device)

        Dim PixelFormat As Stemmer.Cvb.GenApi.EnumerationNode = deviceNodeMap("PixelFormat")
        PixelFormat.Value = "RGB8"

Thank you for your help anyway

2 Likes

Hi @MoDiver,

if you use preconfigured devices as in your example you can change the target pixel format via e.g. the GenICamBrowser. This is stored in the GenICam.ini file in %CVBCONFIG%\Drivers folder. If you want the camera to actually always start sending RGB8 you need to store it in the camera (see UserSetControl in the GenApi features).

If you want to switch at runtime you can do it as you did, but you also need to update the backing store in the ring buffer:

videoDevice.ImageRect.Update(DeviceUpdateMode.UpdateDeviceImage)

In your case it probably works because the camera’s default is some Bayer format that is automatically converted to RGB8. RGB8 is the default target format for any color format a camera sends.

And thank you a lot for the VB .Net examples! :heart:

1 Like