最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android?利用OpenCV制作人臉檢測APP

 更新時間:2021年12月10日 16:33:26   作者:人工智能AI技術(shù)  
本篇文章手把手教大家使用OpenCV來實現(xiàn)一個能在安卓手機上運行的人臉檢測APP。其實不僅僅是能檢測人臉,還能檢測鼻子,嘴巴,眼睛和耳朵。需要的朋友可以參考一下

前言

本篇文章手把手教大家使用OpenCV來實現(xiàn)一個能在安卓手機上運行的人臉檢測APP。其實不僅僅是能檢測人臉,還能檢測鼻子,嘴巴,眼睛和耳朵?;瞬簧倬戇@篇文章,希望點贊收藏關(guān)注。

無圖無真相,先把APP運行的結(jié)果給大家看看。

如上圖所示,APP運行后,點擊“選擇圖片”,從手機中選擇一張圖片,然后點擊“處理”,APP會將人臉用矩形給框起來,同時把鼻子也給檢測出來了。由于目的是給大家做演示,所以APP設(shè)計得很簡單,而且也只實現(xiàn)了檢測人臉和鼻子,沒有實現(xiàn)對其他五官的檢測。而且這個APP也只能檢測很簡單的圖片,如果圖片中背景太復(fù)雜就無法檢測出人臉。

下面我將一步一步教大家如何實現(xiàn)上面的APP!

第一步:下載并安裝Android studio

為了保證大家能下載到和我相同版本的Android Studio,我把安裝包上傳了到微云。下載地址

下載后,一路點擊下一步就安裝好了。當(dāng)然,安裝過程中要聯(lián)網(wǎng),所以可能會中途失敗,如果失敗了,重試幾次,如果還是有問題,那么可能要開啟VPN。

第二步:下載SDK tools

打開Android studio后,點擊“File”->“Settings”

點擊“Appearance & Behavior”->“System Settings”->“Android SDK”->“SDK Tools”。

然后選中“NDK”和“CMake”,點擊“OK”。下載這兩個工具可能要花一點時間,如果失敗了請重試或開啟VPN。

第三步:新建一個Android APP項目

點擊“File”->“New”->“New Project”

選中“Empty Activity”,點擊“Next”

“Language”選擇“Java”,Minimum SDK選擇“API 21”。點擊“Finish”

第四步:下載Opencv

下載地址

下載后解壓。

第五步:導(dǎo)入OpenCV

將opencv-4.5.4-android-sdk\OpenCV-android-sdk下面的sdk復(fù)制到你在第三步創(chuàng)建的Android項目下面。就是第三步圖中的D:\programming\MyApplication下面。然后將sdk文件夾改名為openCVsdk。

選擇“Project”->“settings.gradle”。在文件中添加include ‘:openCVsdk'

選擇“Project”->“openCVsdk”->“build.gradle”。

將apply plugin: 'kotlin-android'改為//apply plugin: ‘kotlin-android'

將compileSdkVersion和minSdkVersion,targetSdkVersion改為31,21,31。

點擊“File”->“Project Structure”

點擊“Dependencies”->“app”->“+”->“Module Dependency”

選中“openCVsdk”,點擊“OK”,以及母窗口的“OK”

在Android項目文件夾的app\src里面創(chuàng)建一個新文件夾jniLibs,然后把openCV文件夾的opencv-4.5.4-android-sdk\OpenCV-android-sdk\sdk\native\staticlibs里面的東西都copy到j(luò)niLibs文件夾中。

下載分類器。解壓后,將下圖中的文件都復(fù)制到項目文件夾的app\src\main\res\raw文件夾下。

第六步:添加代碼

雙擊“Project”->“app”-》“main”-》“res”下面的“activity_main.xml”。然后點擊右上角的“code”。

然后將里面的代碼都換成下面的代碼

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical"
    >

    <Button
        android:id="@+id/select_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="選擇圖片" />
    <Button
        android:id="@+id/process_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="處理" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

雙擊“Project”->“app”-》“main”-》“java”-》“com.example…”下面的“MainActivity”。然后把里面的代碼都換成下面的代碼(保留原文件里的第一行代碼)

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

import org.opencv.android.OpenCVLoader;
import org.opencv.android.Utils;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.imgproc.Imgproc;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import org.opencv.core.MatOfRect;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.objdetect.CascadeClassifier;

import android.content.Context;

public class MainActivity extends AppCompatActivity {

    private double max_size = 1024;
    private int PICK_IMAGE_REQUEST = 1;
    private ImageView myImageView;
    private Bitmap selectbp;

    private static final String    TAG                 = "OCVSample::Activity";
    private static final Scalar    FACE_RECT_COLOR     = new Scalar(0, 255, 0, 255);
    public static final int        JAVA_DETECTOR       = 0;
    public static final int        NATIVE_DETECTOR     = 1;

    private Mat                    mGray;
    private File                   mCascadeFile;
    private CascadeClassifier      mJavaDetector,mNoseDetector;

    private int                    mDetectorType       = JAVA_DETECTOR;

    private float                  mRelativeFaceSize   = 0.2f;
    private int                    mAbsoluteFaceSize   = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        staticLoadCVLibraries();
        myImageView = (ImageView)findViewById(R.id.imageView);
        myImageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
        Button selectImageBtn = (Button)findViewById(R.id.select_btn);
        selectImageBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // makeText(MainActivity.this.getApplicationContext(), "start to browser image", Toast.LENGTH_SHORT).show();
                selectImage();
            }

            private void selectImage() {
                Intent intent = new Intent();
                intent.setType("image/*");
                intent.setAction(Intent.ACTION_GET_CONTENT);
                startActivityForResult(Intent.createChooser(intent,"選擇圖像..."), PICK_IMAGE_REQUEST);
            }
        });

        Button processBtn = (Button)findViewById(R.id.process_btn);
        processBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // makeText(MainActivity.this.getApplicationContext(), "hello, image process", Toast.LENGTH_SHORT).show();
                convertGray();
            }
        });

    }

    private void staticLoadCVLibraries() {
        boolean load = OpenCVLoader.initDebug();
        if(load) {
            Log.i("CV", "Open CV Libraries loaded...");
        }

    }

    private void convertGray() {
        Mat src = new Mat();
        Mat temp = new Mat();
        Mat dst = new Mat();
        Utils.bitmapToMat(selectbp, src);
        Imgproc.cvtColor(src, temp, Imgproc.COLOR_BGRA2BGR);
        Log.i("CV", "image type:" + (temp.type() == CvType.CV_8UC3));
        Imgproc.cvtColor(temp, dst, Imgproc.COLOR_BGR2GRAY);
        Utils.matToBitmap(dst, selectbp);
        myImageView.setImageBitmap(selectbp);

        mGray = dst;
        mJavaDetector = loadDetector(R.raw.lbpcascade_frontalface,"lbpcascade_frontalface.xml");
        mNoseDetector = loadDetector(R.raw.haarcascade_mcs_nose,"haarcascade_mcs_nose.xml");

        if (mAbsoluteFaceSize == 0) {
            int height = mGray.rows();
            if (Math.round(height * mRelativeFaceSize) > 0) {
                mAbsoluteFaceSize = Math.round(height * mRelativeFaceSize);
            }
        }

        MatOfRect faces = new MatOfRect();

        if (mJavaDetector != null) {
            mJavaDetector.detectMultiScale(mGray, faces, 1.1, 2, 2, // TODO: objdetect.CV_HAAR_SCALE_IMAGE
                        new Size(mAbsoluteFaceSize, mAbsoluteFaceSize), new Size());

        }

        Rect[] facesArray = faces.toArray();
        for (int i = 0; i < facesArray.length; i++) {

            Log.e(TAG, "start to detect nose!");

            Mat faceROI = mGray.submat(facesArray[i]);

            MatOfRect noses = new MatOfRect();
            mNoseDetector.detectMultiScale(faceROI, noses, 1.1, 2, 2,
                    new Size(30, 30));

            Rect[] nosesArray = noses.toArray();
            Imgproc.rectangle(src,
                    new Point(facesArray[i].tl().x + nosesArray[0].tl().x, facesArray[i].tl().y + nosesArray[0].tl().y) ,
                    new Point(facesArray[i].tl().x + nosesArray[0].br().x, facesArray[i].tl().y + nosesArray[0].br().y) ,
                    FACE_RECT_COLOR, 3);

            Imgproc.rectangle(src, facesArray[i].tl(), facesArray[i].br(), FACE_RECT_COLOR, 3);
        }

        Utils.matToBitmap(src, selectbp);
        myImageView.setImageBitmap(selectbp);

    }

    private CascadeClassifier loadDetector(int rawID,String fileName) {
        CascadeClassifier classifier = null;
        try {

            // load cascade file from application resources
            InputStream is = getResources().openRawResource(rawID);
            File cascadeDir = getDir("cascade", Context.MODE_PRIVATE);
            mCascadeFile = new File(cascadeDir, fileName);
            FileOutputStream os = new FileOutputStream(mCascadeFile);

            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = is.read(buffer)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            is.close();
            os.close();

            Log.e(TAG, "start to load file:  " + mCascadeFile.getAbsolutePath());
            classifier = new CascadeClassifier(mCascadeFile.getAbsolutePath());

            if (classifier.empty()) {
                Log.e(TAG, "Failed to load cascade classifier");
                classifier = null;
            } else
                Log.i(TAG, "Loaded cascade classifier from " + mCascadeFile.getAbsolutePath());

            cascadeDir.delete();


        } catch (IOException e) {
            e.printStackTrace();
            Log.e(TAG, "Failed to load cascade. Exception thrown: " + e);
        }
        return classifier;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
            Uri uri = data.getData();
            try {
                Log.d("image-tag", "start to decode selected image now...");
                InputStream input = getContentResolver().openInputStream(uri);
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inJustDecodeBounds = true;
                BitmapFactory.decodeStream(input, null, options);
                int raw_width = options.outWidth;
                int raw_height = options.outHeight;
                int max = Math.max(raw_width, raw_height);
                int newWidth = raw_width;
                int newHeight = raw_height;
                int inSampleSize = 1;
                if (max > max_size) {
                    newWidth = raw_width / 2;
                    newHeight = raw_height / 2;
                    while ((newWidth / inSampleSize) > max_size || (newHeight / inSampleSize) > max_size) {
                        inSampleSize *= 2;
                    }
                }

                options.inSampleSize = inSampleSize;
                options.inJustDecodeBounds = false;
                options.inPreferredConfig = Bitmap.Config.ARGB_8888;
                selectbp = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri), null, options);

                myImageView.setImageBitmap(selectbp);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

第七步:連接手機運行程序

首先要打開安卓手機的開發(fā)者模式,每個手機品牌的打開方式不一樣,你自行百度一下就知道了。例如在百度中搜索“小米手機如何開啟開發(fā)者模式”。

然后用數(shù)據(jù)線將手機和電腦連接起來。成功后,Android studio里面會顯示你的手機型號。如下圖中顯示的是“Xiaomi MI 8 UD”,本例中的開發(fā)手機是小米手機。

點擊上圖中的“Run”-》“Run ‘a(chǎn)pp'”就可以將APP運行到手機上面了,注意手機屏幕要處于打開狀態(tài)。你自拍的圖片可以檢測不成功,可以下載我的測試圖片試試。

到此這篇關(guān)于Android 利用OpenCV制作人臉檢測APP的文章就介紹到這了,更多相關(guān)Android OpenCV 人臉檢測APP內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Android?JobScheduler詳細介紹

    Android?JobScheduler詳細介紹

    JobScheduler是Android?5.0引入的系統(tǒng)服務(wù),它可以根據(jù)網(wǎng)絡(luò)狀態(tài)、充電狀態(tài)、電量和存儲狀況等來觸發(fā)相應(yīng)的JobService執(zhí)行任務(wù),它支持多條件組合、持久性任務(wù),以及在API?21以上版本的Android系統(tǒng)中使用,對Android?JobScheduler相關(guān)知識感興趣的朋友跟隨小編一起看看吧
    2024-09-09
  • Android實現(xiàn)中國象棋附源碼下載

    Android實現(xiàn)中國象棋附源碼下載

    這篇文章主要詳細介紹了Android實現(xiàn)中國象棋的具體代碼,供大家參考,感興趣的小伙伴們可以參考一下
    2016-05-05
  • Android 物理按鍵整理及實例代碼

    Android 物理按鍵整理及實例代碼

    這篇文章主要介紹了Android 物理按鍵整理及實例代碼的相關(guān)資料,需要的朋友可以參考下
    2016-10-10
  • Android編程實現(xiàn)GridView控件點擊圖片變暗效果的方法

    Android編程實現(xiàn)GridView控件點擊圖片變暗效果的方法

    這篇文章主要介紹了Android編程實現(xiàn)GridView控件點擊圖片變暗效果的方法,簡單分析了GridView控件事件響應(yīng)及屬性操作的相關(guān)技巧,需要的朋友可以參考下
    2017-06-06
  • 加載頁面遮擋耗時操作任務(wù)頁面--第三方開源之AndroidProgressLayout

    加載頁面遮擋耗時操作任務(wù)頁面--第三方開源之AndroidProgressLayout

    AndroidProgressLayout實現(xiàn)為界面添加圓形進度條。調(diào)用setprogress()方法顯示和隱藏進度條,這篇文章主要介紹了加載頁面遮擋耗時操作任務(wù)頁面--第三方開源之AndroidProgressLayout的相關(guān)資料,需要的朋友可以參考下
    2015-11-11
  • 詳解Java編程中的反射在Android開發(fā)中的應(yīng)用

    詳解Java編程中的反射在Android開發(fā)中的應(yīng)用

    這篇文章主要介紹了詳解Java編程中的反射在Android開發(fā)中的應(yīng)用,主要來獲取安卓系統(tǒng)的屬性值,需要的朋友可以參考下
    2015-07-07
  • Android中二維碼的掃描和生成(使用zxing庫)

    Android中二維碼的掃描和生成(使用zxing庫)

    ZXing是一個開放源碼的,用Java實現(xiàn)的多種格式的1D/2D條碼圖像處理庫,它包含了聯(lián)系到其他語言的端口,下面這篇文章主要給大家介紹了關(guān)于Android中二維碼掃描和生成的相關(guān)資料,主要使用的zxing庫,需要的朋友可以參考下
    2022-09-09
  • Android中自定義控件之液位指示器

    Android中自定義控件之液位指示器

    這篇文章主要介紹了Android中自定義控件之液位指示器 方法的相關(guān)資料,需要的朋友可以參考下
    2016-03-03
  • Android仿貼吧內(nèi)容下的簡單ListView嵌套GridView

    Android仿貼吧內(nèi)容下的簡單ListView嵌套GridView

    這篇文章主要為大家詳細介紹了Android仿貼吧內(nèi)容下的簡單ListView嵌套GridView,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • android實現(xiàn)圓角矩形背景的方法

    android實現(xiàn)圓角矩形背景的方法

    這篇文章主要介紹了android實現(xiàn)圓角矩形背景的方法,以實例形式分析了Android編程實現(xiàn)圓角矩形背景的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-10-10

最新評論

电白县| 繁峙县| 阳谷县| 游戏| 长武县| 阿尔山市| 乌海市| 临海市| 奉化市| 平度市| 台东市| 牟定县| 杭州市| 东乌珠穆沁旗| 如皋市| 承德县| 莱阳市| 庆城县| 屏东市| 深水埗区| 绵阳市| 班玛县| 松江区| 兴化市| 郸城县| 集贤县| 镇赉县| 冕宁县| 高阳县| 茶陵县| 麻阳| 周口市| 平陆县| 内乡县| 年辖:市辖区| 台北县| 任丘市| 潍坊市| 和田市| 宁波市| 吉安市|