在androd.mk中解决本机开放的cv代码错误,用于在android上开发全景

时间:2015-02-18 14:55:50

标签: java opencv image-processing panoramas opencv4android

我正在尝试开发一个用于生成全景图像的Android应用程序,以便在Open CV中使用图像拼接功能。

我在下面给出的网站上使用了代码。

http://ramsrigoutham.com/2012/12/21/panorama-app-on-android-using-stitching-module-opencv/

下面显示的日志中显示错误。 请指导我如何解决错误。

这是native.cpp文件的屏幕截图,其中使用命名空间错误显示在上面给出的图像链接中

Android.mk文件截图在上面给出的图片链接中给出。

http://i.imgur.com/Hm8gtiY.png

这是拼接图像的本地调用。

native.cpp

#include < jni.h >
#include <opencv2/core/core.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/stitching/stitcher.hpp>

#include < vector >
#include < iostream >
#include < stdio.h >
#include < list >
#include< sstream >
#include< string >

using namespace std;
using namespace cv;

extern "C" {
//JNIEXPORT Mat JNICALL Java_org_opencv_samples_tutorial3_Sample3Native_FindFeatures(JNIEnv*, jobject, jlong addrGray, jlong addrRgba)

JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial3_Sample3Native_FindFeatures(
        JNIEnv*, jobject, jlong im1, jlong im2, jlong im3, jint no_images) {

    vector < Mat > imgs;
    bool try_use_gpu = false;
    // New testing
    Mat& temp1 = *((Mat*) im1);
    Mat& temp2 = *((Mat*) im2);
    Mat& pano = *((Mat*) im3);

    for (int k = 0; k < no_images; ++k) {
        string id;
        ostringstream convert;
        convert << k;
        id = convert.str();
        Mat img = imread("/storage/emulated/0/panoTmpImage/im" + id + ".jpeg");

        imgs.push_back(img);
    }

    Stitcher stitcher = Stitcher::createDefault(try_use_gpu);
    Stitcher::Status status = stitcher.stitch(imgs, pano);

}

}

这是我创建的android.mk文件,不知道如何生成它。

Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

include ../../android-development/OpenCV-2.4.10-android-sdk/OpenCV-2.4.10-android-sdk/sdk/native/jni/OpenCV.mk

LOCAL_MODULE    := native_activity
LOCAL_SRC_FILES := native.cpp
LOCAL_LDLIBS    += -lm -llog -landroid
LOCAL_STATIC_LIBRARIES += android_native_app_glue

include $(BUILD_SHARED_LIBRARY)

$(call import-module,android/native_app_glue)

这是主要的Android代码,它具有主GUI并调用OpenCV函数

Sample3Native.java

package org.opencv.samples.tutorial3;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.highgui.Highgui;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;

public class Sample3Native extends Activity implements CvCameraViewListener {
    private static final String TAG = "OCVSample::Activity";

    public static final int VIEW_MODE_RGBA = 0;
    public static final int SAVE_IMAGE_MAT = 1;
    public static final int CAPT_STILL_IM = 2;
    private static int viewMode = VIEW_MODE_RGBA;
//  public static int image_count = 0;
    private MenuItem mStitch;
    private MenuItem mItemCaptureImage;
    private Mat mRgba;
    private Mat mGrayMat;
    private Mat panorama;
    private Mat mtemp;
    private List < Mat > images_to_be_stitched = new ArrayList < Mat >();
    private CameraBridgeViewBase mOpenCvCameraView;
    private long mPrevTime = new Date().getTime();
    private static final int FRAME2GRAB = 10;
    private int mframeNum = 0;
    private static final File tempImageDir = new File(Environment.getExternalStorageDirectory() + File.separator + "panoTmpImage");
    private static final File StitchImageDir = new File(Environment.getExternalStorageDirectory()+ File.separator  + "panoStitchIm");
    private static final String mImageName = "im";
    private static final String mImageExt = ".jpeg";
    private long recordStart = new Date().getTime();
    private static final long MAX_VIDEO_INTERVAL_IN_SECONDS = 3 * 1000; // Convert milliseconds to seconds
    public final Handler mHandler = new Handler();

    // Create runnable for posting
    final Runnable mUpdateResults = new Runnable() {
        public void run() {
            updateResultsInUi();
        }
    };

    private void updateResultsInUi()
    {

    }

    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 Sample3Native() {
        Log.i(TAG, "Instantiated new " + this.getClass());
    }

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        Log.i(TAG, "called onCreate");
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        setContentView(R.layout.tutorial3_surface_view);

        final Button btnVidCapt = (Button) findViewById(R.id.btnVidCapt);
        btnVidCapt.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                startVidCap();
            }
        });

        final Button btnStitch = (Button) findViewById(R.id.btnStitch);
        btnStitch.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                stitchImages();
            }
        });

        final Button btnViewStitchedIm = (Button) findViewById(R.id.btnViewStitchedIm);
        btnViewStitchedIm.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                viewStitchImages();
            }
        });

        final Button btnCapStil = (Button) findViewById(R.id.btnCapStil);
        btnCapStil.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                captStillImage();
            }
        });
        mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.tutorial4_activity_surface_view);
        mOpenCvCameraView.setCvCameraViewListener(this);
    }

    @Override
    public void onPause() {
        if (mOpenCvCameraView != null)
            mOpenCvCameraView.disableView();
        super.onPause();
    }

    @Override
    public void onResume() {
        super.onResume();
        OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this,
                mLoaderCallback);
    }

    public void onDestroy() {
        super.onDestroy();
        if (mOpenCvCameraView != null)
            mOpenCvCameraView.disableView();
    }

    public void onCameraViewStarted(int width, int height) {
        mRgba = new Mat(height, width, CvType.CV_8UC3);
        mGrayMat = new Mat(height, width, CvType.CV_8UC1);
        mtemp = new Mat(height, width, CvType.CV_8UC3);
        panorama = new Mat(height, width, CvType.CV_8UC3);
    }

    public void onCameraViewStopped() {
        mRgba.release();
        mGrayMat.release();
        mtemp.release();
        panorama.release();
    }

    public Mat onCameraFrame(Mat inputFrame) {
        inputFrame.copyTo(mRgba);
        switch (Sample3Native.viewMode) {
        case Sample3Native.VIEW_MODE_RGBA: {
            Core.putText(mRgba, "Video Mode", new Point(10, 50), 3, 1, new Scalar(255, 0, 0, 255), 2);
            // Update start recordtime until starting recording
        }break;
        case Sample3Native.SAVE_IMAGE_MAT: {
            long curTime = new Date().getTime();
            Core.putText(mRgba, "Record Mode", new Point(10, 50), 3, 1, new Scalar(255, 0, 0, 255), 2);
            long timeDiff = curTime - recordStart;
            Log.i("timeDiff", Long.toString(timeDiff));

            if ( timeDiff < MAX_VIDEO_INTERVAL_IN_SECONDS) {
                if ((mframeNum % FRAME2GRAB) == 0) {
                    saveImageToArray(inputFrame);
                    mframeNum++;
                }
                else
                    mframeNum++;
            }
            else
            {
                mframeNum = 0;
                turnOffCapture();
            }
        }break;
        case Sample3Native.CAPT_STILL_IM :
        {
            saveImageToArray(inputFrame);
            Sample3Native.viewMode = Sample3Native.VIEW_MODE_RGBA;
        }
        }
        return mRgba;
    }

    public void startVidCap() {
        if (Sample3Native.viewMode == Sample3Native.VIEW_MODE_RGBA)
        {
            turnOnCapture();
        }
        else if (Sample3Native.viewMode == Sample3Native.SAVE_IMAGE_MAT)
        {
            turnOffCapture();
        }
    }

    private void turnOffCapture()
    {

        Sample3Native.viewMode = Sample3Native.VIEW_MODE_RGBA;
    }

    private void turnOnCapture()
    {

        Sample3Native.viewMode = Sample3Native.SAVE_IMAGE_MAT;
//      startVidCapture.setText("Stop Video Capture");
        images_to_be_stitched.clear();
        recordStart = new Date().getTime();

    }

    public void stitchImages() {
        if(!images_to_be_stitched.isEmpty())
        {
            for (int j = 0; j < images_to_be_stitched.size(); j++) {
                writeImage(images_to_be_stitched.get(j), j);
            }
        Log.i("stitchImages", "Done writing 2 disk. Starting stitching " + images_to_be_stitched.size() + " images");
            FindFeatures(images_to_be_stitched.get(0).getNativeObjAddr(),
                    images_to_be_stitched.get(0).getNativeObjAddr(),
                    panorama.getNativeObjAddr(), images_to_be_stitched.size());
        Log.i("stitchImages", "Done stitching. Writing panarama");
            writePano(panorama);

        Log.i("stitchImages", "deleting temp files");

            deleteTmpIm();
        }
    }

    public void captStillImage()
    {
        Sample3Native.viewMode = Sample3Native.CAPT_STILL_IM;

    }

    private String getFullFileName( int num)
    {
        return mImageName + num + mImageExt;
    }

    private void writeImage(Mat image, int imNum)
    {
        writeImage(image, getFullFileName(imNum));
    }

    private void writeImage(Mat image, String fileName) {
        File createDir = tempImageDir;
        if(!createDir.exists())
            createDir.mkdir();
        Highgui.imwrite(tempImageDir+File.separator + fileName, image);
    }

    private void writePano(Mat image)
    {
        Date dateNow = new  Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmmss");
        if(!StitchImageDir.exists())
            StitchImageDir.mkdir();
        Highgui.imwrite(StitchImageDir.getPath()+ File.separator + "panoStich"+dateFormat.format(dateNow) +mImageExt, image);

    }

    private void deleteTmpIm()
    {
        File curFile;
        for (int j = 0; j < images_to_be_stitched.size(); j++) {
            curFile = new File(getFullFileName(j));
            curFile.delete();
        }
        images_to_be_stitched.clear();
    }

    public void viewStitchImages()
    {

        Intent intent = new Intent(this, GalleryActivity.class);

        startActivity(intent);
    }

    private void saveImageToArray(Mat inputFrame) {
        images_to_be_stitched.add(inputFrame.clone());
    }

    private int FPS() {
        long curTime = new Date().getTime();
        int FPS = (int) (1000 / (curTime - mPrevTime));
        mPrevTime = curTime;
        return FPS;
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        return true;

    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
    return true;
    }

    // public native void FindFeatures(List pano_images, Long stitch );
    public native void FindFeatures(long image1, long image2, long image3,
            int count);
}

2 个答案:

答案 0 :(得分:0)

我打算要求您向我们展示您的Application.mk文件,但由于我没有足够的代表我无法评论您的问题,但是,我能够重现您的问题删除我的工作项目Application.mk的某些行,请尝试将Application.mk调整为以下内容:

APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_ABI := armeabi-v7a
APP_PLATFORM := android-16

答案 1 :(得分:0)

我面临同样的问题,只需删除分号

using namespace std 

使用命名空间cv

及其工作。