0

I am using Zivid.NET, Halcon.NET and ML.NET together. Zivid provides me with a 3D byte array (row, column, channel), Halcon uses HImages/HObjects, ML.NET functionality expects a 1D byte array (same as File.ReadAllBytes())

So far I used a workaround where:

  1. I save()'d Zivid's imageRGBA as a PNG,
  2. which I read with Halcon's read_image() that gives me a HObject.
  3. After some graphical work I saved the HObject again as a PNG using write_image().
  4. Using File.ReadAllBytes() to read that PNG I get the byte[] that my ML.NET functionalities expect.

But this is far from ideal with larger amounts of data.

What I need is:

  1. a way to convert byte[r,c,c] images to HObject/HImage.
  2. a way to convert HObject/HImage images to byte[].

Halcon's read_image() and write_image() don't seem to have any options for this and I haven't found anything helpful so far.

Malinko
  • 124
  • 11

2 Answers2

1

To create an HImage object from byte, you need a pointer to an array and then it's simple:

public HImage(string type, int width, int height, IntPtr pixelPointer)

To get a pointer and acess the data from HImage, the following function is needed:

IntPtr HImage.GetImagePointer1(out string type, out int width, out int height)
Vladimir Perković
  • 1,351
  • 3
  • 12
  • 30
  • Using `public HImage(string type, int width, int height, IntPtr pixelPointer)` resulted in a really distorted image when it receives a pointer to 4-channel image data. It did point me in the right direction where I found `GenImage3()` , with this procedure I could get the correct image, so thanks! – Malinko Nov 15 '22 at 15:10
0

To convert from Zivid.NET's byte[r,c,c] to HImage one can:

var byteArr = imgRGBA.ToByteArray();

byte[,] redByteArray = new byte[1200, 1920];
byte[,] greenByteArray = new byte[1200, 1920];
byte[,] blueByteArray = new byte[1200, 1920];

for (int row = 0; row < 1200; row++)
    for (int col = 0; col < 1920; col++)
    {
        redByteArray[row, col] = byteArr[row, col, 0];
        greenByteArray[row, col] = byteArr[row, col, 1];
        blueByteArray[row, col] = byteArr[row, col, 2];
    }

GCHandle pinnedArray_red = GCHandle.Alloc(redByteArray, GCHandleType.Pinned);
IntPtr pointer_red = pinnedArray_red.AddrOfPinnedObject();

GCHandle pinnedArray_green = GCHandle.Alloc(greenByteArray, GCHandleType.Pinned);
IntPtr pointer_green = pinnedArray_green.AddrOfPinnedObject();

GCHandle pinnedArray_blue = GCHandle.Alloc(blueByteArray, GCHandleType.Pinned);
IntPtr pointer_blue = pinnedArray_blue.AddrOfPinnedObject();

GenImage3(out HObject imgHImage, "byte", 1920, 1200, pointer_red, pointer_green, pointer_blue);

pinnedArray_red.Free();
pinnedArray_green.Free();
pinnedArray_blue.Free();

Still working on the second part.. A better / more efficient method is very welcome.

Malinko
  • 124
  • 11