pull/34/head 1.3.5
Jason 5 years ago
parent 3938349e08
commit fc21250b12
  1. 4
      OpenNSFW/build.gradle
  2. BIN
      OpenNSFW/src/main/assets/nsfw.tflite
  3. 16
      OpenNSFW/src/main/java/com/zwy/opennsfw/core/Classifier.kt
  4. 51
      README.md
  5. 8
      demo/build.gradle
  6. 4
      demo/src/main/java/com/zwy/demo/NSFWApplication.kt

@ -9,8 +9,8 @@ android {
defaultConfig { defaultConfig {
minSdkVersion 16 minSdkVersion 16
targetSdkVersion 29 targetSdkVersion 29
versionCode 4 versionCode 5
versionName "1.3.4" versionName "1.3.5"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
consumerProguardFiles 'consumer-rules.pro' consumerProguardFiles 'consumer-rules.pro'

@ -68,7 +68,7 @@ class Classifier private constructor(config: Config) {
private var instance: Classifier? = null private var instance: Classifier? = null
get() { get() {
if (field == null) { if (field == null) {
// if (config.context == null) throw RuntimeException("context函数未调用,请使用Classifier.Build().context(context)初始化") if (config.context == null) throw RuntimeException("context函数未调用,请使用Classifier.Build().context(context)初始化")
field = Classifier(config) field = Classifier(config)
mClassifier = field mClassifier = field
} }
@ -115,18 +115,18 @@ class Classifier private constructor(config: Config) {
//"/data/user/0/com.zwy.demo/files/nsfw.tflite" //"/data/user/0/com.zwy.demo/files/nsfw.tflite"
init { init {
val file = File( // val file = File(
config.nsfwModuleFilePath // config.nsfwModuleFilePath
?: throw java.lang.NullPointerException("未配置模型路径,请调用Classifier.Build().nsfwModuleFilePath(模型路径)初始化") // ?: throw java.lang.NullPointerException("未配置模型路径,请调用Classifier.Build().nsfwModuleFilePath(模型路径)初始化")
) // )
if (!file.exists()) throw NullPointerException("模型加载失败,请确认路径是否正确") // if (!file.exists()) throw NullPointerException("模型加载失败,请确认路径是否正确")
try { try {
tflite = tflite =
Interpreter(file, getTfLiteOptions(config.isOpenGPU)) Interpreter(loadModelFile(context = config.context!!), getTfLiteOptions(config.isOpenGPU))
if (config.isOpenGPU) "开启GPU加速成功".d() if (config.isOpenGPU) "开启GPU加速成功".d()
} catch (e: Exception) { } catch (e: Exception) {
"不支持GPU加速".e() "不支持GPU加速".e()
tflite = Interpreter(file, getTfLiteOptions(false)) tflite = Interpreter(loadModelFile(context = config.context!!), getTfLiteOptions(false))
} }
imgData = ByteBuffer.allocateDirect( imgData = ByteBuffer.allocateDirect(

@ -9,7 +9,6 @@
### C++参考:[TensorflowLite-Api](https://tensorflow.google.cn/lite/api_docs/cc) ### C++参考:[TensorflowLite-Api](https://tensorflow.google.cn/lite/api_docs/cc)
### JavaScript参考[JS相关文档](https://js.tensorflow.org/api/latest/) ### JavaScript参考[JS相关文档](https://js.tensorflow.org/api/latest/)
>>> 其中Python、C++均有两种数据喂入的方式,可根据需求选择pb模型或tfLite文件,详细请参考上面的链接.Java的目前只能加载pb模型。其他的平台可自行[百度](https://www.baidu.com) >>> 其中Python、C++均有两种数据喂入的方式,可根据需求选择pb模型或tfLite文件,详细请参考上面的链接.Java的目前只能加载pb模型。其他的平台可自行[百度](https://www.baidu.com)
### [pb模型下载](https://github.com/devzwy/NSFW-Python/tree/master/model)
### 本项目移除测试图片,请下载Demo后自行配图测试 ### 本项目移除测试图片,请下载Demo后自行配图测试
#### 即将优化Demo使用MVVM模式,可用作开发脚手架使用 #### 即将优化Demo使用MVVM模式,可用作开发脚手架使用
`Kotlin+okhttp3+rxjava2+retrofit2+koin+glide+greendao+databinding+Livedata` `Kotlin+okhttp3+rxjava2+retrofit2+koin+glide+greendao+databinding+Livedata`
@ -17,21 +16,31 @@
![MVVM](https://github.com/devzwy/open_nsfw_android/blob/dev/img/4.jpg) ![MVVM](https://github.com/devzwy/open_nsfw_android/blob/dev/img/4.jpg)
#### 1.3.2版本优化说明: #### 1.3.5版本优化说明:
模型大小改动较大,原量化模型虽小(6M),但对GPU加速支持不友好,新模型大约26M,完美支持GPU加速并优化识别精度,加速效果明显。建议全部升级该版本。__新版本的GPU加速默认开启状态__,SDK默认会检测设备是否支持,不支持时会自动取消加速(老版本会奔溃) 模型大小改动较大,原量化模型虽小(6M),但对GPU加速支持不友好,新模型大约23M,完美支持GPU加速并优化识别精度,加速效果明显。建议全部升级该版本。__新版本的GPU加速默认开启状态__,SDK默认会检测设备是否支持,不支持时会自动取消加速(老版本会奔溃)
#### 1.3.4版本特殊说明:
由于模型支持GPU加速后模型文件变大,部分用户反馈Apk体积增大,考虑到这方面,在1.3.4版本中增加初始化方式,可通过传入模型文件的路径进行初始化,该模型在`/OpenNSFW/src/main/assets/nsfw.tflite`处,可自行下载并存放适当位置,比如放在后台,app端自行下载后初始化NSFW后使用。初始化方式:
```
Classifier.Build()
// .context(this) //1.3.4版本可不用调用该代码。其他版本必须调用,否则会有异常抛出
// .isOpenGPU(true)//默认不开启GPU加速,默认为true
// .numThreads(100) //分配的线程数 根据手机配置设置,默认1
.nsfwModuleFilePath("/data/user/0/com.zwy.demo/files/nsfw.tflite") //1.3.4版本必须配置模型存放路径,否则会有异常抛出
.build()
```
### 使用方式一 (建议)
### 开始使用
- 添加远程仓库支持 - 添加远程仓库支持
``` ```
allprojects { allprojects {
repositories { repositories {
...
maven { url 'https://jitpack.io' } maven { url 'https://jitpack.io' }
} }
} }
``` ```
- 配置依赖 [![](https://jitpack.io/v/devzwy/open_nsfw_android.svg)](https://jitpack.io/#devzwy/open_nsfw_android) (编译过程报错时请自行使用梯子) - 配置依赖(如果需要自行配置模型路径可适用1.3.4版本,否则请使用最新版本,版本号看右边的icon中的数字) [![](https://jitpack.io/v/devzwy/open_nsfw_android.svg)](https://jitpack.io/#devzwy/open_nsfw_android) (编译过程报错时请自行使用梯子)
``` ```
dependencies { dependencies {
@ -41,28 +50,10 @@
``` ```
### 使用方式二,源码依赖方式 - 以下配置1.3.4版本可跳过
- 克隆源码 __除1.3.4版本外,其他任何版本均需要添加如下代码,否则会有`java.io.FileNotFoundException: This file can not be opened as a file descriptor; it is probably compressed`异常抛出,因为assets下模型文件较大__
```
git clone 'https://github.com/devzwy/open_nsfw_android.git'
```
- 项目中依赖lib
```
dependencies {
implementation project(path: ':OpenNSFW')
}
```
- 扫描时报如下错误
```
java.lang.NullPointerException: Attempt to invoke virtual method 'com.zwy.nsfw.api.NsfwBean com.zwy.nsfw.Classifier.run(android.graphics.Bitmap)' on a null object reference
```
__无论哪种方式依赖项目,都需要添加如下代码__
``` ```
android { android {
...
aaptOptions { aaptOptions {
noCompress "tflite" noCompress "tflite"
} }
@ -70,14 +61,14 @@ __无论哪种方式依赖项目,都需要添加如下代码__
``` ```
- 使用(请使用最新版本1.3.2)
- 建议在Application中全局初始化 - 建议在Application中全局初始化
``` ```
Classifier.Build() Classifier.Build()
.context(this) //必须调用 否则会有异常抛出 .context(this) //1.3.4版本可不用调用该代码。其他版本必须调用,否则会有异常抛出
// .isOpenGPU(true)//是否开启GPU加速 ,默认true // .isOpenGPU(true)//默认不开启GPU加速,默认为true
// .numThreads(10) //分配的线程数 根据手机配置设置,默认1 // .numThreads(100) //分配的线程数 根据手机配置设置,默认1
// .nsfwModuleFilePath("/data/user/0/com.zwy.demo/files/nsfw.tflite") //1.3.4版本必须配置模型存放路径,否则会有异常抛出
.build() .build()
``` ```
- 使用: - 使用:

@ -11,8 +11,8 @@ android {
applicationId "com.zwy.demo" applicationId "com.zwy.demo"
minSdkVersion 19 minSdkVersion 19
targetSdkVersion 29 targetSdkVersion 29
versionCode 4 versionCode 5
versionName "1.3.4" versionName "1.3.5"
multiDexEnabled true multiDexEnabled true
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
} }
@ -83,8 +83,8 @@ dependencies {
implementation "org.jetbrains.anko:anko:0.10.5" implementation "org.jetbrains.anko:anko:0.10.5"
//NSFW鉴黄库 //NSFW鉴黄库
// implementation 'com.github.devzwy:open_nsfw_android:1.3.3' implementation 'com.github.devzwy:open_nsfw_android:1.3.2'
implementation project(path: ':OpenNSFW') // implementation project(path: ':OpenNSFW')
implementation 'pub.devrel:easypermissions:3.0.0' implementation 'pub.devrel:easypermissions:3.0.0'
implementation 'com.github.LuckSiege.PictureSelector:picture_library:2.2.5' implementation 'com.github.LuckSiege.PictureSelector:picture_library:2.2.5'

@ -28,10 +28,10 @@ class NSFWApplication : MultiDexApplication() {
//初始化鉴黄库NSFW //初始化鉴黄库NSFW
Classifier.Build() Classifier.Build()
// .context(this) //必须调用 否则会有异常抛出 .context(this) //1.3.4版本可不用调用该代码。其他版本必须调用,否则会有异常抛出
// .isOpenGPU(true)//默认不开启GPU加速,默认为true // .isOpenGPU(true)//默认不开启GPU加速,默认为true
// .numThreads(100) //分配的线程数 根据手机配置设置,默认1 // .numThreads(100) //分配的线程数 根据手机配置设置,默认1
.nsfwModuleFilePath("/data/user/0/com.zwy.demo/files/nsfw.tflite") // .nsfwModuleFilePath("/data/user/0/com.zwy.demo/files/nsfw.tflite") //1.3.4版本必须配置模型存放路径,否则会有异常抛出
.build() .build()
//全局注入对象 //全局注入对象
startKoin { startKoin {

Loading…
Cancel
Save