Ответ 1
Если я не ошибаюсь, OpenCV SURF Feature Detector работает только с изображениями в оттенках серого. Поэтому попробуйте добавить это после вашего вызова в copyTo по методу onCameraFrame()
:
cvtColor(mRgba, mGrayMat, COLOR_RGBA2GRAY);
Я пытаюсь написать код, который применяет обнаружение объекта 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;
}
}
Примечание. Я пробовал комментировать все, кроме featureDetector.detect(mRgba, keyPoints)
в методе onCameraFrame()
и все еще выдавал ошибку времени выполнения на моем телефоне.
Если я не ошибаюсь, OpenCV SURF Feature Detector работает только с изображениями в оттенках серого. Поэтому попробуйте добавить это после вашего вызова в copyTo по методу onCameraFrame()
:
cvtColor(mRgba, mGrayMat, COLOR_RGBA2GRAY);
Вы уверены, что используете SIFT правильно? Насколько я знаю, SIFT и SURF не включены в дистрибутив OpenCV Android. Чтобы использовать их, вам необходимо скомпилировать незанятый модуль и использовать его в своем проекте. Итак, что вам нужно сделать, это создать проект NDK, скомпилировать незащищенный модуль как отдельную библиотеку. Затем используйте эту библиотеку для компиляции вашей программы. Затем вы сможете создать свое приложение. Вы можете обратиться к этому учебнику.
После получения библиотеки jni вы можете легко перенести ее в JAVA-интерфейс JNI. Затем вы сможете использовать интерфейс JAVA в своем приложении для Android.
SURF или SIFT поддерживают только оттенки серого. Поэтому сначала вы должны преобразовать его в оттенки серого с помощью кода ниже: cvtColor (mRgba, mRgba, CV_BGR2GRAY);
Прокомментировать ответ cid и HMK (извините, у меня нет 50 репутации для "добавить комментарий", поэтому мне нужно создать новый ответ).
Библиотека OpenCV может принимать цветное изображение в качестве входных данных. Ниже приведен мой код обнаружения и описания SIFT. Это работает очень хорошо. Это означает, что вам не нужно преобразовывать изображение в формат серого цвета, хотя алгоритм SIFT работает только на изображении с серой шкалой. Я считаю, что детектор OpenCV сделал некоторую предварительную обработку. (Поскольку подобный приемник и просеивание работают аналогично, я полагаю, что 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;