バイキュービック法で画像の拡大してみようとしたけど、難しすぎた
バイキュービック法で画像の拡大してみようとしたけど、できたようなできていないような感じになった、難しすぎた
2021/04/23追記
やっぱり間違っていたので書き直した
2021/04/23追記ここまで
前回のバイリニア法は
近くの上下左右の4つのピクセルとの距離から拡大後の色を決めていた
距離に応じた重み付けは曲線になる
これはバイリニア法、距離と重みの関係グラフ
1ピクセル先までだから距離の最大は1になる
重みは距離に反比例っていうのか?距離が離れるほど重みは下がる
下がり方は直線だからわかりやすかった
バイキュービックで重みを求める式は
なんでこうなるのかわからないけど、こうらしい
使う式は3つあるけど実際にはA,Bの2つかなあ
距離が0以上1未満のときはAの式
距離が1以上2未満のときはBの式
画質を決める定数を-1にした場合で距離が0.1のときの重みは
距離が0.1だから使う式はA
(-1+2)*(0.1*0.1*0.1)-(-1+3)*(0.1*0.1)+1=0.981
とかになって
定数-1と-0.5のとき距離0から最大の2までを0.1刻みごとの重みを表にすると
こうなって、これをグラフにすると
こう、きれいな曲線になるねえ
距離0から1までの重みははだんだん小さくなって1で0になる、これが式A
1より離れるとマイナスになるのは式Bなんだよねえ
不思議だわ
横方向だけで計算してみる
拡大後のあるピクセルのx座標が元座標だと9.6だった場合に、参照する横範囲は
左から8,9,10,11の4ピクセルになる
それぞれの距離は
1.6, 0.6, 0.4, 1.4
使う式は
B, A, A, Bになる
ピクセルの値が100, 200, 150, 50で
画質を決める定数を-1にしたとき補間される値は194
縦横で計算してみる
これであっているかはわかんないけど、値を見ると大きく外してはいないみたいねえ
参照範囲が元画像の外側になる場合、つまり画像の周縁部の重みはどうすればいいのか
右に見ても、もしもと画像の幅が1ピクセルだった場合は存在しない座標になる
元画像の外側は重みを0にして計算した場合
左2が遠い左、左1が近い左ピクセルになる
結果の補間をグラフにすると
画像だと
グラデーションになっている
なので普通にバイキュービックで拡大すると画像の周縁部は色が明るくなる
こうすると全部200になって
周縁部の色が白(明る)くならなくなった
これでいいのかなあ
バイリニア法と比較してみる
バイキュービックの画質のaは-1
黒背景に白文字の画像の拡大
バイキュービックでa=0
バイキュービックでa=-2
バイリニア
縮小0.5倍
バイリニア
バイリニア
これを2倍
バイキュービックのほうがくっきりした感じになる、輪郭が強調される感じ
同時に輪郭部分のもやもやしたノイズも強調されている
画質を決める定数aを変えてみる
今回の画像だと0がいいかなあ
-1~0がよく使われるそう
今回のもどこか計算間違っているかも
拡大率を上げていくとブロック状になる
普通なら下のバイリニア法みたいにグラデーションになるはずなんだよなあ
それに計算量も増えたから処理時間もものすごく増えて
256x192をカラーで6倍にするだけでも約十秒もかかった
PixelFormat.gray8のBitmapSourceを指定したスケールと画質のaで拡大縮小したBitmapSourceを返す
どこか足りないのか逆に余計なことをしているのかわからん
こんなこと書くよりも
WPFで画像をきれいに拡大縮小するならRenderTransformのScaleTransformを使って
表示方法を
BitmapScalingModeをFantかHighQualityを指定するほうがいろいろ速い
コード
失敗?アプリ
関連記事
次回2018/04/27、1週間後
Lanczos法で画像の拡大してみた ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/15479973.html
2018/4/17、前回
バイリニア法で画像の拡大縮小 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/15464617.html
2018/04/16、前々回
最近傍補間法で画像の拡大縮小試してみた ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/15462921.html