java - studio - OpenCV FeatureDetector
tracking and detection opencv (4)
Estoy tratando de escribir un código que aplique la detección de objetos SURF , así que tomé una de las muestras de openCV (muestra 3) y comencé a actualizar los onCameraViewStarted()
y onCameraFrame()
pero sigo recibiendo un error de tiempo de ejecución cuando lo pruebo Mi teléfono galaxy S3 y no pude encontrar nada que me ayude con mi problema aquí es mi código y lo que actualicé:
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;
}
}
Nota: He intentado comentar todo menos el featureDetector.detect(mRgba, keyPoints)
en el método onCameraFrame()
y aún así le di un error de tiempo de ejecución en mi teléfono.
¿Está seguro de que utiliza SIFT de forma correcta? Por lo que sé, SIFT y SURF no están incluidos en el paquete de distribución de OpenCV Android. Para usarlos, debe compilar el módulo no libre y utilizarlo en su proyecto. Entonces, lo que debe hacer es crear un proyecto NDK, compilar el módulo no libre como una biblioteca independiente. Luego usa esta biblioteca para compilar tu programa. Entonces deberías poder construir tu aplicación. Puedes consultar este tutorial .
Después de obtener la biblioteca jni, puede envolverla fácilmente en una interfaz JAVI de JAVA. Entonces deberías poder usar la interfaz JAVA en tu aplicación de Android.
Para comentar sobre cid y la respuesta de HMK (lo siento, no tengo la reputación de "agregar comentarios", por lo que debo crear una nueva respuesta).
La biblioteca OpenCV puede aceptar imágenes en color como entrada. El siguiente es mi código de extracción SIFT detección y descripción. Funciona bastante bien. Esto significa que no necesita convertir la imagen a un formato de escala de grises, aunque el algoritmo SIFT solo funciona en imágenes de escala de grises. Creo que el detector OpenCV ha hecho algún preprocesamiento. (Dado que el detector de suft y el tamizado funcionan de una manera similar, asumo que el SURF tampoco requiere una entrada en formato de escala de grises)
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;
SURF o SIFT solo son compatibles con la escala de grises. Entonces, primero debe convertirlo a escala de grises con el siguiente código: cvtColor (mRgba, mRgba, CV_BGR2GRAY);
Si no me equivoco, OpenCV SURF Feature Detector solo funciona con imágenes en escala de grises. Así que intente agregar esto después de su llamada a copyTo en el método onCameraFrame()
:
cvtColor(mRgba, mGrayMat, COLOR_RGBA2GRAY);