1

I want to put a PictureBox on WinForm in C # using a Basler camera. But I want to convert IGrabImage to Mat. because I want to insert it into the PictureBox using Mat.

Please let me know your hint or solution.

PixelDataConverter converter = new PixelDataConverter();

    public Form1() {
        InitializeComponent();
        using (Camera camera = new Camera())
        {
            camera.CameraOpened += Configuration.AcquireContinuous;

            camera.Open();
            camera.Parameters[PLCameraInstance.MaxNumBuffer].SetValue(5);
            camera.StreamGrabber.Start();

            IGrabResult grabResult = camera.StreamGrabber.RetrieveResult(5000, TimeoutHandling.ThrowException);

            using (grabResult)
            {
                if (grabResult.GrabSucceeded) {
                    Mat rtnMat = convertToMat(grabResult);                       
                    Cv2.ImShow("test", rtnMat);
                    pictureBox1.Image = BitmapConverter.ToBitmap(frame);
                }
            }

            camera.StreamGrabber.Stop();
            camera.Close();
        }
    }

    private Mat convertToMat(IGrabResult rtnGrabResult) {
        IImage image = rtnGrabResult;
        converter.OutputPixelFormat = PixelType.BGR8packed;
        byte[] buffer = image.PixelData as byte[];
        return new Mat(rtnGrabResult.Width, rtnGrabResult.Height, MatType.CV_8UC1, buffer);
    }

Basler Image:

Basler Image

OpenCvSharp Image:

OpenCvSharp Image

Jeru Luke
  • 20,118
  • 13
  • 80
  • 87
J.Soo
  • 11
  • 1
  • 3
  • So... what is the actual problem? Doesn't the code work? – Nyerguds May 23 '18 at 19:25
  • Basler Image is the desired image. But it comes out like OpenCvSharp Image. – J.Soo May 24 '18 at 00:33
  • That seems like a stride problem to me... you should be able to get the stride ([actual width in bytes of one pixel line](https://stackoverflow.com/questions/2185944/why-must-stride-in-the-system-drawing-bitmap-constructor-be-a-multiple-of-4)) out of that data _somehow_. And if you can't actually give that stride to the Mat constructor, you may have to compact the byte data to trim away any padding. – Nyerguds May 24 '18 at 05:34
  • This isn't just stride, though... there's obvious tripling of images there. Looking at the specs, `CV_8UC1` means a 8-bit single-channel array (grayscale), while `BGR8packed` means 24-bit RGB, so that clearly doesn't match. Also, you have this `PixelDataConverter` object, but you don't actually seem to _use_ it anywhere. – Nyerguds May 24 '18 at 06:45
  • Are you sure it is a RGB image returned from your camera? it looks like a greyscale image to me, therefore PixelType.BGR8packed is not correct and hence you see a triple image rather than a colour one. – ejectamenta Jun 04 '19 at 10:26

1 Answers1

1

Here is the correct way to convert an IGrabResult into an OpenCvSharp.Mat. I didn't try it without the converter but your main problem was the sequence of the new Mat(..) arguments. In OpenCV, you declare the rows first and then the columns. That means first height and then width. And also the MatType for an colored image was wrong like @Nyerguds said. It has to be CV_8UC3.

Corrected code:

private Mat convertToMat(IGrabResult rtnGrabResult) {
        converter.OutputPixelFormat = PixelType.BGR8packed;
        byte[] buffer = new byte[conv.GetBufferSizeForConversion(rtnGrabResult];
        converter.Convert(buffer, rtnGrabResult);
        return new Mat(rtnGrabResult.Height, rtnGrabResult.Width, MatType.CV_8UC3, buffer);
}
MrRobot
  • 11
  • 1