端くれプログラマの備忘録 C#,画像処理 [C#] 画像のシャープネスを強調する (精鋭化)

[C#] 画像のシャープネスを強調する (精鋭化)

ラプラシアンフィルタを使ったコンボリューション (畳み込み演算) 行うことで、手っ取り早く画面のシャープネスを強調することができる。

ラプラシアンフィルタに関しては以下ページがわかりやすい。

フィルター処理
http://www.gifu-nct.ac.jp/elec/yamada/iwata/filter/

サンプルコード

以下の関数では、画像に4近傍精鋭化フィルタを適用している。適用度合いは引数で指定できるようにし、0.0だとシャープネス強調無し、1.0で強調最大となる。

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;
}

実行例

0012

左からレベル0,0、0.5、1.0