C # генерировать двоичную маску без значений серого / шума на изображении? - PullRequest
0 голосов
/ 01 октября 2018

В C #, как мне сгенерировать двоичную маску, в которой нет серых значений / шума на изображении?

Сейчас я могу сгенерировать довольно простой вывод, который выглядит очень близко к тому, что я хочу, ноимеет шум вокруг краев как внутри, так и снаружи белого шарика ( Вам нужно полностью увеличить масштаб, чтобы увидеть шум ).Я планирую использовать изображение позже для обработки изображения, но не могу иметь ничего, кроме черно-белых значений на изображении.

Изображения: Обрезать 1 Обрезать 2

Код:

    public CropedImage(List<Node> nodes)
    {
        InitializeComponent();
        //List<PointF> listpoints = new List<PointF>();
        nodes.ToArray();
        PointF[] points = new PointF[nodes.Count];
        for(int i = 0; i < nodes.Count; ++i)
        {
            points[i].X = nodes[i].X;
            points[i].Y = nodes[i].Y;
        }

        Image SourceImage = ImageOperations.GetImage(MainForm.imageMatrix, pictureBox1);

        using (Graphics g = Graphics.FromImage(SourceImage))
        {
            Color black = ColorTranslator.FromHtml("#000000");
            Color white = ColorTranslator.FromHtml("#FFFFFF");


            using (Brush b = new SolidBrush(black))
            {
                Rectangle rect = new Rectangle();
                g.FillRectangle(b, 0, 0, MainForm.WIDTH, MainForm.HEIGHT);
            }
            using (Brush b2 = new SolidBrush(white))
            {
                g.SmoothingMode = SmoothingMode.AntiAlias;
                g.FillClosedCurve(b2, points, 0);
            }
        }

    }

Ответы [ 2 ]

0 голосов
/ 01 октября 2018

Как насчет изменения

g.SmoothingMode = SmoothingMode.AntiAlias;

на

g.SmoothingMode = SmoothingMode.None;

Если я правильно понимаю, это решит вашу проблему.

0 голосов
/ 01 октября 2018

Как сказал eocron, вы должны проверить все пиксели и округлить их до черного или белого.Самый простой способ сделать это (если вы создаете временное приложение для нескольких изображений) - это использовать методы GetPixel() и SetPixel():

Bitmap bmp = Bitmap.FromFile("image.png");
for(int i=0;i<bmp.Width;i++)
   for(int j=0;j<bmp.Height;j++)
      bmp.SetPixel(i,j, bmp.GetPixel(i,j).R > 127? Color.White: Color.Black); // as its gray I'm only checking Red

Однако, если вы имеете делос большим количеством изображений, особенно больших, или это не временное приложение для работы с несколькими изображениями, и оно станет функцией вашего приложения, приведенный выше код не тот, который вы хотели бы использовать, поскольку он очень медленный, иВы должны использовать LockBits, поскольку это намного быстрее:

 Bitmap bmp = Bitmap.FromFile("image.png"); 
 Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
 System.Drawing.Imaging.BitmapData bmpData = 
 bmp.LockBits(rect,System.Drawing.Imaging.ImageLockMode.ReadWrite,bmp.PixelFormat;
 IntPtr ptr = bmpData.Scan0;
 int bytes  = Math.Abs(bmpData.Stride) * bmp.Height;
 byte[] rgbValues = new byte[bytes];
 System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
 for (int counter = 0; counter < rgbValues.Length; counter += 4)
 {
    int c = rgbValues[counter] > 127 ? 255: 0;
    rgbValues[counter] = c;
    rgbValues[counter+1] = c;
    rgbValues[counter+2] = c;
 }
 System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
 bmp.UnlockBits(bmpData);
...