Как данные изображения интерпретируются для изображения в градациях серого на iPhone? - PullRequest
2 голосов
/ 14 декабря 2010

Как мне понять данные изображения для изображения в градациях серого, учитывая следующий сценарий: я собираю видеоданные из «буфера выборок» и извлекаю раздел 80x20, а затем превращаю его в UIImage в градациях серого.Но когда я изучаю необработанные пиксельные байты, я не в состоянии понять их так, чтобы я мог продолжить и «преобразовать их в двоичную форму» (моя настоящая цель).

Когда я просто сохраняю UIImage в фотоальбом, используя UIImageWriteToSavedPhotosAlbum, чтобы проверить, какие именно данные изображения у меня есть, я действительно получаю простое белое изображение 80x20 (на самом деле оно светло-сероватое).Я сделал простое белое изображение, чтобы упростить вещи, ожидая увидеть только значения между, скажем, 200 или около того и 255, и все же есть разделы данных изображения, заполненные нулями, которые явно предлагают ряды черных пикселей.Любая помощь приветствуется.Соответствующий код и данные изображения (по 16 пикселей за раз) приведены ниже.

Вот как я создаю изображение в оттенках серого 80x20 из части видеоданных CMSampleBufferRef:

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-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-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-

(этот шаблон повторяется для оставшихся байтов, 80 байтов пиксельных данных в 200-х годах, в зависимости от освещения, за которыми следуют 240 байтов нулей - с момента появленияизображение 80x20)

Ответы [ 2 ]

1 голос
/ 14 декабря 2010

Это:

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

Должно быть:

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

Другими словами, для 8-битного серого изображения число байтов в строке равно ширине.

0 голосов
/ 14 декабря 2010

Вы, вероятно, забыли прохождение изображения - вы предполагаете, что ваши изображения хранятся как ширина * высота, но несколько систем сохраняют их как шаг * высота, где шаг> ширина. Нули дополняют, что вы должны пропустить.

Кстати, что вы подразумеваете под "бинаризацией"? Полагаю, вы имеете в виду квантование на менее серые уровни?

...