diff --git a/OpenNSFW/build.gradle b/OpenNSFW/build.gradle index c9b6a928e..474b412e0 100644 --- a/OpenNSFW/build.gradle +++ b/OpenNSFW/build.gradle @@ -9,8 +9,8 @@ android { defaultConfig { minSdkVersion 16 targetSdkVersion 29 - versionCode 4 - versionName "1.3.4" + versionCode 5 + versionName "1.3.5" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" consumerProguardFiles 'consumer-rules.pro' diff --git a/OpenNSFW/src/main/assets/nsfw.tflite b/OpenNSFW/src/main/assets/nsfw.tflite new file mode 100644 index 000000000..9583ed20d Binary files /dev/null and b/OpenNSFW/src/main/assets/nsfw.tflite differ diff --git a/OpenNSFW/src/main/java/com/zwy/opennsfw/core/Classifier.kt b/OpenNSFW/src/main/java/com/zwy/opennsfw/core/Classifier.kt index d87a25ab8..d7443b810 100644 --- a/OpenNSFW/src/main/java/com/zwy/opennsfw/core/Classifier.kt +++ b/OpenNSFW/src/main/java/com/zwy/opennsfw/core/Classifier.kt @@ -68,7 +68,7 @@ class Classifier private constructor(config: Config) { private var instance: Classifier? = null get() { 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) mClassifier = field } @@ -115,18 +115,18 @@ class Classifier private constructor(config: Config) { //"/data/user/0/com.zwy.demo/files/nsfw.tflite" init { - val file = File( - config.nsfwModuleFilePath - ?: throw java.lang.NullPointerException("未配置模型路径,请调用Classifier.Build().nsfwModuleFilePath(模型路径)初始化") - ) - if (!file.exists()) throw NullPointerException("模型加载失败,请确认路径是否正确") +// val file = File( +// config.nsfwModuleFilePath +// ?: throw java.lang.NullPointerException("未配置模型路径,请调用Classifier.Build().nsfwModuleFilePath(模型路径)初始化") +// ) +// if (!file.exists()) throw NullPointerException("模型加载失败,请确认路径是否正确") try { tflite = - Interpreter(file, getTfLiteOptions(config.isOpenGPU)) + Interpreter(loadModelFile(context = config.context!!), getTfLiteOptions(config.isOpenGPU)) if (config.isOpenGPU) "开启GPU加速成功".d() } catch (e: Exception) { "不支持GPU加速".e() - tflite = Interpreter(file, getTfLiteOptions(false)) + tflite = Interpreter(loadModelFile(context = config.context!!), getTfLiteOptions(false)) } imgData = ByteBuffer.allocateDirect( diff --git a/README.md b/README.md index ce986018a..db9e19c2b 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,6 @@ ### C++参考:[TensorflowLite-Api](https://tensorflow.google.cn/lite/api_docs/cc) ### JavaScript参考[JS相关文档](https://js.tensorflow.org/api/latest/) >>> 其中Python、C++均有两种数据喂入的方式,可根据需求选择pb模型或tfLite文件,详细请参考上面的链接.Java的目前只能加载pb模型。其他的平台可自行[百度](https://www.baidu.com) -### [pb模型下载](https://github.com/devzwy/NSFW-Python/tree/master/model) ### 本项目移除测试图片,请下载Demo后自行配图测试 #### 即将优化Demo使用MVVM模式,可用作开发脚手架使用 `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) -#### 1.3.2版本优化说明: -模型大小改动较大,原量化模型虽小(6M),但对GPU加速支持不友好,新模型大约26M,完美支持GPU加速并优化识别精度,加速效果明显。建议全部升级该版本。__新版本的GPU加速默认开启状态__,SDK默认会检测设备是否支持,不支持时会自动取消加速(老版本会奔溃) +#### 1.3.5版本优化说明: +模型大小改动较大,原量化模型虽小(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 { repositories { - ... 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 { @@ -41,28 +50,10 @@ ``` -### 使用方式二,源码依赖方式 -- 克隆源码 -``` - 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 -``` -__无论哪种方式依赖项目,都需要添加如下代码__ +- 以下配置1.3.4版本可跳过 +__除1.3.4版本外,其他任何版本均需要添加如下代码,否则会有`java.io.FileNotFoundException: This file can not be opened as a file descriptor; it is probably compressed`异常抛出,因为assets下模型文件较大__ ``` android { - ... aaptOptions { noCompress "tflite" } @@ -70,14 +61,14 @@ __无论哪种方式依赖项目,都需要添加如下代码__ ``` -- 使用(请使用最新版本1.3.2) - 建议在Application中全局初始化 ``` Classifier.Build() - .context(this) //必须调用 否则会有异常抛出 -// .isOpenGPU(true)//是否开启GPU加速 ,默认true -// .numThreads(10) //分配的线程数 根据手机配置设置,默认1 + .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() ``` - 使用: diff --git a/demo/build.gradle b/demo/build.gradle index 50687d5bf..f2d4d7622 100644 --- a/demo/build.gradle +++ b/demo/build.gradle @@ -11,8 +11,8 @@ android { applicationId "com.zwy.demo" minSdkVersion 19 targetSdkVersion 29 - versionCode 4 - versionName "1.3.4" + versionCode 5 + versionName "1.3.5" multiDexEnabled true testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } @@ -83,8 +83,8 @@ dependencies { implementation "org.jetbrains.anko:anko:0.10.5" //NSFW鉴黄库 -// implementation 'com.github.devzwy:open_nsfw_android:1.3.3' - implementation project(path: ':OpenNSFW') + implementation 'com.github.devzwy:open_nsfw_android:1.3.2' +// implementation project(path: ':OpenNSFW') implementation 'pub.devrel:easypermissions:3.0.0' implementation 'com.github.LuckSiege.PictureSelector:picture_library:2.2.5' diff --git a/demo/src/main/java/com/zwy/demo/NSFWApplication.kt b/demo/src/main/java/com/zwy/demo/NSFWApplication.kt index 503aa0714..afe0123b5 100644 --- a/demo/src/main/java/com/zwy/demo/NSFWApplication.kt +++ b/demo/src/main/java/com/zwy/demo/NSFWApplication.kt @@ -28,10 +28,10 @@ class NSFWApplication : MultiDexApplication() { //初始化鉴黄库NSFW Classifier.Build() -// .context(this) //必须调用 否则会有异常抛出 + .context(this) //1.3.4版本可不用调用该代码。其他版本必须调用,否则会有异常抛出 // .isOpenGPU(true)//默认不开启GPU加速,默认为true // .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() //全局注入对象 startKoin {