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') }