日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

android opencv 获取小图在大图的坐标_Android开发—基于OpenCV实现相机实时图像识别跟踪...

發布時間:2023/12/15 Android 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android opencv 获取小图在大图的坐标_Android开发—基于OpenCV实现相机实时图像识别跟踪... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

利用OpenCV實現實時圖像識別和圖像跟蹤

圖像識別

什么是圖像識別

圖像識別,是指利用計算機對圖像進行處理、分析和理解,以識別各種不同模式的目標和對像的技術。根據觀測到的圖像,對其中的物體分辨其類別,做出有意義的判斷。利用現代信息處理與計算技術來模擬和完成人類的認識、理解過程。一般而言,一個圖像識別系統主要由三個部分組成,分別是:圖像分割、圖像特征提取以及分類器的識別分類。

其中,圖像分割將圖像劃分為多個有意義的區域,然后將每個區域的圖像進行特征提取,最后分類器根據提取的圖像特征對圖像進行相對應的分類。實際上,圖像識別和圖像分割并不存在嚴格的界限。從某種意義上,圖像分割的過程就是圖像識別的過程。圖像分割著重于對象和背景的關系,研究的是對象在特定背景下所表現出來的整體屬性,而圖像識別則著重于對象本身的屬性。

圖像識別的研究現狀

圖像識別的發展經歷了三個階段:文字識別、數字圖像處理與識別、物體識別。

圖像識別作為計算視覺技術體系中的重要一環,一直備受重視。微軟在兩年前就公布了一項里程碑式的成果:它的圖像系統識別圖片的錯誤率比人類還要低。如今,圖像識別技術又發展到一個新高度。這有賴于更多數據的開放、更多基礎工具的開源、產業鏈的更新迭代,以及高性能的AI計算芯片、深度攝像頭和優秀的深度學習算法等的進步,這些都為圖像識別技術向更深處發展提供了源源不斷的動力。

其實對于圖像識別技術,大家已經不陌生,人臉識別、虹膜識別、指紋識別等都屬于這個范疇,但是圖像識別遠不只如此,它涵蓋了生物識別、物體與場景識別、視頻識別三大類。發展至今,盡管與理想還相距甚遠,但日漸成熟的圖像識別技術已開始探索在各類行業的應用。

Android圖像識別相關技術

  • OpenCV
    基于BSD許可(開源)發行的跨平臺計算機視覺庫,可以運行在Linux、Windows、Android和Mac OS操作系統上。
    輕量級而且高效——由一系列 C 函數和少量 C++ 類構成,同時提供了Python、Ruby、MATLAB等語言的接口,實現了圖像處理和計算機視覺方面的很多通用算法
  • TensorFlow
    TensorFlow是一個深度學習框架,支持Linux平臺,Windows平臺,Mac平臺,甚至手機移動設備等各種平臺。
    TensorFlow提供了非常豐富的深度學習相關的API,可以說目前所有深度學習框架里,提供的API最全的,包括基本的向量矩陣計算、各種優化算法、各種卷積神經網絡和循環神經網絡基本單元的實現、以及可視化的輔助工具、等等。
  • YOLO
    YOLO (You Only Look Once)是一種快速和準確的實時對象檢測算法。
    YOLOv3 在 TensorFlow 中實現的完整數據管道。它可用在數據集上來訓練和評估自己的目標檢測模型。
  • ……
  • 基于OpenCV實現

    介紹使用OpenCV來實現指定圖像識別的DEMO:

    實現思路

    ①打開應用的同時開啟攝像頭
    ②對實時攝像頭拍攝的圖像封裝成MAT對象進行逐幀比對:

  • 獲取目標特征并針對各特征集獲取描述符
  • 獲取兩個描述符集合間的匹配項
  • 獲取參考圖像和空間匹配圖像間的單應性
  • 當圖像矩陣符合單應性時,繪制跟蹤圖像的輪廓線
  • 代碼部分

    權限設置

    AndroidMainifest.xml

    <uses-permission android:name="android.permission.CAMERA" />

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <uses-feature android:name="android.hardware.camera" />

    <uses-feature

    android:name="android.hardware.camera.autofocus"

    android:required="false" />

    <uses-feature

    android:name="android.hardware.camera.flash"

    android:required="false" />

    權限提示方法

    private void requestPermissions() {

    final int REQUEST_CODE = 1;

    if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {

    ActivityCompat.requestPermissions(this, new String[]{

    Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE},

    REQUEST_CODE);

    }

    }

    界面設計

    activity_img_recognition.xml

    <?xml version="1.0" encoding="utf-8"?>

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:opencv="http://schemas.android.com/apk/res-auto"

    xmlns:tools="http://schemas.android.com/tools"

    android:id="@+id/activity_img_recognition"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context="com.sueed.imagerecognition.CameraActivity">

    <org.opencv.android.JavaCameraView

    android:id="@+id/jcv"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:visibility="gone"

    opencv:camera_id="any"

    opencv:show_fps="true" />

    </RelativeLayout>

    主要邏輯代碼

    CameraActivity.java 【相機啟動獲取圖像和包裝MAT相關】

    因為OpenCV中JavaCameraView繼承自SurfaceView,若有需要可以自定義編寫extends SurfaceView implements SurfaceHolder.Callback的xxxSurfaceView替換使用。

    package com.sueed.imagerecognition;

    import android.Manifest;

    import android.content.Intent;

    import android.content.pm.PackageManager;

    import android.os.Bundle;

    import android.util.Log;

    import android.view.Menu;

    import android.view.MenuItem;

    import android.view.SurfaceView;

    import android.view.View;

    import android.view.WindowManager;

    import android.widget.ImageView;

    import android.widget.RelativeLayout;

    import android.widget.Toast;

    import androidx.appcompat.app.AppCompatActivity;

    import androidx.core.app.ActivityCompat;

    import androidx.core.content.ContextCompat;

    import com.sueed.imagerecognition.filters.Filter;

    import com.sueed.imagerecognition.filters.NoneFilter;

    import com.sueed.imagerecognition.filters.ar.ImageDetectionFilter;

    import com.sueed.imagerecognition.imagerecognition.R;

    import org.opencv.android.CameraBridgeViewBase;

    import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;

    import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;

    import org.opencv.android.JavaCameraView;

    import org.opencv.android.OpenCVLoader;

    import org.opencv.core.Mat;

    import java.io.IOException;

    // Use the deprecated Camera class.

    @SuppressWarnings("deprecation")

    public final class CameraActivity extends AppCompatActivity implements CvCameraViewListener2 {

    // A tag for log output.

    private static final String TAG = CameraActivity.class.getSimpleName();

    // The filters.

    private Filter[] mImageDetectionFilters;

    // The indices of the active filters.

    private int mImageDetectionFilterIndex;

    // The camera view.

    private CameraBridgeViewBase mCameraView;

    @Override

    protected void onCreate(final Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

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

    //init CameraView

    mCameraView = new JavaCameraView(this, 0);

    mCameraView.setMaxFrameSize(size.MaxWidth, size.MaxHeight);

    mCameraView.setCvCameraViewListener(this);

    setContentView(mCameraView);

    requestPermissions();

    mCameraView.enableView();

    }

    @Override

    public void onPause() {

    if (mCameraView != null) {

    mCameraView.disableView();

    }

    super.onPause();

    }

    @Override

    public void onResume() {

    super.onResume();

    OpenCVLoader.initDebug();

    }

    @Override

    public void onDestroy() {

    if (mCameraView != null) {

    mCameraView.disableView();

    }

    super.onDestroy();

    }

    @Override

    public boolean onCreateOptionsMenu(final Menu menu) {

    getMenuInflater().inflate(R.menu.activity_camera, menu);

    return true;

    }

    @Override

    public boolean onOptionsItemSelected(final MenuItem item) {

    switch (item.getItemId()) {

    case R.id.menu_next_image_detection_filter:

    mImageDetectionFilterIndex++;

    if (mImageDetectionFilters != null && mImageDetectionFilterIndex == mImageDetectionFilters.length) {

    mImageDetectionFilterIndex = 0;

    }

    return true;

    default:

    return super.onOptionsItemSelected(item);

    }

    }

    @Override

    public void onCameraViewStarted(final int width, final int height) {

    Filter Enkidu = null;

    try {

    Enkidu = new ImageDetectionFilter(CameraActivity.this, R.drawable.enkidu);

    } catch (IOException e) {

    e.printStackTrace();

    }

    Filter akbarHunting = null;

    try {

    akbarHunting = new ImageDetectionFilter(CameraActivity.this, R.drawable.akbar_hunting_with_cheetahs);

    } catch (IOException e) {

    Log.e(TAG, "Failed to load drawable: " + "akbar_hunting_with_cheetahs");

    e.printStackTrace();

    }

    mImageDetectionFilters = new Filter[]{

    new NoneFilter(),

    Enkidu,

    akbarHunting

    };

    }

    @Override

    public void onCameraViewStopped() {

    }

    @Override

    public Mat onCameraFrame(final CvCameraViewFrame inputFrame) {

    final Mat rgba = inputFrame.rgba();

    if (mImageDetectionFilters != null) {

    mImageDetectionFilters[mImageDetectionFilterIndex].apply(rgba, rgba);

    }

    return rgba;

    }

    }

    ImageRecognitionFilter.java【圖像特征過濾比對及繪制追蹤綠框】

    package com.nummist.secondsight.filters.ar;

    import java.io.IOException;

    import java.util.ArrayList;

    import java.util.List;

    import org.opencv.android.Utils;

    import org.opencv.calib3d.Calib3d;

    import org.opencv.core.Core;

    import org.opencv.core.CvType;

    import org.opencv.core.DMatch;

    import org.opencv.core.KeyPoint;

    import org.opencv.core.Mat;

    import org.opencv.core.MatOfDMatch;

    import org.opencv.core.MatOfKeyPoint;

    import org.opencv.core.MatOfPoint;

    import org.opencv.core.MatOfPoint2f;

    import org.opencv.core.Point;

    import org.opencv.core.Scalar;

    import org.opencv.features2d.DescriptorExtractor;

    import org.opencv.features2d.DescriptorMatcher;

    import org.opencv.features2d.FeatureDetector;

    import org.opencv.imgcodecs.Imgcodecs;

    import org.opencv.imgproc.Imgproc;

    import android.content.Context;

    import com.nummist.secondsight.filters.Filter;

    public final class ImageDetectionFilter implements Filter {

    // The reference image (this detector's target).

    private final Mat mReferenceImage;

    // Features of the reference image.

    private final MatOfKeyPoint mReferenceKeypoints = new MatOfKeyPoint();

    // Descriptors of the reference image's features.

    private final Mat mReferenceDescriptors = new Mat();

    // The corner coordinates of the reference image, in pixels.

    // CvType defines the color depth, number of channels, and

    // channel layout in the image. Here, each point is represented

    // by two 32-bit floats.

    private final Mat mReferenceCorners = new Mat(4, 1, CvType.CV_32FC2);

    // Features of the scene (the current frame).

    private final MatOfKeyPoint mSceneKeypoints = new MatOfKeyPoint();

    // Descriptors of the scene's features.

    private final Mat mSceneDescriptors = new Mat();

    // Tentative corner coordinates detected in the scene, in

    // pixels.

    private final Mat mCandidateSceneCorners = new Mat(4, 1, CvType.CV_32FC2);

    // Good corner coordinates detected in the scene, in pixels.

    private final Mat mSceneCorners = new Mat(0, 0, CvType.CV_32FC2);

    // The good detected corner coordinates, in pixels, as integers.

    private final MatOfPoint mIntSceneCorners = new MatOfPoint();

    // A grayscale version of the scene.

    private final Mat mGraySrc = new Mat();

    // Tentative matches of scene features and reference features.

    private final MatOfDMatch mMatches = new MatOfDMatch();

    // A feature detector, which finds features in images.

    private final FeatureDetector mFeatureDetector = FeatureDetector.create(FeatureDetector.ORB);

    // A descriptor extractor, which creates descriptors of

    // features.

    private final DescriptorExtractor mDescriptorExtractor = DescriptorExtractor.create(DescriptorExtractor.ORB);

    // A descriptor matcher, which matches features based on their

    // descriptors.

    private final DescriptorMatcher mDescriptorMatcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMINGLUT);

    // The color of the outline drawn around the detected image.

    private final Scalar mLineColor = new Scalar(0, 255, 0);

    public ImageDetectionFilter(final Context context, final int referenceImageResourceID) throws IOException {

    // Load the reference image from the app's resources.

    // It is loaded in BGR (blue, green, red) format.

    mReferenceImage = Utils.loadResource(context, referenceImageResourceID, Imgcodecs.CV_LOAD_IMAGE_COLOR);

    // Create grayscale and RGBA versions of the reference image.

    final Mat referenceImageGray = new Mat();

    Imgproc.cvtColor(mReferenceImage, referenceImageGray, Imgproc.COLOR_BGR2GRAY);

    Imgproc.cvtColor(mReferenceImage, mReferenceImage, Imgproc.COLOR_BGR2RGBA);

    // Store the reference image's corner coordinates, in pixels.

    mReferenceCorners.put(0, 0, new double[]{0.0, 0.0});

    mReferenceCorners.put(1, 0, new double[]{referenceImageGray.cols(), 0.0});

    mReferenceCorners.put(2, 0, new double[]{referenceImageGray.cols(), referenceImageGray.rows()});

    mReferenceCorners.put(3, 0, new double[]{0.0, referenceImageGray.rows()});

    // Detect the reference features and compute their

    // descriptors.

    mFeatureDetector.detect(referenceImageGray, mReferenceKeypoints);

    mDescriptorExtractor.compute(referenceImageGray, mReferenceKeypoints, mReferenceDescriptors);

    }

    @Override

    public void apply(final Mat src, final Mat dst) {

    // Convert the scene to grayscale.

    Imgproc.cvtColor(src, mGraySrc, Imgproc.COLOR_RGBA2GRAY);

    // Detect the scene features, compute their descriptors,

    // and match the scene descriptors to reference descriptors.

    mFeatureDetector.detect(mGraySrc, mSceneKeypoints);

    mDescriptorExtractor.compute(mGraySrc, mSceneKeypoints, mSceneDescriptors);

    mDescriptorMatcher.match(mSceneDescriptors, mReferenceDescriptors, mMatches);

    // Attempt to find the target image's corners in the scene.

    findSceneCorners();

    // If the corners have been found, draw an outline around the

    // target image.

    // Else, draw a thumbnail of the target image.

    draw(src, dst);

    }

    private void findSceneCorners() {

    final List<DMatch> matchesList = mMatches.toList();

    if (matchesList.size() < 4) {

    // There are too few matches to find the homography.

    return;

    }

    final List<KeyPoint> referenceKeypointsList = mReferenceKeypoints.toList();

    final List<KeyPoint> sceneKeypointsList = mSceneKeypoints.toList();

    // Calculate the max and min distances between keypoints.

    double maxDist = 0.0;

    double minDist = Double.MAX_VALUE;

    for (final DMatch match : matchesList) {

    final double dist = match.distance;

    if (dist < minDist) {

    minDist = dist;

    }

    if (dist > maxDist) {

    maxDist = dist;

    }

    }

    // The thresholds for minDist are chosen subjectively

    // based on testing. The unit is not related to pixel

    // distances; it is related to the number of failed tests

    // for similarity between the matched descriptors.

    if (minDist > 50.0) {

    // The target is completely lost.

    // Discard any previously found corners.

    mSceneCorners.create(0, 0, mSceneCorners.type());

    return;

    } else if (minDist > 25.0) {

    // The target is lost but maybe it is still close.

    // Keep any previously found corners.

    return;

    }

    // Identify "good" keypoints based on match distance.

    final ArrayList<Point> goodReferencePointsList = new ArrayList<Point>();

    final ArrayList<Point> goodScenePointsList = new ArrayList<Point>();

    final double maxGoodMatchDist = 1.75 * minDist;

    for (final DMatch match : matchesList) {

    if (match.distance < maxGoodMatchDist) {

    goodReferencePointsList.add(referenceKeypointsList.get(match.trainIdx).pt);

    goodScenePointsList.add(sceneKeypointsList.get(match.queryIdx).pt);

    }

    }

    if (goodReferencePointsList.size() < 4 || goodScenePointsList.size() < 4) {

    // There are too few good points to find the homography.

    return;

    }

    // There are enough good points to find the homography.

    // (Otherwise, the method would have already returned.)

    // Convert the matched points to MatOfPoint2f format, as

    // required by the Calib3d.findHomography function.

    final MatOfPoint2f goodReferencePoints = new MatOfPoint2f();

    goodReferencePoints.fromList(goodReferencePointsList);

    final MatOfPoint2f goodScenePoints = new MatOfPoint2f();

    goodScenePoints.fromList(goodScenePointsList);

    // Find the homography.

    final Mat homography = Calib3d.findHomography(goodReferencePoints, goodScenePoints);

    // Use the homography to project the reference corner

    // coordinates into scene coordinates.

    Core.perspectiveTransform(mReferenceCorners, mCandidateSceneCorners, homography);

    // Convert the scene corners to integer format, as required

    // by the Imgproc.isContourConvex function.

    mCandidateSceneCorners.convertTo(mIntSceneCorners, CvType.CV_32S);

    // Check whether the corners form a convex polygon. If not,

    // (that is, if the corners form a concave polygon), the

    // detection result is invalid because no real perspective can

    // make the corners of a rectangular image look like a concave

    // polygon!

    if (Imgproc.isContourConvex(mIntSceneCorners)) {

    // The corners form a convex polygon, so record them as

    // valid scene corners.

    mCandidateSceneCorners.copyTo(mSceneCorners);

    }

    }

    protected void draw(final Mat src, final Mat dst) {

    if (dst != src) {

    src.copyTo(dst);

    }

    if (mSceneCorners.height() < 4) {

    // The target has not been found.

    // Draw a thumbnail of the target in the upper-left

    // corner so that the user knows what it is.

    // Compute the thumbnail's larger dimension as half the

    // video frame's smaller dimension.

    int height = mReferenceImage.height();

    int width = mReferenceImage.width();

    final int maxDimension = Math.min(dst.width(), dst.height()) / 2;

    final double aspectRatio = width / (double) height;

    if (height > width) {

    height = maxDimension;

    width = (int) (height * aspectRatio);

    } else {

    width = maxDimension;

    height = (int) (width / aspectRatio);

    }

    // Select the region of interest (ROI) where the thumbnail

    // will be drawn.

    final Mat dstROI = dst.submat(0, height, 0, width);

    // Copy a resized reference image into the ROI.

    Imgproc.resize(mReferenceImage, dstROI, dstROI.size(), 0.0, 0.0, Imgproc.INTER_AREA);

    return;

    }

    // Outline the found target in green.

    Imgproc.line(dst, new Point(mSceneCorners.get(0, 0)), new Point(mSceneCorners.get(1, 0)), mLineColor, 4);

    Imgproc.line(dst, new Point(mSceneCorners.get(1, 0)), new Point(mSceneCorners.get(2, 0)), mLineColor, 4);

    Imgproc.line(dst, new Point(mSceneCorners.get(2, 0)), new Point(mSceneCorners.get(3, 0)), mLineColor, 4);

    Imgproc.line(dst, new Point(mSceneCorners.get(3, 0)), new Point(mSceneCorners.get(0, 0)), mLineColor, 4);

    }

    }

    實現效果圖

    確認允許權限:

    實時追蹤指定圖像

    結語

    本文只實現了需要提供完整原圖進行比對才能實現圖像識別,還有許多更加智能方便的識別技術和方法,比如:HOG、SIFT、SURF 等方法經由正負樣本庫進行訓練后可以從圖像中提取一些特征,并通過特征確定物體類別。OpenCV庫中也仍有很大一部分的功能在本文中未能進行實踐,亟待今后繼續探索和研究。更多Python知識請關注我分享更多!

    本文轉載于:Android開發-基于OpenCV實現相機實時圖像識別跟蹤_Sueed-CSDN博客

    總結

    以上是生活随笔為你收集整理的android opencv 获取小图在大图的坐标_Android开发—基于OpenCV实现相机实时图像识别跟踪...的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。