OpenCV的圖像處理——iOS與OpenCV之間圖像轉換

前言

1.OpenCV有專門的iOS平臺的包,可以真接下載導入工程,也可以用cmake把OpenCV源碼編成.a文件,以靜態庫的形式導入工程。
2.我這裏用的Xcode11,OpenCV用的是最4.20這個版本。

圖像轉換

1.iOS所支持的圖像格式是UIImage,OpenCV的圖像格式是Mat,如果要在iOS用OpenCV處理圖像,那得先把UIImage轉成Mat,才能使用OpenCV的庫來做相關的操作。這裏要寫一個轉換函數把數據格式轉換過來就可以了,OC是可以調用C++函數的,這裏直接用C++寫就可以了。
UIImage轉Mat:

void UIImageToMat(UIImage *ui_image, cv::Mat &cv_dst)
{
    assert(ui_image.size.width > 0 && ui_image.size.height > 0);
    assert(ui_image.CGImage != nil || ui_image.CIImage != nil);

    //開緩衝區
    NSInteger width = ui_image.size.width;
    NSInteger height = ui_image.size.height;
    cv::Mat cv_mat8uc4 = cv::Mat((int)height, (int)width, CV_8UC4);

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    if (ui_image.CGImage)
    {
        CGContextRef contextRef = CGBitmapContextCreate(cv_mat8uc4.data, cv_mat8uc4.cols, cv_mat8uc4.rows, 8, cv_mat8uc4.step, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrderDefault);
        CGContextDrawImage(contextRef, CGRectMake(0, 0, width, height), ui_image.CGImage);
        CGContextRelease(contextRef);
    }
    else
    {
        static CIContext* context = nil;
        if (!context)
        {
            context = [CIContext contextWithOptions:@{ kCIContextUseSoftwareRenderer: @NO }];
        }
        CGRect bounds = CGRectMake(0, 0, width, height);
        [context render:ui_image.CIImage toBitmap:cv_mat8uc4.data rowBytes:cv_mat8uc4.step bounds:bounds format:kCIFormatRGBA8 colorSpace:colorSpace];
    }
    CGColorSpaceRelease(colorSpace);

    cv::Mat cv_mat8uc3 = cv::Mat((int)width, (int)height, CV_8UC3);
    cv::cvtColor(cv_mat8uc4, cv_mat8uc3, cv::COLOR_RGBA2BGR);

    cv_dst = cv_mat8uc3;
}

2.OpenCV處理過的圖像是Mat的,如果要在iOS的UIImageView顯示出來,還是要把Mat轉成UIImage.
Mat轉UIImage:

UIImage *MatToUIImage(cv::Mat &cv_src)
{
    assert(cv_src.elemSize() == 1 || cv_src.elemSize() == 3);
    cv::Mat cv_rgb;
    if (cv_src.elemSize() == 1)
    {
        cv::cvtColor(cv_src, cv_rgb, cv::COLOR_GRAY2RGB);
    } else if (cv_src.elemSize() == 3)
    {
        cv::cvtColor(cv_src, cv_rgb, cv::COLOR_BGR2RGB);
    }

    NSData *data = [NSData dataWithBytes:cv_rgb.data length:(cv_rgb.elemSize() * cv_rgb.total())];
    CGColorSpaceRef colorSpace;
    if (cv_rgb.elemSize() == 1)
    {
        colorSpace = CGColorSpaceCreateDeviceGray();
    } else
    {
        colorSpace = CGColorSpaceCreateDeviceRGB();
    }
    CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
    CGImageRef imageRef = CGImageCreate(cv_rgb.cols, cv_rgb.rows, 8, 8 * cv_rgb.elemSize(), cv_rgb.step.p[0], colorSpace, kCGImageAlphaNone|kCGBitmapByteOrderDefault, provider, NULL, false, kCGRenderingIntentDefault);
    UIImage *ui_image = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);
    CGDataProviderRelease(provider);
    CGColorSpaceRelease(colorSpace);

    return ui_image;
}

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章