Java OpenCV特征检测器

Java OpenCV特征检测器,java,android,opencv,image-processing,object-detection,Java,Android,Opencv,Image Processing,Object Detection,我正试图编写一个应用SURF对象检测的代码,所以我取了一个openCV示例(示例3),并开始更新onCameraViewStarted()和onCameraFrame()方法,但当我在galaxy S3手机上尝试时,不断出现运行时错误,我找不到任何有助于解决问题的方法下面是我的代码和我更新的内容: public class Sample3Native extends Activity implements CvCameraViewListener{ private static final S

我正试图编写一个应用SURF对象检测的代码,所以我取了一个openCV示例(示例3),并开始更新
onCameraViewStarted()
onCameraFrame()
方法,但当我在galaxy S3手机上尝试时,不断出现运行时错误,我找不到任何有助于解决问题的方法下面是我的代码和我更新的内容:

public class Sample3Native extends Activity implements CvCameraViewListener{

private static final String TAG = "OCVSample::Activity";

private Mat                    mRgba;
private Mat                    mGrayMat;
private CameraBridgeViewBase   mOpenCvCameraView;

Mat descriptors ;           
List<Mat> descriptorsList;

FeatureDetector featureDetector;
MatOfKeyPoint keyPoints;
DescriptorExtractor descriptorExtractor;
DescriptorMatcher descriptorMatcher;**


private BaseLoaderCallback     mLoaderCallback = new BaseLoaderCallback(this) {
    @Override
    public void onManagerConnected(int status) {
        switch (status) {
            case LoaderCallbackInterface.SUCCESS:
            {
                Log.i(TAG, "OpenCV loaded successfully");

                // Load native library after(!) OpenCV initialization
                System.loadLibrary("native_sample");

                mOpenCvCameraView.enableView();
            } break;
            default:
            {
                super.onManagerConnected(status);
            } break;
        }
    }
};

public void onCameraViewStarted(int width, int height) {
    mRgba = new Mat(height, width, CvType.CV_8UC4);
    mGrayMat = new Mat(height, width, CvType.CV_8UC1);
    featureDetector=FeatureDetector.create(4); // SURF= 4;
    descriptorExtractor=DescriptorExtractor.create(2);//SURF = 2
    descriptorMatcher=DescriptorMatcher.create(6); //BRUTEFORCE_SL2 = 6**

}

 public Mat onCameraFrame(Mat inputFrame) {
    inputFrame.copyTo(mRgba);
    //detect_1(0, mRgba.getNativeObjAddr(), keyPoints.getNativeObjAddr());
    //Now mRgba contains the current frame ( start manipulation part)
    //detecting keypoints
    featureDetector.detect(mRgba, keyPoints);
    //draw keypoints
   // Features2d.drawKeypoints(mRgba, keyPoints, mRgba);
    //finding descriptors
    descriptorExtractor.compute(mRgba, keyPoints, descriptors);
    //Matcher between 2 images or set of images
    // Note: training set and query set are handled here! (in matcher)
   //descriptorsList = descriptorMatcher.getTrainDescriptors();
    //descriptorsList.add(descriptors);
   // descriptorMatcher.add(descriptorsList);

    //Imgproc.cvtColor(mRgba, mGrayMat, Imgproc.COLOR_RGBA2GRAY);
    //FindFeatures(mGrayMat.getNativeObjAddr(), mRgba.getNativeObjAddr());

    return mRgba;
}
}
公共类Sample3Native extends活动实现CvCameraViewListener{
私有静态最终字符串TAG=“OCVSample::Activity”;
私人Mat mRgba;
私人Mat mGrayMat;
私人摄像机BridgeViewBase mOpenCvCameraView;
Mat描述符;
列表描述符列表;
特征检测器特征检测器;
MatOfKeyPoint关键点;
描述符牵引器描述符牵引器;
描述器描述器**
专用BaseLoaderCallback mlLoaderCallback=新BaseLoaderCallback(此){
@凌驾
已连接管理器上的公共无效(int状态){
开关(状态){
案例加载程序CallbackInterface.SUCCESS:
{
Log.i(标记“OpenCV已成功加载”);
//在(!)OpenCV初始化后加载本机库
System.loadLibrary(“本机样本”);
mOpenCvCameraView.enableView();
}中断;
违约:
{
超级管理器已连接(状态);
}中断;
}
}
};
开始时的公共空隙(整数宽度、整数高度){
mRgba=新垫(高度、宽度、CvType.CV_8UC4);
mGrayMat=新垫(高度、宽度、CvType.CV_8UC1);
featureDetector=featureDetector.create(4);//SURF=4;
descriptorExtractor=descriptorExtractor.create(2);//SURF=2
descriptorMatcher=descriptorMatcher.create(6);//BRUTEFORCE_SL2=6**
}
公共Mat onCameraFrame(Mat inputFrame){
inputFrame.copyTo(mRgba);
//检测_1(0,mRgba.getNativeObjAddr(),keyPoints.getNativeObjAddr());
//现在mRgba包含当前帧(开始操作部分)
//检测关键点
特征检测器。检测(mRgba,关键点);
//画关键点
//特征2d.绘图关键点(mRgba、关键点、mRgba);
//寻找描述符
descriptorExtractor.compute(mRgba、关键点、描述符);
//两个图像或一组图像之间的匹配器
//注意:这里处理训练集和查询集!(在matcher中)
//descriptorsList=descriptorMatcher.getTrainDescriptors();
//描述符列表。添加(描述符);
//descriptorMatcher.add(描述符列表);
//Imgproc.CVT颜色(mRgba、mGrayMat、Imgproc.COLOR_RGBA2GRAY);
//FindFeatures(mGrayMat.getNativeObjAddr(),mRgba.getNativeObjAddr());
返回mRgba;
}
}

注意:我尝试过在
onCameraFrame()
方法中对
featureDetector.detect(mRgba,keyPoints)
进行注释,但仍然在手机上给出了运行时错误。

如果我没有弄错的话,OpenCV SURF功能检测器仅适用于灰度图像。因此,请尝试在调用
onCameraFrame()
方法中的copyTo后添加此选项:

cvtColor(mRgba, mGrayMat, COLOR_RGBA2GRAY);

冲浪或筛选只支持灰度。因此,您必须首先使用以下代码将其转换为灰度:
CVT颜色(mRgba、mRgba、CV_BGR2GRAY)

您确定以正确的方式使用SIFT吗? 据我所知,SIFT和SURF不包括在opencvandroid的发行包中。 要使用它们,您需要编译非自由模块并在项目中使用它。因此,您需要做的是创建一个NDK项目,将非自由模块编译为一个独立的库。然后使用此库编译程序。然后您应该能够构建您的应用程序。你可以参考这个


在获得jni库之后,您可以轻松地将其包装到JavaJNI接口。然后,您应该能够在Android应用程序中使用JAVA接口。

对cid和HMK的答案进行评论(对不起,我没有“添加评论”的50%声誉,所以我必须创建一个新的答案)

OpenCV库可以接受彩色图像作为输入。 下面是我的SIFT检测和描述提取代码。它工作得很好。这意味着您不需要将图像转换为灰度格式,尽管SIFT算法仅适用于灰度图像。我相信OpenCV检测器已经做了一些预处理。(由于suft检测器和sift以类似的方式工作,我假设SURF也不需要灰度格式输入)

Mat图像;
image=imread(argv[1],CV\u LOAD\u image\u COLOR);
如果(!image.data)
{

您能否分享有关错误的更多详细信息?即堆栈跟踪/adb logcat输出?
Mat image;
image = imread(argv[1], CV_LOAD_IMAGE_COLOR); 
if(! image.data )
{
    cout <<  "Could not open or find the image" << std::endl ;
    return -1;
}

vector<KeyPoint> keypoints;
Mat descriptors;

// Create a SIFT keypoint detector.
SiftFeatureDetector detector;
detector.detect(image, keypoints);
cout << "Detected " << (int) keypoints.size() << " keypoints" <<endl;

// Compute feature description.
detector.compute(image,keypoints, descriptors);
cout << "Computed feature."<<endl;