本文介绍了Android的 - 模板匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个Android应用程序。程序步骤如下所示


  1. 开启相机

  2. 获取帧

  3. 选择通过触摸屏的边框

  4. 绘制文件夹下的载入模板图片

  5. 应用模板匹配

  6. 显示结果

模板图像的垫子对象不为空。我检查一下。当我运行这个code,我得到以下错误消息。

code:

 公共无效onCameraViewStarted(INT宽度,高度INT){
    mRgba =新垫(高度,宽度,CvType.CV_8UC4);
    临时=新垫(高度,宽度,CvType.CV_8UC4);
}公共布尔onTouch(视图V,MotionEvent事件){
    INT COLS = mRgba.cols();
    INT行= mRgba.rows();    INT xOffset =(mOpenCvCameraView.getWidth() - COLS)/ 2;
    INT yOffset =(mOpenCvCameraView.getHeight() - 行)/ 2;    INT X =(INT)event.getX() - xOffset;
    INT Y =(int)的event.getY() - yOffset;    Log.i(TAG,触摸图像坐标:(+ X +,+ Y +));    如果((X小于0)||(Y℃下)||(X> COLS)||(Y>行))返回false;    mIsColorSelected = TRUE;
    返回true; //不需要后续触摸事件
}私人静电台垫readInputStreamIntoMat(的InputStream的InputStream)抛出IOException
    //读入字节数组
    字节[] = temporaryImageInMemory readStream(InputStream的);    //德code到垫子。使用恰当地描述你的图像的任何IMREAD_选项
    垫outputImage = Highgui.imde code(新MatOfByte(temporaryImageInMemory),Highgui.IMREAD_GRAYSCALE);    返回outputImage;
}私人静态的byte [] readStream(InputStream的流)抛出IOException
    //图像将内容复制到字节数组
    ByteArrayOutputStream缓冲区=新ByteArrayOutputStream();
    INT NREAD;
    字节[]数据=新的字节[16384]    而((NREAD = stream.read(数据,0,data.length))!= - 1){
        buffer.write(数据,0,NREAD);
    }    buffer.flush();
    字节[] = temporaryImageInMemory buffer.toByteArray();
    buffer.close();
    stream.close();
    返回temporaryImageInMemory;
}
公共垫onCameraFrame(CvCameraViewFrame inputFrame){    如果(mIsColorSelected){
   InputStream的INPT = getResources()openRawResource(R.drawable.imgt)。
   太mTemp;
        尝试{
            mRgba.copyTo(临时);
            mTemp = readInputStreamIntoMat(INPT);
        }赶上(IOException异常五){
            // TODO自动生成catch块
            e.printStackTrace();
        }
        // /创建结果矩阵
        INT result_cols = temp.cols() - mTemp.cols()+ 1;
        INT result_rows = temp.rows() - mTemp.rows()+ 1;
        垫结果=新垫(result_rows,result_cols,CvType.CV_32FC1);
        INT match_method = 4;
        // /执行匹配和规范
        Imgproc.matchTemplate(温度,mTemp,因此,match_method);
          Core.normalize(结果,结果,0,1,Core.NORM_MINMAX,-1,新垫());
     / *
         本地化与minMaxLoc最佳匹配
        MinMaxLocResult MMR = Core.minMaxLoc(结果);        点matchLoc;
        如果(match_method == || Imgproc.TM_SQDIFF == match_method Imgproc.TM_SQDIFF_NORMED){
            matchLoc = mmr.minLoc;
        }其他{
            matchLoc = mmr.maxLoc;
        } / *
        // / 告诉我你得到了什么
        Core.rectangle(温度,matchLoc,新点(matchLoc.x + mTemp.cols()
                matchLoc.y + mTemp.rows()),新的标量(0,255,0)); * /
        返回温度;
    }
    其他{
        mRgba = inputFrame.rgba();
    }    返回mRgba;
}


解决方案

有关模板匹配,无论是源图像和模板图像必须是相同的数据类型(<一href=\"http://docs.opencv.org/modules/imgproc/doc/object_detection.html?highlight=matchtemplate#matchtemplate\"相对=nofollow> 1 )。在这里,你的模板图像( mTemp )是灰度图像和源图像( mRgba / 温度)是alpha通道的彩色图像。

所以,让我们改变源代码和模板图像是灰度图像

 临时=新垫(高度,宽度,CvType.CV_8UC1);

和替换 mRgba.copyTo(临时)

  Imgproc.cvtColor(mRgba,温度,Imgproc.COLOR_RGBA2GRAY);

I want to create an android application. Program steps are below

  1. Open camera
  2. Get frames
  3. Select a frame by touch screen
  4. Load template image under drawable folder
  5. Apply template matching
  6. Show result

The mat object of template image is not empty. I check it. When I run this code, I get below error message.

Code :

public void onCameraViewStarted(int width, int height) {
    mRgba = new Mat(height, width, CvType.CV_8UC4);
    temp = new Mat(height, width, CvType.CV_8UC4);
}

public boolean onTouch(View v, MotionEvent event) {
    int cols = mRgba.cols();
    int rows = mRgba.rows();

    int xOffset = (mOpenCvCameraView.getWidth() - cols) / 2;
    int yOffset = (mOpenCvCameraView.getHeight() - rows) / 2;

    int x = (int)event.getX() - xOffset;
    int y = (int)event.getY() - yOffset;

    Log.i(TAG, "Touch image coordinates: (" + x + ", " + y + ")");

    if ((x < 0) || (y < 0) || (x > cols) || (y > rows)) return false;

    mIsColorSelected = true;
    return true; // don't need subsequent touch events
}

private static Mat readInputStreamIntoMat(InputStream inputStream) throws IOException {
    // Read into byte-array
    byte[] temporaryImageInMemory = readStream(inputStream);

    // Decode into mat. Use any IMREAD_ option that describes your image appropriately
    Mat outputImage = Highgui.imdecode(new MatOfByte(temporaryImageInMemory), Highgui.IMREAD_GRAYSCALE);

    return outputImage;
}

private static byte[] readStream(InputStream stream) throws IOException {
    // Copy content of the image to byte-array
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    int nRead;
    byte[] data = new byte[16384];

    while ((nRead = stream.read(data, 0, data.length)) != -1) {
        buffer.write(data, 0, nRead);
    }

    buffer.flush();
    byte[] temporaryImageInMemory = buffer.toByteArray();
    buffer.close();
    stream.close();
    return temporaryImageInMemory;
}
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {

    if(mIsColorSelected) {
   InputStream inpT = getResources().openRawResource(R.drawable.imgt);
   Mat mTemp;
        try {
            mRgba.copyTo(temp);
            mTemp = readInputStreamIntoMat(inpT);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        // / Create the result matrix
        int result_cols = temp.cols() - mTemp.cols() + 1;
        int result_rows = temp.rows() - mTemp.rows() + 1;
        Mat result = new Mat(result_rows, result_cols, CvType.CV_32FC1);
        int match_method = 4;
        // / Do the Matching and Normalize
        Imgproc.matchTemplate(temp, mTemp, result, match_method);
          Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new Mat());
     /*
         Localizing the best match with minMaxLoc
        MinMaxLocResult mmr = Core.minMaxLoc(result);

        Point matchLoc;
        if (match_method == Imgproc.TM_SQDIFF || match_method == Imgproc.TM_SQDIFF_NORMED) {
            matchLoc = mmr.minLoc;
        } else {
            matchLoc = mmr.maxLoc;
        }/*
        // / Show me what you got
        Core.rectangle(temp, matchLoc, new Point(matchLoc.x + mTemp.cols(),
                matchLoc.y + mTemp.rows()), new Scalar(0, 255, 0));*/
        return temp;
    }
    else {
        mRgba = inputFrame.rgba();
    }

    return mRgba;
}
解决方案

For template matching , both source image and template image must be of same data type(1). Here your template image(mTemp) is a gray scale image and source image( mRgba / temp ) is a color image with alpha channel.

So, lets change both source and template images to be gray scale images

temp = new Mat(height, width, CvType.CV_8UC1);

and replace mRgba.copyTo(temp) with

Imgproc.cvtColor(mRgba, temp, Imgproc.COLOR_RGBA2GRAY);

这篇关于Android的 - 模板匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-27 23:06
查看更多