opencvsharp icon indicating copy to clipboard operation
opencvsharp copied to clipboard

Problems with the results of Mat.CopyTo()

Open yan97xh opened this issue 3 years ago • 0 comments

Summary of your issue

i want to achieve the function that,i can use the mouse to draw any lines in picturebox ,and erase the lines. Here's my idea, when i need draw a line , i save the mouse location in the mousemove event of picturebox, and use the Cv2.Polylines() to draw it, the results is ok. when i need the erase , there're some issues. Here's how I did it to achieve erase . the src is intput Mat that need to be erased, the oriImg is the Initial image that without any manipulation. they are CV_8UC3.

  1. i also save the mouse location in the mousemove event of picturebox
  2. i creat a mask that has the same size and type as src.
  3. i use the Cv2.Polylines() to mask .
  4. finally, i use the oriImg.CopyTo(src, mask) It didn't turn out the way I wanted. the outputArray is more shallow than src, but the traces of the line can still be seen.

Environment

vs2019 opencvsharp4 4.5.5.20211231

Example code:

    class yLines
    {
        private int _thickness = 0;
        //是否是橡皮
        public bool IsEraser { set; get; }
        //点位数据
        public List<OpenCvSharp.Point> points = new List<Point>();

        public yLines(bool IsEraser = false)
        {
            this.IsEraser = IsEraser;
        }
        //画笔粗细
        public int thickness
        {
            set
            {
                _thickness = value;
                if (_thickness <= 0)
                    _thickness = 1;
            }
            get
            {
                return _thickness;
            }
        }

        //画笔颜色
        public OpenCvSharp.Scalar color { set; get; }
        //正常线
        public Mat DrawLines(Mat src)
        {
            List<List<OpenCvSharp.Point>> tempL = new List<List<OpenCvSharp.Point>>();
            tempL.Add(points);
            Cv2.Polylines(src, tempL, false, color, thickness);
            return src;
        }
        //橡皮 
        // 更新的图像为 src 最原始的图像为 oriImg 利用copyTo 将原始图像点位的像素覆盖到 src上实现橡皮擦
        public Mat DrawEraser(Mat src, Mat oriImg)
        {
            Mat mask = Mat.Zeros(src.Size(), MatType.CV_8UC3);
            if (src.Size() != oriImg.Size())
                return mask; 
            List<List<OpenCvSharp.Point>> tempL = new List<List<OpenCvSharp.Point>>();
            tempL.Add(points);
            //  mask只有线部分非0  其他都是0
            Cv2.Polylines(mask, tempL, false, color, thickness);  
            oriImg.CopyTo(src, mask);
            return src;  
        }
    }

Output:

图片

the traces of the line can still be seen. and i think the CopyTo() changes the color of only part of the channel

What did you intend to be?

how can i get the result that i want.

yan97xh avatar May 27 '22 09:05 yan97xh