1

グレースケール画像や深度マップ/バンプマップなど、2D矩形のすべてのピクセルにスカラー情報が割り当てられているとします。R

ここに画像の説明を入力

8 bitこのようなスカラー情報は、画像に標準的にエンコードされているため、2^8=256さまざまなトーンを使用できます。便利なことに、ここでのトーンには、かなり直感的な意味があります。white=0black=1gray=somewhere between 0 and 1

画像が .png などで保存されると、トーンtが色0 <= t <= 255でエンコードされます (ピクセルごとに無駄になります)。RGB[t,t,t]16bit


質問: たとえば、グレースケールによって提供される解像度は、8 bit私の目的には十分ではありません。

色の直感的な意味24bitを維持しながら、 (1D) 情報をRGB色空間に無損失でエンコードする確立された方法はありますか?

4

3 に答える 3

4

ヒルベルト曲線を検討することをお勧めします。これは、高次元 (2、3、またはそれ以上) の空間への 1 次元曲線の埋め込みです。

1d 曲線を 2 次元色空間にマッピングした場合は、次のようになります。白い曲線には 2^16 = 65,536 ポイントがあり、2^8 x 2^8 = 256 x 256 次元の色空間に埋め込まれています。曲線上の任意の 2 つの隣接点は非常に似ています。

コードを手元に持っていませんが、これを一般化して曲線を 3 次元に埋め込むことは可能です。必要に応じて、このプロットを生成する Matlab コードを利用できるようにすることができますが、それが非常に役立つとは確信していません...

ここに画像の説明を入力

これは、画像全体でヒルベルト曲線をたどることで得られるカラー スケールです。それほど直感的ではありませんが、65,536 色すべてをカバーしています。

ここに画像の説明を入力

編集- これがコードです

function [x,y] = d2xy(n,d)
# D2XY Embeds a point d into an n*n square (assuming n is a power of 2). For
# example, if n = 8 then we can embed the points d = 0:63 into it.
    x = uint32(0);
    y = uint32(0);
    t = uint32(d);
    n = uint32(n);
    s = uint32(1);
    while s < n
        rx = bitand(1, idivide(t, 2));
        ry = bitand(1, bitxor(t,rx));
        [x,y] = rot(s,x,y,rx,ry);
        x = x + s * rx;
        y = y + s * ry;
        t = idivide(t, 4);
        s = s * 2;
    end
end

function [x,y] = rot(n,x,y,rx,ry)
    if ry == 0
        if rx == 1
            x = n-1-x;
            y = n-1-y;
        end
        # Swap x and y
        t = x; x = y; y = t;
    end
end

b = zeros(65536, 2);

for d = 0:65535
  [x,y] = d2xy(256, d);
  b(d+1,1) = x;
  b(d+1,2) = y;
end

plot(b(:,1), b(:,2)), xlim([-1,256]), ylim([-1,256]), axis square
于 2013-04-03T09:51:23.230 に答える
0

HSV または HSI 色空間はまさにあなたが探しているものです: http://www.mathworks.com/help/matlab/ref/rgb2hsv.html HSI は、色相、彩度、および照明または強度を意味します。色相は色の頻度を示し、色を表すのは非常に直感的です

于 2013-04-03T09:24:04.577 に答える
0

8 に量子化できると思います。つまり、強度 / 8 を 3 色 (グレーが得られます) に分配し、残りのビット (強度 % 8) を分離された R、G、B の LSB に追加します。ローカル追加でできます。のようなもの(テストされていないがコンパイル済み)

int convert(int N) {

    int Q = N / 8,  //  Q + Z == N
        Z = N % 8;

    int R = (Q >>  0) & 0xFF,
        G = (Q >>  8) & 0xFF,
        B = (Q >> 16) & 0xFF,
        S = R + ((Z >> 0) & 1),
        H = G + ((Z >> 1) & 1),
        C = B + ((Z >> 2) & 1);

    return (S << 0) + (H << 8) + (C << 16);
}
于 2013-04-03T11:39:51.910 に答える