使用 FAST 检测器在 Android 上实时识别对象

Posted

技术标签:

【中文标题】使用 FAST 检测器在 Android 上实时识别对象【英文标题】:object recognition in real time on Android with FAST detector 【发布时间】:2013-02-27 03:50:35 【问题描述】:

这项工作的目的是从视频场景中的现有图像中提取实时关键点过程帧由于匹配而无法执行, 就是我可以在图像上实时以圆圈的形式显示对应的关键点

class Sample1View extends SampleViewBase 
    public static final int     VIEW_MODE_RGBA   = 0;
    public static final int  VIEW_MODE_BLUE  = 1; 
    public static final int  VIEW_MODE_YELLOW = 2;
    public static final int  VIEW_MODE_DE = 3;
    private Mat mYuv;
    private Mat mRgba;
    private Mat mGraySubmat;
    private Mat mResult;
    private Mat mIntermediateMat;
 private Bitmap mBitmap;
 private int mViewMode;
 private Mat mColor;
 private Mat mHsv;
 TimingLogger timings;
   private Mat img1;
    private Mat descriptors;
    private MatOfKeyPoint keypoints;
    private FeatureDetector detector;
    private DescriptorExtractor descriptor;
    private DescriptorMatcher matcher;

 private static final String TAG ="Sample::View";

    public Sample1View(Context context) 
        super(context);
        mViewMode = VIEW_MODE_RGBA;

 try 
 img1=Utils.loadResource(getContext(), R.drawable.wings);
  catch (IOException e) 
 // TODO Auto-generated catch block
 Log.w("Activity::LoadResource","Unable to load resource R.drawable.wings");
 e.printStackTrace();
 
        descriptors = new Mat();
        keypoints = new MatOfKeyPoint();
        detector = FeatureDetector.create(FeatureDetector.FAST);
        detector.detect(img1, keypoints);
        descriptor = DescriptorExtractor.create(DescriptorExtractor.ORB);
        descriptor.compute(img1, keypoints, descriptors);
        matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);
    

 @Override
 protected void onPreviewStarted(int previewWidth, int previewHeight) 
     Log.i(TAG, "preview Started");
     synchronized (this) 
         mYuv = new Mat(getFrameHeight() + getFrameHeight() / 2, getFrameWidth(), CvType.CV_8UC1);
         mGraySubmat = mYuv.submat(0, getFrameHeight(), 0, getFrameWidth());
         mRgba = new Mat();
         mIntermediateMat = new Mat();
         mBitmap = Bitmap.createBitmap(previewWidth, previewHeight, Bitmap.Config.ARGB_8888); 
         mHsv = new Mat();
         mColor = new Mat();
         mResult = new Mat();
         
 

 @Override
 protected void onPreviewStopped() 
     Log.i(TAG, "preview Stopped");
     if(mBitmap != null) 
   mBitmap.recycle();
  

  synchronized (this) 
            // Explicitly deallocate Mats
            if (mYuv != null)
                mYuv.release();
            if (mRgba != null)
                mRgba.release();
            if (mGraySubmat != null)
                mGraySubmat.release();
            if (mIntermediateMat != null)
                mIntermediateMat.release();
            mYuv = null;
            mRgba = null;
            mGraySubmat = null;
            mIntermediateMat = null;
            if (mResult != null)
             mResult.release();
            if (mHsv != null)
             mHsv.release();
            if (mColor != null)
             mColor.release();
            mColor = null;
         mResult = null;
         mHsv = null;
        
    

// cvt_YUVtoRGBtoHSV :

    @Override
    protected Bitmap processFrame(byte[] data) 

        mYuv.put(0, 0, data);
        final int viewMode = mViewMode;

                 ColorDetection.cvt_YUVtoRGBtoHSV(mYuv,mGraySubmat);

      MatOfKeyPoint mKeyPoints = new MatOfKeyPoint();
    MatOfDMatch  matches = new MatOfDMatch();
      detector.detect(mGraySubmat, mKeyPoints);
      descriptor.compute(mGraySubmat, mKeyPoints, mIntermediateMat);
      matcher.match(mIntermediateMat, descriptors, matches);
      mIntermediateMat2.create(resultSize, CvType.CV_8UC1);

      Features2d.drawMatches(mGraySubmat, mKeyPoints, mGraySubmat, mKeyPoints, matches, mIntermediateMat2);
      Imgproc.resize(mIntermediateMat2, mIntermediateMat2, mRgba.size());
      Imgproc.cvtColor(mIntermediateMat2, mRgba, Imgproc.COLOR_RGBA2BGRA, 4);
        break;
        
    Bitmap bmp = mBitmap;

    try 
      Utils.matToBitmap(mRgba, bmp);

     catch(Exception e) 
        Log.e("org.opencv.samples.*", "Utils.matToBitmap() throws an exception: " + e.getMessage());
        bmp.recycle();
        bmp = null;
    
    return bmp;
    

    public void setViewMode(int viewMode) 
     mViewMode = viewMode;
    

在日志中

CvException [org.opencv.core.CvException: /home/reports/ci/slave/50-SDK/opencv/modules/features2d/src/draw.cpp:207: 错误: (-215) i1 >= 0 && i1

【问题讨论】:

【参考方案1】:

这篇文章有点老了,但我已经给出了答案。

您的 drawMatches 函数的前四个参数不正确。前两个和后两个是一样的。 您可以将 drawMatches 的前四个参数从 (mGraySubmat, mKeyPoints, mGraySubmat, mKeyPoints, ...); (mGraySubmat, mKeyPoints, img1, 关键点, ...); 或 (img1, 关键点, mGraySubmat, mKeyPoints, ...); 使用适合您的那个。

对于其他读者,如果他们有同样的问题,他们可以尝试用后两个参数更改前两个参数。 例如: (image1, keypointsImage1, image2, keypointsImage2, ...); 到 (image2, keypointsImage2, image1, keypointsImage1, ...); 对我来说,它解决了我的错误。

【讨论】:

以上是关于使用 FAST 检测器在 Android 上实时识别对象的主要内容,如果未能解决你的问题,请参考以下文章

针对 ARM 优化的 FAST 计算

Android:使用传感器实时检测眼睛的运动

资源 | 在TensorFlow 1.0上实现快速图像生成算法Fast PixelCNN++

用于运行时识别的编译时间字符串分配

NHibernate - 仅更新在运行时识别的指定对象属性

使用 Fast/Faster-RCNN 在 C++ 上制作对象检测器的最简单方法是啥?