18

SURFオブジェクト検出を適用するコードを作成しようとしているので、openCV サンプル (サンプル 3) の 1 つを取得し、メソッド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;
}
}

featureDetector.detect(mRgba, keyPoints)注:メソッド以外のすべてにコメントしようとしましたがonCameraFrame()、電話でランタイムエラーが発生しました。

4

4 に答える 4

1

私が間違っていなければ、OpenCV SURF Feature Detector はグレースケール画像でしか動作しません。したがって、メソッドでcopyToを呼び出した後にこれを追加してみてください。onCameraFrame()

cvtColor(mRgba, mGrayMat, COLOR_RGBA2GRAY);
于 2013-07-05T14:42:58.727 に答える
1

SIFT を正しい方法で使用していますか? 私が知る限り、OpenCV Android の配布パッケージには SIFT と SURF は含まれていません。それらを使用するには、nonfree モジュールをコンパイルしてプロジェクトで使用する必要があります。そのため、NDK プロジェクトを作成し、nonfree モジュールをスタンドアロン ライブラリとしてコンパイルする必要があります。次に、このライブラリを使用してプログラムをコンパイルします。その後、アプリケーションをビルドできるはずです。このチュートリアルを参照できます。

jni ライブラリを取得したら、JAVA JNI インターフェイスに簡単にラップできます。これで、Android アプリケーションで Java インターフェイスを使用できるようになります。

于 2013-09-17T09:37:40.560 に答える
0

cid と HMK の回答にコメントするには (申し訳ありませんが、「コメントを追加」の評判が 50 に達していないため、新しい回答を作成する必要があります)。

OpenCV ライブラリは、カラー画像を入力として受け入れることができます。以下は、私の SIFT 検出および説明抽出コードです。それはかなりうまくいきます。つまり、SIFT アルゴリズムはグレースケール画像でのみ機能しますが、画像をグレースケール形式に変換する必要はありません。私は、OpenCV 検出器が何らかの前処理を行ったと考えています。(sift 検出器と sift は同様の方法で動作するため、SURF もグレースケール形式の入力を必要としないと想定しています)

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;
于 2013-09-17T09:46:25.027 に答える
0

SURF または SIFT はグレースケールのみをサポートします。そのため、最初に以下のコードでグレースケールに変換する必要があります: cvtColor( mRgba, mRgba, CV_BGR2GRAY );

于 2013-09-13T10:07:26.893 に答える