ラプラシアンフィルタを使ったコンボリューション (畳み込み演算) 行うことで、手っ取り早く画面のシャープネスを強調することができる。
ラプラシアンフィルタに関しては以下ページがわかりやすい。
フィルター処理
http://www.gifu-nct.ac.jp/elec/yamada/iwata/filter/
サンプルコード
以下の関数では、画像に4近傍精鋭化フィルタを適用している。適用度合いは引数で指定できるようにし、0.0だとシャープネス強調無し、1.0で強調最大となる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
static public Bitmap AdjustSharpness(Bitmap srcImg, float level) { Bitmap dstImg = new Bitmap(srcImg); BitmapData srcDat = srcImg.LockBits( new Rectangle(0, 0, srcImg.Width, srcImg.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); byte[] srcBuf = new byte[srcImg.Width * srcImg.Height * 4]; Marshal.Copy(srcDat.Scan0, srcBuf, 0, srcBuf.Length); BitmapData dstDat = dstImg.LockBits( new Rectangle(0, 0, dstImg.Width, dstImg.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); byte[] dstBuf = new byte[dstImg.Width * dstImg.Height * 4]; Marshal.Copy(dstDat.Scan0, dstBuf, 0, dstBuf.Length); for (int i = 1; i < srcImg.Height - 1; i++) { int dy1 = (i - 1) * (srcImg.Width * 4); int dy = i * (srcImg.Width * 4); int dy2 = (i + 1) * (srcImg.Width * 4); for (int j = 1; j < srcImg.Width - 1; j++) { int dx1 = (j - 1) * 4; int dx = j * 4; int dx2 = (j + 1) * 4; for (int k = 0; k < 3; k++) { int value = (int)((float)srcBuf[dy + dx + k] * (1f + level * 4)) - (int)((float)srcBuf[dy1 + dx + k] * level) - (int)((float)srcBuf[dy + dx1 + k] * level) - (int)((float)srcBuf[dy + dx2 + k] * level) - (int)((float)srcBuf[dy2 + dx + k] * level); value = Math.Min(value, 255); value = Math.Max(value, 0); dstBuf[dy + dx + k] = (byte)value; } } } Marshal.Copy(dstBuf, 0, dstDat.Scan0, dstBuf.Length); dstImg.UnlockBits(dstDat); srcImg.UnlockBits(srcDat); return dstImg; } |
実行例
左からレベル0,0、0.5、1.0