android studio cmake配置opencv3.2.0

来源:互联网 发布:系统优化的方法论 编辑:程序博客网 时间:2024/05/16 07:54

下载:opencv

我下的是3.2.0

解压后将OpenCV-android-sdk\sdk\native\libs文件夹下的所有文件夹复制到项目的app\libs文件夹下

将OpenCV-android-sdk\sdk\native\jni文件夹下的include文件夹复制到项目的app\libs文件夹下

在CMakeLists.txt文件添加代码

#支持-std=gnu++11set(CMAKE_VERBOSE_MAKEFILE on)set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")set(distribution_DIR ../../../../libs)include_directories(libs/include)

add_library(OpenCV_java3 SHARED IMPORTED )set_target_properties(  OpenCV_java3                        PROPERTIES IMPORTED_LOCATION                        ${distribution_DIR}/${ANDROID_ABI}/libopencv_java3.so                        )

target_link_libraries(  native-lib                        ${log-lib}                        OpenCV_java3                         )

配置build.gradle文件在android{}内添加代码

externalNativeBuild {    cmake {        cppFlags "-std=c++11 -frtti -fexceptions"        abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'mips', 'mips64'    }}sourceSets {    main {        jniLibs.srcDirs = ['libs']    }}

android studio ->File->New->Import Module将OpenCV-android-sdk\sdk\java和项目关联起来

在AndroidManifest.xml内添加权限

<uses-permission android:name="android.permission.CAMERA"/><uses-feature android:name="android.hardware.camera" android:required="false"/><uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/><uses-feature android:name="android.hardware.camera.front" android:required="false"/><uses-feature android:name="android.hardware.camera.front.autofocus" android:required="false"/>

在布局文件内添加代码

<org.opencv.android.JavaCameraView    android:id="@+id/activity_camera_view"    android:layout_width="match_parent"    android:layout_height="match_parent"    opencv:show_fps="true"    opencv:camera_id="any"/>

MainActivity

public class MainActivity extends AppCompatActivity implements CameraBridgeViewBase.CvCameraViewListener2{    static {        System.loadLibrary("native-lib");    }    private Mat rgba;    private Mat gray;    private CameraBridgeViewBase mOpenCvCameraView;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);        mOpenCvCameraView = findViewById(R.id.activity_camera_view);        mOpenCvCameraView.setVisibility(CameraBridgeViewBase.VISIBLE);        mOpenCvCameraView.setCvCameraViewListener(this);    }    @Override    public void onCameraViewStarted(int width, int height) {        rgba = new Mat(height, width, CvType.CV_8UC4);        gray = new Mat(height, width, CvType.CV_8UC1);    }    @Override    public void onCameraViewStopped() {        rgba.release();        gray.release();    }    @Override    public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {        rgba = inputFrame.rgba();        gray = inputFrame.gray();        nativeProcessFrame(gray.getNativeObjAddr(), rgba.getNativeObjAddr());        return rgba;    }    @Override    public void onPointerCaptureChanged(boolean hasCapture) {    }    @Override    public void onPause() {        super.onPause();        if (mOpenCvCameraView != null){            mOpenCvCameraView.disableView();        }    }    @Override    public void onResume()    {        super.onResume();        if (!OpenCVLoader.initDebug()) {        } else {            mOpenCvCameraView.enableView();        }    }    @Override    public void onDestroy() {        super.onDestroy();        if (mOpenCvCameraView != null){            mOpenCvCameraView.disableView();        }    }    public native void nativeProcessFrame(long gray,long rgba);}

c++代码

extern "C"JNIEXPORT void JNICALLJava_com_example_opencv_MainActivity_nativeProcessFrame(JNIEnv *env, jobject instance, jlong gray,                                                        jlong rgba) {    // TODO    cv::Mat& g = *(cv::Mat *) gray;    cv::Mat& r = *(cv::Mat *) rgba;    std::vector<cv::KeyPoint> v;    cv::Mat resized;    resize(g, resized, cv::Size(g.cols, g.rows ));    cv::Ptr<cv::ORB> orb = cv::ORB::create();    orb->detect(resized, v);    for (int i = 0; i < v.size(); ++i) {        const cv::KeyPoint& kp = v[i];        circle(r, cv::Point((int) kp.pt.x , (int) kp.pt.y ), 5, cv::Scalar(255, 0, 0, 255));    }}

启动后发现画面是旋转90度的

修改CameraBridgeViewBase代码

protected void deliverAndDrawFrame(CvCameraViewFrame frame) {    Mat modified;    if (mListener != null) {        modified = mListener.onCameraFrame(frame);    } else {        modified = frame.rgba();    }    boolean bmpValid = true;    if (modified != null) {        try {            Utils.matToBitmap(modified, mCacheBitmap);        } catch(Exception e) {            Log.e(TAG, "Mat type: " + modified);            Log.e(TAG, "Bitmap type: " + mCacheBitmap.getWidth() + "*" + mCacheBitmap.getHeight());            Log.e(TAG, "Utils.matToBitmap() throws an exception: " + e.getMessage());            bmpValid = false;        }    }    if (bmpValid && mCacheBitmap != null) {        Canvas canvas = getHolder().lockCanvas();        if (canvas != null) {            canvas.drawColor(0, android.graphics.PorterDuff.Mode.CLEAR);            if (BuildConfig.DEBUG)                Log.d(TAG, "mStretch value: " + mScale);            //开始修改            canvas.save();            //竖屏时以中心为圆点,旋转90度            canvas.rotate(90,canvas.getWidth()/2f,canvas.getHeight()/2f);            //根据角度宽高互换,在JavaCameraView内重新计算mScale            //int width = canvas.getHeight();            //int height = canvas.getWidth();            int width = canvas.getWidth();            int height = canvas.getHeight();            Rect rect = new Rect();            if (mScale != 0) {                rect.left = (int)((width- mScale*mCacheBitmap.getWidth()) / 2);                rect.top = (int)((height - mScale*mCacheBitmap.getHeight()) / 2);                rect.right = (int)((width - mScale*mCacheBitmap.getWidth()) / 2 + mScale*mCacheBitmap.getWidth());                rect.bottom = (int)((height - mScale*mCacheBitmap.getHeight()) / 2 + mScale*mCacheBitmap.getHeight());            } else {                rect.left = (width - mCacheBitmap.getWidth()) / 2;                rect.top = (height - mCacheBitmap.getHeight()) / 2;                rect.right = (width - mCacheBitmap.getWidth()) / 2 + mCacheBitmap.getWidth();                rect.bottom = (height - mCacheBitmap.getHeight()) / 2 + mCacheBitmap.getHeight();            }            canvas.drawBitmap(mCacheBitmap, new Rect(0,0,mCacheBitmap.getWidth(), mCacheBitmap.getHeight()),                    rect, null);            canvas.restore();            //修改结束            if (mFpsMeter != null) {                mFpsMeter.measure();                mFpsMeter.draw(canvas, 20, 30);            }            getHolder().unlockCanvasAndPost(canvas);        }    }}

上面的方法只是旋转画布,图像还是不对的,还是原来旋转90度的,无法正常计算,做人脸识别时根本识别不了人脸

参考

http://blog.csdn.net/aaron121314/article/details/53516037

进行旋转

2017/09/08更新

按上边的方法虽然图片方向对了,可是还是无法正常显示,图片的长宽明显不对

进行如下修改就可以正常显示了

MainActivity中

@Overridepublic void onCameraViewStarted(int width, int height) {    rgba = new Mat();    gray = new Mat();}@Overridepublic void onCameraViewStopped() {    if (rgba != null) {        rgba.release();    }    if (gray != null) {        gray.release();    }}@Overridepublic Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {    Mat r = inputFrame.rgba();    Mat g = inputFrame.gray();    Core.transpose(r, rgba);    Imgproc.resize(rgba, r, rgba.size(), 0.0D, 0.0D, 0);    Core.flip(r, r, 1);    Core.transpose(g, gray);    Imgproc.resize(gray, g, gray.size(), 0.0D, 0.0D, 0);    Core.flip(g, g, 1);        return r;}

CameraBridgeViewBese中

protected void AllocateCache(){    mCacheBitmap = Bitmap.createBitmap( mFrameHeight,mFrameWidth, Bitmap.Config.ARGB_8888);}

将宽高对调一下,图片就可以正常显示了

这是竖屏,横屏没实验,如果横屏显示不对的话,就要判断一下横竖屏再进行参数设置

下一篇准备写基于Camera2的JavaCameraView,Camera2还是挺坑的















原创粉丝点击