package org.opencv.samples.colorblobdetect;
import java.util.ArrayList;
import java.util.List;
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 org.opencv.core.MatOfPoint;
import org.opencv.core.Scalar;
import org.opencv.imgproc.Imgproc;
import org.opencv.video.BackgroundSubtractorMOG;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SurfaceView;
import android.view.WindowManager;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.Toast;
public class MainActivity extends Activity implements CvCameraViewListener2,
OnSeekBarChangeListener {
private static final String TAG = "OCVSample::Activity";
private CameraBridgeViewBase mOpenCvCameraView;
private boolean mIsJavaCamera = true;
private MenuItem mItemSwitchCamera = null;
private BackgroundSubtractorMOG sub;
private Mat mGray;
private Mat mRgb;
private Mat mFGMask;
private List<MatOfPoint> contours;
private double lRate = 0.5;
private SeekBar sb;
// Initialization required by apps using OpenCV Manager
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());
}
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "called onCreate");
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.color_blob_detection_surface_view);
// sets up camera
if (mIsJavaCamera)
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.color_blob_detection_activity_surface_view);
else
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.color_blob_detection_activity_surface_view);
mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
mOpenCvCameraView.setCvCameraViewListener(this);
// sets up seek bar to adjust learning rate
// sb = (SeekBar) findViewById(R.id.seekBar1);
// sb.setProgress(5);
// sb.setMax(10);
// sb.setOnSeekBarChangeListener(this);
}
@Override
public void onPause() {
super.onPause();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
public void onResume() {
super.onResume();
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this,
mLoaderCallback);
}
public void onDestroy() {
super.onDestroy();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
// public boolean onCreateOptionsMenu(Menu menu) {
// Log.i(TAG, "called onCreateOptionsMenu");
// mItemSwitchCamera = menu.add("Toggle Native/Java camera");
// return true;
// }
//
// // Switching between native and Java libraries for controlling cameras,
// may
// // not be working fully!
// public boolean onOptionsItemSelected(MenuItem item) {
// String toastMesage = new String();
// Log.i(TAG, "called onOptionsItemSelected; selected item: " + item);
//
// if (item == mItemSwitchCamera) {
// mOpenCvCameraView.setVisibility(SurfaceView.GONE);
// mIsJavaCamera = !mIsJavaCamera;
//
// if (mIsJavaCamera) {
// mOpenCvCameraView = (CameraBridgeViewBase)
// findViewById(R.id.color_blob_detection_activity_surface_view);
// toastMesage = "Java Camera";
// } else {
// mOpenCvCameraView = (CameraBridgeViewBase)
// findViewById(R.id.color_blob_detection_activity_surface_view);
// toastMesage = "Native Camera";
// }
//
// mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE);
// mOpenCvCameraView.setCvCameraViewListener(this);
// mOpenCvCameraView.enableView();
// Toast toast = Toast.makeText(this, toastMesage, Toast.LENGTH_LONG);
// toast.show();
// }
//
// return true;
// }
public void onCameraViewStarted(int width, int height) {
// creates a new BackgroundSubtractorMOG class with the arguments
sub = new BackgroundSubtractorMOG(3, 4, 0.8, 0.5);
// creates matrices to hold the different frames
mRgb = new Mat();
mFGMask = new Mat();
mGray = new Mat();
// arraylist to hold individual contours
contours = new ArrayList<MatOfPoint>();
}
public void onCameraViewStopped() {
}
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
contours.clear();
// gray frame because it requires less resource to process
mGray = inputFrame.gray();
// this function converts the gray frame into the correct RGB format for
// the BackgroundSubtractorMOG apply function
Imgproc.cvtColor(mGray, mRgb, Imgproc.COLOR_GRAY2RGB);
// apply detects objects moving and produces a foreground mask
// the lRate updates dynamically dependent upon seekbar changes
sub.apply(mRgb, mFGMask, lRate);
// erode and dilate are used to remove noise from the foreground mask
Imgproc.erode(mFGMask, mFGMask, new Mat());
Imgproc.dilate(mFGMask, mFGMask, new Mat());
// drawing contours around the objects by first called findContours and
// then calling drawContours
// RETR_EXTERNAL retrieves only external contours
// CHAIN_APPROX_NONE detects all pixels for each contour
Imgproc.findContours(mFGMask, contours, new Mat(),
Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_NONE);
// draws all the contours in red with thickness of 2
Imgproc.drawContours(mRgb, contours, -1, new Scalar(255, 0, 0), 2);
return mRgb;
}
@Override
public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {
lRate = (double) arg1 / 10.0;
}
@Override
public void onStartTrackingTouch(SeekBar arg0) {
// TODO Auto-generated method stub
}
@Override
public void onStopTrackingTouch(SeekBar arg0) {
// TODO Auto-generated method stub
}
}