OpenCV之圖片黑白處理及其原理解析

支付寶(掃臉登錄)、微信、QQ 、美拍、秒拍、美圖秀秀……
都應用到了OpenCV

核心框架:基於OpenCV框架(圖像處理框架)

OpenCV?
第一點:開源(源代碼+核心算法;改進和優化)
第二點:跨平臺
第三點:支持多個語言
第四點:穩定,性能高 (1999年 V1.0 ~2017.8.3年 V3.3)


利用OpenVC將圖片變爲灰色圖片

1、下載導入framework

首先我們先下載OpenVC中關於iOS的framework。
導入工程中。
build。
我們會發現有個error。

enum { NO, GAIN, GAIN_BLOCKS };  

我們可以將其更改爲

enum { NO_EXPOSURE_COMPENSATOR = 0, GAIN, GAIN_BLOCKS };

或者

enum { CNO, GAIN, GAIN_BLOCKS };  

都可以解決這個問題。

2、在Controller中導入頭文件。

#import <opencv2/opencv.hpp>
//支持iOS平臺
#import <opencv2/imgcodecs/ios.h>

3、使用OpenVC進行處理

- (IBAction)clickImgGray:(id)sender {

     Mat mat_image_src;

    //第一步 : 將iOS平臺的UIImage  -> OpenCV圖片 (Mat 數據結構)

    /*
     參數一: 源文件
     參數二:目標文件  <#cv::Mat &m#>
    */
    UIImageToMat(_imgView.image, mat_image_src);

    //第二步:將彩色圖片 -> 灰色
    /*
     在OpenCV中,有這樣一個方法。
     參數一:源文件
     參數二:目標文件
     參數三:轉換類型

     三通道的顏色 -> Gray

     */
    Mat mat_imag_dst;

    cvtColor(mat_image_src, mat_imag_dst, COLOR_BGR2GRAY);

    //第三步:灰色圖片 -> 可顯示圖片

    cvtColor(mat_imag_dst, mat_image_src, COLOR_GRAY2BGR);


    //將OpenCV圖片(Mat) -> iOS平臺下UIImage

    UIImage *img = MatToUIImage(mat_image_src);

    _imgView.image = img;

}

探究UIImageToMat的實現

    UIImageToMat(_imgView.image, mat_image_src);

上面OpenCV中,只有一個方法。我們自己實現一下一探究竟。

#import <UIKit/UIKit.h>
#import <Accelerate/Accelerate.h>
#import <AVFoundation/AVFoundation.h>
#import <ImageIO/ImageIO.h>
#include "opencv2/core/core.hpp"


//UIImage  -> Mat
void WKUIImageToMat(const UIImage* image, Mat& m);
//UIImage  -> Mat
void WKUIImageToMat(const UIImage* image, Mat& m){

    //第一步:創建顏色空間
    //開闢內存空間
    CGColorSpaceRef colorSpaceRef  = CGImageGetColorSpace(image.CGImage);

    //第二步:根據iOS大小創建OpenCV圖片
    CGFloat width = image.size.width;
    CGFloat height = image.size.height;

    /*
     高
     寬
     規則類型

     在OpenCV裏面有很多規範 (圖像學相關,定義了很多很多宏定義)
     CV_8UC4 表示:使用8位無符號類型 unsigned char, 每一個像素由4個元素組成四個通道的格式(ARGB)
     規範格式(宏定義格式): CV_[位數][是否有符號][類型前綴]C[通道數量]

                CV_8UC4    8位 U:unsigned char 無符號 C  4個通道(ARGB)
                CV_8SC4    8位 S:signed char 有符號   C  4個通道(ARGB)

     都是C++/OC 代碼混合編程
     */
    Mat mat_img_src(height,width,CV_8UC4);
    m = mat_img_src;

    //第三部:創建圖片上下文。 解析UIImage圖片信息 (格式,大小...)

    /*
     數據源
     寬
     高
     每個像素佔用多大內存(一個像素點由RGB組成。R 8位 G 8位 B 8位,佔用內存:3字節)
     每一行佔用的內存( m.step[0] 第一行多大)
     顏色空間
     位圖信息(是否需要透明度)

     kCGImageAlphaNoneSkipLast 不需要透明度
     kCGBitmapByteOrderDefault 默認排版
     */

    CGContextRef cntextRef =  CGBitmapContextCreate(m.data,
                                           width,
                                           height,
                                           8, 
                                           m.step[0],
                                           colorSpaceRef,
                                                          kCGImageAlphaNoneSkipLast|kCGBitmapByteOrderDefault);

    CGContextDrawImage(cntextRef, CGRectMake(0, 0, width, height), image.CGImage);

    CGContextRelease(cntextRef);
    CGColorSpaceRelease(colorSpaceRef);
}

探究MatToUIImage的實現

UIImage* WKMatToUIImage(const cv::Mat& image){


    //第一步:將OpenCV圖片 -> NSData
    NSData *data  = [NSData dataWithBytes:image.data length:image.elemSize() * image.total()];

    //第二步:創建顏色空間
    CGColorSpaceRef colorSpaceRef ;


    if (image.elemSize() == 1) {
        //灰色顏色空間
        colorSpaceRef = CGColorSpaceCreateDeviceGray();
    }else{
        //彩色顏色空間
        colorSpaceRef = CGColorSpaceCreateDeviceRGB();
    }

    //第三步:創建數據集合(C/C++圖片)
    CGDataProviderRef providerRef = CGDataProviderCreateWithCFData((CFDataRef)data);

    //第四步:創建一張圖片

    /*
     圖片寬
     圖片高
     每個像素佔用多大內存(一個像素點由RGB組成。R 8位 G 8位 B 8位,佔用內存:3字節)
     每一個像素佔用內存大小
     每一行佔用的內存大小( m.step[0] 第一行多大)
     顏色空間
     說白了就是圖片是否需要透明度
     數據集合
     數據解碼器
     抗鋸齒
     圖片渲染器
     */
    CGImageRef imageRef =  CGImageCreate(image.cols,
                  image.rows,
                  8,
                  8*image.elemSize(),
                  image.step[0],
                  colorSpaceRef,
                  kCGImageAlphaNone | kCGBitmapByteOrderDefault,
                  providerRef,
                  NULL,
                  false,
                  kCGRenderingIntentDefault);

    CGDataProviderRelease(providerRef);
    CGColorSpaceRelease(colorSpaceRef);

    UIImage *im =  [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);
    return im;
}
發佈了182 篇原創文章 · 獲贊 35 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章