Diemension9

  • News
  • Linux
  • Fuckipred
  • Tiny gems
  • Htc Hero
  • Downloads
  • [mac, opencv] displaying IplImage in cocoa

    update: ended up not using the old version so i didn’t look at it much. today i needed it again and realized it was crap so i rewrote it and here’s a new, (hopefully) less buggy version that also handles single-channel images.

    Through work i found the need to display an IplImage in cocoa.. after looking at CVOCV, James Hurleys example and a couple of other snippets i remembered that opencv can be built for iOS and started browsing through the source. Inside OpenCV-2.4.1/modules/highgui/src/window_cocoa.mm i found what i was looking for (CVView). i rewrote it a bit and came up with the following NSView subclass:

    MyCVView.h

    #import <Foundation/Foundation.h>
    #import <opencv/cv.h>
    
    
    @interface MyCVView : NSView {
    @private
    	NSBitmapImageRep *bm;
    @public
    }
    @property (nonatomic, retain) NSImage *image;
    
    - (void)setImagePrefs:(int)width		// image width
    			   height:(int)height		// " height
    			 channels:(int)nChannels	// usually 4/3/1 (rgba/rgb/monochrome)
    			widthStep:(int)widthStep	// usually width*nChannels
    			    depth:(int)depth;
    - (void)setImageData:(IplImage *)img
       releaseWhenCopied:(BOOL)shouldRelease;
    - (void)drawRect:(NSRect)rect;
    
    @end

    MyCVView.m:

    #import "MyCVView.h"
    
    @implementation MyCVView 
    
    @synthesize image;
    
    - (id)init {
    	if((self = [super init])) [self setCanDrawConcurrently:true];
    	return self;
    }
    
    - (void)setImagePrefs:(int)width
    			   height:(int)height
    			 channels:(int)nChannels
    			widthStep:(int)widthStep
    			    depth:(int)depth
    {
    	if(bm) [bm release];
    	bm = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL
    												 pixelsWide: width
    												 pixelsHigh: height
    											  bitsPerSample: 8	// i only use IPL_DEPTH_8U, if you use others set it as an arg..
    											samplesPerPixel: nChannels
    												   hasAlpha: NO
    												   isPlanar: NO
    											 colorSpaceName: (nChannels == 1 ? NSDeviceWhiteColorSpace :  NSDeviceRGBColorSpace)
    												bytesPerRow: widthStep
    											   bitsPerPixel: nChannels*depth];
    	if(image) [image release];
    	image = [[NSImage alloc] init];
    	[image addRepresentation:bm];
    }
    
    - (void)setImageData:(IplImage *)img
       releaseWhenCopied:(BOOL)shouldRelease
    {
    	if(!bm) [self setImagePrefs:img->width
    						 height:img->height
    					   channels:img->nChannels
    					  widthStep:img->widthStep
    					      depth:img->depth];
    	unsigned char *src = (unsigned char *)img->imageData;
    	unsigned char *dst = [bm bitmapData];
    	if(img->nChannels == 1) memcpy(dst, src, (img->width*img->height));
    	else
    	{	// red-blue swap and flip incorporated
    		for(int i = img->width * img->height - 1; i >= 0; i--)
    		{
    			dst[i * 4 + 0] = src[2];
    			dst[i * 4 + 1] = src[1];
    			dst[i * 4 + 2] = src[0];
    			src += ((CvMat *)img)->step - ((CvMat *)img)->cols;
    		}
    	}
    	[self setNeedsDisplay:YES];
    	if(shouldRelease) cvReleaseImage(&img);
    }
    
    - (void)drawRect:(NSRect)rect {
    	[super drawRect:rect];
    	// autoscaling - if you don't want it replace second part with comment below 
    	NSRect ir = {{0,0}, {[self bounds].size.width, [self bounds].size.height}};
    						// {[image size].width, [image size].height}};
    	if(image != nil)
    	{
    		[image drawInRect: ir
    				 fromRect: NSZeroRect
    				operation: NSCompositeSourceOver
    				 fraction: 1.0];
    	}
    }
    
    - (void)dealloc
    {
    	if(bm) [bm release];
    	if(image) [image release];
        [super dealloc];
    }
    
    @end

    This was built without warnings in xcode 4 on snow leopard and saves some cpu-cycles compared to the original version since the rb-swap and flip is stuffed into a the data-copy-loop. Note that you should not call it CVView (will cause a crash) since opencv already contains a class with that name.

    // sluggo

    Posted

    2012-07-03 #

    Filed under

    News, Tiny Gems

    Tags

    cocoa, iplimage, nsimage, opencv, xcode

    no comments

Top