Swift与C++混编 OpenCV初体验 图片打码~

OpenCV初体验,给图片打码html

提到OpenCV,相信大多数人都据说过,应用领域很是普遍,使用C++开发,天生具备跨平台的优点,咱们学习一次,就能够在各个平台使用,这个仍是很具备诱惑力的。
本文主要记录我第一次使用OpenCV,在iOS开发平台上面搭建开发环境,而且实现一个简单的马赛克功能
开发环境:Swift四、XCode 9.0
ios

 

一、什么是OpenCV?
* 由英特尔公司于1999年发起并参与开发,至今已有18年历史

* OpenCV的全称是Open Source Computer Vision Library

* 是一个跨平台的开源计算机视觉库,可用于开发实时的图像处理、计算机视觉以及模式识别程序。

* 支持C/C++、Java、Python、OC、Swift、Ruby等等语言

* 支持Windows、 Android、 Maemo、 FreeBSD、 OpenBSD、 iOS、 Linux和Mac OS
c++

 

二、难点,思路
* 因为咱们使用的是Swift,因为目前还不能在Swift中使用C++的类,因此咱们得想一个方法,在Swift中调用C++的类

* 其实方法很简单,Swift天生具备跟Objective-C++混编的能力,而Objective-C++里面是能够直接使用C++的类的,上面的问题也就解决了。
swift

 

 

三、马赛克原理
* 其实把图片的像素密度调低,就能够出现马赛克效果了

* 开始作马赛克以前,须要定一个马赛克的级别,表示原图中每几个像素变成新图里面的一个像素

* 取一小块区域左上角的一个像素,并把这个像素填充到整个小区域内

* 以下图,左边是原图,右边是通过变换以后的图,假设马赛克级别为3,每一个数字表示的区域就是处理的一个小单元,取这个最小单元左上角的颜色,填充整个小单元就OK了vim

 

四、开动工程
4.一、搭建c++和swift混编环境
咱们首先要搭建一个c++的环境,而后才能进行c++的开发,而c++环境能够经过iostream里面的cout函数验证
1.首先,咱们使用xCode新建一个swift的iOS项目
2.在工程内,新建一个Objective-C类,继承NSObject,这里会自动提示咱们是否为项目添加桥接文件,选择添加便可(桥接文件是用来向Swift暴露Objective-C方法的)
3.由于咱们要使用Objective-C++,而把Objective-C转成Objective-C++的方法有两种
* 把.m文件的后缀名改成.mm,xCode就会自动识别咱们的代码为Objective-C++了(xCode会经过后缀名自动识别源文件类型)

* 选中要修改的.m文件,在右边的Type属性修改为:Objective-C++ Source(也能够手动指定源文件类型)
数组

 

 

4.在刚才的.mm文件中,添加一个测试方法,在这里测试一下C++环境是否搭建成功框架

 

1 #import "MyUtil.h"
2 #import  <iostream>
3 using namespace std;
4 @implementation MyUtil
5 + (void)testCpp {
6     cout << "Hello Swift and Cpp" << endl;
7 }

5.在前面xCode自动建立的桥接文件中暴漏咱们的测试方法头文件ide

6.在Swift中调用测试方法,控制台输出 "Hello Swift and Cpp" 就正常了函数

4.二、导入OpenCV动态库学习

在iOS开发中导入OpenCV的库很简单,去官网下载咱们须要的framework拖拽到工程文件或者用cocopods导下载便可

4.三、实现马赛克函数

下面进入正题

1.首先在.mm文件中 ,导入OpenCV的头文件,导入头文件以后代码以下,这里有几个坑要注意:

  • 不要在.h文件中去导入OpenCV的相关头文件,不然会报错,错误信息: Core.hpp header must be compiled as C++,看到这个问题,赶忙把头文件移动到.m文件中去

  • 还有就是OpenCV的头文件最好放在#import以前,不然也会报一个错误: enum { NO, FEATHER, MULTI_BAND }; Expected identifier

 

 1 // 倒入OpenCV框架 最好放在Foundation.h UIKit.h以前
 2 // 核心头文件
 3 #import <opencv2/opencv.hpp>
 4 // 对iOS支持
 5 #import <opencv2/imgcodecs/ios.h>
 6 // 倒入矩阵帮助类
 7 #import <opencv2/highgui.hpp>
 8 #import <opencv2/core/types.hpp>
 9 
10 #import "MyUntil.h"
11 #import <iostream>
12 using namespace std;
13 using namespace cv;

2.实现马赛克函数

 1 +(UIImage *)opencvimage:(UIImage *)image level:(int)level{
 2     // 实现功能
 3     // 第一步:将iOS图片->OpenCV图片(Mat矩阵)
 4     Mat mat_image_src;
 5     UIImageToMat(image, mat_image_src);
 6     
 7     // 第二步:肯定高度
 8     int width = mat_image_src.cols;
 9     int height = mat_image_src.rows;
10     
11     // 在OpenCV里面,必需要先把ARGB的颜色空间转换成RGB,不然处理会失败
12     // ARGB->RGB
13     Mat mat_image_dst;
14     cvtColor(mat_image_src, mat_image_dst, CV_RGBA2BGR, 3);
15     // 为了避免影响原始图片,克隆一张保存
16     Mat mat_image_clone = mat_image_dst.clone();
17     
18     //第三步:马赛克处理
19     int xMax = width - level;
20     int yMax = height - level;
21     for (int y = 0; y <= yMax; y += level) {
22         for (int x = 0; x <= xMax; x += level) {
23             // 让整个巨型区域颜色值保持一致
24             // mat_image_clone.at<Vec3d>(i, j)->像素点(颜色值组成->多个)->ARGB->数组
25             // mat_image_clone.at<Vec3d>(i, j)[0]->R值
26             // mat_image_clone.at<Vec3d>(i, j)[1]->G值
27             // mat_image_clone.at<Vec3d>(i, j)[2]->B值
28             Scalar scalar = Scalar(mat_image_clone.at<Vec3b>(y, x)[0],
29                                    mat_image_clone.at<Vec3b>(y, x)[1],
30                                    mat_image_clone.at<Vec3b>(y, x)[2]);
31             //取出要处理的矩形区域
32             Rect2i mosaicRect = Rect2i(x, y, level, level);
33             Mat roi = mat_image_dst(mosaicRect);
34             
35             //将前面处理的小区域拷贝到要处理的区域
36             //CV_8UC3的含义
37             //CV_:表示框架命名空间
38             //8表示:32位色->ARGB->8位 = 1字节 -> 4个字节
39             //U: 无符号类型
40             //C分析:char类型
41             //3表示:3个通道->RGB
42             Mat roiCopy = Mat(mosaicRect.size(), CV_8UC3, scalar);
43             roiCopy.copyTo(roi);
44             
45         }
46     }
47     // 第四步:将OpenCV图片->iOS图片
48     return MatToUIImage(mat_image_dst);
49 }

4.四、在swift中调用马赛克函数

函数已经实现了,接下来就是在Swift中调用了

 1.为了便于测试,咱们在storyboard中搭一个简单的界面,在按钮中切换马赛克图片和原图,界面以下:

2.在按钮点击事件中调用上面的马赛克函数便可

 1   @IBAction func origImageAction(_ sender: UIButton) {
 2         // 显示原图点击事件
 3         _imageView.image = UIImage.init(named: "bgview")
 4     }
 5     
 6     @IBAction func mosaicImageAction(_ sender: UIButton) {
 7         // 打码
 8         /**
 9          + (UIImage *)opencvimage:(UIImage *)image level:(int)level;
10          实现马赛克功能函数
11          @param image 要处理的图片
12          @param level 马赛克等级,越大越模糊
13          @return 处理好的图片
14          */
15         _imageView.image = MyUntil.opencvimage(_imageView.image, level: 5)
16     }

3.效果以下

五、后记

对OpenCV的探索还将继续,不断积累,贵在点滴~

相关文章
相关标签/搜索