IplImageとUIImageの相互変換
既に色々な方が書いており色々なユーティリティとなっているが、私は取りあえずObjective-Cのクラスユーティリティとして使っている。(そのうち手を入れる予定だ)
-
- OpenCVUtil
+ (IplImage*)IplImageFromUIImage:(UIImage*)image { CGImageRef imageRef = image.CGImage; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); IplImage *iplimage = cvCreateImage(cvSize(image.size.width,image.size.height), IPL_DEPTH_8U, 4 ); CGContextRef contextRef = CGBitmapContextCreate( iplimage->imageData, iplimage->width, iplimage->height, iplimage->depth, iplimage->widthStep, colorSpace, kCGImageAlphaPremultipliedLast|kCGBitmapByteOrderDefault); CGContextDrawImage(contextRef, CGRectMake(0, 0, image.size.width, image.size.height), imageRef); CGContextRelease(contextRef); CGColorSpaceRelease(colorSpace); IplImage *ret = cvCreateImage(cvGetSize(iplimage), IPL_DEPTH_8U, 3); cvCvtColor(iplimage, ret, CV_RGBA2BGR); cvReleaseImage(&iplimage); return ret; } + (UIImage*)UIImageFromIplImage:(IplImage*)image { CGColorSpaceRef colorSpace; if (image->nChannels == 1) { colorSpace = CGColorSpaceCreateDeviceGray(); } else { colorSpace = CGColorSpaceCreateDeviceRGB(); //BGRになっているのでRGBに変換 cvCvtColor(image, image, CV_BGR2RGB); } NSData *data = [NSData dataWithBytes:image->imageData length:image->imageSize]; CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data); CGImageRef imageRef = CGImageCreate(image->width, image->height, image->depth, image->depth * image->nChannels, image->widthStep, colorSpace, kCGImageAlphaNone|kCGBitmapByteOrderDefault, provider, NULL, false, kCGRenderingIntentDefault ); UIImage *ret = [UIImage imageWithCGImage:imageRef]; CGImageRelease(imageRef); CGDataProviderRelease(provider); CGColorSpaceRelease(colorSpace); return ret; }
cvCvtColorは重要だ。CGImageの色空間は"RGB"でありIplImageの"BGR"とは違うため、この色の変換を忘れるとおかしなことになってしまう。(赤と青が反転する)
使い方は以下のようになるだろう。
UIImage* src = [UIImage imageNamed:@"icebraker.png"]; IplImage* img = [OpenCVUtil IplImageFromUIImage:src]; /** OpenCVによる画像処理 **/ imgProcessed.image = [OpenCVUtil UIImageFromIplImage:img];