5

私の内側のループには、プロファイリングに問題があることが示されている計算が含まれています。

アイデアは、グレースケールピクセルx(0 <= x <= 1)を取り、「そのコントラストを上げる」ことです。私の要件はかなり緩く、次のとおりです。

  • x <.5の場合、0 <= f(x)<x
  • x> .5の場合、x <f(x)<= 1
  • f(0)= 0
  • f(x)= 1-f(1-x)、つまり「対称」である必要があります
  • できれば、機能はスムーズでなければなりません。

したがって、グラフは次のようになります。

グラフ

私には2つの実装があります(それらの結果は異なりますが、両方とも適合しています):

float cosContrastize(float i) {
    return .5 - cos(x * pi) / 2;
}

float mulContrastize(float i) {
    if (i < .5) return i * i * 2;
    i = 1 - i;
    return 1 - i * i * 2;
}

したがって、これらの実装の1つに対するマイクロ最適化、または独自のより高速な独自の式のいずれかを要求します。

たぶんあなたの一人はビットをいじることさえできます;)

4

3 に答える 3

13

次のsigmoid型の関数を考えてみましょう (目的の範囲に適切に変換されています)。

スクリーンショット


上の図は MATLAB を使用して生成しました。興味があれば、コードは次のとおりです。

x = -3:.01:3;
plot(   x, 2*(x>=0)-1, ...
        x, erf(x), ...
        x, tanh(x), ...
        x, 2*normcdf(x)-1, ...
        x, 2*(1 ./ (1 + exp(-x)))-1, ...
        x, 2*((x-min(x))./range(x))-1  )
legend({'hard' 'erf' 'tanh' 'normcdf' 'logit' 'linear'})
于 2009-09-26T00:27:26.257 に答える
5

単純にしきい値を設定することもできますが、これはばかげていると思います。

return i < 0.5 ? 0.0 : 1.0;

「コントラストの増加」について言及しているので、入力値は輝度値であると想定しています。その場合、それらが離散的 (おそらく 8 ビット値) であれば、ルックアップ テーブルを使用してこれを非常に迅速に行うことができます。

あなたの「mulContrastize」はかなり速く見えます。最適化の 1 つは、整数演算を使用することです。繰り返しますが、入力値は実際には [0..255] の 8 ビットの符号なし値として渡すことができます。(繰り返しますが、おそらく良い仮定ですか?)大まかに次のようなことができます...

int mulContrastize(int i) {
  if (i < 128) return (i * i) >> 7; 
  // The shift is really: * 2 / 256
  i = 255 - i;
  return 255 - ((i * i) >> 7);
于 2009-09-25T23:53:56.433 に答える
4

区分的補間は高速で柔軟です。数回の決定とそれに続く乗算と加算が必要なだけで、任意の曲線を近似できます。また、ルックアップ テーブルによって導入される可能性のある粗さ (またはこれを滑らかにするための補間に続く 2 つのルックアップの追加コスト) を回避しますが、lut はあなたのケースでは完全にうまく機能する可能性があります。

代替テキスト

ほんの数セグメントで、かなり良い一致を得ることができます。ここでは、色のグラデーションに粗さがありますが、絶対色の粗さよりも検出がはるかに困難です。

Eamon Nerbonne がコメントで指摘しているように、セグメンテーションは、「詳細を最大化するために二次導関数などに基づいてセグメンテーション ポイントを選択する」ことで最適化できます。つまり、勾配が最も変化している場所です。明らかに、私の投稿した例では、5 つのセグメントのケースの真ん中に 3 つのセグメントがあっても、それ以上の詳細は追加されません。

于 2009-09-27T15:30:43.930 に答える