CS663 | computer vision
  • outline
  • projects
  • syllabus
  • links

Example OpenCV Android app with Image Processing

first fully read creating OpenCV Android app project

Activity Interface in XML

...... includes a SPINNER and a TEXT

<?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"

tools:context=".MainActivity"
>



<
TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="OpenCV Test App"
android:id="@+id/textView" />

<
Spinner
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/spinner_menu"
android:layout_above="@+id/cameraLinearLayout"
android:layout_alignParentEnd="true"
android:layout_alignBottom="@+id/textView" />

<
LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/cameraLinearLayout"
android:layout_below="@+id/textView">



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


</
LinearLayout>




</
RelativeLayout>

 

strings.xml file (used to create string-array for an adapter to fill in spinner choices)

<resources>

*****whatever you have currently in this file******

ADD THE FOLLOWING

<string-array name="spinner_menu">
<item>Random</item>
<item>Threshold</item>
<item>Greyscale</item>
<item>Edge Detect</item>
<item>Negative</item>
<item>Contrast Stretch</item>
</string-array>

 

 

 

 

Code - Activity File (get zip of project --but, your verison of Android SDK may be different so may not be able to use directly)

NOTE: items in yellow will be different for your project
NOTE: items in blue are new code from our previous simple app that only displayed image

package com.grewe.ilab.imageprocessingproject;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceView;
import android.view.WindowManager;
import android.widget.Toast;

import org.opencv.android.OpenCVLoader;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.core.Mat;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;

import android.widget.Spinner;

public class MainActivity extends AppCompatActivity implements CvCameraViewListener2,OnItemSelectedListener
 {

// will point to our View widget for our image
private CameraBridgeViewBase mOpenCvCameraView;
private static final String TAG = "OCVSample::Activity";

//class variables dealing with Spinner for Image Processing algorithm selection
Spinner spinner_menu;
//grab array of possible menu items from strings.xml file
String[] menu_items;
String menu_item_selected;

@Override
protected void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "called onCreate");
super.onCreate(savedInstanceState);
//Load Layout setContentView(R.layout.activity_main);
//SPINNER SETUP setup menu from strings.xml file this.menu_items = getResources().getStringArray(R.array.spinner_menu); this.menu_item_selected = menu_items[0]; //initialize to first item in arry Log.i("SPINNER", "menu item is " + this.menu_item_selected); //grab a handle to spinner_menu in the XML interface spinner_menu = (Spinner)findViewById(R.id.spinner_menu); // Create an ArrayAdapter using the string array and a default spinner layout ArrayAdapter adapter = ArrayAdapter.createFromResource(this, R.array.spinner_menu, android.R.layout.simple_spinner_item); // Specify the layout to use when the list of choices appears adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); // Apply the adapter to the spinner spinner_menu.setAdapter(adapter); spinner_menu.setSelection(0);//initialize to first item in menu //set this activity to listen to the menu choice in spinner spinner_menu.setOnItemSelectedListener(this); //Load in the OpenCV dependency module code from the jni files you linked in this project // inside the OpenCV module if (!OpenCVLoader.initDebug()) { Toast.makeText(MainActivity.this, "Unable to load OpenCV", Toast.LENGTH_LONG).show(); } getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); // grab a "handle" to the OpenCV class responsible for viewing Image // look at the XML the id of our CameraBridgeViewBase is HelloOpenCVView mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.HelloOpenCvView); //set it visible, register the listener and enbale the view so connected to camera mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE); mOpenCvCameraView.setCvCameraViewListener(this); // the activity will listen to events on Camera -call onCameraFrame mOpenCvCameraView.enableView(); } // disable JavaCameraView if app going on pause @Override public void onPause() { super.onPause(); if (mOpenCvCameraView != null) mOpenCvCameraView.disableView(); } //enable the JavaCameraView if app resuming @Override public void onResume() { super.onResume(); if (mOpenCvCameraView != null) mOpenCvCameraView.enableView(); } //Disable view of JavaCameraView if app is being destoryed @Override public void onDestroy() { super.onDestroy(); if (mOpenCvCameraView != null) mOpenCvCameraView.disableView(); } //method invoked when camera view is started public void onCameraViewStarted(int width, int height) { } //method invoked when camera view is stoped public void onCameraViewStopped() { } // THIS IS THE main method that is called each time you get a new Frame/Image // Implement to be a CVCameraViewListener2 public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) { //store in the imageMat (instance of OpenCV's Mat class, a 2D matrix) the RGB(A=alpha) image Mat imageMat = inputFrame.rgba(); //Process Image as desired --note the following is commented out but gives you an idea // now you use the Mat class to represent the Image and you can use method calls // like imageMat // make calls like to get a pixel at i,j imageMat.get // double pixel[] = new double[3]; // pixel = imageMat.get(20,10); this wil retrieve pixel and column = 20, row =10 // similarly can set a pixel in Mat via imageMat.set(i,j,pixel); // read API on Mat class for OPenCV // A VERY USEFUL class to call image processing routines is ImagProc // This code in comments shows how to do the Sobel Edge Detection on our image in imageMat /* Mat gray = inputFrame.gray(); Mat mIntermediateMat = new Mat(); Imgproc.Sobel(gray, mIntermediateMat, CvType.CV_8U, 1, 1); Core.convertScaleAbs(mIntermediateMat, mIntermediateMat, 10, 0); Imgproc.cvtColor(mIntermediateMat, imageMat, Imgproc.COLOR_GRAY2BGRA, 4); */ //START IMAGE PROCESSING OPTIONS //Using OPenCV create the greyscale image from the current input color image Mat gray = inputFrame.gray(); //SELECT IMAGE PROCESSING ALGORITHM // Based on spinner menu selected item stored as this.menu_item_selected perform appropriate // operation and return a Mat if(this.menu_item_selected.equals("Random")) { //OPTION RANDOM //return imageMat; //create random number 0 to 1 and return color if < .5 and grey otherwise Random rand = new Random(System.currentTimeMillis()); if (rand.nextDouble() < 0.5) { Log.d("SPINNER", "return color"); return imageMat;} else { Log.d("SPINNER", "return greyscale"); return gray;} } else if(this.menu_item_selected.equals("Greyscale")) { //OPTION GREYSCALE Log.d("SPINNER", "return greyscale"); return gray; } else if(this.menu_item_selected.equals("Threshold")) { //OPTION THRESHOLD urrently always threshold the greyscale image at value of 100 /* FROM OPENCV DOCUMENTATION : threshold(Mat src,Mat dst,double thresh, double maxval,int type) The function applies fixed-level thresholding to a single-channel array. The function is typically used to get a bi-level (binary) image out of a grayscale image type = THRESH_BINARY if src(x,y) > thresh then dest(x,y) = maxval; 0 otherwise */ Log.i("SPINNER", "performing thresholding"); Imgproc.threshold(gray,gray, 100.0, 255.0, Imgproc.THRESH_BINARY ); return gray; } else { // OPTION OTHERS - for now return color for all other choices return gray; } } //Spinner Menu Selection response method public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) { // An item was selected. You can retrieve the selected item using this.menu_item_selected = parent.getItemAtPosition(pos).toString(); Log.i("SPINNER", "choice is" + this.menu_item_selected); } //Spinner Menu Selected method if nothing selected --initializes to first algorithm in item list public void onNothingSelected(AdapterView<?> parent) { this.menu_item_selected = this.menu_items[0]; }

 

Random selected = Output sometimes grey sometimes color (note is emulator running with emulated camera)

 

Greyscale selected =

Threshold selected=

 

cs663:computer vision

  • home
  • outline
  • projects
  • syllabus
  • links