1

これが重複している場合はまず申し訳ありません。私の質問に答える主題が見つかりませんでした。

32 ビット浮動小数点値を short int (16 ビット) および unsigned char (8 ビット) 値に変換するために使用される小さなプログラムをコーディングしています。これは HDR 画像用です。

ここから、次の関数を取得できます(クランプなし):

static inline uint8_t u8fromfloat(float x)
{
    return (int)(x * 255.0f);
}

同じように、(pow( 2,16 ) -1)

しかし、その後、順序付けられたディザリング、特にベイヤー ディザリングについて考えるようになりました。uint8_t に変換するには、unsigned short に 4x4 マトリックスと 8x8 マトリックスを使用できると思います。

また、この方法でプロセスを高速化するためのルックアップ テーブルも考えました。

uint16_t LUT[0x10000] // 2¹⁶ values contained

float に対応する 2^16 の unsigned short 値を格納します。unsigned short ↔ unsigned int の間の暗黙的なキャストのため、この同じテーブルを uint8_t にも使用できます。

しかし、このようなルックアップ テーブルはメモリが膨大になるのではないでしょうか? また、このようなテーブルをどのように埋めますか?!

今、私は混乱しています、あなたによると何が最善でしょうか?

uwind 回答後の編集: U8/U16 に変換する前に、同時に基本的な色空間変換も行いたいとしましょう。 . その場合、LUT を使用した方が効率的ではないでしょうか。そして、ええ、LUTのインデックス作成にはまだ問題があります。

4

3 に答える 3

1

私の見方では、ルックアップテーブルは、インデックスを作成するために、floatを整数型に変換する必要があるため役に立ちません。キャッチ22。

テーブルには0x10000*sizeof(uint16_t)バイトが必要です。これは128KBです。現代の基準ではそれほど多くはありませんが、一方でキャッシュは貴重です。しかし、私が言ったように、インデックスを作成するためにfloatを整数に変換する必要があるため、テーブルはソリューションにあまり追加しません。

整数として再解釈されたfloatのrawビットでインデックス付けされたテーブルを作成できますが、それは32ビットである必要があり、非常に大きくなります(8GB程度)。

概説した簡単なランタイム変換に進みます。

于 2013-01-08T11:12:38.737 に答える
0

乗算にとどまります-うまくいきます。

事実上、最新のすべての CPU には、このようなものに適応したベクトル命令 (SSE、AVX など) があるため、そのためのプログラミングを検討することができます。または、可能であれば、コードを自動的にベクトル化するコンパイラーを使用します (Intel C、GCC も)。table-lookup が可能な解決策である場合でも、メモリの待ち時間に悩まされないため、多くの場合、これはより高速になります。

于 2013-01-08T11:16:53.483 に答える
0

まず、 は 24 ビットの精度を持っていることに注意してください。これは、16 ビットや 8 ビットにもfloat収まりません。int第 2 に、float の範囲ははるかに大きく、いずれにも格納できませんintlong long int

したがって、質問のタイトルは実際には間違っています。float を short または char に正確に変換する方法はありません。0 と 1 の間の float 値を 8 ビットまたは 16 ビットの int範囲にマップします。


上記で使用したコードの場合、問題なく動作します。ただし、値 255 が返される可能性は非常に低いです。入力として正確に 1.0が必要なためです。そうでない場合、254.99999 などの値は 254 として切り捨てられます。代わりに、値を丸める必要があります。

return (int)(x * 255.0f + .5f);

または、リンクで提供されているコードを使用して、よりバランスの取れた配布を行います

static inline uint8_t u8fromfloat_trick(float x)
{
    union { float f; uint32_t i; } u;
    u.f = 32768.0f + x * (255.0f / 256.0f);
    return (uint8_t)u.i;
}

16 ビット値のテーブルは大きすぎて cache に収まらないため、LUT を使用しても高速にはなりません。実際、パフォーマンスが大幅に低下する可能性があります。上記のスニペットでは、浮動小数点命令は 2 つだけ、またはFMAでは 1 つだけ必要です。また、SIMD はパフォーマンスを 4 ~ 32 倍 (またはそれ以上) 向上させるため、テーブル ルックアップを並列化するのがはるかに難しいため、LUT メソッドは簡単に優れたパフォーマンスを発揮します。

于 2013-10-09T01:08:02.347 に答える