Search code examples
c#opencvcamera-calibration

C# OpenCV DrawChessboardCorners' lines are black and white when saving image


The FindCheckerBoard Method takes a BitmapSource as an input, and convert it to Mat by using BitmapSourceConverter.

Then it goes through processes such as FindChessboardCorners and CornerSubPix. With the points found from CornerSubPix, I used DrawChessBoardCorners on the original Mat.

Here is the problem, and what I have tried to debug it.

  1. When I use Cv2.ImShow() to see the image, the image has colored lines for checkerboards.
  2. When I use Cv2.ImWrite() to save the image as a file, the lines suddenly become white lines instead of colored lines.
  3. I used ImageViewer to debug the Mat variable which I applied Imshow() and ImWrite(), it shows "Black" lines.

How can I save the output as an image with colored lines?


Edited: I tried the almost same logic in opencv-python, and the saved image has colored lines. I'm assuming it's with either opencvsharp or BitmapSource input.

public int FindCheckerBoard(JObject param, BitmapSource imageSource, out BitmapSource imageResult)
    {
        JObject _param = param;
        Mat matSource = OpenCvSharp.WpfExtensions.BitmapSourceConverter.ToMat(imageSource);
        Mat matResult = matSource.Clone();

        Size patternSize = new Size(4, 6);
        Size imageSize = new Size(0, 0);
        List<Mat> objectPoints = new List<Mat>();
        var objectPointsArray = Create3DChessboardCorners(patternSize, 0.02f).ToArray();
        var objectPointsMat = Mat<Point3f>.FromArray(objectPointsArray);

        imageSize.Width = matSource.Width;
        imageSize.Height = matSource.Height;
        Mat<Point2f> corner = new Mat<Point2f>();
        var ret = Cv2.FindChessboardCorners(matSource, patternSize, corner);
        if (ret)
        {
            Mat gray = new Mat();
            Point2f[] corner2 = null;
            if (matSource.Channels() >= 3)
            {
                Cv2.CvtColor(matSource, gray, ColorConversionCodes.BGR2GRAY);
                corner2 = Cv2.CornerSubPix(gray, corner.ToArray(), new OpenCvSharp.Size(11, 11), new OpenCvSharp.Size(-1, -1), TermCriteria.Both(30, 0.001));
            }
            else
            {
                corner2 = Cv2.CornerSubPix(matSource, corner.ToArray(), new OpenCvSharp.Size(11, 11), new OpenCvSharp.Size(-1, -1), TermCriteria.Both(30, 0.001));
            }

            var showPicture = _param[SHOW_PICTURE].ToObject<bool>();
            Cv2.DrawChessboardCorners(matResult, patternSize, corner2, ret);
            if (showPicture == true)
            {
                Cv2.ImShow("FindCheckerBoard", matResult);
                Cv2.ImWrite(@"C:\1.png", matResult);
                Cv2.WaitKey(0);
            }
        }
        imageResult = OpenCvSharp.WpfExtensions.BitmapSourceConverter.ToBitmapSource(matResult);

enter image description here

enter image description here


Solution

  • It turned out that the matSource which is converted from BitmapSource is MatType of 8UC4 and the python's Mat which is from Imread() is 8UC3.

    By converting 8UC4 to 8UC3, the output image has colored lines.

     Cv2.CvtColor(matSource, matSource, ColorConversionCodes.BGRA2BGR);