由于最近做項(xiàng)目要使用opencv的原因,需要使用到這個(gè)功能
是要將image 轉(zhuǎn)成?cv::Mat 識(shí)別
- (cv::Mat)cvMatFromUIImage:(UIImage*)image{
? ? @autoreleasepool {
?? ? ? ? ? CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage);
?? ? ? ? ? CGFloatcols = image.size.width;
?? ? ? ? ? CGFloatrows = image.size.height;
?? ? ? ? ? cv::Mat cvMat(rows, cols, CV_8UC4); // 8 bits per component, 4 channels (color channels + alpha)
?? ? ? ? ? CGContextRefcontextRef =CGBitmapContextCreate(cvMat.data,? ? ? ? ? ? ? ? // Pointer to? data
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? cols,? ? ? ? ? ? ? ? ? ? ? // Width of bitmap
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? rows,? ? ? ? ? ? ? ? ? ? ? // Height of bitmap
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 8,? ? ? ? ? ? ? ? ? ? ? ? ? // Bits per component
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? cvMat.step[0],? ? ? ? ? ? ? // Bytes per row
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? colorSpace,? ? ? ? ? ? ? ? // Colorspace
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // kCGImageAlphaNoneSkipLast |kCGBitmapByteOrderDefault // 此處有修改適配laplacian的接入色值轉(zhuǎn)換
?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? kCGBitmapByteOrder32Little|kCGImageAlphaPremultipliedFirst);// Bitmap info flags
?? ? ? ? ? CGContextDrawImage(contextRef,CGRectMake(0,0, cols, rows), image.CGImage);
?? ? ? ? ? CGColorSpaceRelease(colorSpace);
?? ? ? ? ? CGContextRelease(contextRef);
?? ? ? ? ? colorSpace =NULL;
?? ? ? ? ? contextRef =NULL;
?? ? ? ? ? returncvMat;
? ? }
}
而且這個(gè)方法要頻繁使用,會(huì)導(dǎo)致內(nèi)存不斷飆升,最終閃退。使用了@autoreleasepool {} 和?? ? ? ? ? CGColorSpaceRelease(colorSpace);? ? ?CGContextRelease(contextRef); 釋放內(nèi)存和管理,都發(fā)現(xiàn)沒用,很崩潰!目前似乎都還沒解決成功。
最終使用了其他方式:UIImage --> base64 --> CVMat? 完美解決了。但是識(shí)別率下降了
代碼如下
-(NSString *)UIImageToBase64Str:(UIImage *) image{
? ? NSData *data = UIImagePNGRepresentation(image);
? ? NSString* str? =? ? ? [database64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
? ? return str;
}
static cv::MatBase2Mat(std::string&base64_data) {
? ? cv::Mat img;
? ? std::strings_mat;
? ? s_mat =base64Decode(base64_data.data(), base64_data.size());
? ? std::vector base64_img(s_mat.begin(), s_mat.end());
? ? img =cv::imdecode(base64_img, CV_LOAD_IMAGE_COLOR);
? ? return img;
}
staticstd::stringbase64Decode(constchar* Data,intDataByte) {
? ? //解碼表
? ? constcharDecodeTable[] =
? ? {
? ? ? ? 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
? ? ? ? 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
? ? ? ? 62,// '+'
? ? ? ? 0,0,0,
? ? ? ? 63,// '/'
? ? ? ? 52,53,54,55,56,57,58,59,60,61,// '0'-'9'
? ? ? ? 0,0,0,0,0,0,0,
? ? ? ? 0,1,2,3,4,5,6,7,8,9,10,11,12,
? ? ? ? 13,14,15,16,17,18,19,20,21,22,23,24,25,// 'A'-'Z'
? ? ? ? 0,0,0,0,0,0,
? ? ? ? 26,27,28,29,30,31,32,33,34,35,36,37,38,
? ? ? ? 39,40,41,42,43,44,45,46,47,48,49,50,51,// 'a'-'z'
? ? };
? ? std::stringstrDecode;
? ? intnValue;
? ? inti =0;
? ? while(i < DataByte) {
? ? ? ? if(*Data !='\r'&& *Data !='\n') {
? ? ? ? ? ? nValue = DecodeTable[*Data++] <<18;
? ? ? ? ? ? nValue += DecodeTable[*Data++] <<12;
? ? ? ? ? ? strDecode += (nValue &0x00FF0000) >>16;
? ? ? ? ? ? if(*Data !='=') {
? ? ? ? ? ? ? ? nValue += DecodeTable[*Data++] <<6;
? ? ? ? ? ? ? ? strDecode += (nValue &0x0000FF00) >>8;
? ? ? ? ? ? ? ? if(*Data !='=') {
? ? ? ? ? ? ? ? ? ? nValue += DecodeTable[*Data++];
? ? ? ? ? ? ? ? ? ? strDecode += nValue &0x000000FF;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? i +=4;
? ? ? ? }
? ? ? ? else{
? ? ? ? ? ? Data++;
? ? ? ? ? ? i++;
? ? ? ? }
? ? }
? ? returnstrDecode;
}