程序员首选内裤点击打开链接
你先需要自己下载opencv3.0SDK,项目下载点击打开链接
先看效果图
接下来是代码
布局部分
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${relativePackage}.${activityClass}" >
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btnId"
android:text="开始检测"/>
<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/txtResultId"
android:layout_toRightOf="@id/btnId"
android:gravity="center"
android:textSize="25sp"
android:textColor="#ff0000"/>
<ImageView android:id="@+id/img1Id"
android:layout_width="240px"
android:layout_height="320px"
android:layout_below="@id/btnId"
android:layout_centerHorizontal="true"/>
<ImageView android:id="@+id/img2Id"
android:layout_width="240px"
android:layout_height="320px"
android:layout_below="@id/img1Id"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
java部分
package com.example.motiondetect;
public class CameraTest {
public static native int grayProc1(int[] pixels, int w, int h);
public static native int grayProc(int[] pix1,int[] pix2, int w, int h);
}
package com.example.motiondetect;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.videoio.VideoCapture;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
public class MainActivity extends Activity {
private VideoCapture cap;
private Button btnObj;
private Bitmap bmp1;
private Bitmap bmp2;
private TextView txtObj;
private ImageView imgObj1;
private ImageView imgObj2;
//OpenCV类库加载并初始化成功后的回调函数,在此我们不进行任何操作
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
@Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS:{
System.loadLibrary("test");
} break;
default:{
super.onManagerConnected(status);
} break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnObj=(Button)findViewById(R.id.btnId);
//将lena图像加载程序中并进行显示
bmp1 = BitmapFactory.decodeResource(getResources(), R.drawable.i21);
bmp2=BitmapFactory.decodeResource(getResources(), R.drawable.i22);
txtObj=(TextView)findViewById(R.id.txtResultId);
imgObj1=(ImageView)findViewById(R.id.img1Id);
imgObj2=(ImageView)findViewById(R.id.img2Id);
imgObj1.setImageBitmap(bmp1);
imgObj2.setImageBitmap(bmp2);
btnObj.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
int w = bmp1.getWidth();
int h = bmp1.getHeight();
int[] pix1 = new int[w*h];
bmp1.getPixels(pix1, 0, w, 0, 0, w, h);
int[] pix2 = new int[w*h];
bmp2.getPixels(pix2, 0, w, 0, 0, w, h);
int r=CameraTest.grayProc(pix1,pix2, w, h);
Log.e("","rusult="+r );
txtObj.setText(r<=5?"they are the same":(r>10?"they are different":"they are somewhat similar"));
}
});
}
@Override
public void onResume(){
super.onResume();
//通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是
//OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存在于OpenCV安装包的apk目录中
Log.e("",""+OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback));
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
bmp1.recycle();
bmp2.recycle();
super.onDestroy();
}
}
jni部分
#include <CameraTest.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <android/log.h>
#define LOG_TAG "JNI"
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
using namespace cv;
//JNIEXPORT void JNICALL Java_com_example_motiondetect_CameraTest_openCamera(
// JNIEnv * env, jclass cls) {
//
//}
JNIEXPORT jint JNICALL Java_com_example_motiondetect_CameraTest_grayProc1(
JNIEnv *env, jclass cls, jintArray pix, jint w, jint h) {
jint *cbuf;
cbuf = env->GetIntArrayElements(pix, false);
Mat matSrc(h, w, CV_8UC4, (unsigned char*) cbuf);
Mat matSrc1, matSrc2;
// CV_Assert(matSrc.channels()==3);
cv::resize(matSrc, matSrc1, cv::Size(357, 419), 0, 0, cv::INTER_NEAREST);
cv::resize(matSrc, matSrc2, cv::Size(480, 800), 0, 0, cv::INTER_LANCZOS4);
cv::Mat matDst1, matDst2;
cv::resize(matSrc1, matDst1, cv::Size(8, 8), 0, 0, cv::INTER_CUBIC);
cv::resize(matSrc2, matDst2, cv::Size(8, 8), 0, 0, cv::INTER_CUBIC);
cv::cvtColor(matDst1, matDst1, CV_BGR2GRAY);
cv::cvtColor(matDst2, matDst2, CV_BGR2GRAY);
int iAvg1 = 0, iAvg2 = 0;
int arr1[64], arr2[64];
for (int i = 0; i < 8; i++) {
uchar* data1 = matDst1.ptr<uchar>(i);
uchar* data2 = matDst2.ptr<uchar>(i);
int tmp = i * 8;
for (int j = 0; j < 8; j++) {
int tmp1 = tmp + j;
arr1[tmp1] = data1[j] / 4 * 4;
arr2[tmp1] = data2[j] / 4 * 4;
iAvg1 += arr1[tmp1];
iAvg2 += arr2[tmp1];
}
}
iAvg1 /= 64;
iAvg2 /= 64;
for (int i = 0; i < 64; i++) {
arr1[i] = (arr1[i] >= iAvg1) ? 1 : 0;
arr2[i] = (arr2[i] >= iAvg2) ? 1 : 0;
}
int iDiffNum = 0;
for (int i = 0; i < 64; i++)
if (arr1[i] != arr2[i])
++iDiffNum;
LOGE("iDiffNum =%d", iDiffNum);
if (iDiffNum <= 5)
LOGE("two images are very similar!");
else if (iDiffNum > 10)
LOGE("they are two different images!");
else
LOGE("two image are somewhat similar!");
env->ReleaseIntArrayElements(pix, cbuf, 0);
return iDiffNum;
}
JNIEXPORT jint JNICALL Java_com_example_motiondetect_CameraTest_grayProc(
JNIEnv *env, jclass cls, jintArray pix1, jintArray pix2, jint w,
jint h) {
jint *cbuf;
cbuf = env->GetIntArrayElements(pix1, false);
jint *dbuf;
dbuf = env->GetIntArrayElements(pix2, false);
Mat matSrc1(h, w, CV_8UC4, (unsigned char*) cbuf);
Mat matSrc2(h, w, CV_8UC4, (unsigned char*) dbuf);
cv::Mat matDst1, matDst2;
cv::resize(matSrc1, matDst1, cv::Size(8, 8), 0, 0, cv::INTER_CUBIC);
cv::resize(matSrc2, matDst2, cv::Size(8, 8), 0, 0, cv::INTER_CUBIC);
cv::cvtColor(matDst1, matDst1, CV_BGR2GRAY);
cv::cvtColor(matDst2, matDst2, CV_BGR2GRAY);
int iAvg1 = 0, iAvg2 = 0;
int arr1[64], arr2[64];
for (int i = 0; i < 8; i++) {
uchar* data1 = matDst1.ptr<uchar>(i);
uchar* data2 = matDst2.ptr<uchar>(i);
int tmp = i * 8;
for (int j = 0; j < 8; j++) {
int tmp1 = tmp + j;
arr1[tmp1] = data1[j] / 4 * 4;
arr2[tmp1] = data2[j] / 4 * 4;
iAvg1 += arr1[tmp1];
iAvg2 += arr2[tmp1];
}
}
iAvg1 /= 64;
iAvg2 /= 64;
for (int i = 0; i < 64; i++) {
arr1[i] = (arr1[i] >= iAvg1) ? 1 : 0;
arr2[i] = (arr2[i] >= iAvg2) ? 1 : 0;
}
int iDiffNum = 0;
for (int i = 0; i < 64; i++)
if (arr1[i] != arr2[i])
++iDiffNum;
LOGE("iDiffNum =%d", iDiffNum);
if (iDiffNum <= 5)
LOGE("two images are very similar!");
else if (iDiffNum > 10)
LOGE("they are two different images!");
else
LOGE("two image are somewhat similar!");
env->ReleaseIntArrayElements(pix1, cbuf, 0);
env->ReleaseIntArrayElements(pix2, dbuf, 0);
return iDiffNum;
}