Getting Pixel Data From CIImage
-
Hey,
I am trying as hard as I can to get pixel data from a CIImage, but am
failing, pretty miserably. I am using
render:toBitmap:rowBytes:bounds:format:colorSpace: from CIContext and
it seems to work, but doesn't really. I get data in my int*
pointer, but it never changes! What am I doing wrong? I posted my
code. The part in need of assistance is near the bottom of
(void)captureOutput. I would greatly appreciate your help.
Thank You,
Bridger Maxwell
- (void)captureOutput:(QTCaptureOutput *)captureOutput
didOutputVideoFrame:(CVImageBufferRef)videoFrame
withSampleBuffer:(QTSampleBuffer *)sampleBuffer
fromConnection:(QTCaptureConnection *)connection
{
CIImage* image = [CIImage imageWithCVImageBuffer:videoFrame];
[monoChromeFilter setValue:image forKey:@"inputImage"]; //First we
monochrome it (only black and white
//[smoothingFilter setValue:[monoChromeFilter
valueForKey:@"outputImage"] forKey:@"inputImage"];
if (needsNewBackground) { //If the flag has been raised we will
capture a new background
[backgroundFilter setValue:[monoChromeFilter
valueForKey:@"outputImage"] forKey:@"inputBackgroundImage"];
if (videoDeviceInput) {
needsNewBackground = NO;
}
}
[backgroundFilter setValue:[monoChromeFilter
valueForKey:@"outputImage"] forKey:@"inputImage"]; //Now we subtract
the background from the monochrome image
[colorCorrectionFilter setValue:[backgroundFilter
valueForKey:@"outputImage"] forKey:@"inputImage"];
CIImage* finalImage = [colorCorrectionFilter valueForKey:@"outputImage"];
size_t rowBytes = [self optimalRowBytesForWidth:[finalImage
extent].size.width bytesPerPixel:4];
int* imageData;
[[[NSGraphicsContext currentContext] CIContext] render:finalImage
toBitmap:imageData rowBytes:rowBytes
bounds:[finalImage extent]
format:kCIFormatARGB8
colorSpace:CGColorSpaceCreateWithName(kCGColorSpaceGenericGray)];
blobDetector->computeBlobs(imageData);
NSLog(@"On Frame %i there are %i blobs. Sample byte 5:
%i",frameCount++,blobDetector->getBlobNb(),imageData[19]);
[outputView setImage:finalImage];
[outputView setNeedsDisplay:YES];
//CIContext* theContext = [outputView ciContext];
}
- (void) drawBlobsOnCIImage:(CIImage *)image {
for (int n=0 ; n< blobDetector->getBlobNb() ; n++)
{
*blob = blobDetector->getBlob(n);
if (blob->isOk())
{
NSRect rectangle = NSMakeRect(blob->xMin, blob->yMin, blob->xMax -
blob->xMin , blob->yMax - blob->yMin);
}
}
}
- (size_t)optimalRowBytesForWidth: (size_t)width bytesPerPixel:
(size_t)bytesPerPixel
{
size_t rowBytes = width * bytesPerPixel;
//Widen rowBytes out to a integer multiple of 16 bytes
rowBytes = (rowBytes + 15) & ~15;
//Make sure we are not an even power of 2 wide.
//Will loop a few times for rowBytes <= 16.
while( 0 == (rowBytes & (rowBytes - 1) ) )
rowBytes += 16;
return rowBytes;
} -
Hi,
If you are using Leopard (10.5), you could do something like this:
CIImage* imageBlurred = .....
NSBitmapImageRep* bitmap = [[[NSBitmapImageRep alloc] initWithCIImage:
imageBlurred] autorelease];
// Getting pixels data
// this returns a pointer to the pixel data
[bitmap bitmapData]
regards
Nikolai Hellwig
Am 13.05.2008 um 03:06 schrieb Bridger Maxwell:> Hey,
> I am trying as hard as I can to get pixel data from a CIImage, but am
> failing, pretty miserably. I am using
> render:toBitmap:rowBytes:bounds:format:colorSpace: from CIContext and
> it seems to work, but doesn't really. I get data in my int*
> pointer, but it never changes! What am I doing wrong? I posted my
> code. The part in need of assistance is near the bottom of
> (void)captureOutput. I would greatly appreciate your help.
>
>
> Thank You,
> Bridger Maxwell
>
>
>
> - (void)captureOutput:(QTCaptureOutput *)captureOutput
> didOutputVideoFrame:(CVImageBufferRef)videoFrame
> withSampleBuffer:(QTSampleBuffer *)sampleBuffer
> fromConnection:(QTCaptureConnection *)connection
>
> {
>
> CIImage* image = [CIImage imageWithCVImageBuffer:videoFrame];
>
>
>
> [monoChromeFilter setValue:image forKey:@"inputImage"]; //First we
> monochrome it (only black and white
>
> //[smoothingFilter setValue:[monoChromeFilter
> valueForKey:@"outputImage"] forKey:@"inputImage"];
>
>
>
> if (needsNewBackground) { //If the flag has been raised we will
> capture a new background
>
> [backgroundFilter setValue:[monoChromeFilter
> valueForKey:@"outputImage"] forKey:@"inputBackgroundImage"];
>
> if (videoDeviceInput) {
>
> needsNewBackground = NO;
>
> }
>
> }
>
>
>
> [backgroundFilter setValue:[monoChromeFilter
> valueForKey:@"outputImage"] forKey:@"inputImage"]; //Now we subtract
> the background from the monochrome image
>
> [colorCorrectionFilter setValue:[backgroundFilter
> valueForKey:@"outputImage"] forKey:@"inputImage"];
>
> CIImage* finalImage = [colorCorrectionFilter
> valueForKey:@"outputImage"];
>
> size_t rowBytes = [self optimalRowBytesForWidth:[finalImage
> extent].size.width bytesPerPixel:4];
>
> int* imageData;
>
> [[[NSGraphicsContext currentContext] CIContext] render:finalImage
>
> toBitmap:imageData rowBytes:rowBytes
>
> bounds:[finalImage extent]
>
> format:kCIFormatARGB8
>
> colorSpace:CGColorSpaceCreateWithName(kCGColorSpaceGenericGray)];
>
>
>
> blobDetector->computeBlobs(imageData);
>
> NSLog(@"On Frame %i there are %i blobs. Sample byte 5:
> %i",frameCount++,blobDetector->getBlobNb(),imageData[19]);
>
>
>
> [outputView setImage:finalImage];
>
> [outputView setNeedsDisplay:YES];
>
> //CIContext* theContext = [outputView ciContext];
>
> }
>
>
>
>
> - (void) drawBlobsOnCIImage:(CIImage *)image {
>
> for (int n=0 ; n< blobDetector->getBlobNb() ; n++)
>
> {
>
> *blob = blobDetector->getBlob(n);
>
> if (blob->isOk())
>
> {
>
> NSRect rectangle = NSMakeRect(blob->xMin, blob->yMin, blob->xMax -
> blob->xMin , blob->yMax - blob->yMin);
>
> }
>
> }
>
>
>
> }
>
>
>
>
> - (size_t)optimalRowBytesForWidth: (size_t)width bytesPerPixel:
> (size_t)bytesPerPixel
>
> {
>
> size_t rowBytes = width * bytesPerPixel;
>
>
>
> //Widen rowBytes out to a integer multiple of 16 bytes
>
> rowBytes = (rowBytes + 15) & ~15;
>
>
>
> //Make sure we are not an even power of 2 wide.
>
> //Will loop a few times for rowBytes <= 16.
>
> while( 0 == (rowBytes & (rowBytes - 1) ) )
>
> rowBytes += 16;
>
>
>
> return rowBytes;
>
> } -
You can also create a CGBitmapContext (with CGBitmapContextCreate) and
create a CIContext from that (with +[CIContext
contextWithCGContext:options:]) and draw to the CIContext. It will
draw the pixels into the bitmap. This will work for Tiger and Leopard.
On May 13, 2008, at 1:51 AM, Nikolai Hellwig wrote:> If you are using Leopard (10.5), you could do something like this:
>
> CIImage* imageBlurred = .....
> NSBitmapImageRep* bitmap = [[[NSBitmapImageRep alloc]
> initWithCIImage: imageBlurred] autorelease];
>
> // Getting pixels data
> // this returns a pointer to the pixel data
> [bitmap bitmapData]


