Android OpenCV 3D图片智能识别

原理简介

3D图片分为左右图和上下图,本程序的主要目的是将图片判断是左右图、上下图还是2D图片。原理采用灰度直方图匹配的方式,首先将图片分割为左右图,判断是否类似,然后将图片分割为上下图,判断是否类似,最终将得到的结果进行分析,得出最后结果。本程序中阈值选择为0.1.

代码实现

关键代码如下:
	private static final String TAG = TDImageRecognition.class.getSimpleName();
	public static final int LRMODEL = 1;
	public static final int RLMODEL = 2;
	public static final int TDMODEL = 3;
	public static final int DTMODEL = 4;
	public static final int SDMODEL = 5;

	static {
		try {
			System.loadLibrary("tdimage");
		} catch (UnsatisfiedLinkError use) {
			Log.e(TAG, "WARNING: Could not load libtd_image.so");
		}
	}

	public static int imageRecognition(Bitmap bitmap) {
		if (bitmap == null)
			return 0;
		int w = bitmap.getWidth(), h = bitmap.getHeight();
		int[] pix = new int[w * h];
		bitmap.getPixels(pix, 0, w, 0, 0, w, h);
		int result = TDImageRecognition.tDImageRecognition(pix, w, h);
		return result;
	}

	public static native int[] imageRecognition(int[] sourceImage, int w, int h);

	public static native int tDImageRecognition(int[] sourceImage, int w, int h);
	
	public static native int _getVideoType(String path);

通过JNI的方式调用OPENCV进行识别
JNIEXPORT jint JNICALL Java_com_runmit_imagerecognition_utils_TDImageRecognition_tDImageRecognition(
		JNIEnv * env, jobject obj, jintArray buf, jint w, jint h) {

	std::vector lrImages(2);
	std::vector tdImages(2);
	int* cbuf = env->GetIntArrayElements(buf, false);
	IplImage* grayImage = changeArrayToGrayImage(cbuf, w, h);
	//截取左边图片
	IplImage* leftImage = splitImage(grayImage,w/2,h,0,0);
	//截取右边图片
	IplImage* rightImage = splitImage(grayImage,w/2,h,w/2,0);
	//上面图片
	IplImage* topImage = splitImage(grayImage,w,h/2,0,0);
	//下面图片
	IplImage* bottomImage = splitImage(grayImage,w,h/2,0,h/2);

	double lrResult = calHist(leftImage,rightImage);
	double tdResult = calHist(topImage,bottomImage);

	cvReleaseImage(&grayImage);
	cvReleaseImage(&leftImage);
	cvReleaseImage(&rightImage);
	cvReleaseImage(&topImage);
	cvReleaseImage(&bottomImage);

	if(lrResult <= THRESHOLD && tdResult > THRESHOLD) {
		return LRMODEL;
	}

	if(lrResult > THRESHOLD && tdResult <= THRESHOLD) {
		return TDMODEL;
	}

	return SDMODEL;
}
用到的帮助类
#include 
#include 
#include 
#include "ImageUtils.h"
using namespace cv;
extern "C" {


//分割图片
IplImage* splitImage(IplImage* src, int w, int h, int origX,int origY ) {

    if(src == NULL) {
      return NULL;
      printf("the image is null");
	}
    CvSize size= cvSize(w, h);//区域大小
    cvSetImageROI(src,cvRect(origX,origY,size.width, size.height));//设置源图像ROI
    IplImage* pDest = cvCreateImage(size,src->depth,src->nChannels);//创建目标图像
    cvCopy(src,pDest); //复制图像
    cvResetImageROI(src);//源图像用完后,清空ROI
    return pDest;
}

//
double calHist(IplImage* img1,IplImage* img2){

	int hist_size=256;
	float range[] = {0,255};
    float* ranges[]={range};
	CvHistogram* gray_hist = cvCreateHist(1,&hist_size,CV_HIST_ARRAY,ranges,1);
	cvCalcHist(&img1,gray_hist,0,0);

	CvHistogram* gray_hist2 = cvCreateHist(1,&hist_size,CV_HIST_ARRAY,ranges,1);
    cvCalcHist(&img2,gray_hist2,0,0);
	double  result = cvCompareHist(gray_hist,gray_hist2,CV_COMP_BHATTACHARYYA);
	cvReleaseImage(&img1);
	cvReleaseImage(&img2);
	cvReleaseHist(&gray_hist);
	cvReleaseHist(&gray_hist2);
    return result;
}

IplImage * change4channelTo3InIplImage(IplImage * src) {
	if (src->nChannels != 4) {
		return NULL;
	}

	IplImage * destImg = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 3);
	for (int row = 0; row < src->height; row++) {
		for (int col = 0; col < src->width; col++) {
			CvScalar s = cvGet2D(src, row, col);
			cvSet2D(destImg, row, col, s);
		}
	}
	cvReleaseImage(&src);
	return destImg;
}

IplImage* changeArrayToGrayImage(int* cbuf,int w,int h) {

	if (cbuf == NULL) {
		return 0;
	}
	Mat matImage(h, w, CV_8UC4, (unsigned char*) cbuf);
	IplImage  image = IplImage(matImage);
	IplImage* image3channel = change4channelTo3InIplImage(&image);
	IplImage* grayImage = cvCreateImage(cvGetSize(image3channel),IPL_DEPTH_8U,1);

	cvCvtColor(image3channel,grayImage,CV_BGR2GRAY); //关键
	//cvReleaseImage(&image);
    cvReleaseImage(&image3channel);
	return grayImage;

}

}

Android.mk文件
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
OpenCV_INSTALL_MODULES:=on
OPENCV_CAMERA_MODULES:=off
OPENCV_LIB_TYPE:=STATIC
#include ../includeOpenCV.mk 
ifeq ("$(wildcard $(OPENCV_MK_PATH))","") 
#try to load OpenCV.mk from default install location 
include /home/wang1/Documents/opencv/OpenCV-3.1.0-android-sdk/OpenCV-android-sdk/sdk/native/jni/OpenCV.mk 
else 
include $(OPENCV_MK_PATH)
endif
LOCAL_MODULE    := tdimage
LOCAL_C_INCLUDES += core/include
LOCAL_SRC_FILES :=                                \
                   core/ImageUtils.cpp            \
                   core/TDImageRecognition.cpp    \
                   
LOCAL_LDLIBS    += -lm -llog 
include $(BUILD_SHARED_LIBRARY) 

运行效果如下:

Android OpenCV 3D图片智能识别_第1张图片

代码下载


http://download.csdn.net/detail/xiaowang0924/9456408

你可能感兴趣的:(OpenCV,android)