2010-12-13 3 views
2

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

Когда я просто сохраняю 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-0-0-0-0-0-0-0-0-0-0-0-0-0-0-

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

ответ

1

Это:

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

Должно быть:

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

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

+0

Вы пригвоздили его ergosys. Спасибо. Я полностью застрял и стал обработкой изображений noob. – Alyoshak

0

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

Кстати, что вы подразумеваете под «бинаризацией»? Наверное, вы имеете в виду квантование до менее серого уровня?

+0

Чтобы преобразовать изображение в двуугольник, все его пиксели превращаются в белый или черный. Обычно это делается так: «Если пиксель на изображении имеет значение интенсивности меньше порогового значения, соответствующий пиксель в результирующем изображении устанавливается на черный. В противном случае, если значение интенсивности пикселя больше или равно пороговую интенсивность, результирующий пиксель устанавливается на белый. Таким образом, создание бинаризованного изображения или изображение с двумя цветами, черным (0) и белым (255). " – Alyoshak

+0

Я никогда не слышал о шаге изображения. Позвольте мне проверить это. Возможно, это то, что происходит здесь. – Alyoshak

+0

Я бы назвал это преобразование в «двууровневое изображение»/«1-битное монохромное изображение» или квантование до черно-белого. Если вы хотите в будущем подтвердить свое приложение, вы не должны предполагать, что ваш формат изображения всегда будет использовать 8-битные цветовые компоненты. – koan