Skip to content

Commit

Permalink
Add opencv lib,fix devzwy#1
Browse files Browse the repository at this point in the history
  • Loading branch information
devzwy committed May 20, 2019
1 parent 388704b commit 41c1a2d
Show file tree
Hide file tree
Showing 365 changed files with 35,447 additions and 39 deletions.
1 change: 1 addition & 0 deletions .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 39 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,42 @@
```
### Demo运行结果:

![图片](https://github.com/devzwy/open_nsfw_android/blob/master/img/1.png)
![图片](https://github.com/devzwy/open_nsfw_android/blob/master/img/1.png)




0.9254902 0.7764706 0.7254902 0.92156863 0.77254903 0.72156864

[16:16+224,16:16+224,:] [16:240,16:240,:]


0.90588236-R 0.75686276-G 0.68235296-B ------0.01960784 0.01960784 0.04313724
0.90196079 0.75294119 0.6784314

[:,:,:: -1]
0.68235296-B 0.75686276-G 0.90588236-R


*255 转换为int

174 193 231

-[104, 117, 123]

70 76 108


opencv假设图像是RGB三分量组成的图像,那么图像的

第一通道是R,

第二通道是G,

第三通道是B

Img[:,:,2]代表R通道,也就是红色分量图像;

Img[:,:,1]代表G通道,也就是绿色分量图像;

Img[:,:,0]代表B通道,也就是蓝色分量图像。
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,6 @@ dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
// implementation project(path: ':nsfw')
implementation 'com.github.devzwy:open_nsfw_android:1.2.1'
implementation project(path: ':nsfw')
// implementation 'com.github.devzwy:open_nsfw_android:1.2.1'
}
2 changes: 2 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.open_nsfw_android">
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/icon"
Expand Down
Binary file removed app/src/main/assets/aaa.png
Binary file not shown.
Binary file removed app/src/main/assets/ccc.gif
Binary file not shown.
Binary file added app/src/main/assets/img/nsfw_test_01.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/assets/img/nsfw_test_02.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/assets/img/nsfw_test_03.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/assets/img/nsfw_test_04.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/assets/img/nsfw_test_05.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/assets/img/nsfw_test_06.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/assets/img/nsfw_test_07.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/assets/img/nsfw_test_08.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/assets/img/nsfw_test_09.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/main/assets/img/nsfw_test_10.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed app/src/main/assets/timg-10.jpeg
Binary file not shown.
47 changes: 38 additions & 9 deletions app/src/main/java/com/example/open_nsfw_android/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,54 @@ class MainActivity : AppCompatActivity() {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//assets 目录下的timg-10.jpeg为正常静态图片 ccc.gif 为动态正常图片 可用作测试
val b = BitmapFactory.decodeStream(resources.assets.open("aaa.png"))
iv.setImageBitmap(b)
// val b = BitmapFactory.decodeStream(resources.assets.open("img/06 (1).jpg"))
// iv.setImageBitmap(b)
nsfwHelper = NsfwHelper.getInstance(this, true, 1)

bt_.setOnClickListener {
//同步识别
val nsfwBean = nsfwHelper?.scanBitmapSyn(b)
Log.d("demo", nsfwBean.toString())
tvv.text = "识别成功:\n\tSFW score : ${nsfwBean?.sfw}\n\tNSFW score : ${nsfwBean?.nsfw}"
if (nsfwBean?.nsfw ?: 0f > 0.7) {
tvv.text = "${tvv.text} \n \t - 色情图片"
} else {
tvv.text = "${tvv.text} \n \t - 正常图片"
for (a in resources.assets.list("img")) {
val b = BitmapFactory.decodeStream(resources.assets.open("img/${a}"))
val nsfwBean = nsfwHelper?.scanBitmapSyn(b)
Log.d("demo", nsfwBean.toString() + " - ${a}")
tvv.text = "识别成功:\n\tSFW score : ${nsfwBean?.sfw}\n\tNSFW score : ${nsfwBean?.nsfw},- ${a}"
if (nsfwBean?.nsfw ?: 0f > 0.7) {
tvv.text = "${tvv.text} \n \t - 色情图片"
} else {
tvv.text = "${tvv.text} \n \t - 正常图片"
}
}
// val nsfwBean = nsfwHelper?.scanBitmapSyn(b)
// Log.d("demo", nsfwBean.toString())
// tvv.text = "识别成功:\n\tSFW score : ${nsfwBean?.sfw}\n\tNSFW score : ${nsfwBean?.nsfw}"
// if (nsfwBean?.nsfw ?: 0f > 0.7) {
// tvv.text = "${tvv.text} \n \t - 色情图片"
// } else {
// tvv.text = "${tvv.text} \n \t - 正常图片"
// }
// //异步识别,接口回调识别结果
// nsfwHelper?.scanBitmap(b) { sfw, nsfw ->
// Log.d("demo", "sfw:$sfw,nsfw:$nsfw")
// }
}
}

// override fun onResume() {
// super.onResume()
// if (!OpenCVLoader.initDebug()) {
// OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);
// } else {
// mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
// }
// }

// internal var mLoaderCallback: LoaderCallbackInterface = object : LoaderCallbackInterface {
// override fun onManagerConnected(status: Int) {
//
// }
//
// override fun onPackageInstall(operation: Int, callback: InstallCallbackInterface) {
//
// }
// }
}
6 changes: 4 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ buildscript {
repositories {
google()
jcenter()

}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.0'
Expand All @@ -19,7 +19,9 @@ allprojects {
repositories {
google()
jcenter()
maven { url 'https://jitpack.io' }
maven {
url 'https://jitpack.io'
}
}
}

Expand Down
44 changes: 44 additions & 0 deletions nsfw/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.

cmake_minimum_required(VERSION 3.4.1)

# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.

add_library( # Sets the name of the library.
native-lib

# Sets the library as a shared library.
SHARED

# Provides a relative path to your source file(s).
src/main/cpp/native-lib.cpp )

# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.

find_library( # Sets the name of the path variable.
log-lib

# Specifies the name of the NDK library that
# you want CMake to locate.
log )

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library.
native-lib

# Links the target library to the log library
# included in the NDK.
${log-lib} )
37 changes: 36 additions & 1 deletion nsfw/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,40 @@ android {
versionName "1.0"

testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags "-frtti -fexceptions"
}
}
ndk {

// Specifies the ABI configurations of your native
// libraries Gradle should build and package with your APK.
// abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'mips', 'mips64'
abiFilters 'armeabi-v7a'
}
}

buildTypes {
debug{
minifyEnabled false //开启混淆
minifyEnabled false //开启混淆®
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}

externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}

sourceSets {
main {
jniLibs.srcDirs = ['libs']
assets.srcDir("main/assets")
}
}

}

dependencies {
Expand All @@ -32,4 +56,15 @@ dependencies {
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'org.tensorflow:tensorflow-lite:+'
implementation 'org.tensorflow:tensorflow-lite-gpu:+'
implementation project(path: ':openCVLibrary340')
}

task nativeLibsToJar(type: Jar, description: 'create a jar archive of the native libs') {
destinationDir file("$buildDir/native-libs")
baseName 'native-libs'
from fileTree(dir: 'libs', include: '**/*.so')
into 'lib/'
}
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn(nativeLibsToJar)
}
Binary file added nsfw/libs/armeabi-v7a/libopencv_calib3d.a
Binary file not shown.
Binary file added nsfw/libs/armeabi-v7a/libopencv_core.a
Binary file not shown.
Binary file added nsfw/libs/armeabi-v7a/libopencv_dnn.a
Binary file not shown.
Binary file added nsfw/libs/armeabi-v7a/libopencv_features2d.a
Binary file not shown.
Binary file added nsfw/libs/armeabi-v7a/libopencv_flann.a
Binary file not shown.
Binary file added nsfw/libs/armeabi-v7a/libopencv_highgui.a
Binary file not shown.
Binary file added nsfw/libs/armeabi-v7a/libopencv_imgcodecs.a
Binary file not shown.
Binary file added nsfw/libs/armeabi-v7a/libopencv_imgproc.a
Binary file not shown.
Binary file added nsfw/libs/armeabi-v7a/libopencv_java3.so
Binary file not shown.
Binary file added nsfw/libs/armeabi-v7a/libopencv_ml.a
Binary file not shown.
Binary file added nsfw/libs/armeabi-v7a/libopencv_objdetect.a
Binary file not shown.
Binary file added nsfw/libs/armeabi-v7a/libopencv_photo.a
Binary file not shown.
Binary file added nsfw/libs/armeabi-v7a/libopencv_shape.a
Binary file not shown.
Binary file added nsfw/libs/armeabi-v7a/libopencv_stitching.a
Binary file not shown.
Binary file added nsfw/libs/armeabi-v7a/libopencv_superres.a
Binary file not shown.
Binary file added nsfw/libs/armeabi-v7a/libopencv_video.a
Binary file not shown.
Binary file added nsfw/libs/armeabi-v7a/libopencv_videoio.a
Binary file not shown.
Binary file added nsfw/libs/armeabi-v7a/libopencv_videostab.a
Binary file not shown.
5 changes: 4 additions & 1 deletion nsfw/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
<manifest package="com.zwy.nsfw"/>
<manifest package="com.zwy.nsfw" xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
</manifest>
24 changes: 24 additions & 0 deletions nsfw/src/main/cpp/native-lib.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include <jni.h>
#include <string>

extern "C"
JNIEXPORT void JNICALL
Java_com_zwy_nsfw_JniLoader_argb2bgr(JNIEnv *env, jobject thiz,
jbyteArray rgbSrc_,
jbyteArray bgrDesc_) {
jbyte *rgbSrc = env->GetByteArrayElements(rgbSrc_, NULL);
jbyte *bgrDesc = env->GetByteArrayElements(bgrDesc_, NULL);
printf("s[]=%s\n","C+++++++++");/*输出数组字符串s[]=Hello,Comrade*/
int wh = env->GetArrayLength(rgbSrc_) / 4 ;


//#pragma omp parallel for
for (int i = 0; i < wh; ++i) {
bgrDesc[i * 3] = rgbSrc[i * 4 + 2]; //B
bgrDesc[i * 3 + 1] = rgbSrc[i * 4 + 1]; //G
bgrDesc[i * 3 + 2] = rgbSrc[i * 4 ]; //R
}

env->ReleaseByteArrayElements(rgbSrc_, rgbSrc, JNI_ABORT);
env->ReleaseByteArrayElements(bgrDesc_, bgrDesc, JNI_COMMIT);
}
53 changes: 32 additions & 21 deletions nsfw/src/main/java/com/zwy/nsfw/Classifier.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,15 @@
import android.content.res.AssetFileDescriptor;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Matrix;
import android.os.SystemClock;
import android.util.Log;
import com.zwy.nsfw.api.NsfwBean;
import org.opencv.android.OpenCVLoader;
import org.opencv.android.Utils;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;
import org.tensorflow.lite.Interpreter;
import org.tensorflow.lite.gpu.GpuDelegate;

Expand Down Expand Up @@ -35,7 +41,7 @@ public abstract class Classifier {
/**
* Preallocated buffers for storing image data in.
*/
private int[] intValues = new int[getImageSizeX() * getImageSizeY()];
private int[] intValues = new int[224 * 224];

/**
* Options for configuring the Interpreter.
Expand Down Expand Up @@ -100,6 +106,7 @@ protected Classifier(Activity activity, Boolean isGPU, int numThreads) throws IO
* DIM_PIXEL_SIZE
* getNumBytesPerChannel());
imgData.order(ByteOrder.LITTLE_ENDIAN);
OpenCVLoader.initDebug();
Log.d(TAG, "Tensorflow Lite Image Classifier Initialization Success.");
}

Expand All @@ -122,40 +129,44 @@ private void convertBitmapToByteBuffer(Bitmap bitmap_) {
if (imgData == null || bitmap_ == null) {
return;
}
Bitmap bitmap = Bitmap.createScaledBitmap(bitmap_, 224, 224, false);

imgData.rewind();
// intValues= ImageUtil.bitmap2BGR(bitmap);
Matrix m = new Matrix();
m.setScale(-1, 1);//水平翻转
Bitmap reversePic = Bitmap.createBitmap(bitmap_, 0, 0, bitmap_.getWidth(), bitmap_.getHeight(), m, true);
//把每个像素的颜色值转为int 存入intValues
bitmap.getPixels(intValues, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
// bitmap.copyPixelsToBuffer(imgData);
reversePic.getPixels(intValues, 0, 224, 16, 16, 224, 224);
// Convert the image to floating point.
int pixel = 0;
long startTime = SystemClock.uptimeMillis();
for (int i = 0; i < getImageSizeX(); ++i) {
for (int j = 0; j < getImageSizeY(); ++j) {

//操作每一个像素
//拿出每一个像素点对应的R、G、B的int值
//对每一个int值减去阈值 R-123 B-104 G-117
//将R、G、B 利用 B、G、R顺序重新写入数组
//将数组传入tflite获取回传结果
for (int i = 16; i < 240; ++i) {
for (int j = 16; j < 240; ++j) {
final int color = intValues[pixel++];
int r1 = Color.red(color) - 123;
int g1 = Color.green(color) - 117;
int b1 = Color.blue(color) - 104;
int r1 = Color.red(color);
int g1 = Color.green(color);
int b1 = Color.blue(color);

int rr1 = r1 - 123;
int gg1 = g1 - 117;
int bb1 = b1 - 104;

imgData.putFloat(b1);
imgData.putFloat(g1);
imgData.putFloat(r1);
imgData.putFloat(bb1);
imgData.putFloat(gg1);
imgData.putFloat(rr1);
}
}
long endTime = SystemClock.uptimeMillis();
Log.d(TAG, "Timecost to put values into ByteBuffer: " + (endTime - startTime) + "ms");
}

public NsfwBean run(Bitmap bitmap) {
convertBitmapToByteBuffer(bitmap);
Mat mat = new Mat();
Utils.bitmapToMat(bitmap, mat, false);
//线性采样
Mat mat1 = new Mat();
Imgproc.resize(mat, mat1, new Size(256, 256), 0, 0, Imgproc.INTER_CUBIC);
Bitmap bitmap_256 = Bitmap.createBitmap(256, 256, Bitmap.Config.RGB_565);
Utils.matToBitmap(mat1, bitmap_256);
convertBitmapToByteBuffer(bitmap_256);
long startTime = SystemClock.uptimeMillis();
float[][] labelProbArray = new float[1][2];
tflite.run(imgData, labelProbArray);
Expand Down
Loading

0 comments on commit 41c1a2d

Please sign in to comment.