+1

OpenCV part3: Sử dụng openCV tạo thực tế ảo trên android (Make An Augmented Reality for Android with openCV)

I. Thực tế ảo là gì

Thực tế ảo là tất cả những thông tin được thêm vào nguồn dữ liệu mà chúng ta có thể thu thập thông qua các giác quan để cung cấp nâng cao hoặc tăng cường tầm nhìn. Chủ yếu nó là thông tin về hình ảnh mặc dù không có lý do tại sao nó không thể là âm thanh. Bên cạnh đó, Shazam là một ví dụ tuyệt vời của một âm thanh dựa trên ứng dụng AR, nó lắng nghe để chơi nhạc và sau đó cung cấp cho bạn thông tin về các nghệ sĩ và bài hát.

Tuy nhiên, hầu hết mọi người nghĩ về AR là một phần của video và tôi không có khác nhau vì vậy chúng tôi sẽ thực hiện một hệ thống AR video dựa vào hướng dẫn này. Phương pháp cơ bản để AR được thể hiện trong biểu đồ dưới đây. Các phương hướng trông như thế này:

arflow.png

  1. Chiếc máy ảnh này chụp một hình ảnh của thế giới
  2. AR kiểm tra các hình ảnh cho một số loại tính năng nhận biết - có lẽ một khuôn mặt, một tòa nhà, một số văn bản hay cái gì khác. Điều này có thể đòi hỏi một số mã xử lý hình ảnh khá tinh vi.
  3. Căn cứ vào những gì nó tìm thấy, các ứng dụng AR sau đó nhìn lên một số dữ liệu bổ sung để 'tăng cường' chế độ xem . Đây có thể là văn bản, một mô hình 3D hoặc lưới hoặc một cái gì đó tương tự.
  4. Các ứng dụng AR nhúng dữ liệu bổ sung này trong hình ảnh. Nó có thể trôi nổi trên các đỉnh của tính năng được công nhận hoặc, trong trường hợp của một mô hình 3D, nó có thể đòi hỏi ánh sáng tinh tế và bóng để làm cho nó pha trộn trong như thể nó là một phần của hình ảnh
  5. Cuối cùng, các ứng dụng cho thấy hình ảnh này cho chúng tôi trên màn hình của thiết bị AR của chúng tôi. Nếu chúng ta có thể làm điều này 30 lần mỗi giây sau đó chúng tôi có một ứng dụng AR nhập vai tuyệt vời.

II.Getting started

Điều đầu tiên chúng ta cần làm là để có thể cho phép các máy ảnh và bắt đầu chụp các khung hình video và hiển thị chúng trên màn hình của thiết bị của chúng tôi. Tạo một dự án mới với một Hoạt động trống và tạo ra các tập tin sau đây:

activity_main.xml

<RelativeLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:opencv="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">
    <org.opencv.android.NativeCameraView
        android:id="@+id/main_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        opencv:show_fps="true"
        opencv:camera_id="any"/>
</RelativeLayout>

Cách bố trí này chỉ đơn giản là định nghĩa một cái nhìn duy nhất mà sẽ hiển thị các khung lấy từ máy ảnh mặc định. Các hạng mục chính cần lưu ý từ cách bố trí là chúng ta cần phải include một không gian tên mới:

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

định nghĩa để sử dụng các thành phần OpenCV trong bố cục.

Sau đó chúng ta đi đến để xác định một NativeCameraView. Dòng OpenCV:show_fps="true" sẽ cho phép người xem để Automagically chỉ số lượng khung hình mỗi giây được xử lý mà sẽ cung cấp cho chúng ta một biện pháp hiệu quả như thế nào mã của chúng tôi là. Cũng lưu ý OpenCV:camera_id="any" mà sẽ làm cho thiết bị sử dụng máy ảnh đầu tiên mà nó tìm thấy là một để cung cấp các khung hình video. Các camera_id có thể được thiết lập để được một ID cụ thể trên các thiết bị với nhiều máy quay.

Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.sindesso.ardemo1"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="17"
        android:targetSdkVersion="17" />
        <uses-permission android:name="android.permission.CAMERA"/>
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.sindesso.ardemo1.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

chúng ta cần phải khai báo: <uses-permission android:name="android.permission.CAMERA"/> để cho phép truy cập máy ảnh.

MainActivity.java

import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Mat;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.view.WindowManager;

/* 1. Note that we implement CvCameraViewListener2 */
public class MainActivity extends Activity implements CvCameraViewListener2 {
/*
 * For logging
 */
private final String TAG = getClass( ).getCanonicalName();

/*
 * 2. The Camera View
 */
private CameraBridgeViewBase mOpenCvCameraView;
/*
 * 3. Load and initialise OpenCV
 */
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
    @Override public void onManagerConnected(int status) {
        switch (status) {
            case LoaderCallbackInterface.SUCCESS:
                Log.i(TAG, "OpenCV loaded successfully");
                mOpenCvCameraView.enableView();
                break;
            default:
                super.onManagerConnected(status);
                break;
        }
     }
  };      public MainActivity()
      Log.i(TAG, "Instantiated new " + this.getClass());
  }
  @Override
  public void onCreate(Bundle savedInstanceState) {
      Log.i(TAG, "called onCreate");
      super.onCreate(savedInstanceState);
      /*
       *4. Ensure that screen doesn't turn off
       */          getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
      setContentView(R.layout.activity_main);
      /*
       *5. Add myself as callback for camera
       */
       mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.main_view);
      mOpenCvCameraView.setCvCameraViewListener(this);      }
  @Override
  public void onPause() {
      super.onPause();
      /*
       *6. Stope view when app is paused
       */
      if (mOpenCvCameraView != null)               mOpenCvCameraView.disableView();
  }
  @Override
  public void onResume() {
       super.onResume();
       /*
        * 7. Call the asynch loader on another thread
        */
    OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback);
  }
  public void onDestroy() {
      super.onDestroy();
      if (mOpenCvCameraView != null) {
          mOpenCvCameraView.disableView();
      }
  }
      /*
       *8. Called every time the camera grabs a frame.
       */
      public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
      return inputFrame.rgba();
  }
  @Override
  public void onCameraViewStarted(int width, int height) {}
  @Override
  public void onCameraViewStopped() {}
}

Lớp hoạt động (lớp Activity) được thực hiện (implement) các phương thức (method):

public Food onCameraFrame (CvCameraViewFrame input frame)

public void onCameraViewStarted(int width, int height)

public void onCameraViewStopped()

Trong số các hàm được nêu thì hàm được quan tâm nhất là OnCameraFrame vì nó sẽ được gọi khắp gọi thời điểm mỗi khi có một khung mới để xử lý.

private CameraBridgeViewBase mOpenCvCameraView : điều khiển khi camera được bật, xử lý các khung hình, kêu gọi người nghe bên ngoài để thực hiện bất kỳ điều chỉnh vào khung và sau đó rút ra các kết quả khung màn hình. Khối mã này được gọi là trước khi xây dựng Hoạt động được gọi. Đó là điều cơ bản để tải và khởi tạo thư viên OpenCV. Dòng mOpenCvCameraView.enableView() cho phép người xem để nó có thể bắt đầu với khung hình chụp và hiển thị từ máy ảnh. Một khi chúng ta bắt đầu và onCreate được gọi, nó đảm bảo rằng màn hình được giữ thiết lập và bố trí trên layout. mOpenCvCameraView.setCvCameraViewListener(this); thêm Hoạt động như một người biết lắng nghe để xem. Mỗi lần một khung được sản xuất, phương thức onCameraFrame (CvCameraViewFrame inputFrame) sẽ được gọi, cho chúng ta một cơ hội để xử lý hình ảnh và tìm thấy bất kỳ vật dụng hữu ích hoặc augmentable trong nó, trước khi nó được hiển thị. Dừng máy ảnh hoặc khởi động lại nó khi ứng dụng bị tạm dừng hoặc tiếp tục. Phương pháp này là ruột của khả năng AR của chúng tôi. Ở đây chúng tôi đã thông qua một bản sao của khung và có cơ hội để xử lý nó trước khi nó được hiển thị. Chúng tôi dự kiến ​​sẽ trở lại một instace Mat mà là một ma trận OpenCV được mô tả ở đây, nhưng về cơ bản là một ma trận đại diện cho nội dung hình ảnh. Trong ví dụ của mình, chúng tôi chỉ trả lại các hình ảnh màu RGB như một ma trận từ khung. Chúng tôi đều có thể sử dụng phương pháp gray() của CvCameraViewFrame để trả lại một hình ảnh màu xám.

tham khảo Link : Augmented Reality Tutorial


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.