tdnki @ ウィキ
ImageProcessing
最終更新:
Bot(ページ名リンク)
-
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