色合いのような色のある色空間、つまり元々円形の色の画像があるとします。
たとえば、一般的なHSLまたはHSVチャネルでは、色相0または色相256の両方がまったく同じ色、通常は純粋な赤色に対応し、255は少し青みがかったが、依然としてほぼ純粋な赤色です。
ここで、0と255が接触する線に沿ってガウスのぼかしを適用すると、遠くに滑らかになり、2つの赤の間に勾配が形成されます虹。 - この結果はほとんど望ましくないでしょう。画像の色合いを正しく滑らかにするには?
明度/値および/または彩度0の特異点のために2番目の問題が発生します。その場合、色相は技術的に任意の値をとることができます。 - 色空間を変換するとき、ほとんどの色空間変換は単に色相0を選択します。ほとんどの通常のユースケースでは問題にならないためです。しかし、もし私がぼかしていたら、それは絶対にあります。
少なくとも(重要な)最初の問題、理想的には2番目の問題を適切に処理するために、標準的なガウスブラーアルゴリズムを変更する必要がありますか?
私は2番目のものがより厳しいと仮定し、色相チャンネルだけではできませんでしたが、特異性のために他の2つの特殊な場合には情報が必要ですが、うまくいけば、最初。便宜上
特定のアルゴリズムが答えのために必要であれば、たとえば、使用されているように、素敵なシンプルかつ高速な方法は、繰り返しボックスの畳み込みを使用して近似なり、here
は、ここでのコピー+です水平3と3つの垂直ボックスのコンボリューションをやって、そのサイトから貼り付けます。
function gaussBlur_4 (scl, tcl, w, h, r) {
var bxs = boxesForGauss(r, 3);
boxBlur_4 (scl, tcl, w, h, (bxs[0]-1)/2);
boxBlur_4 (tcl, scl, w, h, (bxs[1]-1)/2);
boxBlur_4 (scl, tcl, w, h, (bxs[2]-1)/2);
}
function boxBlur_4 (scl, tcl, w, h, r) {
for(var i=0; i<scl.length; i++) tcl[i] = scl[i];
boxBlurH_4(tcl, scl, w, h, r);
boxBlurT_4(scl, tcl, w, h, r);
}
function boxBlurH_4 (scl, tcl, w, h, r) {
var iarr = 1/(r+r+1);
for(var i=0; i<h; i++) {
var ti = i*w, li = ti, ri = ti+r;
var fv = scl[ti], lv = scl[ti+w-1], val = (r+1)*fv;
for(var j=0; j<r; j++) val += scl[ti+j];
for(var j=0 ; j<=r ; j++) { val += scl[ri++] - fv ; tcl[ti++] = Math.round(val*iarr); }
for(var j=r+1; j<w-r; j++) { val += scl[ri++] - scl[li++]; tcl[ti++] = Math.round(val*iarr); }
for(var j=w-r; j<w ; j++) { val += lv - scl[li++]; tcl[ti++] = Math.round(val*iarr); }
}
}
function boxBlurT_4 (scl, tcl, w, h, r) {
var iarr = 1/(r+r+1);
for(var i=0; i<w; i++) {
var ti = i, li = ti, ri = ti+r*w;
var fv = scl[ti], lv = scl[ti+w*(h-1)], val = (r+1)*fv;
for(var j=0; j<r; j++) val += scl[ti+j*w];
for(var j=0 ; j<=r ; j++) { val += scl[ri] - fv ; tcl[ti] = Math.round(val*iarr); ri+=w; ti+=w; }
for(var j=r+1; j<h-r; j++) { val += scl[ri] - scl[li]; tcl[ti] = Math.round(val*iarr); li+=w; ri+=w; ti+=w; }
for(var j=h-r; j<h ; j++) { val += lv - scl[li]; tcl[ti] = Math.round(val*iarr); li+=w; ti+=w; }
}
}
function boxesForGauss(sigma, n) // standard deviation, number of boxes
{
var wIdeal = Math.sqrt((12*sigma*sigma/n)+1); // Ideal averaging filter width
var wl = Math.floor(wIdeal); if(wl%2==0) wl--;
var wu = wl+2;
var mIdeal = (12*sigma*sigma - n*wl*wl - 4*n*wl - 3*n)/(-4*wl - 4);
var m = Math.round(mIdeal);
// var sigmaActual = Math.sqrt((m*wl*wl + (n-m)*wu*wu - n)/12);
var sizes = []; for(var i=0; i<n; i++) sizes.push(i<m?wl:wu);
return sizes;
}
しかし、私は必ずしも特定の言語での特定の実装では、必要な実際のアルゴリズムの変更で主に興味があります。
私は誰もあなたの第2段落を理解するとは思わない。 – gpasch