opencv ios image transparente cargada sin transparencia

Estoy desarrollando una aplicación ios que utiliza alguna funcionalidad opencv (eliminar el background, las detecciones de bordes, etc.)

Entre otras cosas, cargo imágenes transparentes (pngs). Por algún motivo cuando cargo las imágenes, opencv decide ignorar algunas áreas transparentes y respetar a otras. Puedo ver esto convirtiendo mi UIImage semi transparente en un IplImage y luego de return a UIImage (sin hacer ninguna operación en el progtwig) y guardando ambas imágenes en el file local.

Este es el código que estoy usando para convertir el UIImage a un IplImage y al revés:

- (IplImage *)CreateIplImageFromUIImageWithTransparency:(UIImage *)image { // Getting CGImage from UIImage CGImageRef imageRef = image.CGImage; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); // Creating temporal IplImage for drawing IplImage *iplimage = cvCreateImage( cvSize(image.size.width,image.size.height), IPL_DEPTH_8U, 4 ); // Creating CGContext for temporal IplImage CGContextRef contextRef = CGBitmapContextCreate( iplimage->imageData, iplimage->width, iplimage->height, iplimage->depth, iplimage->widthStep, colorSpace, kCGImageAlphaPremultipliedLast|kCGBitmapByteOrderDefault ); // Drawing CGImage to CGContext CGContextDrawImage( contextRef, CGRectMake(0, 0, image.size.width, image.size.height), imageRef ); CGContextRelease(contextRef); CGColorSpaceRelease(colorSpace); // Creating result IplImage IplImage *ret = cvCreateImage(cvGetSize(iplimage), IPL_DEPTH_8U, 4); cvCvtColor(iplimage, ret, CV_RGBA2BGRA); cvReleaseImage(&iplimage); return ret; } - (UIImage *)UIImageFromIplImage:(IplImage *)image { CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 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, kCGBitmapByteOrderDefault | kCGImageAlphaLast , provider, NULL, false, kCGRenderingIntentDefault); UIImage *ret = [UIImage imageWithCGImage:imageRef]; CGImageRelease(imageRef); CGDataProviderRelease(provider); CGColorSpaceRelease(colorSpace); return ret; } 

¿Qué podría estar causando este comportamiento?

Gracias

Este código funciona para mí. Modifiqué el código de aquí

Leyendo desde UIImage

 -(cv::Mat)CVMat { CGColorSpaceRef colorSpace = CGImageGetColorSpace(self.CGImage); CGFloat cols = self.size.width; CGFloat rows = self.size.height; cv::Mat cvMat(rows, cols, CV_8UC4); // 8 bits per component, 4 channels CGContextRef contextRef = CGBitmapContextCreate(cvMat.data, // Pointer to backing data cols, // Width of bitmap rows, // Height of bitmap 8, // Bits per component cvMat.step[0], // Bytes per row colorSpace, // Colorspace //kCGImageAlphaNoneSkipLast | kCGImageAlphaPremultipliedLast | kCGBitmapByteOrderDefault); // Bitmap info flags CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), self.CGImage); CGContextRelease(contextRef); return cvMat; } 

Convertir de nuevo a UIImage:

 + (UIImage *)imageWithCVMat:(const cv::Mat&)cvMat { return [[UIImage alloc] initWithCVMat:cvMat]; } - (id)initWithCVMat:(const cv::Mat&)cvMat { NSData *data = [NSData dataWithBytes:cvMat.data length:cvMat.elemSize() * cvMat.total()]; CGColorSpaceRef colorSpace; if (cvMat.elemSize() == 1) { colorSpace = CGColorSpaceCreateDeviceGray(); } else { colorSpace = CGColorSpaceCreateDeviceRGB(); } CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data); CGImageRef imageRef = CGImageCreate(cvMat.cols, // Width cvMat.rows, // Height 8, // Bits per component 8 * cvMat.elemSize(), // Bits per pixel cvMat.step[0], // Bytes per row colorSpace, // Colorspace kCGImageAlphaPremultipliedLast | kCGBitmapByteOrderDefault, // Bitmap info flags provider, // CGDataProviderRef NULL, // Decode false, // Should interpolate kCGRenderingIntentDefault); // Intent self = [self initWithCGImage:imageRef]; CGImageRelease(imageRef); CGDataProviderRelease(provider); CGColorSpaceRelease(colorSpace); return self; } 

Creo que aquí es donde está el problema:

 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 

¿No deberías estar usando RGBA aquí?

 IplImage *ret = cvLoadImage("file.png", CV_LOAD_IMAGE_UNCHANGED); 

echando un vistazo al doc: http://opencv.willowgarage.com/documentation/c/reading_and_writing_images_and_video.html

CV_LOAD_IMAGE_UNCHANGED la image cargada se cargará tal cual mientras que el argumento pnetworkingeterminado convierte tu img en RGB