android studio cmake配置opencv3.2.0

下载: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++11
set(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 JNICALL
Java_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中

@Override
public void onCameraViewStarted(int width, int height) {

    rgba = new Mat();

    gray = new Mat();

}


@Override
public void onCameraViewStopped() {
    if (rgba != null) {
        rgba.release();
    }
    if (gray != null) {
        gray.release();
    }
}


@Override
public 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还是挺坑的















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值