Reputation: 31
i am developing an app that detects a yellow object and whenever the object is detected it speaks object detected. the problem i am facing is that it gives me a very low frame rate of around 1-2 frames per second. i want to improve this frame rate. please help me. is there any way to reduce the resolution, even that would increase frame rate. here is my code:
package org.opencv.samples.imagemanipulations;
import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewFrame;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.CameraBridgeViewBase.CvCameraViewListener2;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.util.Log;
import android.view.WindowManager;
public class ImageManipulationsActivity extends Activity implements CvCameraViewListener2, TextToSpeech.OnInitListener {
private static final String TAG = "OCVSample::Activity";
private CameraBridgeViewBase mOpenCvCameraView;
private Mat mRgba;
int count = 0;
private TextToSpeech myTTS;
private int MY_DATA_CHECK_CODE = 0;
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 ImageManipulationsActivity() {
Log.i(TAG, "Instantiated new " + this.getClass());
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "called onCreate");
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.image_manipulations_surface_view);
myTTS= new TextToSpeech(this,this);
Intent checkTTSIntent = new Intent();
checkTTSIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
startActivityForResult(checkTTSIntent, MY_DATA_CHECK_CODE);
mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.image_manipulations_activity_surface_view);
mOpenCvCameraView.setCvCameraViewListener(this);
}
@Override
public void onPause()
{
super.onPause();
if (mOpenCvCameraView != null)
mOpenCvCameraView.disableView();
}
@Override
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 void onCameraViewStarted(int width, int height) {
mRgba = new Mat();
new Size();
new Mat();
}
public void onCameraViewStopped() {
// Explicitly deallocate Mats
if (mRgba != null)
mRgba.release();
mRgba = null;
}
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
mRgba = inputFrame.rgba();
Size s=mRgba.size();
for (int i = 0; i < s.height; i++) {
for (int j = 0; j < s.width; j++) {
double[] rgb=mRgba.get(i,j);
double a=rgb[0];
double b=rgb[1];
double c=rgb[2];
if ((a>=225) && (a<=240) && (b>=215) && (b<= 230) && (c>=90) && (c<= 150)) {
count=count++;
}
}
}
if (count>1000) {
myTTS.speak("object detected", TextToSpeech.QUEUE_FLUSH, null);
}
return mRgba;
}
protected void onActivityResult1(int requestCode, int resultCode, Intent data) {
if (requestCode == MY_DATA_CHECK_CODE) {
if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) {
myTTS = new TextToSpeech(this, this);
}
else {
Intent installTTSIntent = new Intent();
installTTSIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
startActivity(installTTSIntent);
}
}
}
public void onInit(int initStatus) {
if (initStatus == TextToSpeech.SUCCESS) {
if(myTTS.isLanguageAvailable(Locale.US)==TextToSpeech.LANG_AVAILABLE)
myTTS.setLanguage(Locale.US);
}
else if (initStatus == TextToSpeech.ERROR) {
Toast.makeText(this, "Sorry! Text To Speech failed...", Toast.LENGTH_LONG).show();
}
}
}
Upvotes: 0
Views: 1534
Reputation: 5839
Obviously most of your time is being spent in onCameraFrame. Right now you are checking every single pixel, but you don't have to. If (0, 0) isn't yellow, then (0, 1) probably isn't either.
Try checking every 10 pixels. If any of those pixels are yellow, then do a secondary full-resolution scan around the yellow pixels.
for (int i = 0; i < s.height; i+=10)
for (int j = 0; j < s.width; j+=10)
if(yellow)
addPixelToListToCheckLater(i, j);
while(pixels still remain to be double checked){
currenti = nextIInList;
currentj = nextJInList;
for (int i = currenti - 10; i < currenti + 10; i++)
for (int j = currentj - 10; j < currentj + 10; j++)
if(yellow)
count++;
}
Upvotes: 4