本文欢迎转载,转载请注明出处:

https://my.oschina.net/227/blog/796485

前言

在开发项目中,有的时候需要用户上传照片到后台服务器审核,如果照片不清晰的话,那就得用户重新上传。有没有办法在上传之前就判断照片是否清晰呢?为了解决这个问题,我们可以用到一个图像处理框架“openCV”。"openCV"非常强大,我们这里只是用了它的很小一点点。

openCV官网:http://opencv.org/

思路:

如果读者了解信号处理,就会知道最直接的方法就是计算图片的快速傅里叶变换,然后查看高低频的分布。如果图片有少量的高频成分,那么该图片就可以被认为是模糊的。然而,区分高频量多少的具体阈值却是十分困难的,不恰当的阈值将会导致极差的结果。

查阅了相关资料,了解到了目前比较好的方法是“拉普拉斯方差算法”。

简单来说就是只需要将图片中的某一通道(一般用灰度值)用的拉普拉斯掩模做卷积运算,得到的像素矩阵,在把矩阵中的数值求方差。如果图像越清晰,边缘越锐利,像素之间的差别越大,则方差越大。反之图像模糊,边缘之间像素差别小,那方差越小。

步骤一:

去openCV官网下载给iOS用的“opencv2.framework”包,并导入xcode工程中

地址: (输入浏览器回车后过几秒钟就会自动下载)

https://sourceforge.net/projects/opencvlibrary/files/opencv-ios/2.4.13/opencv2.framework.zip/download

步骤二:

在需要使用的地方添加头文件“#import <opencv2/opencv.hpp>”,并且把当前的“.m”的objective-c文件改成“.mm”的objc/c++文件,或者在PCH里添加头文件,注意在PCH里添加的时候要如下所示

#ifdef __cplusplus
#import <opencv2/opencv.hpp>
#endif

这样做的原因是openCV的库是c++文件,加入这段表明这个库只有在c++文件导入,作用和“#ifdef __OBJC__”的效果类似。上面说改成“.mm”也是这个原因。

步骤三:

把UIImage图像转换成cvMat类型,让openCV可以处理

+ (cv::Mat)cvMatFromUIImage:(UIImage *)image
{CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage);CGFloat cols = image.size.width;CGFloat rows = image.size.height;cv::Mat cvMat(rows, cols, CV_8UC4); // 8 bits per component, 4 channels (color channels + alpha)CGContextRef contextRef = CGBitmapContextCreate(cvMat.data,                 // Pointer to  datacols,                       // Width of bitmaprows,                       // Height of bitmap8,                          // Bits per componentcvMat.step[0],              // Bytes per rowcolorSpace,                 // ColorspacekCGImageAlphaNoneSkipLast |kCGBitmapByteOrderDefault); // Bitmap info flagsCGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), image.CGImage);CGContextRelease(contextRef);return cvMat;
}+ (UIImage *)UIImageFromCVMat:(cv::Mat)cvMat
{NSData *data = [NSData dataWithBytes:cvMat.data length:cvMat.elemSize()*cvMat.total()];CGColorSpaceRef colorSpace;if (cvMat.elemSize() == 1) {//可以根据这个决定使用哪种colorSpace = CGColorSpaceCreateDeviceGray();} else {colorSpace = CGColorSpaceCreateDeviceRGB();}CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);// Creating CGImage from cv::MatCGImageRef imageRef = CGImageCreate(cvMat.cols,                                 //widthcvMat.rows,                                 //height8,                                          //bits per component8 * cvMat.elemSize(),                       //bits per pixelcvMat.step[0],                            //bytesPerRowcolorSpace,                                 //colorspacekCGImageAlphaNone|kCGBitmapByteOrderDefault,// bitmap infoprovider,                                   //CGDataProviderRefNULL,                                       //decodefalse,                                      //should interpolatekCGRenderingIntentDefault                   //intent);// Getting UIImage from CGImageUIImage *finalImage = [UIImage imageWithCGImage:imageRef];CGImageRelease(imageRef);CGDataProviderRelease(provider);CGColorSpaceRelease(colorSpace);return finalImage;
}

步骤四:

进行计算,代码如下

//方差参考值
const double delta = 100;+ (BOOL) whetherTheImageBlurry:(UIImage*)image{unsigned char *data;int height,width,step;int Iij;double Iave = 0, Idelta = 0;cv::Mat mat = [OpenCVExtension cvMatFromUIImage:image];if(!mat.empty()){cv::Mat gray;cv::Mat outGray;// 将图像转换为灰度显示cv::cvtColor(mat,gray,CV_RGB2GRAY);// 用openCV的Laplacian函数做灰度图做拉普拉斯计算,得到outGraycv::Laplacian(gray, outGray, gray.depth());//将得到的outGray转化为图片信息类IplImageIplImage ipl_image(outGray);data   = (uchar*)ipl_image.imageData;  //图片像素信息height = ipl_image.height;             //图片像素高度width  = ipl_image.width;              //图片像素宽度step   = ipl_image.widthStep;          //排列的图像行大小,以字节为单位for(int i=0;i<height;i++){    //求方差for(int j=0;j<width;j++){Iij   = (int) data[i*width+j];Idelta    = Idelta + (Iij-Iave)*(Iij-Iave);}}Idelta = Idelta/(width*height);std::cout<<"矩阵方差为:"<<Idelta<<std::endl;}return (Idelta > delta) ? YES : NO;
}

在实验中发现,当方差大于100的时候,图片是清晰的。

这样我们就得到了识别图像清晰度的方法。

代码地址

本篇文章代码的例子,可以登录github搜索TTImageBlurryEvaluation查看。

或者直接登录:https://github.com/coco227/TTImageBlurryEvaluation

参考文献:

《用 Opencv 和 Python 对汪星人做模糊检测》(http://python.jobbole.com/83702/)

《Analysis of focus measure operators for shape-from-focus》[2013 Pertuz et al.]

转载于:https://my.oschina.net/227/blog/796485

iOS 中如何识别图片清晰度相关推荐

  1. iOS中常见的图片压缩方法

    1.对图片进行压缩,iOS自带的API提供了函数对图片进行压缩 //两种方法将图片按不同的格式压缩NSData *imageData = UIImageJPEGRepresentation(info[ ...

  2. IOS中设置圆角图片

    2019独角兽企业重金招聘Python工程师标准>>> ##iOS设置圆角的三种方式 <hr/> 1 方法一 通过设置layer的属性 UIImageView *imag ...

  3. iOS中怎样给图片右下角打水印

    1.首先对自带的UIImage进行分类(Category) .h文件如下 // // UIImage+Mo.h // 图片水印 // // Created by MoPellet on 15/4/22 ...

  4. 在vue项目中 使用swiper轮播图的关于 在ios中图片白边闪屏踩坑记录

    场景描述: 近日,接到一个需求,改善APP首页的布局,需要在顶部添加一个可滚动的栏目导航,以切换栏目然后切换栏目内容类似于唯品会目前的切换效果.如下图 问题描述: 在切换顶部栏目的时候,下面内容页的b ...

  5. 使用脚本删除ios工程中未使用图片

    使用脚本删除ios工程中未使用图片 最近在读唐巧大神的<iOS开发进阶>,学到了一个大招:使用脚本删除ios中未使用的图片(纸书上有点小问题,参考github上的issue:使用脚本删除i ...

  6. IOS手机长按图片无法弹出识别二维码

    在 h5 中长按图片二维码会弹出识别结果,有保存.分享.以及二维码中包含的跳转链接等,会引导我们点击跳转.当小程序中使用 web-view 嵌套时,该图片亦能长按识别. 以上功能在安卓上没有问题,但是 ...

  7. Python识别图片的清晰度

    说一下,真实煎熬了一下午,为了找Python 如何识别一张图片的人脸清晰度,真实好心累啊.废话不多说,进入主题. import cv2 #导入cv2def getImageVar(imgPath):i ...

  8. iOS中如何优化Cell中图片的下载性能

    在iOS开发中使用最为常见的是UITableView,其中UITabelViewCell中下载图片,会影响用户下拉刷新UI,导致卡顿,用户体验不好,在这篇blog中,我将以一个例子来说明如何优化UIT ...

  9. JS 图片压缩上传并在iOS中矫正方向

    JS 图片压缩上传并在iOS中矫正方向 最近在项目中,用到图片上传.如果不进行压缩再上传的话,动辄34兆的图片,上传起来会相当漫长.还有一点就是,在iOS中所拍摄的图片在本地显示是没有问题的,但是上传 ...

最新文章

  1. python smtp模块发送邮件
  2. Oracle KFED 和 KFOD 工具说明
  3. LeetCode 292 Nim Game
  4. Tecplot如何导入多个DAT文件后激活solution time按钮
  5. jinja2模板注入_Flask jinja2 模板注入思路总结
  6. Delphi高手突破学习笔记三
  7. 流类库——输入输出流控制详解
  8. html5按钮组水平均分,ichart.js绘制虚线、平均分虚线效果的实现代码_javascript技巧...
  9. 计算机网络谢希仁课后答案详解+计算机网络释疑与习题解答PDF+各章重点题目
  10. 如何删除管理员也无法删除的文件夹
  11. HDU 2209 翻纸牌游戏 By Assassin 模拟
  12. 在网吧想免费上网又何不自己动动手呢?
  13. 小程序长按识别公众号二维码-已实现
  14. 【Python学习记录】Numpy广播机制(broadcast)
  15. 面试题--5个数能组成多少中不同的二叉搜索树的结构--卡特兰数
  16. 文本处理---行未添加逗号和引号
  17. C语言编程>第二十八周 ① 多功能进制转换器设计
  18. Dreamweaver CS3设计的缺陷
  19. Exchange Server 2010 邮件发送延迟排错
  20. FC-AE监控卡应用方案

热门文章

  1. 减脂期必看,13种怎么吃也不会胖的低热量食物
  2. Java面向对象笔记 • 【第10章 Swing编程初级应用】
  3. 含源码 | C语言做可写入文件的账号密码登录系统
  4. 【100%通过率】华为OD机试真题 C++ 实现【最接近最大输出功率的设备 /查找充电设备组合】
  5. appinventor认识
  6. Web Service与Rest API
  7. CIC-IDS-2018数据集分析笔记
  8. 政策解读│软件产业企业所得税优惠政策介绍(2022年版)
  9. 北航计算机学院直博多少年,北航硕博连读需要几年
  10. 安大计算机学院ACM,安徽大学计算机科学与技术学院硕士生导师:张磊