1

我已经下载并成功运行了opencv4android sdk中提供的示例。

能够简单地显示相机帧而无需任何处理,

 public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
     return inputFrame.rgba();
 }

想用一些预定义的图像模板处理实时帧以识别该模板。我已经参考了这篇文章并相应地实施了。但我只得到黑屏。

private Mat mCameraMat = new Mat();
private Mat mTemplateMat;

 public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
    mCameraMat = inputFrame.rgba();
    initialize();

     int match_method = Imgproc.TM_SQDIFF;

        // Create the result matrix
        int result_cols = mCameraMat.cols() - mTemplateMat.cols() + 1;
        int result_rows = mCameraMat.rows() - mTemplateMat.rows() + 1;
        Log.d(TAG, " mCameraMat cols "+mCameraMat.cols());
        Log.d(TAG, " mCameraMat rows "+mCameraMat.rows());
        Log.d(TAG, " mTemplateMat cols "+mTemplateMat.cols());
        Log.d(TAG, " mTemplateMat rows "+mTemplateMat.rows());

       Mat result = new Mat(result_rows, result_cols, CvType.CV_32F);

        // Do the Matching and Normalize
        Imgproc.matchTemplate(mCameraMat, mTemplateMat, 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;
        }

        Rect roi = new Rect((int) matchLoc.x, (int) matchLoc.y, mTemplateMat.cols(), mTemplateMat.rows());
        Core.rectangle(mCameraMat, new Point(roi.x, roi.y), new Point(roi.width - 2, roi.height - 2), new Scalar(255, 0, 0, 255), 2);           
 return result;
}

public void initialize(){

    try {
        if (mCameraMat.empty())
            return;
        if(mTemplateMat == null){
            Mat temp = Utils.loadResource(Tutorial1Activity.this, R.drawable.icon);
            mTemplateMat = new Mat(temp.size(), CvType.CV_32F);
            Imgproc.cvtColor(temp, mTemplateMat, Imgproc.COLOR_BGR2RGBA);
            Log.d(TAG, "initialize mTemplateMat cols "+mTemplateMat.cols());
            Log.d(TAG, "initialize mTemplateMat rows "+mTemplateMat.rows());
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

笔记:

我的最终目标是从现场摄像机中识别出扑克牌。请建议最好的方法。我应该使用图像模板或其他任何东西来加快速度吗?

这就是我想从实时相机中识别多张卡的方式:

结果应该是:♠A ♠K ♠Q ♠J ♠10 当相机预览如下所示

在此处输入图像描述

4

1 回答 1

0

模板匹配不太可能是这里的最佳方法。

  1. 尝试aSIFT进行仿射不变 SIFT 匹配或正常 SIFT(存在 OpenCV 实现)。但是,由于这些是在 C++ 中的,您可能希望使用 JNI 在 Android 设备上从 Java 调用它。这可能是从 4 个符号中检测卡片花色的最佳方法。
  2. 检测和识别卡片上的数字/字母的另一种选择是使用像MSER这样的文本检测器,然后在 MSER 过滤器指示的感兴趣区域上使用文本识别器。

在任何情况下,您都不太可能从您在图像中显示的图像中产生最佳结果。使用第一种方法,您可能能够获得可接受的完整正面、直立图像的性能。

于 2015-07-02T15:03:56.657 回答