[C#] 濾鏡筆記 – 銳利化

2012-12-05

 

銳利化開始有點複雜要導入矩陣的觀念,因為他跟之前模糊化一樣

必須和周圍的點一起套入公式進行處理

可以參考這篇:

http://stackoverflow.com/questions/903632/sharpen-on-a-bitmap-using-c-sharp

http://blog.csdn.net/jiangxinyu/article/details/6222322

關於拉普拉絲的矩陣是長這樣

// 建立3x3 矩陣 拉普拉斯
//  -1  -1  -1    (0,0) | (1,0) | (2,0) 
//  -1  +9  -1    (0,1) | (1,1) | (2,1)
//  -1  +1  -1    (0,2) | (1,2) | (2,2)


中心點加上9 周圍八點-1 後取相加平均…


public static Bitmap AdjustLaplaceSharpen(Bitmap src)
{
 
 
    // 建立3x3 矩陣 拉普拉斯
    //  -1  -1  -1    (0,0) | (1,0) | (2,0) 
    //  -1  +9  -1    (0,1) | (1,1) | (2,1)
    //  -1  +1  -1    (0,2) | (1,2) | (2,2)
    double[,] filter = new double[3, 3];
    filter[0, 0] = filter[0, 1] = filter[0, 2] = filter[1, 0] = filter[1, 2] = filter[2, 0] = filter[2, 1] = filter[2, 2] = -1;
    filter[1, 1] = 9;
    //矩陣總和
    var factor = filter[0, 0] + filter[0, 1] + filter[0, 2] + filter[1, 0] + filter[1, 1] + filter[1, 2] + filter[2, 0] + filter[2, 1] + filter[2, 2];
    
    Bitmap bSrc = (Bitmap)src.Clone();
 
    // 依照 Format24bppRgb 每三個表示一 Pixel 0: 藍 1: 綠 2: 紅
    BitmapData bitmapData = src.LockBits(new Rectangle(0, 0, src.Width, src.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
    //  Clone 一份出來做參考值
    BitmapData bmSrc = bSrc.LockBits(new Rectangle(0, 0, bSrc.Width, bSrc.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
    System.IntPtr Scan0 = bitmapData.Scan0;
    System.IntPtr SrcScan0 = bmSrc.Scan0;
    unsafe
    {
        byte* p = (byte*)(void*)Scan0;
        byte* pSrc = (byte*)(void*)SrcScan0;
 
        int nOffset = bitmapData.Stride + 6 - src.Width * 3;
        int nWidth = src.Width - 2;
        int nHeight = src.Height - 2;
        int nPixel;
 
        for (int y = 0; y < nHeight; ++y)
        {
            for (int x = 0; x < nWidth; ++x)
            {
                nPixel = (int)((((pSrc[2] * filter[0, 0]) + (pSrc[5] * filter[0, 1]) + (pSrc[8] * filter[0, 2]) +
                    (pSrc[2 + bitmapData.Stride] * filter[1, 0]) + (pSrc[5 + bitmapData.Stride] * filter[1, 1]) + (pSrc[8 + bitmapData.Stride] * filter[1, 2]) +
                    (pSrc[2 + bitmapData.Stride * 2] * filter[2, 0]) + (pSrc[5 + bitmapData.Stride * 2] * filter[2, 1]) + (pSrc[8 + bitmapData.Stride * 2] * filter[2, 2])) / factor) );
                nPixel = Math.Min(Math.Max(nPixel, 0), 255);
 
                p[5 + bitmapData.Stride] = (byte)nPixel;
                nPixel = (int)((((pSrc[1] * filter[0, 0]) + (pSrc[4] * filter[0, 1]) + (pSrc[7] * filter[0, 2]) +
                    (pSrc[1 + bitmapData.Stride] * filter[1, 0]) + (pSrc[4 + bitmapData.Stride] * filter[1, 1]) + (pSrc[7 + bitmapData.Stride] * filter[1, 2]) +
                    (pSrc[1 + bitmapData.Stride * 2] * filter[2, 0]) + (pSrc[4 + bitmapData.Stride * 2] * filter[2, 1]) + (pSrc[7 + bitmapData.Stride * 2] * filter[2, 2])) / factor));
                nPixel = Math.Min(Math.Max(nPixel, 0), 255);
 
                p[4 + bitmapData.Stride] = (byte)nPixel;
                nPixel =(int) ((((pSrc[0] * filter[0, 0]) + (pSrc[3] * filter[0, 1]) + (pSrc[6] * filter[0, 2]) +
                    (pSrc[0 + bitmapData.Stride] * filter[1, 0]) + (pSrc[3 + bitmapData.Stride] * filter[1, 1]) + (pSrc[6 + bitmapData.Stride] * filter[1, 2]) +
                    (pSrc[0 + bitmapData.Stride * 2] * filter[2, 0]) + (pSrc[3 + bitmapData.Stride * 2] * filter[2, 1]) + (pSrc[6 + bitmapData.Stride * 2] * filter[2, 2])) / factor));
                nPixel = Math.Min(Math.Max(nPixel, 0), 255);
                
                p[3 + bitmapData.Stride] = (byte)nPixel;
                p += 3;
                pSrc += 3;
            }
 
            p += nOffset;
            pSrc += nOffset;
        }
    }
 
    src.UnlockBits(bitmapData);
    bSrc.UnlockBits(bmSrc);
 
    return src;
}



中間你會覺得很複雜 其實他就是 先拷貝一份  bmpSrc 出來  然後進行參考後 套入矩陣公式  (九宮格點色值*權重)總和平均


所以會有比較複雜的加減值 之後你會發現 透過矩陣方式去做運算 其實後面有很多濾鏡跟模板都是用這方式套用很方便..


結果:



2012-08-20_153309


當麻許的超技八 2014 | Donma Hsu Design.