Зашумление изображения v2.0 - C#

Узнай цену своей работы

Формулировка задачи:

Всем доброго времени суток! Нашла интересную и полезную тему на просторах форума (Зашумление изображения). К сожалению, она старовата (да и не моя), а вопросы у меня возникли. Собственно для этого и была данная Разъясните мне пожалуйста вот эту строчку:
Листинг программы
  1. byte r = (byte)(rnd.Next(0, 2) == 1 ? color.R : 255);
Как именно генерируется/выбирается случайный пиксель? Почему в результате получаем картинку с разноцветным шумом (скрин прилагается),хотя автор говорил
Если нужен ровный белый шум
(или я что-то не то понимаю под белым шумом?) И как в конечном итоге "зашумить" изображение белым и серым цветом?

Решение задачи: «Зашумление изображения v2.0»

textual
Листинг программы
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Drawing.Imaging;
  5. using System.Net;
  6. using System.Windows.Forms;
  7.  
  8. namespace WindowsFormsApplication330
  9. {
  10.     public partial class Form1 : Form
  11.     {
  12.         public Form1()
  13.         {
  14.             InitializeComponent();
  15.             //загружаем изображение
  16.             var img = new Bitmap(new WebClient { Proxy = null }.OpenRead("http://vignette2.wikia.nocookie.net/callofduty/images/1/11/Personal_Sasi_don_image.jpg/revision/latest?cb=20140511142238"));
  17.  
  18.             //добавляем шум
  19.             var img1 = AddSpeckleNoise(img, 0.04f);
  20.             //выводим
  21.             new PictureBox { Image = img, Parent = this, Size = new Size(250, 200), SizeMode = PictureBoxSizeMode.StretchImage };
  22.             new PictureBox { Image = img1, Parent = this, Size = new Size(250, 200), SizeMode = PictureBoxSizeMode.StretchImage, Left = 300 };
  23.         }
  24.  
  25.         Bitmap AddSpeckleNoise(Bitmap bmp, float v = 0.04f)
  26.         {
  27.             var res = (Bitmap)bmp.Clone();
  28.             var rnd = new Random();
  29.             var stdDev = Math.Sqrt(v);//девиация - корень из дисперсии
  30.  
  31.             using (var wr = new ImageWrapper(res))
  32.                 foreach (var p in wr)
  33.                 {
  34.                     var c = wr[p];
  35.                     var noise = (rnd.NextDouble() - 0.5f) * 2 * stdDev;//равномерное распр со средним = 0, дисперсия = v
  36.                     wr.SetPixel(p, c.R + noise * c.R, c.G + noise * c.G, c.B + noise * c.B);//Id=Is+n*Is
  37.                 }
  38.  
  39.             return res;
  40.         }
  41.     }
  42.  
  43.     /// <summary>
  44.     /// Обертка над Bitmap для быстрого чтения и изменения пикселов.
  45.     /// Также, класс контролирует выход за пределы изображения: при чтении за границей изображения - возвращает DefaultColor, при записи за границей изображения - игнорирует присвоение.
  46.     /// </summary>
  47.     public class ImageWrapper : IDisposable, IEnumerable<Point>
  48.     {
  49.         /// <summary>
  50.         /// Ширина изображения
  51.         /// </summary>
  52.         public int Width { get; private set; }
  53.         /// <summary>
  54.         /// Высота изображения
  55.         /// </summary>
  56.         public int Height { get; private set; }
  57.         /// <summary>
  58.         /// Цвет по-умолачнию (используется при выходе координат за пределы изображения)
  59.         /// </summary>
  60.         public Color DefaultColor { get; set; }
  61.  
  62.         private byte[] data;//буфер исходного изображения
  63.         private byte[] outData;//выходной буфер
  64.         private int stride;
  65.         private BitmapData bmpData;
  66.         private Bitmap bmp;
  67.  
  68.         /// <summary>
  69.         /// Создание обертки поверх bitmap.
  70.         /// </summary>
  71.         /// <param name="copySourceToOutput">Копирует исходное изображение в выходной буфер</param>
  72.         public ImageWrapper(Bitmap bmp, bool copySourceToOutput = false)
  73.         {
  74.             Width = bmp.Width;
  75.             Height = bmp.Height;
  76.             this.bmp = bmp;
  77.  
  78.             bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
  79.             stride = bmpData.Stride;
  80.  
  81.             data = new byte[stride * Height];
  82.             System.Runtime.InteropServices.Marshal.Copy(bmpData.Scan0, data, 0, data.Length);
  83.  
  84.             outData = copySourceToOutput ? (byte[])data.Clone() : new byte[stride * Height];
  85.         }
  86.  
  87.         /// <summary>
  88.         /// Возвращает пиксел из исходнго изображения.
  89.         /// Либо заносит пиксел в выходной буфер.
  90.         /// </summary>
  91.         public Color this[int x, int y]
  92.         {
  93.             get
  94.             {
  95.                 var i = GetIndex(x, y);
  96.                 return i < 0 ? DefaultColor : Color.FromArgb(data[i + 3], data[i + 2], data[i + 1], data[i]);
  97.             }
  98.  
  99.             set
  100.             {
  101.                 var i = GetIndex(x, y);
  102.                 if (i >= 0)
  103.                 {
  104.                     outData[i] = value.B;
  105.                     outData[i + 1] = value.G;
  106.                     outData[i + 2] = value.R;
  107.                     outData[i + 3] = value.A;
  108.                 };
  109.             }
  110.         }
  111.  
  112.         /// <summary>
  113.         /// Возвращает пиксел из исходнго изображения.
  114.         /// Либо заносит пиксел в выходной буфер.
  115.         /// </summary>
  116.         public Color this[Point p]
  117.         {
  118.             get { return this[p.X, p.Y]; }
  119.             set { this[p.X, p.Y] = value; }
  120.         }
  121.  
  122.         /// <summary>
  123.         /// Заносит в выходной буфер значение цвета, заданные в double.
  124.         /// Допускает выход double за пределы 0-255.
  125.         /// </summary>
  126.         public void SetPixel(Point p, double r, double g, double b)
  127.         {
  128.             if (r < 0) r = 0;
  129.             if (r >= 256) r = 255;
  130.             if (g < 0) g = 0;
  131.             if (g >= 256) g = 255;
  132.             if (b < 0) b = 0;
  133.             if (b >= 256) b = 255;
  134.  
  135.             this[p.X, p.Y] = Color.FromArgb((int)r, (int)g, (int)b);
  136.         }
  137.  
  138.         int GetIndex(int x, int y)
  139.         {
  140.             return (x < 0 || x >= Width || y < 0 || y >= Height) ? -1 : x * 4 + y * stride;
  141.         }
  142.  
  143.         /// <summary>
  144.         /// Заносит в bitmap выходной буфер и снимает лок.
  145.         /// Этот метод обязателен к исполнению (либо явно, лмбо через using)
  146.         /// </summary>
  147.         public void Dispose()
  148.         {
  149.             System.Runtime.InteropServices.Marshal.Copy(outData, 0, bmpData.Scan0, outData.Length);
  150.             bmp.UnlockBits(bmpData);
  151.         }
  152.  
  153.         /// <summary>
  154.         /// Перечисление всех точек изображения
  155.         /// </summary>
  156.         public IEnumerator<Point> GetEnumerator()
  157.         {
  158.             for (int y = 0; y < Height; y++)
  159.                 for (int x = 0; x < Width; x++)
  160.                     yield return new Point(x, y);
  161.         }
  162.  
  163.         System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
  164.         {
  165.             return GetEnumerator();
  166.         }
  167.  
  168.         /// <summary>
  169.         /// Меняет местами входной и выходной буферы
  170.         /// </summary>
  171.         public void SwapBuffers()
  172.         {
  173.             var temp = data;
  174.             data = outData;
  175.             outData = temp;
  176.         }
  177.     }
  178. }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

15   голосов , оценка 3.6 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут