ミムの部屋

社内SEが,興味をもったことを書いていきます.

opencv でカメラビューに円を検知する(opencv,androidアプリ,カメラビュー)

opencvを用いて,カメラビューで円を検知し描画するソースコードを載せます.
とりあえず,下の感じです.
説明は適宜追加する可能性があります.

opencvの主処理

//android関連
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

//opencv関連
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.Scalar;
import org.opencv.imgproc.Imgproc;
import org.opencv.core.Point;


/**
 * Created by あああああ on 2017/07/02.
 */
public class CameraActivity extends Activity implements CameraBridgeViewBase.CvCameraViewListener{
    // カメラビューのインスタンス
	// CameraBridgeViewBase は JavaCameraView/NativeCameraView のスーパークラス
	private CameraBridgeViewBase mCameraView;

    // ライブラリ初期化完了後に呼ばれるコールバック (onManagerConnected)
    // public abstract class BaseLoaderCallback implements LoaderCallbackInterface
    private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
        @Override
        public void onManagerConnected(int status) {
            switch (status) {
                // 読み込みが成功したらカメラプレビューを開始
                case LoaderCallbackInterface.SUCCESS:
                    mCameraView.enableView();
                    break;
                default:
                    super.onManagerConnected(status);
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera);

        Log.d("camera","onCreate");
        // カメラビューのインスタンスを変数にバインド
        mCameraView = (CameraBridgeViewBase) findViewById(R.id.camera_view);
        // リスナーの設定 (後述)
        mCameraView.setCvCameraViewListener(this);

    }

    @Override
    protected void onResume() {
        super.onResume();
        // 非同期でライブラリの読み込み/初期化を行う
        // static boolean initAsync(String Version, Context AppContext, LoaderCallbackInterface Callback)
        if (!OpenCVLoader.initDebug()) {
            Log.d("onResume", "Internal OpenCV library not found. Using OpenCV Manager for initialization");
            OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_0_0, this, mLoaderCallback);
        } else {
            Log.d("onResume", "OpenCV library found inside package. Using it!");
            mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);

        }
    }

    @Override
    public void onCameraViewStarted(int width, int height) {
        // カメラプレビュー開始時に呼ばれる
        Log.d("camera","viewstart");
    }
    @Override
    public void onCameraViewStopped() {
        // カメラプレビュー終了時に呼ばれる
    }

    // CvCameraViewListener の場合
    // フレームをキャプチャする毎(30fpsなら毎秒30回)に呼ばれる
    @Override
    public Mat onCameraFrame(Mat inputFrame) {
        // 円を検出する部分
        Mat gray = new Mat(inputFrame.rows(), inputFrame.cols(), CvType.CV_8SC1);
        Imgproc.cvtColor(inputFrame, gray, Imgproc.COLOR_RGB2GRAY);
        Mat circles = new Mat();// 検出した円の情報格納する変数
        Imgproc.HoughCircles(gray, circles, Imgproc.CV_HOUGH_GRADIENT, 2, 10, 160, 50, 10, 20);

        Point pt = new Point();
        // 検出した直線上を緑線で塗る
        for (int i = 0; i < circles.cols(); i++){
            double data[] = circles.get(0, i);
            pt.x = data[0];
            pt.y = data[1];
            double rho = data[2];
            Imgproc.circle(inputFrame, pt, (int)rho, new Scalar(0, 200, 0), 5);
        }
        Log.d("onCamera", "1");

        return inputFrame;
    }

    // CvCameraViewListener2 の場合
//    @Override
//    public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
//        Mat circles = new Mat();
//        Mat gray = new Mat();
//        Imgproc.cvtColor(inputFrame,gray,Imgproc.COLOR_RGB2GRAY);
//        Imgproc.HoughCircles(gray,circles,Imgproc.CV_HOUGH_GRADIENT,2,10,160,50,10,20);
//        return inputFrame;
//    }
    public interface CvCameraViewFrame {
        // 1チャンネルグレースケールのMatインスタンスを返す
        public Mat gray();
    }
}

AndroidMainfeset.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.exampl.あああああああ">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".Library.LibraryActivity"
            android:label="@string/library_images"
            >

        </activity>
        <activity
            android:name=".Camera.CameraActivity"
            android:label="@string/library_images"
            android:screenOrientation="landscape">

        </activity>
    </application>

    <!--権限設定-->
    <uses-permission android:name="android.permission.INTERNET" />
    <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"/>
</manifest>

カメラビューのlayout

<?xml version="1.0" encoding="utf-8"?>
<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:orientation="vertical"
    tools:context="com.example.あああああああ.Camera.CameraActivity">

    <org.opencv.android.JavaCameraView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:visibility="visible"
        android:id="@+id/camera_view"
        opencv:show_fps="true"
        opencv:camera_id="any" />

</RelativeLayout>

build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 24
    buildToolsVersion "24.0.0"

    defaultConfig {
        applicationId "com.example.ああああああ"
        minSdkVersion 15
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:24.2.1'
    compile project(':openCVLibrary320')
}