まず第一に、ループの各サイクルで結果からフロートからintに不必要に(そして誤って)変換します。君の red
, green
と blue
タイプのフロートである必要があり、畳み込みの後にのみ整数にキャストする必要があります(RGBに戻った場合):
float red=0.0f, green = 0.0f, blue = 0.0f
for(int i = x;i<x+3;i++){
for(int j = y;j<y+3;j++){
int color = a.getRGB(i,j);
red += ((color >> 16) & 0xff)*matrix[(i-x)*3+j-y];
green += ((color >> 8) & 0xff)*matrix[(i-x)*3+j-y];
blue += ((color >> 0) & 0xff)*matrix[(i-x)*3+j-y];
}
}
return (a.getRGB(x, y)&0xFF000000) | (((int)red) << 16) | (((int)green) << 8) | ((int)blue);
結果の色の出血は、あなたの係数が matrix
間違っている:
0.1710991401561097f + 0.2196956447338621f + 0.1710991401561097f + 0.2196956447338621f + 0.28209479177387814f + 0.2196956447338621f + 0.1710991401561097f + 0.2196956447338621f + 0.1710991401561097f = 1.8452741
ぼやけた畳み込みマトリックスの係数の合計は1.0でなければなりません。このマトリックスを画像に適用すると、255を超える色が表示される場合があります。それが起こると、次のチャネル(青から緑など)にチャンネルが「ブリード」されます。このマトリックスを使用した完全に緑の画像は、次のようになります。
green = 255 * 1.8452741 ~= 471 = 0x01D7; rgb = 0xFF01D700;
これは、赤のヒントを備えた緑の濃い緑です。
係数を分割することでそれを修正できます 1.8452741
, 、しかし、あなたはそれを確認したい:
(int)(255.0f * (sum of coefficients)) = 255
そうでない場合は、チャネルのサイズを255に制限するチェックを追加する必要があり、それらを包み込ませないでください。例えば:
if (red > 255.0f)
red = 255.0f;
効率/最適化について:
速度の違いは、この不必要なキャストと呼び出しMath.roundによって説明される可能性がありますが、より可能性の高い候補は、画像にアクセスする方法です。私はBufferEdimageとラスターに十分に精通しておらず、基礎となる画像バッファーにアクセスする最も効率的な方法についてアドバイスします。