【发布时间】:2016-04-23 04:30:12
【问题描述】:
我正在尝试为 Android 编写图像拼接应用程序。我将 Android NDK 用于 OpenCV 的本机部分。有 3 种不同的行为是不应该发生的,我很乐意解释它们为什么会发生。
只有一些图像(来自设备上的相同相机/相同分辨率)不会崩溃。崩溃时的错误低于我的 C++ 代码。
图像拼接的结果看起来就像它只是桶装了一张图像。 (我大约 20% 的时间得到这个结果,而其他 80% 的时间它崩溃了)。我认为这与 for 循环 中的 resize 行有关。书中的示例将列和行除以 10。当我这样做时,图像只是略微桶状,但非常像素化。同样,在这种情况下,它看起来也只有一张图片。
-
如果我不这样设置拼接器设置:
stitcher.setRegistrationResol(-1); /// 0.6 stitcher.setSeamEstimationResol(-1); /// 0.1 stitcher.setCompositingResol(-1); //1 stitcher.setPanoConfidenceThresh(-1); //1 stitcher.setWaveCorrection(true); stitcher.setWaveCorrectKind(detail::WAVE_CORRECT_HORIZ);输出图像将为空。这对我来说很奇怪,因为书中的示例没有它们也能正常工作。
我一直在使用来自this book 的第 6 章作为我项目的 C++ 部分。这是我的 C++ 代码:
#include <jni.h>
#include "aaron_picstitch_MyNDK.h"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <opencv2/stitching/stitcher.hpp>
#include <opencv2/core/mat.hpp>
#include <vector>
#include <android/log.h>
using namespace std;
using namespace cv;
char FILEPATH[100] = "/storage/emulated/0/PicStitch/cppResult.jpg";
//char FILEPATH1[100] = "/storage/emulated/0/PicStitch/cppTesta.jpg";
//char FILEPATH2[100] = "/storage/emulated/0/PicStitch/cppTestb.jpg";
JNIEXPORT void JNICALL Java_aaron_picstitch_CameraActivity_stitchImages(JNIEnv *env, jobject , jobjectArray images, jint size, jlong panoAddr)
{
vector <Mat> imgs = vector<Mat>();
Mat pano = Mat();
Mat temp = Mat();
Mat &srcRes = *(Mat *)panoAddr, img;
jclass clazz = (env)->FindClass("org/opencv/core/Mat");
jmethodID getNativeObjAddr = (env)->GetMethodID(clazz, "getNativeObjAddr", "()J");
__android_log_print(ANDROID_LOG_VERBOSE, "IN CPP TESTTEST", "ADDR: %lld", panoAddr);
int i = 0;
for (i = 0; i < size; i++)
{
jobject obj = (env->GetObjectArrayElement(images, i));
jlong result = (env)->CallLongMethod(obj, getNativeObjAddr, NULL);
img = *(Mat *)result;
resize(img, temp, Size(img.rows/2, img.cols/2));
imgs.push_back(temp);
env->DeleteLocalRef(obj);
}
env->DeleteLocalRef(images);
Stitcher stitcher = Stitcher::createDefault();
__android_log_print(ANDROID_LOG_VERBOSE, "IN CPP", "HERE 1 temp rows is: %d", temp.rows);
stitcher.setRegistrationResol(-1); /// 0.6
stitcher.setSeamEstimationResol(-1); /// 0.1
stitcher.setCompositingResol(-1); //1
stitcher.setPanoConfidenceThresh(-1); //1
stitcher.setWaveCorrection(true);
stitcher.setWaveCorrectKind(detail::WAVE_CORRECT_HORIZ);
__android_log_print(ANDROID_LOG_VERBOSE, "IN CPP", "Right before .stitch");
Stitcher::Status status = stitcher.stitch(imgs, pano);
__android_log_print(ANDROID_LOG_VERBOSE, "IN CPP", "HERE 2 Pano rows is : %d", pano.rows);
if (status == Stitcher::OK)
{
__android_log_print(ANDROID_LOG_VERBOSE, "IN CPP", "STITCHING SHOULD WORK");
}
//pano.copyTo(srcRes);
imwrite(FILEPATH, pano);
}
这是第 1 条中的错误:
04-22 20:51:47.192 32115-32651/aaron.picstitch E/cv::error(): OpenCVError Assertion failed (s >= 0) in void cv::setSize(cv::Mat&, int, int const*, const size_t*, bool), file /hdd2/buildbot/slaves/slave_ardbeg1/50-SDK/opencv/modules/core/src/matrix.cpp, line 116
04-22 20:51:47.192 32115-32651/aaron.picstitch A/libc: Fatal signal 6 (SIGABRT), code -6 in tid 32651 (AsyncTask #1)
另一个不那么大的奇怪问题是我在项目的 Java 部分中将 getNativeObjAddr() 用于 Mat 对象,所以我可以将结果放入其中,但每当我尝试访问它时都会出现段错误。不知道为什么会发生这种情况,但可以解决这个问题。
感谢您对我的问题提出任何想法!
【问题讨论】:
标签: java android c++ opencv android-ndk