2010-12-13 19 views
2

次のシナリオでは、グレースケールイメージのイメージデータをどのように理解できますか?「サンプルバッファ」からビデオデータをキャプチャし、80x20セクションを抽出してグレースケールUIImageに変換します。しかし、生のピクセルのバイトを調べると、私はそれらを「二進化」することができるように(私の実際の目標)、それらの意味を理解できません。iPhone上のグレースケール画像の画像データはどのように解釈されますか?

UIImageWriteToSavedPhotosAlbumを使って写真のアルバムにUIImageを保存するだけで、どのような画像データを持っているかを確認すると、実際には白い80x20の画像が得られます(実際は明るい灰色がかっています)。私は平らな白いイメージをキャプチャして物事を単純化しました。たとえば、200からそのように255の間の値しか見ないことを期待していましたが、黒いピクセルの行を明確に示唆する0でいっぱいのイメージデータのセクションがあります。どんな助けもありがとうございます。関連コードと画像データ(一度に16画素)は以下の通りです。ここ

私はCMSampleBufferRef映像データの部分から80x20のグレースケール画像を作成する方法である:次いで

UIImage *imageFromImage(UIImage *image, CGRect rect) 
{ 
    CGImageRef sourceImageRef = [image CGImage]; 
    CGImageRef newImageRef = CGImageCreateWithImageInRect(sourceImageRef, rect); 

    CGImageRef grayScaleImg = grayscaleCGImageFromCGImage(newImageRef); 
    CGImageRelease(newImageRef); 

    UIImage *newImage = [UIImage imageWithCGImage:grayScaleImg scale:1.0 orientation:UIImageOrientationLeft]; 

    return newImage; 
} 

CGImageRef grayscaleCGImageFromCGImage(CGImageRef inputImage) 
{ 
    size_t width = CGImageGetWidth(inputImage); 
    size_t height = CGImageGetHeight(inputImage); 

    // Create a gray scale context and render the input image into that 
    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceGray(); 
    CGContextRef context = CGBitmapContextCreate(NULL, width, height, 8, 
        4*width, colorspace, kCGBitmapByteOrderDefault); 

    CGContextDrawImage(context, CGRectMake(0,0, width,height), inputImage); 

    // Get an image representation of the grayscale context which the input 
    // was rendered into. 
    CGImageRef outputImage = CGBitmapContextCreateImage(context); 

    // Cleanup 
    CGContextRelease(context); 
    CGColorSpaceRelease(colorspace); 

    return (CGImageRef)[(id)outputImage autorelease]; 
} 

と、私はコンソールに画素データをダンプするために、次のコードを使用する場合:

CGImageRef inputImage = [imgIn CGImage]; 
CGDataProviderRef dataProvider = CGImageGetDataProvider(inputImage); 
CFDataRef imageData = CGDataProviderCopyData(dataProvider); 
const UInt8 *rawData = CFDataGetBytePtr(imageData); 

size_t width = CGImageGetWidth(inputImage); 
    size_t height = CGImageGetHeight(inputImage); 

    size_t numPixels = height * width; 
for (int i = 0; i < numPixels ; i++) 
{ 
    if ((i % 16) == 0) 
      NSLog(@" -%i-%i-%i-%i-%i-%i-%i-%i-%i-%i-%i-%i-%i-%i-%i-%i-\n\n", rawData[i],   
      rawData[i+1], rawData[i+2], rawData[i+3], rawData[i+4], rawData[i+5], 
      rawData[i+6], rawData[i+7], rawData[i+8], rawData[i+9], rawData[i+10], 
      rawData[i+11], rawData[i+12], rawData[i+13], rawData[i+14], rawData[i+15]); 
} 

私は一貫して、次のような出力が得られます。

を-216-217-214-215-217-215-216-213-214-214-214-215-215-217-216-216-

-219-219-216-219-220-217-212-214-215-214-217-220-219-217-214-219-

-216-216-218-217-218 -221-217-213-214-212-214-212-212-214-214-213-

-213-213-212-213-212-214-216-214-212-214-216-214-212-210-211- 210-213-210-213-208-

-212-208-208-210-206-207-206-207-210-205-206-208-209-210-210-207-

-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-

-0-0-0 -0-0-0-0-0-0-0-0-0-0-0-0-0-

-0-0-0-0-0-0-0-0-0- 0-0-0-0-0-0-0-

-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0 -

-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-

-0-0-0-0 -0-0-0-0-0-0-0-0-0-0-0-0-

-0-0-0-0-0-0-0-0-0-0- 0-0-0-0-0-0-

-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-

-0-0-0-0-0-0-

-0-0-0-0-0 -0-0-0-0-0-0-0-0-0-0-0-

-0-0-0-0-0-0-0-0-0-0-0- 0-0-0-0-0-

-0-0-0-0-0-0-0-0-0-0-0-0-0-0-012-0-0-0-0-0-0-

-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-

-0-0-0-0-0-0

-0-0-0-0-0-0-0-0-0-0--0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-

(このパターンは、残りのバイトのための80のバイトを繰り返します明るさに応じて200のピクセルデータ、続いて240バイトのゼロ - イメージが80x20であるため合計1600バイトがあります)

答えて

1

これ:

CGContextRef context = CGBitmapContextCreate(NULL, width, height, 8, 
       4*width, colorspace, kCGBitmapByteOrderDefault); 

あるべき:すなわち

CGContextRef context = CGBitmapContextCreate(NULL, width, height, 8, 
       width, colorspace, kCGBitmapByteOrderDefault); 

を、8ビットのグレー画像に対して、行あたりのバイト数は幅と同じです。

+0

あなたはそれをエルギスに釘付けにした。本当にありがとう。私は完全に立ち往生し、画像処理の騒ぎです。 – Alyoshak

0

あなたはおそらくイメージストライドを忘れていますwidth * heightとして格納されますが、いくつかのシステムではstride> heightのストライド* heightとして格納されます。ゼロは、スキップする必要があるパディングです。ところで

、あなたは「2値化」に何を意味するのですか?私はより少ないグレーレベルに量子化することを意味すると思いますか?

+0

イメージを2値化するとは、すべてのピクセルを白または黒に変えることを意味します。これは通常、次のように行われます。「イメージ内のピクセルの強度値がしきい値よりも小さい場合は、結果イメージの対応するピクセルが黒に設定されます。そうでない場合、ピクセル強度値が黒画素(0)と白画素(255)の2色のみの画像を作成する」というように、画素の色は白に設定されている。 – Alyoshak

+0

私はイメージストライドについて聞いたことがありません。これをチェックしてみましょう。多分それはここで起こっていることです。 – Alyoshak

+0

私はそれを「2値画像」/「1ビットモノクロ画像」に変換するか、白黒に量子化すると言います。アプリケーションを将来的に証明したい場合は、イメージフォーマットが常に8ビットカラーコンポーネントを使用すると想定してはいけません。 – koan

関連する問題