中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

OpenCV4Android中如何運用手機攝像頭獲取Canny邊緣

發布時間:2021-12-15 18:07:16 來源:億速云 閱讀:305 作者:柒染 欄目:大數據

OpenCV4Android中如何運用手機攝像頭獲取Canny邊緣,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。

在圖像中獲取主要影響的邊緣用處比較廣泛,這樣就用到了Canny邊緣的效果

Canny邊緣的提取流程

  1. 高斯模糊

  2. 梯度計算

  3. 非最大信息壓制

  4. 高低閾值鏈接

  5. 顯示

還是用我們的Demo

不過這次我們加上新的東西,因為正好學習了OpenCV里面調用手機里的攝像頭功能獲取圖片信息,花了整整一天算是入了個門吧.

首先在原來的MainActivity里面增加一個按鈕

OpenCV4Android中如何運用手機攝像頭獲取Canny邊緣

OpenCV4Android中如何運用手機攝像頭獲取Canny邊緣

對應增加的事件

OpenCV4Android中如何運用手機攝像頭獲取Canny邊緣

照相機頁面

OpenCV4Android中如何運用手機攝像頭獲取Canny邊緣

首先我們增加了一個opencvcarema.xml頁面和一個OpenCVCarema的activity

opencvcarema.xml

這里面可以直接增加org.opencv.android.JavaCameraView,然后又在下方增加了一個按鈕

OpenCV4Android中如何運用手機攝像頭獲取Canny邊緣

OpenCV4Android中如何運用手機攝像頭獲取Canny邊緣

OpenCvCarema

這個class我們需要繼承Activity并且引用了

CameraBridgeViewBase.CvCameraViewListener2

里面幾個的方法

按鈕獲取當前圖像提取邊緣

OpenCV4Android中如何運用手機攝像頭獲取Canny邊緣

里面就是根據獲取的圖像創建一個bitbmp的圖像,然后把獲取的圖像mRgbaF先用高斯模糊后,再轉成灰度圖,然后再運用Canny邊緣提取出新的Mat,再將提取完的轉回為bmp圖像,因為我們需要返回數據,所以返回時把bmp圖像轉為byte[]發送回去,原來我們的MainActivity里的onActivityResult里面增加了返回照相機數據

OpenCV4Android中如何運用手機攝像頭獲取Canny邊緣

照相機獲取圖像時加入了橫豎屏的判斷

在OpenCV調用照相機時,默認的都是橫屏,所以我們豎屏手機打開時會是個90的旋轉樣子,非常不友好,經常查找資料和多次測試,我自己修改了onCameraFrame這個函數

OpenCV4Android中如何運用手機攝像頭獲取Canny邊緣

標紅的這塊是就是判斷當前手機屏幕是橫屏和豎屏,通過寬度和高度進行對比,寬度大于高度時就是橫屏,小于時就是豎屏.

如果是豎屏我們就執行以下步驟:

  • 先將水平圖像轉為垂直.

  • 轉完后的圖像再縮放為原來的大小.

  • 再將圖像沿Y軸進行翻轉(如果不翻轉的話看到的圖像是左右互調的)

下面的我們的視頻效果,最后有OpenCVCarema.java整個類的代碼

下面的整個OpenCvCarema.java的類

package dem.vaccae.opencvdemo;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Camera;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.support.annotation.Nullable;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;

import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.OpenCVLoader;
import org.opencv.android.Utils;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;

import java.io.ByteArrayOutputStream;

/**
 * Created by Administrator on 2018-01-01.
 */

public class OpenCvCarema extends Activity implements CameraBridgeViewBase.CvCameraViewListener2 {

    private static final String TAG = "OpenCvCameraActivity";

    static {
        OpenCVLoader.initDebug();
    }


    private Mat mRgba;
    private Mat mRgbaF;
    private Mat mFlipRgba;

    private Camera mCamera;

    private CameraBridgeViewBase mOpenCvCameraView;

    private Button btnCanny;

    //是否按下按鍵
    private boolean isbtn = false;
    private Bitmap bmp;


    public OpenCvCarema() {
        Log.i(TAG, "Instantiated new " + this.getClass());
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        Log.i(TAG, "called onCreate");
        super.onCreate(savedInstanceState);

        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        setContentView(R.layout.opencvcarema);


        mOpenCvCameraView = findViewById(R.id.opencvcaremaview);
        mOpenCvCameraView.enableView();
        mOpenCvCameraView.setCvCameraViewListener(this);
        //后置攝像頭
        mOpenCvCameraView.setCameraIndex(CameraBridgeViewBase.CAMERA_ID_BACK);

        btnCanny = findViewById(R.id.btnCanny);
        btnCanny.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                isbtn = true;
                bmp = Bitmap.createBitmap(mRgbaF.width(), mRgbaF.height(), Bitmap.Config.ARGB_8888);

                //先進行高斯模糊
                Imgproc.GaussianBlur(mRgbaF, mRgbaF, new Size(3, 3), 0, 0, Imgproc.BORDER_DEFAULT);
                //先改為灰度圖像
                Imgproc.cvtColor(mRgbaF, mRgbaF, Imgproc.COLOR_BGRA2GRAY);
                //t代表低閾值,高閾值一般是低閾值的2倍,所以threshold用t*2或t*3即可,
                //apertureSize這里輸入3,就是代表3*3的眼膜
                //L2gradient這個是對精度要求,如果是true精度會高,但是會慢,所以一般來說我們都用false就可以了
                Imgproc.Canny(mRgbaF, mFlipRgba, 112, 112 * 2, 3, false);

                Utils.matToBitmap(mFlipRgba, bmp);

                //將圖片壓縮成byte[]傳遞回去
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                bmp.compress(Bitmap.CompressFormat.PNG, 100, baos);
                byte[] bitmapByte = baos.toByteArray();

                Intent rtnintent = new Intent();
                rtnintent.putExtra("bitmap", bitmapByte);
                OpenCvCarema.this.setResult(Activity.RESULT_OK, rtnintent);
                finish();
            }
        });
    }

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

    @Override
    protected void onResume() {
        super.onResume();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mOpenCvCameraView.disableView();
    }

    @Override
    public void onCameraViewStarted(int width, int height) {
        mRgba = new Mat();
        mRgbaF = new Mat();
        mFlipRgba = new Mat();
    }

    @Override
    public void onCameraViewStopped() {
        mFlipRgba.release();
        mRgbaF.release();
    }

    @Override
    public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
        if (!isbtn) {
            //注意
            mRgba = inputFrame.rgba();

            //獲取屏幕寬和高用于判斷是橫屏還是豎屏
            DisplayMetrics dm = getResources().getDisplayMetrics();
            if (dm.widthPixels < dm.heightPixels) {
                //轉置函數,可以水平的圖像變為垂直
                Core.transpose(mRgba, mFlipRgba);
                //將轉置后的圖像縮放為mRgbaF的大小
                Imgproc.resize(mFlipRgba, mRgbaF, mRgba.size(), 0.0D, 0.0D, 0);
                //flipCode>0將mRgbaF水平翻轉(沿Y軸翻轉)得到mRgba
                Core.flip(mRgbaF, mRgbaF, 1);
            } else {
                mRgbaF = mRgba;
            }
        }
        return mRgbaF;
    }

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

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

看完上述內容,你們掌握OpenCV4Android中如何運用手機攝像頭獲取Canny邊緣的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

鹰潭市| 福泉市| 隆回县| 凤城市| 濮阳县| 栾川县| 龙泉市| 察隅县| 乡城县| 宁明县| 宿松县| 安图县| 鸡泽县| 贞丰县| 德昌县| 蓬莱市| 景洪市| 阳春市| 临漳县| 钟祥市| 伊金霍洛旗| 阆中市| 隆尧县| 岑溪市| 商城县| 万州区| 万盛区| 娄底市| 策勒县| 水城县| 四川省| 资中县| 罗甸县| 高邑县| 沙湾县| 白玉县| 雅江县| 宁乡县| 嘉兴市| 玉门市| 石河子市|