Domanda

Come faccio a dare un senso ai dati di immagine per una scala di grigi immagine dato il seguente scenario: i dati video capture I dalla "tampone" e l'estratto una sezione 80x20 e poi trasformarla in un UIImage scala di grigi. Ma quando esamino il pixel grezzo byte non sono in grado di dare un senso di loro in un modo che mi permettesse di andare avanti e "binarizzare" loro (il mio vero obiettivo).

Quando ho semplicemente salvare l'UIImage all'album di foto utilizzando UIImageWriteToSavedPhotosAlbum per verificare che tipo di dati di immagine che ho, anzi ottengo pianura un'immagine, bianco 80x20 (in realtà è la luce-grigio). Ho catturato un'immagine bianca normale per semplificare le cose, aspettandosi di vedere solo i valori tra, diciamo, 200 o giù di lì e 255, e tuttavia ci sono sezioni dei dati di immagine piene di zeri, che suggeriscono chiaramente righe di pixel neri. Ogni aiuto è apprezzato. Il relativo codice ei dati di immagine (16 pixel per volta) sono inferiori.

Ecco come ho creato l'immagine in scala di grigi 80x20 da una porzione dei dati video 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];
}

e poi, quando uso il seguente codice per scaricare i dati dei pixel alla console:

    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]);
}

ho sempre ottengo in uscita come segue:

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

(questo ripete modello per i restanti byte, 80 byte di dati di pixel a 200 di, a seconda illuminazione, seguiti da 240 byte di zeri - c'è un totale di 1600 byte poiché l'immagine è 80x20)

È stato utile?

Soluzione

Questa:

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

Dovrebbe essere:

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

In altre parole, per un'immagine grigio 8 bit, il numero di byte per riga è uguale alla larghezza.

Altri suggerimenti

Probabilmente avete dimenticato immagine stride - si sta assumendo che le immagini vengono memorizzate come altezza larghezza * ma diversi sistemi di memorizzarle come falcata * altezza in cui stride> larghezza. Gli zeri sono riempimento che si dovrebbe saltare.

A proposito, che cosa vuoi dire "binarizzare"? Credo che si quantizzazione media ad un livello inferiore di grigio?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top