Why am I getting empty stitched image?
Hi,
I have two webcams connected to my android tablet - I am capturing the frames and stitching them and display. My java code -
Log.i(TAG, "Processing .......");
Mat left = null, right = null;
//HEIGHT = 640 and WIDTH=480
left = new Mat(HEIGHT + HEIGHT / 2, WIDTH, CvType.CV_8UC1);
right = new Mat(HEIGHT + HEIGHT / 2, WIDTH, CvType.CV_8UC1);
//list of images to be stitiched
ArrayList<Mat> mats = new ArrayList<>(2);
mats.add(left);
mats.add(right);
// for testing purpose only - if captured frames are proper.
// I am able to capture the frames and save them as PNG. It displays fine.
Bitmap bmpL = Bitmap.createBitmap(left.cols(), left.rows(), Bitmap.Config.ARGB_8888);
Bitmap bmpR = Bitmap.createBitmap(right.cols(), right.rows(), Bitmap.Config.ARGB_8888);
while (true) {
//ensuring frames from both cams
try {
synchronized (obL) {
obL.wait();
}
synchronized (obR) {
obR.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
if (frameL == null || frameR == null) continue;
isProcessing = true;
//adding frame data to Mats
left.put(0, 0, frameL);
Log.d(TAG, "Left: " + left.toString());
right.put(0, 0, frameR);
Log.d(TAG, "Right: " + right.toString());
/* Test Code. Frames are fine and can save them as PNG and see the image
Utils.matToBitmap(left, bmpL);
Utils.matToBitmap(right, bmpR);
saveImage(bmpL, "L");
saveImage(bmpR,"R");
bmpL.recycle();
bmpR.recycle();
*/
// Below line always produces 0x0 mat
// sample info: Mat [ 0*0*CV_8UC1, isCont=false, isSubmat=false, nativeObj=0xffffffffb4b2e7b0, dataAddr=0x0 ]
Mat result = NativeStitcherWrapper.stitch(mats, false, false);
isProcessing = false;
}
}
I am using OpenCV Stitcher.cpp for stitching and here is relevant C++ code being called via JNI
jclass matClass = env->FindClass("org/opencv/core/Mat");
jmethodID getNativeAddr = env->GetMethodID(matClass, "getNativeObjAddr", "()J");
int numImgs = env->GetArrayLength(jInputArray);
vector<Mat> natImgs;
for (int i = 0; i < numImgs; ++i) {
natImgs.push_back(
*(Mat *) env->CallLongMethod(
env->GetObjectArrayElement(jInputArray, i),
getNativeAddr
)
);
}
/* The core stitching calls: */
Stitcher stitcher = Stitcher::createDefault();
stitcher.setWaveCorrection((bool) waveCorrect);
Ptr<detail::Blender> blender;
if ((bool) multiBand) {
blender = new detail::MultiBandBlender();
} else {
blender = new detail::FeatherBlender();
}
stitcher.setBlender(blender);
Mat result;
Stitcher::Status status = stitcher.stitch(natImgs, result);
stringstream ss;
if (status != Stitcher::OK) {
__android_log_print(ANDROID_LOG_VERBOSE, APPNAME, "Could not stitch", 1);
}
ss << "status: ";
ss << status;
string str;
str.append("cols: ");
ss << " cols: ";
ss << result.cols;
ss << " rows: ";
ss << result.rows;
string str1 = ss.str();
const char *log = str1.c_str();
__android_log_print(ANDROID_LOG_VERBOSE, APPNAME, log, 1);
// cout << "cols: "<<result.cols<< "="" rows:="" "<<result.rows<<="" endl;<="" p="">
*(Mat *) jResultMat = result;
Appreciate any pointer/suggestions.
Without images it is difficult to understand. First I don't know java I cannot check your program but when you use stitching class you must have enough descriptor in each image to match and threshold must be high enough. You can try something like this :