[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)
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 出來 然後進行參考後 套入矩陣公式 (九宮格點色值*權重)總和平均
所以會有比較複雜的加減值 之後你會發現 透過矩陣方式去做運算 其實後面有很多濾鏡跟模板都是用這方式套用很方便..
結果:
