OpenCV初体验,给图片打码

提到OpenCV,相信大多数人都听说过,应用领域非常广泛,使用C++开发,天生具有跨平台的优势,我们学习一次,就可以在各个平台使用,这个还是很具有诱惑力的。
本文主要记录我第一次使用OpenCV,在iOS开发平台上面搭建开发环境,并且实现一个简单的马赛克功能
开发环境:Swift4、XCode 9.0

1、什么是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

2、难点,思路
* 由于我们使用的是Swift,由于目前还不能在Swift中使用C++的类,所以我们得想一个方法,在Swift中调用C++的类

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

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

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

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

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

4、开动工程
4.1、搭建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++环境是否搭建成功

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

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

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

4.2、导入OpenCV动态库

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

4.3、实现马赛克函数

下面进入正题

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

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

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

 // 倒入OpenCV框架 最好放在Foundation.h UIKit.h之前
// 核心头文件
#import <opencv2/opencv.hpp>
// 对iOS支持
#import <opencv2/imgcodecs/ios.h>
// 倒入矩阵帮助类
#import <opencv2/highgui.hpp>
#import <opencv2/core/types.hpp> #import "MyUntil.h"
#import <iostream>
using namespace std;
using namespace cv;

2.实现马赛克函数

 +(UIImage *)opencvimage:(UIImage *)image level:(int)level{
// 实现功能
// 第一步:将iOS图片->OpenCV图片(Mat矩阵)
Mat mat_image_src;
UIImageToMat(image, mat_image_src); // 第二步:确定高度
int width = mat_image_src.cols;
int height = mat_image_src.rows; // 在OpenCV里面,必须要先把ARGB的颜色空间转换成RGB,否则处理会失败
// ARGB->RGB
Mat mat_image_dst;
cvtColor(mat_image_src, mat_image_dst, CV_RGBA2BGR, );
// 为了不影响原始图片,克隆一张保存
Mat mat_image_clone = mat_image_dst.clone(); //第三步:马赛克处理
int xMax = width - level;
int yMax = height - level;
for (int y = ; y <= yMax; y += level) {
for (int x = ; x <= xMax; x += level) {
// 让整个巨型区域颜色值保持一致
// mat_image_clone.at<Vec3d>(i, j)->像素点(颜色值组成->多个)->ARGB->数组
// mat_image_clone.at<Vec3d>(i, j)[0]->R值
// mat_image_clone.at<Vec3d>(i, j)[1]->G值
// mat_image_clone.at<Vec3d>(i, j)[2]->B值
Scalar scalar = Scalar(mat_image_clone.at<Vec3b>(y, x)[],
mat_image_clone.at<Vec3b>(y, x)[],
mat_image_clone.at<Vec3b>(y, x)[]);
//取出要处理的矩形区域
Rect2i mosaicRect = Rect2i(x, y, level, level);
Mat roi = mat_image_dst(mosaicRect); //将前面处理的小区域拷贝到要处理的区域
//CV_8UC3的含义
//CV_:表示框架命名空间
//8表示:32位色->ARGB->8位 = 1字节 -> 4个字节
//U: 无符号类型
//C分析:char类型
//3表示:3个通道->RGB
Mat roiCopy = Mat(mosaicRect.size(), CV_8UC3, scalar);
roiCopy.copyTo(roi); }
}
// 第四步:将OpenCV图片->iOS图片
return MatToUIImage(mat_image_dst);
}

4.4、在swift中调用马赛克函数

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

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

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

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

3.效果如下

5、后记

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

Swift与C++混编 OpenCV初体验 图片打码~的更多相关文章

  1. Swift和Objective-C混编注意事项

    前言 Swift已推出数年,与Objective-C相比Swift的语言机制及使用简易程度上更接地气,大大降低了iOS入门门槛.当然这对新入行的童鞋没来讲,的确算是福音,但对于整个iOS编程从业者来讲 ...

  2. Swift和Objective-C混编注意

    前言 Swift已推出数年,与Objective-C相比Swift的语言机制及使用简易程度上更接地气,大大降低了iOS入门门槛.当然这对新入行的童鞋们来讲,的确算是福音,但对于整个iOS编程从业者来讲 ...

  3. swift:Optional Type 、Swift和Objective-C混编的讲解

    ❤️❤️❤️swift中的Optional Type的?和!含义:其实就是一个装包和拆包的过程 optional的含义: Optional事实上是一个枚举类型,Optional包含None和Some两 ...

  4. Swift和Objective-C混编的注意啦

    文/仁伯安(授权) 原文链接:http://www.jianshu.com/p/2ed48b954612 前言 Swift已推出数年,与Objective-C相比Swift的语言机制及使用简易程度上更 ...

  5. swift c++ oc 混编

    http://www.tuicool.com/articles/QZNrErM iOS 里面 Swift与Objective-C混编,Swift与C++混编的一些比较 时间 2015-03-23 23 ...

  6. iOS开发之swift与OC混编出现的坑,oc中不能对swift的代理进行调用,不能访问swift中的代理,swift中的回调方法

    1. Swift与oc混编译具体怎么实现,这儿我就不重复讲出了,网上有大把的人讲解. 2. 在swift与OC混编的编译环境下, oc类不能访问swift创建类中的代理? 解决方法如下: 在代理的头部 ...

  7. iOS8开发~Swift(五)Swift与OC混编

    一.概要 首先看<The Swift Programming Language>中提到"Swift's compatibility with Objective-C lets y ...

  8. 使用Pods中使用Swift和Objective-C混编-编译不通过的原因

    iOS开发#使用Pods中使用Swift和Objective-C混编-编译不通过的原因-ld: symbol(s) not found for architecture arm64 问题基本描述 在P ...

  9. iOS 里面 Swift与Objective-C混编,Swift与C++混编的一些比较

        即使你尽量用Swift编写iOS程序,难免会遇到部分算法是用C++语言编写的.那你只能去问问”度娘“或“狗哥”怎么用Swift调用C++算法.   一,C,C++, Objective-C,S ...

随机推荐

  1. centos命令安装

    1.解决ifconfig命令失效:需要安装net-tools工具 yum install net-tools 2.免密码登录 (1)通过命令,产生公钥信息 ssh-keygen -t rsa 如果提示 ...

  2. NB学校的NB课程的NB教材——CSAPP

    CMU是全美以至全球公认的CS最猛的大学之一,没办法,作为CS的发源地,再加上三位神一样的人先后在此任教:Alan Perlis(CS它祖宗+第一届Turing奖获得者).Allen Newell(A ...

  3. .Net ABP 框架 service 无法访问

    最近在看ABP框架,按照文档写好service后,怎么也访问不到,后来发现,忘记把service类设置为public的了! 不写public ABP框架就不能将这个service映射为controll ...

  4. No grammar constraints (DTD or XML Schema) referenced in the document.

    问题描述 web.xml 使用 Servlet4.0 版本,No grammar constraints (DTD or XML Schema) referenced in the document. ...

  5. 主席树套树状数组——带修区间第k大zoj2112

    主席树带修第k大 https://www.cnblogs.com/Empress/p/4659824.html 讲的非常好的博客 首先按静态第k大建立起一组权值线段树(主席树) 然后现在要将第i个值从 ...

  6. struts2-第一章-基础用法3

    一,结果类型配置 在之前servlet学习中,知道网页页面路径跳转有两种方式,内部跳转(请求转发)和外部跳转(重定向),两者的区别,内部跳转浏览器地址不会变化 可以保存上一次请求的数据 外部跳转浏览器 ...

  7. 4.2 Oracle Dataguard failover 操作步骤

    在11g里面,Oracle认为最理想的情况是,虽然Oracle数据库不能打开,但是可以启动到 mount状态.Mount状态之所以重要,就在于如果可以到这个阶段,控制文件control_file就可以 ...

  8. C语言作业2

    一.实验目的与要求 1.if语句的应用 ●掌握C语言的逻辑运算和关系运算的规则 ●学会正确的使用关系表达式和逻辑表达式 ●掌握if-else语句的使用方法 2.switch/case语句的应用 ●   ...

  9. tomcat配置文件及性能优化

    收藏两个地址 配置文件: https://www.cnblogs.com/sunshine-1/p/8990044.html 性能调优: https://www.cnblogs.com/zhuawan ...

  10. About The Order of The Declarations And Definition When Making a Member Function a Friend.关于使类成员成为另一个类友元函数的声明顺序和定义。

    If only member function clear of WindowMgr is a friend of Screen, there are some points need to note ...