Iawfy_ 2022-01-04 09:33 采纳率: 50%
浏览 78
已结题

c#opencvsharp在winform中实现图像马赛克卡死

相关变量

        public struct ImageMosaic
        {
            // 原图
            public static string Image;
            // 判断是否已经马赛克 避免重复打码
            public static bool[,] IsMosaic;

            public static ManualResetEvent MosaicEvent = new ManualResetEvent(false);
            
            public static int MosaicSize;

            public static bool IsEnterPbx;

            public static bool IsLeave;
        }

马赛克线程

 public static Thread MosaicTask = new Thread(() =>
          {
              while (true)
              {
                  yVariables.ImageMosaic.MosaicEvent.WaitOne();
                  if (yVariables.ImageMosaic.IsLeave == true)
                  {
                      yVariables.ImageMosaic.MosaicEvent.Reset();
                  }
                  OpenCvSharp.Mat mm = new OpenCvSharp.Mat();
                  mm = yImageConvert.ImageToMat(Form1.Instance.pbxMosaic.Image);
                  bool en = true;
                  int MX = 0, MY = 0;
                  Form1.Instance.Invoke(new Action(() =>
                  {
                      MX = Form1.Instance.pbxMosaic.PointToClient(Control.MousePosition).X;
                      MY = Form1.Instance.pbxMosaic.PointToClient(Control.MousePosition).Y;
                  }));

                  // 获取的是鼠标相对于picbox左上角的位置 需要转化成相对于图像左上角的位置
                  // 图片大小不一定等于picbox的大小 picbox的sizemode是StretchImage  
                  // 鼠标位置对应成比例  在原图上处理 而不是在picbox内的图片处理
                  en = MX > 0 && MX < Form1.Instance.pbxMosaic.Width;
                  en = en && MY > 0 && MY < Form1.Instance.pbxMosaic.Height;
                  if (en)
                  {
                      int x = MX * mm.Width / Form1.Instance.pbxMosaic.Width;

                      int y = MY * mm.Height / Form1.Instance.pbxMosaic.Height;  

                      if (yVariables.ImageMosaic.IsMosaic[y, x] == false)
                      {
                          yVariables.ImageMosaic.IsMosaic[y, x] = true;

                          for (int i = x - yVariables.ImageMosaic.MosaicSize; i <= x + yVariables.ImageMosaic.MosaicSize; i++)
                          {
                              for (int j = y - yVariables.ImageMosaic.MosaicSize; j <= y + yVariables.ImageMosaic.MosaicSize; j++)
                              {
                                  //边界考虑
                                  if (i < 0) i = 0;
                                  if (i >= mm.Width) i = mm.Width - 1;
                                  if (j < 0) j = 0;
                                  if (j >= mm.Height) j = mm.Height - 1;
                                  //if (yVariables.ImageMosaic.IsMosaic[j, i] == false)
                                  //{
                                      yVariables.ImageMosaic.IsMosaic[j, i] = true;
                                      OpenCvSharp.Vec3b color = new OpenCvSharp.Vec3b(); 
                                      color.Item0 = (byte)(mm.Get<OpenCvSharp.Vec3b>(y, x).Item0);
                                      color.Item1 = (byte)(mm.Get<OpenCvSharp.Vec3b>(y, x).Item1); 
                                      color.Item2 = (byte)(mm.Get<OpenCvSharp.Vec3b>(y, x).Item2); 
                                      mm.Set(j, i, color);
                                  //}
                              }
                          }
                          Form1.Instance.pbxMosaic.Image = yImageConvert.MatToBitmap(mm);
                      } 
                      Thread.Sleep(50); 
                  }
                  else
                  {
                      yVariables.ImageMosaic.MosaicEvent.Reset();
                      yVariables.ImageMosaic.IsLeave = true;
                      yVariables.ImageMosaic.IsEnterPbx = false;
                  }

              }
          });

控件事件

        //图像选择 初始变量
        private void button1_Click_1(object sender, EventArgs e)
        {
            string path = yFileOperates.SelectPic();
            if (path != "" && path != yVariables.ImageMosaic.Image)
            {
                yVariables.ImageMosaic.Image = path;
                Bitmap map = new Bitmap(yVariables.ImageMosaic.Image);
                pbxMosaic.Image = map;
                tbxMosaiImage.Text = yVariables.ImageMosaic.Image;
                yVariables.ImageMosaic.IsMosaic = new bool[map.Height, map.Width];
                if(yImageMosaic.MosaicTask.IsAlive) yVariables.ImageMosaic.MosaicEvent.Reset();
                for (int i = 0; i < map.Height; i++)
                {
                    for (int j = 0; j < map.Width; j++)
                    {
                        yVariables.ImageMosaic.IsMosaic[i, j] = false;
                    }
                }
            }
        }

        //线程启动
        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            if (pbxMosaic.Image == null) return;
            if (!yImageMosaic.MosaicTask.IsAlive)
                yImageMosaic.MosaicTask.Start();
            yVariables.ImageMosaic.IsLeave = false;
            yVariables.ImageMosaic.IsEnterPbx = true;
            yVariables.ImageMosaic.MosaicEvent.Set();
        }
        //暂停
        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {
            yVariables.ImageMosaic.MosaicEvent.Reset();
        }

        private void pictureBox1_MouseLeave(object sender, EventArgs e)
        {
            if (yVariables.ImageMosaic.IsEnterPbx == true)
            {
                yVariables.ImageMosaic.IsEnterPbx = false;
                yVariables.ImageMosaic.IsLeave = true;
                yVariables.ImageMosaic.MosaicEvent.Reset();
            }
        }

刚开始运行起来的时候是正常的 但当在picturebox内一直按下鼠标时 再把鼠标移出picturebox 再回来时有时候就会不进线程,打断点也监测不到了,mousedown事件还是正常触发的,但是线程的isalive状态还是true的 。这种情况也是时而发生不确定什么原因造成的,而且发生后只能重启程序,更换图片都不行

  • 写回答

0条回答 默认 最新

    报告相同问题?

    问题事件

    • 系统已结题 1月12日
    • 创建了问题 1月4日

    悬赏问题

    • ¥15 高通uboot 打印ubi init err 22
    • ¥20 PDF元数据中的XMP媒体管理属性
    • ¥15 R语言中lasso回归报错
    • ¥15 网站突然不能访问了,上午还好好的
    • ¥15 有没有dl可以帮弄”我去图书馆”秒选道具和积分
    • ¥15 semrush,SEO,内嵌网站,api
    • ¥15 Stata:为什么reghdfe后的因变量没有被发现识别啊
    • ¥15 振荡电路,ADS仿真
    • ¥15 关于#c语言#的问题,请各位专家解答!
    • ¥15 这个如何解决详细步骤