Swift与C++混编 OpenCV初体验 图片打码~
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初体验 图片打码~的更多相关文章
- Swift和Objective-C混编注意事项
前言 Swift已推出数年,与Objective-C相比Swift的语言机制及使用简易程度上更接地气,大大降低了iOS入门门槛.当然这对新入行的童鞋没来讲,的确算是福音,但对于整个iOS编程从业者来讲 ...
- Swift和Objective-C混编注意
前言 Swift已推出数年,与Objective-C相比Swift的语言机制及使用简易程度上更接地气,大大降低了iOS入门门槛.当然这对新入行的童鞋们来讲,的确算是福音,但对于整个iOS编程从业者来讲 ...
- swift:Optional Type 、Swift和Objective-C混编的讲解
❤️❤️❤️swift中的Optional Type的?和!含义:其实就是一个装包和拆包的过程 optional的含义: Optional事实上是一个枚举类型,Optional包含None和Some两 ...
- Swift和Objective-C混编的注意啦
文/仁伯安(授权) 原文链接:http://www.jianshu.com/p/2ed48b954612 前言 Swift已推出数年,与Objective-C相比Swift的语言机制及使用简易程度上更 ...
- swift c++ oc 混编
http://www.tuicool.com/articles/QZNrErM iOS 里面 Swift与Objective-C混编,Swift与C++混编的一些比较 时间 2015-03-23 23 ...
- iOS开发之swift与OC混编出现的坑,oc中不能对swift的代理进行调用,不能访问swift中的代理,swift中的回调方法
1. Swift与oc混编译具体怎么实现,这儿我就不重复讲出了,网上有大把的人讲解. 2. 在swift与OC混编的编译环境下, oc类不能访问swift创建类中的代理? 解决方法如下: 在代理的头部 ...
- iOS8开发~Swift(五)Swift与OC混编
一.概要 首先看<The Swift Programming Language>中提到"Swift's compatibility with Objective-C lets y ...
- 使用Pods中使用Swift和Objective-C混编-编译不通过的原因
iOS开发#使用Pods中使用Swift和Objective-C混编-编译不通过的原因-ld: symbol(s) not found for architecture arm64 问题基本描述 在P ...
- iOS 里面 Swift与Objective-C混编,Swift与C++混编的一些比较
即使你尽量用Swift编写iOS程序,难免会遇到部分算法是用C++语言编写的.那你只能去问问”度娘“或“狗哥”怎么用Swift调用C++算法. 一,C,C++, Objective-C,S ...
随机推荐
- Java虚拟机学习笔记——JVM垃圾回收机制
Java虚拟机学习笔记——JVM垃圾回收机制 Java垃圾回收基于虚拟机的自动内存管理机制,我们不需要为每一个对象进行释放内存,不容易发生内存泄漏和内存溢出问题. 但是自动内存管理机制不是万能药,我们 ...
- 十 LVS 负载均衡
回顾nginx 反向代理负载均衡 负载均衡的妙用 负载均衡(Load Balance)集群提供了一种廉价.有效.透明的方法, 来扩展网络设备和服务器的负载.带宽.增加吞吐量.加强网络数据处理能力. 提 ...
- python3与mysql交互
1.安装pymysql模块 pip3 install pymysql3 2.pymysql的简单使用: # /usr/bin/env python3 import pymysql class Mysq ...
- 【玩转开源】BananaPi R2 —— 第二篇 Openwrt 网口配置分析
上次和大家分享了如何烧录和安装Openwrt到BananaPi R2,运行Openwrt的R2目前就具备路由器的功能了,这次我们来看看R2运行Openwrt的性能如何,同时也会讲解一些常用的网络知识. ...
- 创建自己的library类库包并使用webpack4.x打包发布到npm
创建自己的library类库包并使用webpack4.x打包发布到npm 我们在开发过程中,可能经常要使用第三方类库,比如jquery.lodash等.我们通过npm,下载安装完之后,就可以使用了,简 ...
- haproxy4-acl配置
访问控制设定: 匹配后可进行那些操作: Use _backend : 当符合条件时使用特定的backend后端, Use_backend <backend> [{if | unles ...
- spring boot 项目打成war包部署到服务器
这是spring boot学习的第二篇了,在上一篇已经整合了spring boot项目了,如果还有小伙伴没有看得可以先去看第一篇 基础整合spring boot项目 到这里的小伙伴应该都是会整合基本的 ...
- 微软开源大规模数据处理项目 Data Accelerator
微软开源了一个原为内部使用的大规模数据处理项目 Data Accelerator.自 2017 年开发以来,该项目已经大规模应用在各种微软产品工作管道上. 据微软官方开源博客介绍,Data Accel ...
- 浅谈Java线程安全
浅谈Java线程安全 - - 2019-04-25 17:37:28 线程安全 Java中的线程安全 按照线程安全的安全程序由强至弱来排序,我们可以将Java语言中各种操作共享的数据分为以下五类 ...
- 日常报错记录4:ssh工程复制粘贴顺序。
今天要复制一个项目. 久久不能如愿. web.xml里面老是有红的,比如applicationContext.xml字段. 它应该是web.xml要找它,于是,我先把applicationContex ...