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 
//支持iOS平台
#import 

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 
#import 
#import 
#import 
#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;
}

你可能感兴趣的:(IT)