このメールは、OSASK-ML投稿フォームから書き込まれた内容です。 お名前: I.Tak. [osask 6734]に返信です。 > > i8はRGB値の差を最小にすることではなく、単にリニア性を求めて作ら > >れています。基本の数式が線形なのです。最大値が0xc0だったら飽和させ > >よう、などという仮定の話は忘れてください。i8にそんな仕掛けはない > >からです。 > > 忘れてもいいんですが、ようするに何を目指しているかが明確になる > と思ったので、質問してみたわけです。つまりはその辺の理解が変わっ > たということなんでしょうか。 そうです。i8を作ったときは混同していました。両方同時に達成できる ようなパレット設定に助けられたと思います。 > 本当にn8は飽和しているのかなあ。コントラストを上げたら、飽和す > ることがある、という主張は僕も理解できます。しかしグラデーション > をn8変換したものをみる限りでは、「飽和した」という印象を持つこと > ができません。この部分に関しては、できれば違う説明を期待します。 じゃあn系はコントラストを操作している, という点を説明します。 n系はタイルなしだと [ 0, 64)→0 [ 64,128)→1 [128,192)→2 [192,256)→3 と変換しますね。各ゾーン間の距離はいくつかというと, 64です。タイル ありだと, [ 0, 78)→[0,1) [ 78,157)→[1,2) [157,236)→[2,3) [236,256)→3 と変換されます。ゾーン間の距離は78です。 ゾーン間の距離というのは等高線の幅にあたるもので, これがころころ と変わるのはコントラストを変えていると言えるのではありませんか? > i8が限界だというのも根拠がほしいです(それがあれば、n8が飽和を > 損なっていることが僕にも分かります)。僕はi8がすかすかに余ってい > るようにみえます(すかすかというほどひどくはないですが)。域を十 > 分に使っていないというか。 原画のコントラストを保存するのは, 小柳さんの指摘のように, ゾーン 間の距離とパレット値の差が同じになるときです。パレット値の差は均等 割り付けなら最大85になりますから, ゾーン間の距離は85に固定である べきで, そのときコントラストが最大になります。それがi8です。 > ということは、I.Tak.さんとしては筆の誤りとかそういうことではな > くて、i8こそ優れている、というのが客観的に主張可能であると、本当 > に思っているわけですね。 そうですよ。出力に違いがあるからには, ある基準によって優劣がつく はずです。逆に, 出力が違うのに同程度であることを示すのは難しいの ではないかと……。 > 僕はパレットによって結果的にRGB値がどうなったのかという所はあま > り見ていません。それはパレットをいじればどうにでもなることです。だ > から僕が考える減色処理は、全く異なる色空間への線形変換であり、空間 > が異なる以上、もとの絵との「誤差」は重視しないのです(印象は気にし > ますよ)。相似でありさえすればいい、という感じです(数値にこだわる > わけではないので、相似こそ第一というわけでもないですが)。 RGB値がどうなったのか, ではなくて, パレットインデックス値の割り 振り方でコントラストを変えたというのです。 0と3はたくさん出るのに1と2は少ししか出ないような変換とか, 0と3は ほとんど出なくて1と2ばかり出る変換とかはコントラストを変えていると 言えませんか? > I.Tak.さんの説明の式だと、タイルを含めた階調数を入れないで考え > ています。僕はそれを含めて考えるほうが違いが分かりやすいと思って > いるので、そうします。 タイルは小数点以下で表現するのが便利だと思いますよ。2.65と書くと, 2に3が65%混ざることがすぐ分かります。 > i8だと、どんな式になるのかな。見た目で判断すると、 > > y = (int) (12/256 * x + 0.5) = (最近値) (12/256 * x) > > でしょうか?これはどういう出力を考えていることになるんだろう。 > [0, 12)?あれ?これでいいのかな??? いいんですよ。それで12が出力されるのはおかしいと思われたのかも 知れませんが, 繰り上げなので12が出るのは正常です。 > 例えばスキャナーやデジタルカメラは[0.00, 1.00)までの連続的な値 > を256階調に「減色」しているわけですが、この時もI.Tak.さんは255倍 > して四捨五入するのが「正しい」と思うでしょうか?僕はそれもありだ > と思いますし、256倍して切り捨てるのもありだと思うのですが・・・ > 。四捨五入のほうが絶対的にいいと思うんだろうなあ。・・・そのセン > スは分からない・・・。 256倍して切り捨てると, パレットは 1/512, 3/512, ... , 511/512 になります。これではコントラストが下がります。 > リニア性に戻ると、ようするに、変換係数的に見て飽和しているとい > うのが、主張の根幹であるように思います。I.Tak.さんの方法だと、本 > 当に飽和したと主張するなら、変換係数は3.125/255.5のほうが妥当な > 気がするのですが、これはどうでしょうか。I.Tak.さんにとって画面で > 表現可能なのは、[0.00, 3.00]ではなく、(-.125, 3.125)のはずです。 > これいっぱいに展開しないと、それより変換係数の大きいものを飽和し > たとは主張できないように、僕には思えます(コントラストが上がった > という主張は可能かもしれませんが、今のところは与えられた範囲でめ > いいっぱいに展開する、という立場で合意していると僕は思っているの > で、それは考慮しないことにします)。 パレットは色空間の中の点にすぎないという観点に立つと, 3/255という 係数で飽和します。川合さんのゾーンモデルではそうはならないようですが。 > 入力を[0, 256)と考えるかどうかが、そして出力を[0, 13)と考える > かどうかが分かれ道なんだろうなあ。こう考えると、n8のほうがリニア > に思えると思うんだけど・・・。I.Tak.さんはどう思っていますか? そう考えればn8の方が正解だと思います。でも出力は 12 までではない んですか? パレットがあるのは 0, 4, 8, 12 のところだけですから, 13 というのは12と存在しない色との混色になってしまいます。 切り捨てと四捨五入と切り上げの違いは誤差の違いでしかない, という ことは, ある日突然四捨五入や切り上げに統一したとしても大きな破綻は 無いはずです。しかし↑のようなn8は破綻します。 > これは僕が、そもそも入力を[0, 256)と考えているところに起因する > でしょう。真っ暗から真っ白までのグラデーションをデジタルカメラや > スキャナーに与えた場合、解像度が十分なら全ての輝度の本数が一致す > るのが(一つの)理想だと思っているのです。 それはいわゆるパレット (数値がどの明るさを表わすか) の選び方により ます。小柳さんの指摘のようにパレットを選べば全ての輝度の本数は一致 します。しかしそれではパレット全体の幅は元よりも狭くなります。 > (等高線) > 「受ける印象」のターゲットが違うんでしょうねえ。ただ単に近い色 > を出すことがgoodであると考えれば、使える色は何でも使うべきですし > 飽和してでも、という発想は妥当です。16bitカラーからの減色でも、 > 緑をわざわざ5bitに落としてからやるのはRGB値を近くするという目的 > からすると妥協になると思います(数値的な誤差は広がるわけで、リニ > ア性を損ねている)。i8ではそうなっていないようですが。 色ずれもマッハバンドも気にはなりますが, 一般にマッハバンドは努力を 認めて無視してあげるべきだと思います。離れて見たらどうですか。 色ずれは微妙なところです。人間は色相よりも輝度に敏感である一方で, もともと存在しなかった色相が入るとやっぱり気づいてしまいます。 「受ける印象」が本当に等高線の間隔だけで決まると思いますか? 地図ならともかく, 絵では等高線がどの程度の"高さ"にあるかは一目瞭然 です。 0 1 2 3 というグラデーションと 0 0 3 3 というグラデーション (?) では, 等高線の間隔こそ違うものの受ける印象は 近くなりませんか? > >> n系のアルゴリズムの場合、256階調の絵を、128階調に減色し、それ > >> をさらに64階調に減色し、それをさらに32階調に減色し・・・とやって > >> 仮に最終的に2階調に減色したとしましょう。この結果と、最初の256階 > >> 調の絵をいきなり2階調に減色した場合とで、全く差は生じません。 > > > > タイリングしないときはそうでしょう。 > > そうです。タイリングしない場合の話です。僕にとって、タイリング > は、画面に表現するときの手法であって、減色処理そのものではありま > せん。それで上記のような表現をしました。だから、 だから13段階を前提にしないと話が分かりにくいんですね。 私もタイリングは補助的なものだと思います。しかし川合さんの考えるよう な補助とは違っていて, 小数点以下の成分だと考えているのです。 > >> itak系のアルゴリズムでは、途中に他の変換を施してから最終結果に > >> 至っても、結果は不変、という変換の組み合わせは事実上ありません( > >> もちろん、最後に1階調にするなどの自明的なものはありますが)。 > > > > それは誤解です。4階調パレットで減色してから2階調パレットで減色 > >すると結果は不変です。i系には自己相似性があり、それ以上の階調でも > >同じことです。 > > そうなのかな。つまり、フルカラーからi8をしてi4に行っても、フル > カラーからいきなりi4に行っても同じだという主張ですよね? > > 例えば、c0c0c0の点を考えます。これはいきなりi4に行くと、ffffff > になると思います。・・・一方、i8を経由すると、ffffffとaaaaaaのタ > イルになると思われます。aaaaaaの色って、i4ではタイルになりません > か?ということは必ずffffffになる、とはいえない気が・・・。場所に > よっては変わりませんか? 部分フラッシュを考慮すると, タイリングは座標を引き数に持つ関数です (川合さんもこの点は考慮していますね)。するとタイリングを含めて完全に 一致する二段階変換が可能になります。あのルーチンについてはあまり解説 してこなかったのでこの機会に解説しましょう。 i8では固定小数点で計算をしていますが, 小数点以下に振動する成分 を加えています。 EDX ^= 0x20202000; /* 中略 */ EAX += EDX; これです。これ (EDX) はx座標とy座標の関数になっていて, f(x,y) = (x&1)*3 ^ (y&1)*2 みたいになっています。実際には毎回座標値から計算するわけにはいかない ので初期値を与えてxor演算で振動させるわけです。 で, これと四捨五入のための定数を入力値に足して切り捨てます (四捨 五入定数は振動成分の単位の半分です)。はい終わり。タイリングのコスト は足し算のみですし, 他の部分 (グラフの傾きなど) ではタイリングを 考慮しません。 ある値より大きいか否かを判断する方法には, 引き算をしてキャリーを 見るのと足し算をしてキャリーを見るのとがありますが, これは足し算で キャリーを出しているわけですね。 で, 二段階変換する問題です。その前に確認ですが, i4' (内側と外側で 場合分けするi4と区別し, i8の純粋な縮小版をi4'としましょう。一応) で 0xa0から0xe0の色を減色すると 0 1 1 1 と出力されます (パレットインデクス)。0xc0は1の塗り潰しになりません。 さて0xc0をi8で減色すると aa ff ff ff となります。i4'で減色するときの様子を詳しく追ってみましょう。 振動成分 + 四捨五入定数である 20 e0 a0 60 を足すとこうなります↓。 ca 1df 19f 15f 切り捨てればこう↓です。 0 1 1 1 期待通りに完全一致しました。では 0xd0 ではどうでしょうか。i8の出力は aa ff ff aa ↑です。うまくいきますかね? とにかく振動成分 + 四捨五入定数を足しますと, ca 1df 19f 10a ↑こうですね。では切り捨てます。 0 1 1 1 ↑また期待通りになりました。……ここまで予想して作ったわけではないん ですけどねえ(^^;;; ちなみにこうした多段変換で不変になる系列は出力最大値が3倍になる 系列です。 > > ちなみに2階調のi系変換を平面に四つ並べれば、4階調のi系変換になり > >ます。n系にはこうした自己相似性がありません。係数がタイリングの細か > >さ (n8では4段階) に左右される (i系では左右されません) ことと合わせ > >て、何か無理のあるアルゴリズムであることが暗示されていると思います。 > > ここの話がよくわからない・・・。 タイリングで作る色を原色と同じように扱うのはいいのですが (i系 でもタイリングの細かさによって四捨五入定数が変化します), それが グラフの傾きという線型関数の背骨をいじってしまうのは無理があると 思います。入力最大値と出力最大値 (パレットインデクス) が変わらない 限り, グラフの傾きは変わらないはずではありませんか? > とりあえず、自己相似性は僕には関心がないので、指摘されても、ふ > ーん、という程度です。I.Tak.さんはそこも気にしているのですか? 直感的にこれは正しいことに違いないと感じて作りましたが, その必要性は 線型の定義によって示せます。 線型の定義である f(a+x) = f(a) + f(x) は, 「線型関数を[0,a]で定義すれば後の区間の定義も自動的に決まる」 ということを示しています。例えば[a,2a]での定義は f(x-a) + f(a) と 書けます。"並べる"というのはそういう意味でいいました (自己相似性と 言うとやっぱり少し違うかも知れません)。 i8は, [0,85]→[0,1]変換をまさにこの方法で"並べた"出力をします。 n8はそうではないようです。