作者:桔梗的坚守 | 来源:互联网 | 2023-09-16 17:45
C++代码:
#include
#include
#include
#include
#include
#include #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, "keymatch", __VA_ARGS__)
extern "C"{using namespace cv;using namespace std;void printMAtMessage(Mat &mat);JNIEXPORT jintArray JNICALL
Java_com_findai_xkk_myopencv_MainActivity_stringFromJNI(JNIEnv *env,jobject /* this */,jintArray pixels_, jint w, jint h) {jint* pixels = env->GetIntArrayElements(pixels_, NULL);if (pixels==NULL){return 0;}//图片一进来时是ARGB 通过mat转换BGRAMat img(h,w,CV_8UC4,(uchar *)pixels); //pixels 操作的是同一份数据h = h/2,w = w/2;resize(img,img,Size(w,h));printMAtMessage(img);Mat temp;
//转化为单通道灰度图,并打印信息cvtColor(img,temp,COLOR_RGBA2GRAY);
// printMAtMessage(temp);int summat[h][w] ;// Mat cal_mat = temp.clone();int max_cha = 0;
// LOGD("rows: %d",temp.rows);
// LOGD("cols: %d",temp.cols);
// LOGD("w: %d",w);
// LOGD("h: %d",h);
// int kk=0;for(int i =6 ;i// int sum_d = 0;for(int j =6;j// LOGD("DDD %d",temp.at(i,j));int sum_s = temp.at(i-1,j)+temp.at(i-2,j)+temp.at(i-3,j)+temp.at(i-4,j)+temp.at(i-5,j);
// LOGD("------================211111111111111111111111111===------------ %d %s",i,j);int sum_x = temp.at(i+1,j)+temp.at(i+2,j)+temp.at(i+3,j)+temp.at(i+4,j)+temp.at(i+5,j);
// LOGD("------==============22222222222222222222=====------------");int cha = sum_s - sum_x;
// LOGD("------===============3333333333333333333333333====------------");summat[i][j] = abs(cha);
// LOGD("------===============33333333333 %d 33333333333333====------------",summat[i][j]);
// temp.at(i,j)=255;
// kk++;
// LOGD("i: %d",i);
// LOGD("j: %d",j);
// LOGD("------==============444444444444444444444444=====------------");if(max_cha// LOGD("max %d",max_cha);
// LOGD("------============44666666666666666666666666666666666=======------------");}
// sum_d = sum_d + ;}}int std_max = max_cha*0.4;
// LOGD("------=========== %d ========------------",max_cha);for(int i =6 ;i// int max_col = 0;
// int max_i = 0;
// int max_j = 0;for(int j =6;j// LOGD("DDD %d",temp.at(i,j));
// int sum_s = temp.at(i-1,j)+temp.at(i-2,j)+temp.at(i-3,j)+temp.at(i-4,j)+temp.at(i-5,j);
// int sum_x = temp.at(i+1,j)+temp.at(i+2,j)+temp.at(i+3,j)+temp.at(i+4,j)+temp.at(i+5,j);
// int cha = sum_s - sum_x;
// int cur_gray = summat[i][j];
// LOGD("------=======cur_gray==== %d ========------------",cur_gray);if(summat[i][j] > std_max){// LOGD("------=======cur_gray==== %d ========------------",cal_mat.at(i,j));temp.at(i,j)=255;}
// if(max_cha// max_cha = cha;
// }
// sum_d = sum_d + ;}}//转化为四通道。特别注意:在调用ov图像处理函数时,一定要好好考虑一下图片的位数和通道.否则可能出现各种问题.cvtColor(temp,temp,COLOR_GRAY2BGRA);
// printMAtMessage(temp);uchar* tempData = temp.data;//对应数据指针int size = w*h;jintArray result = env->NewIntArray(size);
//env->SetIntArrayRegion(result,0,size,pixels);env->SetIntArrayRegion(result, 0, size, (const jint *) tempData);env->ReleaseIntArrayElements(pixels_, pixels, 0);return result;
}
void printMAtMessage(Mat &mat) {LOGD("***************************Mat信息开始************************");LOGD("mat.rows %d",mat.rows);LOGD("mat.cols %d",mat.cols);LOGD("mat.total %d",mat.total());LOGD("mat.channels %d",mat.channels());LOGD("mat.depth %d",mat.depth());LOGD("mat.type %d",mat.type());LOGD("mat.flags %d",mat.flags);LOGD("mat.elemSize %d",mat.elemSize());LOGD("mat.elemSize1 %d",mat.elemSize1());LOGD("***************************Mat信息结束************************");
}}
JAVA代码:
package com.findai.xkk.myopencv;import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;
import android.widget.TextView;import org.opencv.android.OpenCVLoader;
import org.opencv.android.Utils;
import org.opencv.core.Mat;public class MainActivity extends AppCompatActivity {// Used to load the 'native-lib' library on application startup.static {System.loadLibrary("native-lib");}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//非常重要,启动opencv,必须写在最前面OpenCVLoader.initDebug();setContentView(R.layout.activity_main);Bitmap bmp = BitmapFactory.decodeResource(getResources(),R.mipmap.eye);ImageView imageView = findViewById(R.id.iv_pro_img);int w = bmp.getWidth();int h = bmp.getHeight();
// System.out.println(w);
// System.out.println(h);int[] pixels = new int[w*h];bmp.getPixels(pixels, 0, w, 0, 0, w, h);long startTime = System.currentTimeMillis();int[] resultInt = stringFromJNI(pixels, w, h);long endTime = System.currentTimeMillis();Log.e("JNITime",""+(endTime-startTime));Bitmap resultImg = Bitmap.createBitmap(w/2,h/2, Bitmap.Config.ARGB_8888);//(@ColorInt int[] pixels, int offset, int stride,int x, int y, int width, int height)
// System.out.println(w/2);
// System.out.println(h/2);resultImg.setPixels(resultInt, 0, w/2, 0, 0, w/2,h/2);imageView.setImageBitmap(resultImg);}/*** A native method that is implemented by the 'native-lib' native library,* which is packaged with this application.*/public native int[] stringFromJNI(int[] pixels, int w, int h);
}
核心思路:
眼睑处,灰度变化最大,所以上下采集一定空间范围的灰度值进行计算,同时减少噪声的干扰。算法实时性较高,能达到100FPS。
之前尝试过深度学习,MRCNN等方法,效果是不错,但是实时性跟不上,不适合在移动端部署。故采用传统图像处理方法,尝试过Sobel的梯度变化等等方法,最终本算法 简单有效实时性高。
效果图:
GitHUB:
https://github.com/xkkjiayou/MYOPencv_real
JNI C++参考:
https://blog.csdn.net/wulafly/article/details/71076594
https://blog.csdn.net/qq_29540745/article/details/52487832
https://blog.csdn.net/wjb820728252/article/details/78357269
https://blog.csdn.net/brcli/article/details/76407986