客户端图片智能裁剪

iOS客户端图片智能裁剪

?

概述

所谓智能裁剪其实就是按照指定尺寸裁剪或显示出包含图片核心特征的区域,目前很多智能裁剪都是在服务器端做的,在客户端需要访问时直接裁剪放到Redis或者提前裁剪好以备访问。但是找了一圈直接在iOS客户端进行裁剪的库还不多,或者使用成本比较高,不能即拿即用。但是有时候客户端可能并非直接从服务器端获取数据而是读取相册数据,不可能先把图片存放到服务器端裁剪然后再拿来用,考虑到这种场景也不再少数,因此就有必要思考一套客户端智能裁剪的方案。

免费好用的智能裁剪库

最近两天整理了之前开发一个软件过程中自己开发的一个客户端智能裁剪库供有需要的同学使用,当然后面有时间的话会整理开源。说是库本质就是一套算法而已,但是在编写这套算法期间也参考评估过很多已有或者想要使用而没有使用的解决方案。

首先说一下目前在网上比较容易找到的一些库存在的问题:

  • 没有iOS对应的版本,集成起来极其复杂,之前为了用一个不错的库甚至在iOS调用Python库
  • 速度慢,生成一张智能裁剪后的图片需要1s左右,不再可容忍范围之内
  • 人像识别不准确,图片中占比较小的人脸识别不出来,甚至有可能出现误识别(这个其实比识别不出来问题还大)
  • 基于专利收费算法实现(例如使用SRUF),不仅开发者使用起来要引用大量的库而且有收费风险
  • 集成比较麻烦,使用起来光配置环境就要摆弄半天,还不一定能成功

当然,事实上在探索过程中也走了不少的弯路,遇到的问题要比上面多得多,包括有些算法只能裁剪横图,对于宽高比较小的竖图支持很差,又或者引入大量的库造成app本身大小直线上升等等。。。因此这也就是为什么自己要开发一个新的库SmartCrop.framework而不是基于现有库来做的原因。

那么SmartCrop.framework智能裁剪库又有什么特点呢:

  • 跨平台,当然既然作为一个iOS开发者一定要包含iOS版本(尽管此文中只提供了iOS版本,不过其实这个库本身基于c++实现,天然具有跨平台特性,后续有时间也会整理其他平台的版本)
  • 速度快,几乎可以做到实时裁剪??(当然这个比较理想,不过测试中本文提供的库对于裁剪1000px以上的大图iPhone X上已经可以做到0.1s以下,后续会持续优化)
  • 精准的人脸识别,基于神经网络进行识别,让人像识别更加精准迅速(尽管需要一个训练好的模型,不过模型本身并不大)
  • 免费、好用,没有专利之争、集成迅速,按照步骤一分钟之内完成

当然,SmartCrop.framework也并非完美,这个库本身基于OpenCV的c++算法实现,综合了很多算法实现了特征点检测,这也就是说App需要集成opencv2.framework。另外算法本身还有优化空间,特别是特征点检测中对于色差分辨不是特变明显的图片裁剪精准度会有下降,后面也会进一步优化,不过对比了几个线上已有的库来说精准度应该要比这些库提高不少,毕竟再好的智能裁剪也是基于某些特征,和人为的意识还有不少差别。

和其他库的对比

这里选取了之前使用过的一个Python库作为对比,在iOS中运行10张1000px左右的图片裁剪需要15s左右,这也是之前app中使用的实际结果。当然这其中有间接调用Python的成本,以至于后来直接测试了它的Android版本,大概耗时10s。下面是10张图的裁剪结果对比,为了方便看出裁剪效果使用了横图裁剪成竖图的对比,而图片选择部分尽量包括了人像和非人像图片,视频中每组图有三张,分别是原图、第三方库裁剪后的效果、SmartCrop.framework裁剪后的效果:

当然从视频不难看出,SmartCrop.framework人像裁剪相当精准,第1、3、4中的人脸第三方库没有识别出来,在非人脸识别的图片中第6张树的裁剪不理想。当然SmartCrop.framework也不是百分百完美,最后一张猫的图片裁剪效果不如第三方库,因为除了猫之外将右侧的树识别成了关键特征位置。当然也会发现第2张图片中两个库都识别出了多个人脸,也都在有限的宽度内裁剪除了两个人,但是位置不同,这个和裁剪策略和特征分析算法有关。

简单的使用方法

引入SmartCrop.framework只需要从这里下载SmartCropDemo,找到其中的SmartCrop.framework直接将此库拖拽到自己的项目中,在Xcode的Embedded Binaries中添加SmartCrop.framework即可(或者Build Phase的Copy File中添加SmartCrop.framework),然后在Linked Frameworks and Libraries中添加libc++.tbd,最后将opencv2.framework拖拽到项目中即可(注意由于github文件大小限制,这个库没有直接在code中提供,可以到这里直接下载解压使用)。

SmartCrop.framework在开发的过程中尽量的简化,通篇只有一个类SmartCropper,此类也只有两个方法并且以ObjC静态方法出现:

+(UIImage *)cropImage:(UIImage *)image size:(CGSize)size;
+(CGRect)cropRectWithImage:(UIImage *)image size:(CGSize)size;

而通常情况下直接调用最上面的一个方法即可满足裁剪需求,那么为什么还要提供第二个API呢?原因是有些情况下并不想裁剪图片而只想找到图片的核心区域,SmartCrop.framework也已经做好了。

当然Swift中使用也仅仅需要一个bridge header而已,然后调用SmartCropper.cropImage(image, size:size)即完成了所有裁剪操作。

SmartCrop裁剪效果:

原图

?

SmartCrop裁剪后

?

原图

?

SmartCrop裁剪后

?

原图

?

SmartCrop裁剪后

?

性能究竟怎么样

Demo界面:

?

为了验证性能做了一个上面提到的demo,在主界面选择Photo Library可以实时预览相册中的图片智能裁剪后的效果,按住主界面可以对比原图;点击Browser是对于前面提到的10张测试图的实时预览,可以从下面的展示效果看到几乎是实时生成的,没有太多卡顿,上面说的1000px以上的图片,低于0.1s可以完成裁剪应该不会太夸张,当然实际使用中不会每张图都实时显示实时生成,可以提前存储,加上预加载可以做到0卡顿效果。

运行效果如下:

还要说一下,SmartCrop.framework本身基于OpenCV 3.4.4进行开发,理论上可以向下兼容几个版本,但是太旧的api可能无法使用,为了获得更稳定的效果建议直接使用3.4.4版本。另外文中所有演示图片来源于互联网,仅作为演示学习之用,如存在版权问题请联系本人([email protected]),即刻下线。

原文地址:https://www.cnblogs.com/kenshincui/p/ke-hu-duan-tu-pian-zhi-neng-cai-jian.html

时间: 2024-11-09 19:13:20

客户端图片智能裁剪的相关文章

通过Nginx访问FastDFS文件系统并进行图片文件裁剪的性能测试和分析

前段时间公司的分布式图片文件系统(FastDFS)做了图片裁剪和缩放功能,并把缩放计算和FastDFS做了解耦分离,前端用虚拟机作为图片文件缩放的访问代理层(Nginx Proxy),后端使用nginx直接访问FastDFS的文件系统.以下是测试和分析过程. 1测试场景 为了测试解耦后的图片读取并发和分析系统瓶颈,我们在内网中搭建了一个测试环境.以下是测试环境的网络的物理架构图: 上图中: NginxProxy:CPU解耦后的图片裁剪代理服务器 Storage:图片的存储服务器 ab:图片访问的

仿优酷Android客户端图片左右滑动(自动滑动)

最终效果: 页面布局main.xml: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent

Qt 制作透明背景图片与裁剪图片(很实用)

这两天想做一个五子棋游戏,想从零开始自己绘制各种图片素材,将经验心得整理如下. 制作透明背景图片: void MyPainter::DrawKit() { QImage image(30, 30, QImage::Format_ARGB32); memset(image.bits(), 0x00, image.byteCount()); // 绘制图片 QPainter painter(&image); painter.setPen(QPen(Qt::red, 2, Qt::SolidLine)

高仿优酷Android客户端图片左右滑动(自动切换)

本例是用ViewPager去做的实现,支持自动滑动和手动滑动,不仅优酷网,实际上有很多商城和门户网站都有类似的实现: 具体思路: 1. 工程中需要添加android-support-v4.jar,才能使用ViewPager控件. 2. 图片的自动切换: 可使用Timer或者ScheduledExecutorService,这个有多重方式可以实现. 同时要切换底部的dots(园点) 3.Handler+Message机制更新UI,这个相信大家都很熟练,不再描述 4. 实现的一些细节:注意本例中的优

Web Service(1):用Web Service实现客户端图片上传到网站

由于项目需要,通过本地客户端,把图片上传到网站.通过webservice. 这是客户端代码: 1 private void btnimg_Click(object sender, EventArgs e) 2 { 3 this.yanzheng(); 4 mylocalhost.MySoapHeader myheader = new mylocalhost.MySoapHeader();///这是soapheader 5 mylocalhost.MyWebService myService =

android选择本地图片并裁剪

本文使用Android原生的选择和裁剪功能.下面是代码: public class PickAndCropActivity extends AppCompatActivity implements View.OnClickListener { public static final int REQUEST_CODE_PICK_IMG = 1; public static final int REQUEST_CODE_CROP_IMG = 2; /** * ImageView展示选择的图片和裁剪得

android开发——从相冊中选择图片不裁剪

转载请注明出处:http://blog.csdn.net/zhoubin1992/article/details/46864777 问题: 在郭神的第一行代码中,第8章的从相冊中选择图片这块,从相冊选一张裁剪后显示到屏幕.可是执行后会发现从相冊选了图片后.没有弹出裁剪的界面,直接返回. 方案: 查找原因时,发现SD卡路径下的output_image.jpg是一个0字节文件.所以 这张图片没有生成.然后我认为是向系统发送选择照片的意图出了问题.我好奇的查看了下系统的图库应用(gallery)源代码

Android笔记之 图片自由裁剪

前言--项目中需要用到对用户头像的裁剪和上传功能.关于裁剪,一开始是想自己来做,但是觉得这个东西应该谷歌有开发吧,于是一搜索官方文档,果然有.于是,就果断无耻地用了Android自带有关于照片的自由裁剪.因为时间太紧,虽然不太华丽,但是胜在能用,节省时间嘛. 具体是通过 Intent的action来实现的. 关键代码如下: public void imageCut(Uri uri) { Intent intent = new Intent("com.android.camera.action.C

java可以实现对图片的裁剪功能么

原文:java可以实现对图片的裁剪功能么 代码下载地址:http://www.zuidaima.com/share/1550463233002496.htm 想对原图进行裁剪,比如对用户上传的头像进行裁剪. 原图: 运行效果图: java可以实现对图片的裁剪功能么