Học tập‎ > ‎C#‎ > ‎

Xử lý ảnh trong C#: Làm mịn hình ảnh bằng convolution

    Làm mịn ảnh là một dạng của làm mờ ảnh dựa trên phương pháp convolution (Đại số chân chập).
Đầu tiên chúng ta lấy ra từng ô vuông nhỏ của hình ảnh, trong các ô vuông sẽ chứa các điểm ảnh, thường là 3x3. Lấy mẫu càng nhỏ thì độ chính xác càng cao, với hình ảnh có kích thước lớn chúng ta có thể lấy mẫu lớn hơn để xử lý.
Điểm ảnh trung tâm của ma trân là điểm ảnh chính mà chúng ta cần quan tâm.
Đầu tiên ta gán các trọng số cho các điểm ảnh trong bảng (ma trận), tuỳ thuộc vào hiệu ứng mà chúng ta muốn thực hiện.
Cuối cùng ta gán kết quả cho điểm ảnh trung tâm.

Cấu trúc dữ liệu cơ bản dùng cho phương pháp này là 1 class chứa mảng 2 chiều cũng như các trọng số và phần bù:

  1. public class ConvolutionMatrix  
  2. {  
  3.     public int MatrixSize = 3;  
  4.   
  5.     public double[,] Matrix;  
  6.     public double Factor = 1;  
  7.     public double Offset = 1;  
  8.   
  9.     public ConvolutionMatrix(int size)  
  10.     {  
  11.         MatrixSize = 3;  
  12.         Matrix = new double[size, size];  
  13.     }  
  14.   
  15.     public void SetAll(double value)  
  16.     {  
  17.         for (int i = 0; i < MatrixSize; i++)  
  18.         {  
  19.             for (int j = 0; j < MatrixSize; j++)  
  20.             {  
  21.                 Matrix[i, j] = value;  
  22.             }  
  23.         }  
  24.     }  
  25. }  

Với class trên chúng ta đã có thể thực hiện thuật toán Convolution.

  1. public Bitmap Convolution3x3(Bitmap b, ConvolutionMatrix m)  
  2. {  
  3.     Bitmap newImg = (Bitmap)b.Clone();  
  4.     Color[,] pixelColor = new Color[3, 3];  
  5.     int A, R, G, B;  
  6.   
  7.     for (int y = 0; y < b.Height - 2; y++)  
  8.     {  
  9.         for (int x = 0; x < b.Width - 2; x++)  
  10.         {  
  11.             pixelColor[0, 0] = b.GetPixel(x, y);  
  12.             pixelColor[0, 1] = b.GetPixel(x, y + 1);  
  13.             pixelColor[0, 2] = b.GetPixel(x, y + 2);  
  14.             pixelColor[1, 0] = b.GetPixel(x + 1, y);  
  15.             pixelColor[1, 1] = b.GetPixel(x + 1, y + 1);  
  16.             pixelColor[1, 2] = b.GetPixel(x + 1, y + 2);  
  17.             pixelColor[2, 0] = b.GetPixel(x + 2, y);  
  18.             pixelColor[2, 1] = b.GetPixel(x + 2, y + 1);  
  19.             pixelColor[2, 2] = b.GetPixel(x + 2, y + 2);  
  20.   
  21.             A = pixelColor[1, 1].A;  
  22.   
  23.             R = (int)((((pixelColor[0, 0].R * m.Matrix[0, 0]) +  
  24.                          (pixelColor[1, 0].R * m.Matrix[1, 0]) +  
  25.                          (pixelColor[2, 0].R * m.Matrix[2, 0]) +  
  26.                          (pixelColor[0, 1].R * m.Matrix[0, 1]) +  
  27.                          (pixelColor[1, 1].R * m.Matrix[1, 1]) +  
  28.                          (pixelColor[2, 1].R * m.Matrix[2, 1]) +  
  29.                          (pixelColor[0, 2].R * m.Matrix[0, 2]) +  
  30.                          (pixelColor[1, 2].R * m.Matrix[1, 2]) +  
  31.                          (pixelColor[2, 2].R * m.Matrix[2, 2]))  
  32.                                 / m.Factor) + m.Offset);  
  33.   
  34.             if (R < 0)  
  35.             {  
  36.                 R = 0;  
  37.             }  
  38.             else if (R > 255)  
  39.             {  
  40.                 R = 255;  
  41.             }  
  42.   
  43.             G = (int)((((pixelColor[0, 0].G * m.Matrix[0, 0]) +  
  44.                          (pixelColor[1, 0].G * m.Matrix[1, 0]) +  
  45.                          (pixelColor[2, 0].G * m.Matrix[2, 0]) +  
  46.                          (pixelColor[0, 1].G * m.Matrix[0, 1]) +  
  47.                          (pixelColor[1, 1].G * m.Matrix[1, 1]) +  
  48.                          (pixelColor[2, 1].G * m.Matrix[2, 1]) +  
  49.                          (pixelColor[0, 2].G * m.Matrix[0, 2]) +  
  50.                          (pixelColor[1, 2].G * m.Matrix[1, 2]) +  
  51.                          (pixelColor[2, 2].G * m.Matrix[2, 2]))  
  52.                                 / m.Factor) + m.Offset);  
  53.   
  54.             if (G < 0)  
  55.             {  
  56.                 G = 0;  
  57.             }  
  58.             else if (G > 255)  
  59.             {  
  60.                 G = 255;  
  61.             }  
  62.              
  63.             B = (int)((((pixelColor[0, 0].B * m.Matrix[0, 0]) +  
  64.                          (pixelColor[1, 0].B * m.Matrix[1, 0]) +  
  65.                          (pixelColor[2, 0].B * m.Matrix[2, 0]) +  
  66.                          (pixelColor[0, 1].B * m.Matrix[0, 1]) +  
  67.                          (pixelColor[1, 1].B * m.Matrix[1, 1]) +  
  68.                          (pixelColor[2, 1].B * m.Matrix[2, 1]) +  
  69.                          (pixelColor[0, 2].B * m.Matrix[0, 2]) +  
  70.                          (pixelColor[1, 2].B * m.Matrix[1, 2]) +  
  71.                          (pixelColor[2, 2].B * m.Matrix[2, 2]))  
  72.                                 / m.Factor) + m.Offset);  
  73.   
  74.             if (B < 0)  
  75.             {  
  76.                 B = 0;  
  77.             }  
  78.             else if (B > 255)  
  79.             {  
  80.                 B = 255;  
  81.             }  
  82.             newImg.SetPixel(x+1, y+1, Color.FromArgb(A, R, G, B));  
  83.         }  
  84.     }  
  85.     return newImg;  
  86. }  

Sau khi hoàn thành tất cả, chúng ta sẽ thực hiện chức năng làm mịn hình ảnh bằng cách gán một giá trị cụ thể cho điểm ảnh trung tâm và các điểm ảnh xung quanh sẽ được gán giá trị là 1. mảng sẽ có dạng:
111
181
111

Tham số trọng số được tính bằng cách cọng trọng số tất cả điểm ảnh trong bảng, trong trườn hợp này là 8+1+1+1+1+1+1+1+1=16. Và phần bù được set là 0. Phần bù này sẽ chyển đổi tất cả màu thành giá trị quy định.

  1. public void ApplySmooth(double weight)  
  2. {  
  3.     ConvolutionMatrix matrix = new ConvolutionMatrix(3);  
  4.     matrix.SetAll(1);  
  5.     matrix.Matrix[1,1] = weight;  
  6.     matrix.Factor = weight + 8;  
  7.     bitmapImage = Convolution3x3(bitmapImage, matrix);  
  8.   


Dịch từ: http://www.smokycogs.com/blog/image-processing-in-c-sharp-smoothing-using-convolution/
Comments