1

これは最後の2時間私を困惑させます。画像ファイルを読み取ると、MatlabのimreadとC#のImage.FromFileの間でピクセル値が異なりますか?

aa=imread('myfile.tif')

max(aa(:)) = 248 in matlab

C#では

var image2Array = imageToByteArray((Bitmap) Image.FromFile("myfile.tif"));
byte maxx = 0;
foreach(var a in image2Array)
{
     maxx = Math.Max(maxx, a);
}
//maxx = 255

さらに、Matlabでは、

aa(1,1) = 13, 
aa(1,2) = 13 

しかしC#では

image2Array[0]=17,  
image2Array[1]=0

それらは同じである必要があります。

ところで、この場合、ピクセルタイプはuint8です。したがって、寸法の違いはありません。

Imageからバイト配列を取得する方法を聞かれたら、MSDNドキュメントを使用してこのメ​​ソッドを作成しました。

    public byte[] imageToByteArray(Bitmap bmp)
    {
        // Lock the bitmap's bits.  
        Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
        BitmapData bmpData = bmp.LockBits(
            rect,
            ImageLockMode.ReadWrite,
            bmp.PixelFormat);

        // Get the address of the first line.
        IntPtr ptr = bmpData.Scan0;

        // Declare an array to hold the bytes of the bitmap. 
        int bytes = Math.Abs(bmpData.Stride)*bmp.Height;
        byte[] rgbValues = new byte[bytes];

        // Copy the RGB values into the array.
        System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
        // Unlock the bits.
        bmp.UnlockBits(bmpData);
        return rgbValues;
    }

私はここで何を間違えましたか?結果として得られる2つの画像は同じように見えるため、異なる読み取りアルゴリズムを使用していると思われます。

アップデート:

私がやっていたことに何も悪いことはないと思います。私は、tifをビットマップとして読み取ることが問題の原因であると結論付けました。この理論を確認するために、

  1. 2つの画像を表示しましたが、まったく同じように見えました。ですから、私の側には間違いはないと思います。

  2. opencvで同じファイルを読み取ろうとしましたが、そのピクセル値はmatlabのものとまったく同じでした。これは私にとって驚くべきことでした。これからは、C#でビットマップを慎重に使用します。

4

2 に答える 2

5

imageToByteArrayメソッドバイト配列を返しますが、各バイトがピクセルであると想定することはできません。はPixelFormat、ピクセルデータがバイト配列にどのように格納されるかを決定します。

これを文書化した私が見た中で最高のサイトは、BobPowellのlockbitsページです。

PixelFormatがの場合、Format8bppIndexedこの(テストされていない)コードは各ピクセルのカラー値を提供するはずです。

var bmp = (Bitmap)Bitmap.FromFile("myfile.tif");

// ******* Begin copying your imageToByteArray method
// Lock the bitmap's bits.  
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
BitmapData bmpData = bmp.LockBits(
    rect,
    ImageLockMode.ReadWrite,
    bmp.PixelFormat);

// Get the address of the first line.
IntPtr ptr = bmpData.Scan0;

// Declare an array to hold the bytes of the bitmap. 
int bytes = Math.Abs(bmpData.Stride) * bmp.Height;
byte[] imageData = new byte[bytes];

// Copy the RGB values into the array.
System.Runtime.InteropServices.Marshal.Copy(ptr, imageData, 0, bytes);
// Unlock the bits.
bmp.UnlockBits(bmpData);
// ******* End copying your imageToByteArray method

// Now loop through each pixel...  The byte array contains extra bytes
// used for padding so we can't just loop through every byte in the array.
// This is done by using the Stride property on bmpData.
for (int y = 0; y < bmpData.Height; y++)
{
    for (int x = 0; x < bmpData.Width; x++)
    {
        var offset = (y * bmpData.Stride) + x;

        // The byte in the image array gives the offset into the palette
        var paletteIndex = imageData[offset];

        // Given the offset, find the matching color in the palette
        var color = bmp.Palette.Entries[offset];

        // Look at the color value here...
    }
}
于 2012-09-20T23:26:30.290 に答える
2

TIFFには多くの形式があり、ビットマップとして読み取ろうとしています。

代わりに独自のTIFFリーダーを使用して読むことをお勧めします:.NET用の優れたTiffライブラリ

于 2012-09-21T14:37:34.503 に答える