5

BitmapFrames の配列があり、ヒストグラム ストレッチを行う必要があります。これはヒストグラムの均等化とは異なり、最終的な結果は...ちょっと。問題は、ヒストグラムを取得した後に何をすべきかまったくわからないことです。

これまでのところ、私のコードはヒストグラムの配列を作成するので、各値のピクセル数がわかります。でもその後どうしたらいいのかわからない。

これは私がこれまでに持っているコードです...今はヒストグラムを作成し、ヒストグラムを均等化します...これは私が望むものではありません...ヒストグラムについてもっと学びたいと思っていました

[Cmdlet(VerbsData.ConvertTo, "HistoStretch")]
public class HistoStretchCmdlet : PSCmdlet
{
    private BitmapFrame[] bFrame, outFrame;
    private BitmapSource src;
    private double pixelsize;
    private byte[] pixels, outPixels;
    private byte MAX_VAL;
    private int[] histogram;
    private int cf, start;

    [Parameter(ValueFromPipeline = true,
        ValueFromPipelineByPropertyName = true), ValidateNotNullOrEmpty]
    public BitmapFrame[] Bitmap
    {
        get
        {
            return bFrame;
        }
        set
        {
            bFrame = value;
        }
    }

    protected override void ProcessRecord()
    {
        base.ProcessRecord();
        Console.Write("Applying a histogram stretch to the image...\n\n");
        outFrame = new BitmapFrame[bFrame.Length];
        for (int c = 0; c < bFrame.Length; c++)
        {
            MAX_VAL = (byte)((1 << bFrame[c].Format.BitsPerPixel) - 1);
            histogram = new int[MAX_VAL + 1];
            for (int i = 0; i <= MAX_VAL; i++)
            {
                histogram[i] = 0;
            }

            pixelsize = bFrame[c].PixelWidth * bFrame[c].PixelHeight;
            pixels = new byte[(int)pixelsize];
            outPixels = new byte[(int)pixelsize];
            bFrame[c].CopyPixels(pixels,(int)bFrame[c].Width * (bFrame[c].Format.BitsPerPixel / 8),0);

            for (int i = 0; i < pixelsize; i++)
            {
                histogram[(int)pixels[i]] = histogram[(int)pixels[i]] + 1;
            }
            for (int i = 0; i <= MAX_VAL; i++)
            {
                Console.Write("{0}: {1}\n", i, histogram[i]);
            }
            for (int i = 0; i <= MAX_VAL; i++)
            {
                if (histogram[i] >= 1)
                {
                    start = i;
                    break;
                }
            }

            for (int i = 0; i < pixelsize; i++)
            {
                cf = 0;
                for (int g = 0; g <= MAX_VAL; g++)
                {
                    cf += histogram[g];
                    if (g == pixels[i])
                    {
                        break;
                    }
                }
                outPixels[i] = (byte)(cf * (MAX_VAL / pixelsize));
            }

            src = BitmapSource.Create(bFrame[c].PixelWidth, bFrame[c].PixelHeight, bFrame[c].DpiX, bFrame[c].DpiY,
                bFrame[c].Format, bFrame[c].Palette, outPixels, (int)(bFrame[c].Width * (bFrame[c].Format.BitsPerPixel / 8)));
            outFrame[c] = BitmapFrame.Create(src);
        }
        WriteObject(outFrame);
    }
}

これは、私の先生によると、ヒストグラムは次のようになります。

http://www.fileden.com/files/2009/8/18/2547657/histostretch.PNG

上記のコードを実行したところ、真っ黒な画像が得られました。ここに私のコードがあります:

outFrame = new BitmapFrame[bFrame.Length];
        for (int c = 0; c < bFrame.Length; c++)
        {
            MAX_VAL = (byte)((1 << bFrame[c].Format.BitsPerPixel) - 1);
            histogram = new int[MAX_VAL + 1];
            for (int i = 0; i <= MAX_VAL; i++)
            {
                histogram[i] = 0;
            }

            pixelsize = bFrame[c].PixelWidth * bFrame[c].PixelHeight;
            pixels = new byte[(int)pixelsize];
            outPixels = new byte[(int)pixelsize];
            bFrame[c].CopyPixels(pixels,(int)bFrame[c].Width * (bFrame[c].Format.BitsPerPixel / 8),0);
            max = pixels[0];
            min = pixels[0];

            for (int i = 0; i < pixelsize; i++)
            {
                histogram[(int)pixels[i]] = histogram[(int)pixels[i]] + 1;
                if((int)pixels[i] > max)
                    max = pixels[i];
                if((int)pixels[i] < min)
                    min = pixels[i];
            }

            dynamic = max - min;

            for (int i = 0; i < pixelsize; i++)
            {
                outPixels[i] = (byte)(((pixels[i] - min) / dynamic) * MAX_VAL);
            }
4

3 に答える 3

9

ヒストグラム ストレッチは、次のようなピクセル値のマッピングです。

  • 最小値 (例: 図の 84) は 0 になります。
  • 最大値 (例: 図の 153) は 255 (8 ビット イメージの場合) になります。
  • すべての中間値はその範囲の間で補間されます (図を参照)。

つまり、ヒストグラム ストレッチとは、画像データのダイナミック (84:153) を可能な限り最大のダイナミック (0:255) にストレッチすることを意味します。

これは、ヒストグラムのピークの高さには影響せず、その広がりのみに影響するはずです (この図は、この点で少し誤解を招く可能性があります)。

ヒストグラム ストレッチ http://cct.rncan.gc.ca/resource/tutor/fundam/images/linstre.gif

画像ソース

実際には、これは画像のピクセルに適用するマッピングです (疑似コード):

maxVal = image.maximumValue() # 153
minVal = image.minumumValue() # 84
dynamic = maxVal-minVal
for pixel in image.Pixels():
    newPixel = ((pixel-minVal)/dynamic)*255
于 2009-08-19T10:46:08.310 に答える
0

カメラの照明やゲイン/オフセットを制御できる場合は、それらを最適化し、必要に応じてヒストグラムを引き伸ばすことができます。

于 2009-08-19T10:51:04.573 に答える
0

float を考慮することを忘れないでください。したがって、dabonz413 の回答をわずかに変更します。

maxVal = image.maximumValue() # 153
minVal = image.minumumValue() # 84
dynamic = maxVal-minVal
for pixel in image.Pixels():
    newPixel = ((float) (pixel-minVal)/dynamic)*255
于 2015-02-20T09:23:06.690 に答える