Convert OpenCV Mat to UIImage

96 views Asked by At

My goal is to process image from camera frame using openCV and then display the processed image back to user on UI.

I added opencv2.framework into my project (4.7.0), created OpenCVWrapper.h and OpenCVWrapper.mm.

Opencv2 provides me possibility to create Mat object from image, by init: let mat = Mat(uiImage: someImage) So i converted image from camera to Mat object, then performed some operations, and the last step I want to do is to convert it back to UIImage so I can display it to user.

As far as I know, there is no similar opposite init (Mat -> UIImage), so I created functions in my wrapper. In OpenWrapper.mm (from docs of openCV, docs)[(https://docs.opencv.org/4.x/d3/def/tutorial_image_manipulation.html) ) :

\+(UIImage \*)UIImageFromCVMat:(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);
// Creating CGImage from cv::Mat
CGImageRef imageRef = CGImageCreate(cvMat.cols, //width
cvMat.rows, //height
8, //bits per component
8 \* cvMat.elemSize(), //bits per pixel
cvMat.step\[0\], //bytesPerRow
colorSpace, //colorspace
kCGImageAlphaNone|kCGBitmapByteOrderDefault,// bitmap info
provider, //CGDataProviderRef
NULL, //decode
false, //should interpolate
kCGRenderingIntentDefault //intent
);
// Getting UIImage from CGImage
UIImage \*finalImage = \[UIImage imageWithCGImage:imageRef\];
CGImageRelease(imageRef);
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpace);
return finalImage;
}

and in OpenCVWrapper.h :

+ (UIImage \*)UIImageFromCVMat:(Mat \*)cvMat; but when I call this function simply like this:

let image = UIImage()
let matImage = Mat(uiImage: image)
let backUIImage = OpenCVWrapper.uiImage(fromCVMat: matImage)

I am getting error: Thread 1: EXC_BAD_ACCESS (code=1, address=0x113f41cb0) Anyone has idea what am I doing wrong ? Thanks for any tips

0

There are 0 answers