javaandroid中opencv的使用

opencv使用帮助
http://docs.opencv.org/

opencv图片灰度化:

package com.testopencv.haveimgfun; 
 public class LibImgFun {  
 static {   
         System.loadLibrary("ImgFun");   
        }   
       /** * @param width the current view width * @param height the current view height */ 
     public static native int[] ImgFun(int[] buf, int w, int h);  
 }


 class ClickEvent implements View.OnClickListener {  
        public void onClick(View v) {  
            if (v == btnNDK) {  
                long current = System.currentTimeMillis();  
                Bitmap img1 = ((BitmapDrawable) getResources().getDrawable(  
                        R.drawable.lena)).getBitmap();  
                int w = img1.getWidth(), h = img1.getHeight();  
                int[] pix = new int[w * h];  
                img1.getPixels(pix, 0, w, 0, 0, w, h);  
                int[] resultInt = LibImgFun.ImgFun(pix, w, h);  
                Bitmap resultImg = Bitmap.createBitmap(w, h, Config.RGB_565);  
                resultImg.setPixels(resultInt, 0, w, 0, 0, w, h);  
                long performance = System.currentTimeMillis() - current;  
                imgView.setImageBitmap(resultImg);  
                HaveImgFun.this.setTitle("w:" + String.valueOf(img1.getWidth())  
                        + ",h:" + String.valueOf(img1.getHeight()) + "NDK耗时"  
                        + String.valueOf(performance) + " 毫秒");  
            } else if (v == btnRestore) {  
                Bitmap img2 = ((BitmapDrawable) getResources().getDrawable(  
                        R.drawable.lena)).getBitmap();  
                imgView.setImageBitmap(img2);  
                HaveImgFun.this.setTitle("使用OpenCV进行图像处理");  
            }  
        }  

LibImgFun代码:

#include <jni.h>
#include <stdio.h>
#include <stdlib.h>
#include <opencv2/opencv.hpp>
using namespace cv;
IplImage * change4channelTo3InIplImage(IplImage * src);

extern "C" {
JNIEXPORT jintArray JNICALL Java_com_testopencv_haveimgfun_LibImgFun_ImgFun(
        JNIEnv* env, jobject obj, jintArray buf, int w, int h);
JNIEXPORT jintArray JNICALL Java_com_testopencv_haveimgfun_LibImgFun_ImgFun(
        JNIEnv* env, jobject obj, jintArray buf, int w, int h) {

    jint *cbuf;
    cbuf = env->GetIntArrayElements(buf, false);
    if (cbuf == NULL) {
        return 0;
    }

    Mat myimg(h, w, CV_8UC4, (unsigned char*) cbuf);
    IplImage image=IplImage(myimg);
    IplImage* image3channel = change4channelTo3InIplImage(&image);

    IplImage* pCannyImage=cvCreateImage(cvGetSize(image3channel),IPL_DEPTH_8U,1);

    cvCanny(image3channel,pCannyImage,50,150,3);

    int* outImage=new int[w*h];
    for(int i=0;i<w*h;i++)
    {
        outImage[i]=(int)pCannyImage->imageData[i];
    }

    int size = w * h;
    jintArray result = env->NewIntArray(size);
    env->SetIntArrayRegion(result, 0, size, outImage);
    env->ReleaseIntArrayElements(buf, cbuf, 0);
    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);
        }
    }

    return destImg;
}

来自:http://blog.csdn.net/watkinsong/article/details/9849973

二值化:

#include "opencv2/opencv.hpp" 
using namespace cv;  

void Java_com_test_MainActivity(JNIEnv* env jclass jthis){  
    Mat mat = imread("/test.jpg");  
    mat = mat >50;    //二值化 
   imwrite("out.jpg",mat);  
}  

人脸检测:

package com.tcl.uviewer.features.featuresImpl;

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.highgui.Highgui;
import org.opencv.objdetect.CascadeClassifier;

public class Test
{

public static void detectFace(String imagePath)
{
System.out.println("\nRunning DetectFaceDemo");

// 导入opencv的库
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);

// 从配置文件lbpcascade_frontalface.xml中创建一个人脸识别器,该文件位于opencv安装目录中
CascadeClassifier faceDetector = new CascadeClassifier(
"C:/lbpcascade_frontalface.xml");
Mat image = Highgui.imread(imagePath);

// 在图片中检测人脸
MatOfRect faceDetections = new MatOfRect();
faceDetector.detectMultiScale(image, faceDetections);

System.out.println(String.format("Detected %s faces",
faceDetections.toArray().length));

// 在每一个识别出来的人脸周围画出一个方框
for (org.opencv.core.Rect rect : faceDetections.toArray())
{
Core.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x
+ rect.width, rect.y + rect.height), new Scalar(0, 255, 0));
}

// 将结果保存到文件
String filename = "faceDetection.png";
System.out.println(String.format("Writing %s", filename));
Highgui.imwrite(filename, image);
}

public static void main(String[] args)
{
String imagePath = "C:/005.jpg";
Test.detectFace(imagePath);
}
}
 System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        System.out.println("\nRunning FaceDetector");

        CascadeClassifier faceDetector = new CascadeClassifier(FaceDetector.class.getResource("haarcascade_frontalface_alt.xml").getPath());
        Mat image = Highgui
                .imread(FaceDetector.class.getResource("shekhar.JPG").getPath());

        MatOfRect faceDetections = new MatOfRect();
        faceDetector.detectMultiScale(image, faceDetections);

        System.out.println(String.format("Detected %s faces", faceDetections.toArray().length));

        for (Rect rect : faceDetections.toArray()) {
            Core.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height),
                    new Scalar(0, 255, 0));
        }

        String filename = "ouput.png";
        System.out.println(String.format("Writing %s", filename));
        Highgui.imwrite(filename, image);

识别结果:
javaandroid中opencv的使用_第1张图片
来源:
http://yuanhuan.blog.51cto.com/3367116/1301368
http://yjdingkai.iteye.com/blog/1532450
http://www.cnblogs.com/endless-on/p/3491154.html

人脸识别匹配代码:

public double CmpPic(String path) {  
        int l_bins = 20;  
        int hist_size[] = { l_bins };  

        float v_ranges[] = { 0, 100 };  
        float ranges[][] = { v_ranges };  

        IplImage Image1 = cvLoadImage(Environment.getExternalStorageDirectory()  
                + "/FaceDetect/faceDone.jpg", CV_LOAD_IMAGE_GRAYSCALE);  
        IplImage Image2 = cvLoadImage(path, CV_LOAD_IMAGE_GRAYSCALE);  

        IplImage imageArr1[] = { Image1 };  
        IplImage imageArr2[] = { Image2 };  

        CvHistogram Histogram1 = CvHistogram.create(1, hist_size,  
                CV_HIST_ARRAY, ranges, 1);  
        CvHistogram Histogram2 = CvHistogram.create(1, hist_size,  
                CV_HIST_ARRAY, ranges, 1);  

        cvCalcHist(imageArr1, Histogram1, 0, null);  
        cvCalcHist(imageArr2, Histogram2, 0, null);  

        cvNormalizeHist(Histogram1, 100.0);  
        cvNormalizeHist(Histogram2, 100.0);  

        return cvCompareHist(Histogram1, Histogram2, CV_COMP_CORREL);  
    }  

参考:http://blog.csdn.net/sky286753213/article/details/11887913
demo下载地址:http://download.csdn.net/detail/sky286753213/6617075

androidstudio opencv demo:
https://github.com/quanhua92/OpenCV_Java_AndroidStudio

how to use opencv-java in androidstudio?:
http://www.quan404.com/2015/07/how-to-use-opencv-android-in-android.html

opencv的匹配图片:

   mMatches为识别结果
    /** * * 对场景图片帧进行相关处理 * 其中在这里获取匹配对 * 然后绘制获取的线框 */
    @Override
    public void apply(final Mat src, final Mat dst) {
        Imgproc.cvtColor(src, mGraySrc, Imgproc.COLOR_RGBA2GRAY);

        mFeatureDetector.detect(mGraySrc, mSceneKeypoints);
        mDescriptorExtractor.compute(mGraySrc, mSceneKeypoints,
                mSceneDescriptors);
        mDescriptorMatcher.match(mSceneDescriptors,
                mReferenceDescriptors, mMatches);

        findSceneCorners();
        draw(src, dst);
    }

    private void findSceneCorners() {

        List<DMatch> matchesList = mMatches.toList();
        // 匹配对太少
        if (matchesList.size() < 4) {
            // There are too few matches to find the homography.
            return;
        }       
        // 将MatOfKeyPoint数据结构存储的特征点数据转换成List,便于后面获取
        List<KeyPoint> referenceKeypointsList =
                mReferenceKeypoints.toList();
        List<KeyPoint> sceneKeypointsList =
                mSceneKeypoints.toList();

        // Calculate the max and min distances between keypoints.
        // 计算特征点之间的最大和最小距离
        double maxDist = 0.0;
        double minDist = Double.MAX_VALUE;
        for(DMatch match : matchesList) {
            double dist = match.distance;
            if (dist < minDist) {
                minDist = dist;
            }
            if (dist > maxDist) {
                maxDist = dist;
            }
        }

        // The thresholds for minDist are chosen subjectively
        // based on testing. The unit is not related to pixel
        // distances; it is related to the number of failed tests
        // for similarity between the matched descriptors.
        // 根据距离对角点进行取舍
        if (minDist > 50.0) {
            // The target is completely lost.
            // Discard any previously found corners.
            mSceneCorners.create(0, 0, mSceneCorners.type());
            return;
        } else if (minDist > 25.0) {
            // The target is lost but maybe it is still close.
            // Keep any previously found corners.
            return;
        }

        // Identify "good" keypoints based on match distance.
        ArrayList<Point> goodReferencePointsList =
                new ArrayList<Point>();
        ArrayList<Point> goodScenePointsList =
                new ArrayList<Point>();
        // 最佳距离极限为minDist的1.75倍,然后拾取在此范围的点到ArrayList中
        double maxGoodMatchDist = 1.75 * minDist;
        for(DMatch match : matchesList) {
            if (match.distance < maxGoodMatchDist) {
               goodReferencePointsList.add(
                       referenceKeypointsList.get(match.trainIdx).pt);
               goodScenePointsList.add(
                       sceneKeypointsList.get(match.queryIdx).pt);
            }
        }

        // 如果在范围内的(拾取到的)点数小于4,则表示没有发现标志
        if (goodReferencePointsList.size() < 4 ||
                goodScenePointsList.size() < 4) {
            // There are too few good points to find the homography.
            return;
        }

        // 再从ArrayList转换成MatOfPoint2f数据结构(OpenCV中),同样是为了后面的处理
        // 一个是参考图片的点数据,一个是图像帧的点数据
        MatOfPoint2f goodReferencePoints = new MatOfPoint2f();
        goodReferencePoints.fromList(goodReferencePointsList);

        MatOfPoint2f goodScenePoints = new MatOfPoint2f();
        goodScenePoints.fromList(goodScenePointsList);

        // 计算单应性矩阵,根据最佳参考图像和场景图片的特征点(需要描述)
        Mat homography = Calib3d.findHomography(
                goodReferencePoints, goodScenePoints);
        /** * 根据单应性矩阵对参考图像帧进行透视变换,将2D场景转换成3D * 保存在mCandidateSceneCorners */
        Core.perspectiveTransform(mReferenceCorners,
                mCandidateSceneCorners, homography);
        // 对mCandidateSceneCorners进行类型转换
        mCandidateSceneCorners.convertTo(mIntSceneCorners,
                CvType.CV_32S);
        // 输入数据(四边形)必须是凸面
        if (Imgproc.isContourConvex(mIntSceneCorners)) {
            mCandidateSceneCorners.copyTo(mSceneCorners);
        }
    }

显示结果:
javaandroid中opencv的使用_第2张图片
参考:http://arvrschool.com/read.php?tid=163&fid=52

你可能感兴趣的:(opencv)