shimat / opencvsharp

OpenCV wrapper for .NET
Apache License 2.0
5.39k stars 1.15k forks source link

The Scalar issue in Cv2.Rectangle() and Cv2.Line() #1414

Closed yan97xh closed 1 year ago

yan97xh commented 2 years ago

Summary of your issue

   when i use the mat from the  Mat mm = new Mat(string path) ,  i draw Rect or Line on this mat using Cv2.Rectangle() and Cv2.Line(),  the result is show normally.
  but, when i use the mat from OpenCvSharp.Extensions.BitmapConverter.ToMat(Bitmap bitmap), No matter how I change the scalar ,  the results of drawing is abnormal , 
  i show the results in the picturebox , it just like using the  scalar.white  no matter what scalar i have chosed.

Environment

vs2019, opencvsharp4 4.5.5.20211231

Example code:

        private void button1_Click(object sender, EventArgs e)
        {
            string path = @"E:\myPictures\LenaSource\lena_JPG.jpg";
            pictureBox1.Image = new Bitmap(path);
            pictureBox2.Image = new Bitmap(path);

            Mat mm = new Mat(path);
            Bitmap bitmap = new Bitmap(pictureBox2.Image);
            Mat mm2 = OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap);

            OpenCvSharp.Rect rect = new Rect(50, 50, 100, 100);
            Cv2.Rectangle(mm, rect, Scalar.Red, 1, LineTypes.AntiAlias);
            Cv2.Rectangle(mm2, rect, Scalar.Red, 1, LineTypes.AntiAlias);

            //Cv2.Line(mm, 50, 50, 150, 50, Scalar.Red);
            //Cv2.Line(mm, 50, 50, 50, 150, Scalar.Red);
            //Cv2.Line(mm, 150, 50, 150, 150, Scalar.Red);
            //Cv2.Line(mm, 150, 150, 50, 150, Scalar.Red);

            //Cv2.Line(mm2, 50, 50, 150, 50, Scalar.Red);
            //Cv2.Line(mm2, 50, 50, 50, 150, Scalar.Red);
            //Cv2.Line(mm2, 150, 50, 150, 150, Scalar.Red);
            //Cv2.Line(mm2, 150, 150, 50, 150, Scalar.Red);

            pictureBox1.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mm);
            pictureBox2.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mm2);   
        }

Output:

using the Cv2.Rectangle() 企业微信截图_16505936883114

using the Cv2.Line() li

What did you intend to be?

  the results of using the mat from OpenCvSharp.Extensions.BitmapConverter.ToMat(Bitmap bitmap) is different from the results of using the  mat from new mat(string path). 
   the results of using Cv2.Rectangle() is also different from the results of using Cv2.Line() where the mat is from OpenCvSharp.Extensions.BitmapConverter.ToMat(Bitmap bitmap).  
  in theory , they should be the same.
  I wonder what went wrong in the process of my use.  
  And,  How to use the mat from OpenCvSharp.Extensions.BitmapConverter.ToMat(Bitmap bitmap)  correctly to draw rect and lines.
shimat commented 2 years ago

Could you tell me the depth/channels of bitmap and mm2 ?

My expectation is that bitmap.PixelFormat is PixelFormat.Format32bppRgb and mm2.Type is 8UC4. new Bitmap(file) will usually create a PixelFormat.Format32bppRgb Bitmap.

Cv2.Line and Cv2.Rectangle should work as expected for 8UC3 (BGR) Mat, but should have unintended results for 8UC4 Mat.

You may be able to work around this problem by doing the following:

Bitmap bitmap = new Bitmap(pictureBox2.Image);
using Mat mm2 = new Mat(bitmap.Height, bitmap.Width, MatType.CV_8UC3);
OpenCvSharp.Extensions.BitmapConverter.ToMat(bitmap, mm2);
yan97xh commented 2 years ago

thanks, I used your method to solve the problem。

i checked the mm2.Type is 8UC4 , but , i use the mm2.ConvertTo(mm2, MatType.CV_8UC3) ,it doesn't work, the result is still 8UC4. i use the Cv2.CvtColor(mm2, mm2, ColorConversionCodes.BGRA2BGR), the result is changed to 8UC3

stale[bot] commented 1 year ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.