iOS开发-图片离线鉴黄 基于TensorFlow nsfw oc版

  • 前言-基于TensorFlow鉴黄
  • 效果
    • 首先要引入Firebase
    • 鉴黄类的封装
    • OC版本的鉴黄demo
    • Swift版本的鉴黄

前言-基于TensorFlow鉴黄

iOS开发中有需要离线鉴黄的地方而且需要oc版本的,找了很久只有swift版本,虽然可以桥接但是还是喜欢用oc的,所以分享一下自己的鉴黄oc版本。

效果

首先要引入Firebase

  • 注册firebase
  • 注册firebase地址
  • 使用自己的项目Bundle ID在firebase上注册
  • 生成的 GoogleService-Info.plist 导入自己的项目 (注意和Info.plist同级)
  • 使用Cocoapods导入Firebase基础库和鉴黄库
  pod 'Firebase/Auth'# login basepod 'FirebaseMLModelInterpreter', '~> 0.22.0'# 鉴黄

  • 在 AppDelegate.m 中
  • 引入
#import <Firebase/Firebase.h>
  • 在application:didFinishLaunchingWithOptions:函数中写入
[FIRApp configure]; //Firebase 基础配置

鉴黄类的封装

  • BaseIdentifyImageManager.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>NS_ASSUME_NONNULL_BEGIN
/*1.pod 'Firebase/Auth'(导入基础库) pod 'FirebaseMLModelInterpreter', '~> 0.22.0'# 鉴黄2.nsfw.tflite add file3.只能在真机运行*/
typedef void(^CompletIdentifyBlock)(BOOL canShow, CGFloat valid);
@interface BaseIdentifyImageManager : NSObject+ (void)checkImage:(UIImage *)image completBlock:(CompletIdentifyBlock)completBlock;@endNS_ASSUME_NONNULL_END
  • BaseIdentifyImageManager.m
#import "BaseIdentifyImageManager.h"
#if (TARGET_IPHONE_SIMULATOR && TARGET_OS_IPHONE)
#else //真机
#import <FirebaseMLModelInterpreter/FIRModelInputs.h>
#import <FirebaseMLModelInterpreter/FIRModelOutputs.h>
#import <FirebaseMLModelInterpreter/FIRModelInterpreter.h>
#import <FirebaseMLModelInterpreter/FIRCustomLocalModel.h>
#import <FirebaseMLModelInterpreter/FIRModelInputOutputOptions.h>
static CGFloat const kPersentTag = 0.3;
#endif@implementation BaseIdentifyImageManager#pragma mark - manager+ (void)checkImage:(UIImage *)image completBlock:(CompletIdentifyBlock)completBlock {#if (TARGET_IPHONE_SIMULATOR && TARGET_OS_IPHONE)return;
#else //真机
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"int INPUTWIDTH = 224;UIImage *scig = [self _scaleToSize:image size:CGSizeMake(256, 256)];scig = [self _imageFromImage:scig inRect:CGRectMake(16, 16, INPUTWIDTH, INPUTWIDTH)];NSString *modelPath = [NSBundle.mainBundle pathForResource:@"nsfw" ofType:@"tflite"];FIRCustomLocalModel *localModel = [[FIRCustomLocalModel alloc] initWithModelPath:modelPath];FIRModelInterpreter *fi = [FIRModelInterpreter modelInterpreterForLocalModel:localModel];CGImageRef cgImage = scig.CGImage;// Your input image//long imageWidth = CGImageGetWidth(image);//long imageHeight = CGImageGetHeight(image);CGContextRef context = [self _createARGBBitmapContextFromImage:cgImage];CGContextDrawImage(context, CGRectMake(0, 0, INPUTWIDTH, INPUTWIDTH), cgImage);UInt8 *imageData = CGBitmapContextGetData(context);CGContextRelease(context);FIRModelInputs *inputs = [[FIRModelInputs alloc] init];NSMutableData *inputData = [[NSMutableData alloc] initWithCapacity:0];int offs =0;for (int row = offs; row < INPUTWIDTH+offs; row++) {for (int col = offs; col < INPUTWIDTH+offs; col++) {long offset = 4 * (row * INPUTWIDTH + col);//Float32 alph = imageData[offset];Float32 red = imageData[offset];Float32 green = imageData[offset+1];Float32 blue = imageData[offset+2];Float32 red1 = red - 123;Float32 green1 = green - 117;Float32 blue1 = blue - 104;[inputData appendBytes:&blue1 length:sizeof(blue1)];[inputData appendBytes:&green1 length:sizeof(green1)];[inputData appendBytes:&red1 length:sizeof(red1)];}}NSError * error = nil;[inputs addInput:inputData error:&error];FIRModelInputOutputOptions *ioOptions = [[FIRModelInputOutputOptions alloc] init];[ioOptions setInputFormatForIndex:0type:FIRModelElementTypeFloat32dimensions:@[@1, @224, @224, @3]error:&error];if (error != nil) {return;}[ioOptions setOutputFormatForIndex:0type:FIRModelElementTypeFloat32dimensions:@[@1,@2]error:&error];if (error != nil) {return;}[fi runWithInputs:inputs options:ioOptions completion:^(FIRModelOutputs *outputs, NSError *error) {dispatch_async(dispatch_get_main_queue(), ^{NSArray *ou = [outputs outputAtIndex:0 error:nil];NSNumber *f = ou[0][0];float value = 1 - [f floatValue];if (completBlock) {BOOL canShow = NO;if(value >= kPersentTag) { //色情图片canShow = YES;} else { //不是canShow = NO;}completBlock(canShow, value);}//NSLog(@"%@; %@",ou[0][0], ou[0][1]);//NSLog(@"e:%@",error);});}];
#pragma clang diagnostic pop
#endif
}+ (UIImage *)_scaleToSize:(UIImage *)image size:(CGSize)size {// 创建一个bitmap的context// 并把它设置成为当前正在使用的contextUIGraphicsBeginImageContext(size);// 绘制改变大小的图片[image drawInRect:CGRectMake(0, 0, size.width, size.height)];// 从当前context中创建一个改变大小后的图片UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();// 使当前的context出堆栈UIGraphicsEndImageContext();// 返回新的改变大小后的图片return scaledImage;
}+ (UIImage *)_imageFromImage:(UIImage *)image inRect:(CGRect)rect {//将UIImage转换成CGImageRefCGImageRef sourceImageRef = [image CGImage];//按照给定的矩形区域进行剪裁CGImageRef newImageRef = CGImageCreateWithImageInRect(sourceImageRef, rect);//将CGImageRef转换成UIImageUIImage *newImage = [UIImage imageWithCGImage:newImageRef];//返回剪裁后的图片return newImage;
}+ (CGContextRef)_createARGBBitmapContextFromImage:(CGImageRef)inImage {CGContextRef context = NULL;CGColorSpaceRef colorSpace;void * bitmapData;int bitmapByteCount;int bitmapBytesPerRow;// Get image width, height. We'll use the entire image.size_t pixelsWide = CGImageGetWidth(inImage);size_t pixelsHigh = CGImageGetHeight(inImage);// Declare the number of bytes per row. Each pixel in the bitmap in this// example is represented by 4 bytes; 8 bits each of red, green, blue, and// alpha.bitmapBytesPerRow = (int)(pixelsWide * 4);bitmapByteCount = (int)(bitmapBytesPerRow * pixelsHigh);// Use the generic RGB color space.colorSpace = CGColorSpaceCreateDeviceRGB();if (colorSpace == NULL) {fprintf(stderr, "Error allocating color space\n");return NULL;}// Allocate memory for image data. This is the destination in memory// where any drawing to the bitmap context will be rendered.bitmapData = malloc( bitmapByteCount );if (bitmapData == NULL) {fprintf (stderr, "Memory not allocated!");CGColorSpaceRelease( colorSpace );return NULL;}// Create the bitmap context. We want pre-multiplied ARGB, 8-bits// per component. Regardless of what the source image format is// (CMYK, Grayscale, and so on) it will be converted over to the format// specified here by CGBitmapContextCreate.CGImageAlphaInfo alpInfo = CGImageGetAlphaInfo(inImage);context = CGBitmapContextCreate (bitmapData,pixelsWide,pixelsHigh,8, // bits per componentbitmapBytesPerRow,colorSpace,alpInfo);// kCGImageAlphaNoneSkipFirstif (context == NULL) {free (bitmapData);fprintf (stderr, "Context not created!");}// Make sure and release colorspace before returningCGColorSpaceRelease(colorSpace);return context;
}#pragma mark - manager end@end
  • 导入训练模型
  • ps:在下面分享的Swift版本的鉴黄里面有文件
  • 使用
__weak typeof(self) weakSelf = self;
[BaseIdentifyImageManager checkImage:newPhoto completBlock:^(BOOL canShow, CGFloat valid) {NSLog(@"valid %f", valid);weakSelf.testView.text = [NSString stringWithFormat:@"图片指数值 - %f", valid];
}];

OC版本的鉴黄demo

OC版本的鉴黄demo地址

Swift版本的鉴黄

Swift版本的鉴黄地址

iOS开发-图片离线鉴黄 基于TensorFlow nsfw oc版相关推荐

  1. IOS开发基础之微博项目第1天-OC版

    IOS开发基础之微博项目第1天-OC版 纯代码创建的项目,具有参考价值 该资料来自2014年7月3号,虽然时间过去较长,但是oc和swift不同,oc语法迭代更新慢 具有一定的参考意义 涉及xib加载 ...

  2. c++ 图片验证码识别_基于tensorflow 实现端到端的OCR:二代身份证号识别

    最近在研究OCR识别相关的东西,最终目标是能识别身份证上的所有中文汉字+数字,不过本文先设定一个小目标,先识别定长为18的身份证号,当然本文的思路也是可以复用来识别定长的验证码识别的. 本文实现思路主 ...

  3. iOS开发 图片选择器、图片多选功能的实现

    版权声明:本文为博主原创文章,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接. Photos.framework是iOS8后苹果推出的一套替代AssetsLibrary.f ...

  4. iOS开发图片格式选择

    图片是如何显示的 在讲解如何选择图片格式之前,我感觉有必要先了解下,图片是如何展示的.如果我们要展示一张图片,一般步骤是这样的: /// Assets.xcassets中的图片,不需要后缀 let i ...

  5. c语言 将url图片存到本地_一个22万张NSFW图片的鉴黄数据集?我有个大胆的想法……...

    如果你想训练一个内容审核系统过滤不合适的信息,或用 GAN 做一些大胆的新想法,那么数据集是必不可少的.例如图像鉴黄,我们需要使用卷积神经网络训练一个分类器,以区分正常图像与限制级图像.但限制级的图像 ...

  6. 一个22万张NSFW图片的鉴黄数据集?我有个大胆的想法……

    机器之心报道,机器之心编辑部. 如果你想训练一个内容审核系统过滤不合适的信息,或用 GAN 做一些大胆的新想法,那么数据集是必不可少的.例如图像鉴黄,我们需要使用卷积神经网络训练一个分类器,以区分正常 ...

  7. iOS开发图片控件(ImageView)绑定代码并显示一张图片

    我在之前的一篇博客<iOS中如何显示一张图片>中谈到如何使用Image View来显示图片,这个操作是直接在Main.storyboard实现的.也就是说这张图片是写死在界面中了.但是在以 ...

  8. iOS开发图片纯色填充(两种方式)和缩小图片

    UIImage图标换色和变换大小 这里的图片大都指只有两个色的图标,有时候我们的图标需要根据不同的状态显示不同的颜色,有一种简单的处理方式是,将不同状态的颜色图标都切出来,变换状态的时候直接使用相应的 ...

  9. iOS开发 - 图片实现多层折叠效果

    为什么80%的码农都做不了架构师?>>>    #效果 #Demo Demo地址:https://github.com/Resory/RYMutipleFoldImageView 如 ...

最新文章

  1. GitHub 热榜:中国博士开发可交互全球疫情地图,登上柳叶刀!
  2. Win10+Python3.6下Pytorch安装(基于conda或pip)
  3. android+studio入门指南+pdf,android+studio使用指南v0.1.pdf
  4. 怎样利用超图客户端打点_渗透测试——XSS利用工具BeEF攻击演示
  5. python类型转换-Python基本数据类型转换
  6. 数据中心在未来数据管理中的作用
  7. java规定数组的下标_Java数组元素下标的范围是
  8. 成员变量和类变量的区别:
  9. nginx 二进制包安装mysql_二进制安装mysql5.7
  10. 深度学习笔记(47) 神经风格迁移
  11. 移动游戏开发图书推荐
  12. Alt属性 添加的意义
  13. oracle 表(下)
  14. Failed to run the WC DB work queue associated with 错误的解决
  15. 闪讯(NetKeeper)——OpenWrt安装闪讯(NetKeeper)插件(校园网电信宽带闪讯(NetKeeper)认证解决方案)
  16. ubuntu16如何开wifi
  17. ks 曲线_Ks密度曲线分布图绘图
  18. PDF文件实现在线盖章
  19. TCP四次挥手中的2MSL是什么?
  20. 2-10-Mysql认实和搭建LAMP环境部署Ucenter和Ucenter-home网站

热门文章

  1. 基于BERT的自动标题生成
  2. 笔记本蓝牙崩溃、图标消失不能打开蓝牙功能-解决办法(由于蓝牙串口连接出现的问题)
  3. java 随机句子_Java基础三(Scanner键盘输入、Random随机数、流程控制语句)
  4. 【附源码】计算机毕业设计Python安卓便利猫电影购票系统安卓app14g1h(源码+程序+LW+调试部署)
  5. uniapp封装require
  6. 打开关闭软键盘,点击屏幕其他地方关闭软键盘
  7. 有哪些好用的开源网盘?
  8. 《我不是药神》与AI研制新药
  9. 【承】Redis 原理篇——关于 Redis 中的事务
  10. 长期戴耳机会诱发中耳炎?我们该如何科学佩戴耳机预防中耳炎