tdnki @ ウィキ
ImageProcessing
最終更新:
tdnki
-
view
4. 画像処理
漫画風の画像処理を実装していく。
4-1. 三値化
グレースケールの画像を、白、黒、グレーの三値に変換する。
閾値は動かしながら良いものを選ぶ。
閾値は動かしながら良いものを選ぶ。
ComicFinder.cpp
const int threshold_black_and_gray = 60; const int threshold_gray_and_white = 120; int lum; for (int k = 0; k < width*height; k++) { lum = p_src[k]; if (lum < threshold_black_and_gray) { lum = 0x00; } else if (lum < threshold_gray_and_white) { lum = 0x80; } else { lum = 0xff; } p_dst[k*4+0] = p_dst[k*4+1] = p_dst[k*4+2] = lum; p_dst[k*4+3] = 0xff; }
より漫画っぽくするために、グレー(128/255)を、白と黒の市松模様で表現する。
グレーと判定されたピクセルのx座標とy座標のパリティが一致したら黒、不一致なら白とした。
グレーと判定されたピクセルのx座標とy座標のパリティが一致したら黒、不一致なら白とした。
ComicFinder.cpp
for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { lum = p_src[i*width+j]; if (lum < threshold_black_and_gray) { lum = 0x00; } else if (lum < threshold_gray_and_white) { lum = ((i+j) % 2) == 0 ? 0x00 : 0xff; } else { lum = 0xff; } p_dst[(i*width+j)*4+0] = p_dst[(i*width+j)*4+1] = p_dst[(i*width+j)*4+2] = lum; p_dst[(i*width+j)*4+3] = 0xff; } }
4-2. 輪郭抽出
三値化前の画像の輪郭を抽出し、主線として重ねあわせる。
輪郭抽出のアルゴリズムにはSobelフィルタを使用し、この結果を適当な閾値で二値化したものを主線とした。
輪郭抽出のアルゴリズムにはSobelフィルタを使用し、この結果を適当な閾値で二値化したものを主線とした。
ComicFinder.cpp
const int threshold_edge = 32; int fx, fy, im, ip, jm, jp; for (int i = 0; i < height; i++) { im = i-1; ip = i+1; im = im < 0 ? 0 : im; ip = ip > height-1 ? height-1 : ip; for (int j = 0; j < width; j++) { jm = j-1; jp = j+1; jm = jm < 0 ? 0 : jm; jp = jp > width-1 ? width-1 : jp; fx = 0; fx += p_src[im*width+jm] * -1; fx += p_src[i *width+jm] * -2; fx += p_src[ip*width+jm] * -1; fx += p_src[im*width+jp] * 1; fx += p_src[i *width+jp] * 2; fx += p_src[ip*width+jp] * 1; fy = 0; fy += p_src[im*width+jm] * -1; fy += p_src[im*width+j ] * -2; fy += p_src[im*width+jp] * -1; fy += p_src[ip*width+jm] * 1; fy += p_src[ip*width+j ] * 2; fy += p_src[ip*width+jp] * 1; lum = abs(fx) + abs(fy); lum = lum < threshold_edge ? 0xff : 0x00; p_dst[(i*width+j)*4+0] = p_dst[(i*width+j)*4+1] = p_dst[(i*width+j)*4+2] = lum & p_dst[(i*width+j)*4+0]; p_dst[(i*width+j)*4+3] = 0xff; } }
アップロードする際に画像縮小したため、スクリーントーン部分が補間処理によってグレーに戻ってしまった。
アプリ内でも拡縮により同様のことが起き得るので、コード上でトーンを適用する位置については再考の余地がある。
アプリ内でも拡縮により同様のことが起き得るので、コード上でトーンを適用する位置については再考の余地がある。
ここまでのソース
ComicFinder.zip