Android OpenCV VideoCapture::retrieve(&;mat)导致致命信号11
因此,我正在尝试制作一个android应用程序,它将通过OpenCV通过JNI和NDK逐帧打开一个视频文件,检测每个帧中的人脸并显示它们(最终目标是加速算法,更好地适应糟糕的移动处理) 我尝试的第一个方法没有结果,它只返回null 第二种方法是,它确实可以像预期的那样工作,但速度非常慢(高达2fps;太慢),部分原因是您必须从FFMpegMMR的位图转换为Mat,然后进行检测和绘制,然后再转换回位图,这是我的穴居人非常愿意尝试的 我目前正在使用的第三种方法是VideoCapture grab()和retrieve()。我为本机代码制作了一个包装器,主要是通过从OpenCV示例复制facedtector。我还尝试了read(),据说它将两者结合在一起,但它也会导致致命信号11(在某些被上帝抛弃的OpenCV或Android平台级别上出现分段错误) 下面是应用程序获取绝对文件路径的方式(请注意,它确实适用于FFMpegMMR): 这是调用本机方法的java包装器和使用结果的地方:Android OpenCV VideoCapture::retrieve(&;mat)导致致命信号11,android,opencv,android-ndk,Android,Opencv,Android Ndk,因此,我正在尝试制作一个android应用程序,它将通过OpenCV通过JNI和NDK逐帧打开一个视频文件,检测每个帧中的人脸并显示它们(最终目标是加速算法,更好地适应糟糕的移动处理) 我尝试的第一个方法没有结果,它只返回null 第二种方法是,它确实可以像预期的那样工作,但速度非常慢(高达2fps;太慢),部分原因是您必须从FFMpegMMR的位图转换为Mat,然后进行检测和绘制,然后再转换回位图,这是我的穴居人非常愿意尝试的 我目前正在使用的第三种方法是VideoCapture grab()
class AsyncPlay extends AsyncTask<String, Mat, Bitmap>
{
@Override
protected Bitmap doInBackground(String... params) {
//for(;play;)
{
if(play)
{
if(currentTime==0)
{
test=new Test();
test.startTime.setToNow();
test.type="Video";
frameGrabber.open(videoFilePath);
}
//publishProgress(retriever.getFrameAtTime(currentTime*1000+111,
// FFmpegMediaMetadataRetriever.OPTION_CLOSEST));
Mat tmp=new Mat();
//frameGrabber.read(tmp);
frameGrabber.grab();
frameGrabber.retrieve(tmp);
publishProgress(tmp);
currentTime+=111;
if(currentTime*1000>=duration*1000)
{
currentTime=0;
test.endTime.setToNow();
tester.publishResult(test);
frameGrabber.release();
}
}
try
{
Thread.sleep(111);
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}
@Override
protected void onProgressUpdate(Mat... values) {
//face detection logic goes here
//Bitmap bmp=values[0];
//Mat rgbMat = new Mat();
//Utils.bitmapToMat(bmp, rgbMat);
DetectionResult detectionResult = openCVFaceDetector.detectFromImage(values[0], Imgproc.COLOR_RGB2GRAY);//Detecting with a native detector from OpenCV
test.addDetection(detectionResult.detection);
imageViewOriginal.setImageBitmap(detectionResult.detectedImage);
super.onProgressUpdate(values);
}
};`
这是它的本机部分(导致错误的确切行是result=((VideoCapture*)thiz)->retrieve(*((Mat*)imageMat));
,它位于方法nativeRetrieve()中
<调试这个代码的问题是,它是Eclipse中的JNI,我不知道如何在Eclipse中进行调试C++,这就是为什么我使用日志消息来查找代码中的缺陷。不起作用,我发现并消除了一个bug,我忘记了将其传递给方法。retrieve()的问题是我一生都找不到它的源代码。highgui.hpp中有部分定义,但没有实现,我可以将日志消息放在其中帮助我调试
可能的解决办法是:
- retrieve()支持的不同文件格式,只是我不知道可能是哪种文件格式
- 使用非绝对文件路径?尽管open()和grab()都不会导致致命信号
- 放弃整个东西,使用PNG(不过我真的很想弄清楚)
同时,我会尝试在Eclipse中调试C++并尝试另一种格式。
< P>找到它,最后,按照Aleksander的建议,我设法找到了从java传递到JNI的对象的类型不匹配。 事实证明,错误出现在java部分,在java部分中声明了本机方法。我没有传递Mat,而是传递了Mat.getNativeObjAddr(),这是一个很长的过程 所以不是 private static native boolean nativeRetrieve(long thiz, Mat imageMat);
private static native boolean nativeRead(long thiz, Mat imageMat);
public boolean retrieve(Mat imageMat)
{
return nativeRetrieve(mNativeObj, imageMat);
}
public boolean read(Mat imageMat)
{
return nativeRead(mNativeObj, imageMat);
}
我用了这个:
private static native boolean nativeRetrieve(long thiz, long imageMat);
private static native boolean nativeRead(long thiz, long imageMat);
public boolean retrieve(Mat imageMat)
{
return nativeRetrieve(mNativeObj, imageMat.getNativeObjAddr());
}
public boolean read(Mat imageMat)
{
return nativeRead(mNativeObj, imageMat.getNativeObjAddr());
}
注意:通过C++,C++中的错误类型不会触发异常,即使代码在Test.catch中。TIG.catch可能是错误的,我不知道。< / P> OK,我以前使用Python包装器,并且面对同样的事情。基本上你需要查看C++文档并尝试理解C++上的问题。IDE。请将代码缩短为仅与错误相关的那些东西,即抛出它的方法、它的设置和失败方法调用的方法?在C++方面,我将其缩小到<代码>结果=((VixCopthOx*)THZ)->检索((*((Mat*)IMAGEMAT)))。这就是我所能得到的,因为我没有找到highgui的源代码。好吧,对不起,我对JNI不太在行,所以这可能是个愚蠢的问题,但是为什么你在调用
(*((Mat*)imageMat)时,会这样使用(VideoCapture*)thiz
具有它必须拥有的类型,即C++中的代码> Matt和MIN,int通道=0 < /COD>。我在Python绑定中遇到的问题之一是,有时您对Python(java)有一个引用。侧到一些C++对象,没有C++类型的期望,这是错误的。TIZ是我正在使用的视频捕获对象。因为这是JNI,在CPP里面没有真正的类,在构造类之后,当你有引用时,你必须把这个引用从java端传递到原生CPP方法。ce in.cpp中,您还必须将其强制转换为所需的类才能获得其方法。我复制了大部分代码示例DetectionBasedTracker,它可以正常工作。您基本上是以长格式传递引用,然后取消引用并强制转换它。您确实提出了一个很好的观点,我将对此进行研究,看看我是否以某种方式弄乱了文件类型。就是这样!我通过的是垫子而不是长垫子(指垫子)。非常感谢你的建议,你本可以挽救我的理智。我需要帮助,可以吗?
#include <string>
#include <vector>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <FrameGrabber_jni.h>
#include <android/log.h>
#define LOG_TAG "FrameGrabber"
#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
using namespace std;
using namespace cv;
inline void jStringToString(JNIEnv * jenv, jstring jString, string stdName)
{
LOGD("Java_boris_springar_diplomska_FrameGrabber_jStringToString enter");
LOGD("grabber is Making jnamestr");//this is buggy as hell, the line serves as a debug tool
const char* jnamestr = jenv->GetStringUTFChars(jString, NULL);
string stdNameTmp(jnamestr);
stdName=stdNameTmp;
LOGD("grabber is releasing jnamestr");
jenv->ReleaseStringUTFChars(jString, jnamestr);
}
/*
* CONSTRUCTOR AND DESTRUCTOR
*/
JNIEXPORT jlong JNICALL Java_boris_springar_diplomska_FrameGrabber_nativeCreateObject
(JNIEnv * jenv, jclass, jstring jFileName)
{
LOGD("Java_boris_springar_diplomska_FrameGrabber_nativeCreateObject enter");
string stdFileName;
jStringToString(jenv, jFileName,stdFileName);
jlong result = 0;
try
{
result = (jlong)new VideoCapture(stdFileName);
}
catch(cv::Exception& e)
{
LOGD("nativeCreateObject caught cv::Exception: %s", e.what());
jclass je = jenv->FindClass("org/opencv/core/CvException");
if(!je)
je = jenv->FindClass("java/lang/Exception");
jenv->ThrowNew(je, e.what());
}
catch (...)
{
LOGD("nativeCreateObject caught unknown exception");
jclass je = jenv->FindClass("java/lang/Exception");
jenv->ThrowNew(je, "Unknown exception in JNI code of FrameGrabber.nativeCreateObject()");
return 0;
}
LOGD("Java_boris_springar_diplomska_FrameGrabber_nativeCreateObject exit");
return result;
}
//should work
JNIEXPORT void JNICALL Java_boris_springar_diplomska_FrameGrabber_nativeDestroyObject
(JNIEnv * jenv, jclass, jlong thiz)
{
LOGD("Java_boris_springar_diplomska_FrameGrabber_nativeDestroyObject enter");
try
{
if(thiz != 0)
{
delete (VideoCapture*)thiz;
}
}
catch(cv::Exception& e)
{
LOGD("nativeestroyObject caught cv::Exception: %s", e.what());
jclass je = jenv->FindClass("org/opencv/core/CvException");
if(!je)
je = jenv->FindClass("java/lang/Exception");
jenv->ThrowNew(je, e.what());
}
catch (...)
{
LOGD("nativeDestroyObject caught unknown exception");
jclass je = jenv->FindClass("java/lang/Exception");
jenv->ThrowNew(je, "Unknown exception in JNI code of FrameGrabber.nativeDestroyObject()");
}
LOGD("Java_boris_springar_diplomska_FrameGrabber_nativeDestroyObject exit");
}
/*
* CORE METHODS
*/
//Open function opens the filename for playing
JNIEXPORT jboolean JNICALL Java_boris_springar_diplomska_FrameGrabber_nativeOpen
(JNIEnv * jenv, jclass,jlong thiz,jstring jFileName)
{
LOGD("Java_boris_springar_diplomska_FrameGrabber_open enter");
string stdFileName;
jStringToString(jenv, jFileName,stdFileName);
jboolean result = false;
try
{
result = ((VideoCapture*)thiz)->open(stdFileName);
}
catch(cv::Exception& e)
{
LOGD("frame grabber open exception caught cv::Exception: %s", e.what());
jclass je = jenv->FindClass("org/opencv/core/CvException");
if(!je)
je = jenv->FindClass("java/lang/Exception");
jenv->ThrowNew(je, e.what());
}
catch (...)
{
LOGD("frame grabber open caught unknown exception");
jclass je = jenv->FindClass("java/lang/Exception");
jenv->ThrowNew(je, "Unknown exception in JNI code of FrameGrabber.open()");
return 0;
}
LOGD("Java_boris_springar_diplomska_FrameGrabber_open exit");
return result;
}
//grab grabs the next frame from file or camera
JNIEXPORT jboolean JNICALL Java_boris_springar_diplomska_FrameGrabber_nativeGrab
(JNIEnv * jenv, jclass,jlong thiz)
{
LOGD("Java_boris_springar_diplomska_FrameGrabber_grab enter");
jboolean result = false;
try
{
result = ((VideoCapture*)thiz)->grab();
}
catch(cv::Exception& e)
{
LOGD("frame grabber grab exception caught cv::Exception: %s", e.what());
jclass je = jenv->FindClass("org/opencv/core/CvException");
if(!je)
je = jenv->FindClass("java/lang/Exception");
jenv->ThrowNew(je, e.what());
}
catch (...)
{
LOGD("frame grabber grab caught unknown exception");
jclass je = jenv->FindClass("java/lang/Exception");
jenv->ThrowNew(je, "Unknown exception in JNI code of FrameGrabber.grab()");
return 0;
}
LOGD("Java_boris_springar_diplomska_FrameGrabber_grab exit");
return result;
}
//retrieve retrieves the next frame and writes it to the image matrix
JNIEXPORT jboolean JNICALL Java_boris_springar_diplomska_FrameGrabber_nativeRetrieve
(JNIEnv * jenv, jclass,jlong thiz, jlong imageMat)
{
LOGD("Java_boris_springar_diplomska_FrameGrabber_retrieve enter");
jboolean result = false;
try
{
LOGD("grabber trying to retrieve");
result = ((VideoCapture*)thiz)->retrieve((*((Mat*)imageMat)));//should write the current frame to the image matrix
}
catch(cv::Exception& e)
{
LOGD("frame grabber retrieve exception caught cv::Exception: %s", e.what());
jclass je = jenv->FindClass("org/opencv/core/CvException");
if(!je)
je = jenv->FindClass("java/lang/Exception");
jenv->ThrowNew(je, e.what());
}
catch (...)
{
LOGD("frame grabber retrieve caught unknown exception");
jclass je = jenv->FindClass("java/lang/Exception");
jenv->ThrowNew(je, "Unknown exception in JNI code of FrameGrabber.retrieve(fileName)");
return 0;
}
LOGD("Java_boris_springar_diplomska_FrameGrabber_retrieve exit");
return result;
}
//read combines grab and retrieve and writes the stuff to the image matrix
JNIEXPORT jboolean JNICALL Java_boris_springar_diplomska_FrameGrabber_nativeRead
(JNIEnv * jenv, jclass,jlong thiz, jlong imageMat)
{
LOGD("Java_boris_springar_diplomska_FrameGrabber_read enter");
LOGD("grabber setting result to false");
jboolean result = false;
try
{
LOGD("grabber trying to read capture");
result = ((VideoCapture*)thiz)->read((*((Mat*)imageMat)));//should write the current frame to the image matrix
}
catch(cv::Exception& e)
{
LOGD("frame grabber read exception caught cv::Exception: %s", e.what());
jclass je = jenv->FindClass("org/opencv/core/CvException");
if(!je)
je = jenv->FindClass("java/lang/Exception");
jenv->ThrowNew(je, e.what());
}
catch (...)
{
LOGD("frame grabber read caught unknown exception");
jclass je = jenv->FindClass("java/lang/Exception");
jenv->ThrowNew(je, "Unknown exception in JNI code of FrameGrabber.open(fileName)");
return 0;
}
LOGD("Java_boris_springar_diplomska_FrameGrabber_read exit");
return result;
}
//Release releases the resource it's using, I hope
JNIEXPORT void JNICALL Java_boris_springar_diplomska_FrameGrabber_nativeRelease
(JNIEnv * jenv, jclass,jlong thiz)
{
LOGD("Java_boris_springar_diplomska_FrameGrabber_release enter");
jboolean result = false;
try
{
((VideoCapture*)thiz)->release();//should release
}
catch(cv::Exception& e)
{
LOGD("frame grabber read exception caught cv::Exception: %s", e.what());
jclass je = jenv->FindClass("org/opencv/core/CvException");
if(!je)
je = jenv->FindClass("java/lang/Exception");
jenv->ThrowNew(je, e.what());
}
catch (...)
{
LOGD("frame grabber release caught unknown exception");
jclass je = jenv->FindClass("java/lang/Exception");
jenv->ThrowNew(je, "Unknown exception in JNI code of FrameGrabber.open(fileName)");
}
LOGD("Java_boris_springar_diplomska_FrameGrabber_release exit");
}
07-22 17:36:24.886: D/FrameGrabber(15359): Java_boris_springar_diplomska_FrameGrabber_nativeCreateObject enter
07-22 17:36:24.886: D/FrameGrabber(15359): Java_boris_springar_diplomska_FrameGrabber_jStringToString enter
07-22 17:36:24.886: D/FrameGrabber(15359): grabber is Making jnamestr
07-22 17:36:24.886: D/FrameGrabber(15359): grabber is releasing jnamestr
07-22 17:36:24.886: D/FrameGrabber(15359): Java_boris_springar_diplomska_FrameGrabber_nativeCreateObject exit
07-22 17:36:24.936: I/dalvikvm(15359): threadid=3: reacting to signal 3
07-22 17:36:24.936: I/dalvikvm(15359): Wrote stack traces to '/data/anr/traces.txt'
07-22 17:36:24.946: D/libEGL(15359): loaded /system/lib/egl/libEGL_mali.so
07-22 17:36:24.956: D/libEGL(15359): loaded /system/lib/egl/libGLESv1_CM_mali.so
07-22 17:36:24.976: D/libEGL(15359): loaded /system/lib/egl/libGLESv2_mali.so
07-22 17:36:25.006: D/OpenGLRenderer(15359): Enabling debug mode 0
07-22 17:36:27.336: D/FrameGrabber(15359): Java_boris_springar_diplomska_FrameGrabber_open enter
07-22 17:36:27.336: D/FrameGrabber(15359): Java_boris_springar_diplomska_FrameGrabber_jStringToString enter
07-22 17:36:27.336: D/FrameGrabber(15359): grabber is Making jnamestr
07-22 17:36:27.336: D/FrameGrabber(15359): grabber is releasing jnamestr
07-22 17:36:27.336: D/FrameGrabber(15359): Java_boris_springar_diplomska_FrameGrabber_open exit
07-22 17:36:27.336: D/FrameGrabber(15359): Java_boris_springar_diplomska_FrameGrabber_grab enter
07-22 17:36:27.336: D/FrameGrabber(15359): Java_boris_springar_diplomska_FrameGrabber_grab exit
07-22 17:36:27.336: D/FrameGrabber(15359): Java_boris_springar_diplomska_FrameGrabber_retrieve enter
07-22 17:36:27.336: D/FrameGrabber(15359): grabber trying to retrieve
07-22 17:36:27.336: A/libc(15359): Fatal signal 11 (SIGSEGV) at 0x1d400019 (code=1)
private static native boolean nativeRetrieve(long thiz, Mat imageMat);
private static native boolean nativeRead(long thiz, Mat imageMat);
public boolean retrieve(Mat imageMat)
{
return nativeRetrieve(mNativeObj, imageMat);
}
public boolean read(Mat imageMat)
{
return nativeRead(mNativeObj, imageMat);
}
private static native boolean nativeRetrieve(long thiz, long imageMat);
private static native boolean nativeRead(long thiz, long imageMat);
public boolean retrieve(Mat imageMat)
{
return nativeRetrieve(mNativeObj, imageMat.getNativeObjAddr());
}
public boolean read(Mat imageMat)
{
return nativeRead(mNativeObj, imageMat.getNativeObjAddr());
}