Android - 模板匹配

时间:2015-03-24 16:50:18

标签: android opencv highgui

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

  1. 打开相机
  2. 获取框架
  3. 通过触摸屏选择框架
  4. 在可绘制文件夹下加载模板图像
  5. 应用模板匹配
  6. 显示结果
  7. 模板图像的mat对象不为空。我检查一下。当我运行此代码时,我收到以下错误消息。

    enter image description here

    代码:

    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;
    }
    

1 个答案:

答案 0 :(得分:3)

对于模板匹配,源图像和模板图像必须具有相同的数据类型(1)。您的模板图片(mTemp)是灰度图像,源图像(mRgba / temp)是带有Alpha通道的彩色图像。

因此,让我们将源图像和模板图像都更改为灰度图像

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

并将mRgba.copyTo(temp)替换为

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