Ask Your Question
0

IP Camera frames manipulation

asked 2013-06-26 17:11:40 -0600

Is it possible to receive the video stream from an ip camera to my android application and manipulate it in order to accomplish face and movement detection. I search the forum but i wasn't able to find something similar. Any given guidelines will be most helpful

edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted
1

answered 2013-06-28 05:05:24 -0600

berak gravatar image

i needed that too, so i hacked something. create an ordinary Android application, add the opencv libs, and add

<uses-permission android:name="android.permission.INTERNET" />

to the manifest.

here's the code:

package com.berak.mjpg;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import org.opencv.android.BaseLoaderCallback;
import org.opencv.android.LoaderCallbackInterface;
import org.opencv.android.OpenCVLoader;
import org.opencv.android.Utils;
import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.highgui.Highgui;

import com.berak.mjpg.R;

import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.graphics.Bitmap;
import android.util.Log;
import android.view.Menu;
import android.widget.ImageView;

public class MainActivity extends Activity {

    MjpgTask task;

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

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public void onPause() {
        super.onPause();
        task.doRun = false;
        task.cancel(true);
    }

    private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
        @Override
        public void onManagerConnected(int status) {
            switch (status) {
            case LoaderCallbackInterface.SUCCESS:
                break;
            default:
                super.onManagerConnected(status);
                break;
            }
        }
    };

    @Override
    public void onResume() {
        super.onResume();

        boolean r = OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_5,this, mLoaderCallback);
        Log.e("MJPG", "opencv onboard : " + r);

        task = new MjpgTask();
        task.execute("http://82.135.240.133/mjpg/video.mjpg?resolution=352x288");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        task.doRun = false;
        task.cancel(true);
    }

    private class MjpgTask extends AsyncTask<String, Integer, Long> {
        byte[] arr = new byte[100000];
        boolean doRun = false;

        protected Long doInBackground(String... urls) {
            long totalSize = 0;
            try {
                URL url = new URL(urls[0]);
                HttpURLConnection con = (HttpURLConnection) url.openConnection();
                InputStream in = con.getInputStream();
                doRun = in.available() > 0;
                while (doRun) {
                    int i = 0;
                    // check for jpeg soi sequence: ff d8
                    for (; i < 1000; i++) {
                        int b = in.read();
                        if (b == 0xff) {
                            int b2 = in.read();
                            if (b2 == 0xd8)
                                break;
                        }
                    }
                    if (i > 999) {
                        Log.e("MJPG", "bad head!");
                        continue;
                    }
                    arr[0] = (byte) 0xff;
                    arr[1] = (byte) 0xd8;
                    i = 2;
                    // check for jpeg eoi sequence: ff d9
                    for (; i < 100000; i++) {
                        int b = in.read();
                        arr[i] = (byte) b;
                        if (b == 0xff) {
                            i++;
                            int b2 = in.read();
                            arr[i] = (byte) b2;
                            if (b2 == 0xd9)
                                break;
                        }
                    }
                    i++; // total bytecount
                    publishProgress(i);
                }
            } catch (Exception e) {
                Log.e("MJPG", e.toString());
            }
            return totalSize;
        }

        // This is called each time you call publishProgress()
        protected void onProgressUpdate(Integer... progress) {
            int nBytes = progress[0];
            Log.e("MJPG", "got an image, " + nBytes + " bytes!");
            // Bitmap bm = BitmapFactory.decodeByteArray(arr, 0, nBytes);
            Mat ocvImg = Highgui.imdecode(new MatOfByte(arr),Highgui.IMREAD_UNCHANGED);

            // .. your processing here ..

            // convert back:
            Bitmap bm = Bitmap.createBitmap(ocvImg.cols(), ocvImg.rows(),Bitmap.Config.ARGB_8888);
            Utils.matToBitmap(ocvImg, bm);
            if (bm != null && bm.getHeight() > 0) {
                ImageView v = (ImageView) findViewById(R.id.imageView1);
                v.setImageBitmap(bm);
            }
        }

        // This is called when doInBackground() is finished
        protected void onPostExecute(Long result) {
        }
    }
}
edit flag offensive delete link more

Comments

can you please give me an explanation on what you did since i am new to the opecv development?

mariospalechoros gravatar imagemariospalechoros ( 2013-07-08 11:20:57 -0600 )edit

i have been running and debugging your code and it looks to work very well but because i am new to opencv can you give me an example of how can i process the images.I basically wanted to do a face detection app.I stacked for a few days now.

mariospalechoros gravatar imagemariospalechoros ( 2013-07-25 11:08:30 -0600 )edit
1

hmm, did you look at OpenCV/samples/face-detection/src/org/opencv/samples/facedetect/FdActivity.java ? basically, you want the same steps as taken there for the JAVA_DETECTOR, that is:

  • initialize and load a CascadeClassifier (same as in BaseLoaderCallback)
  • in onProgressUpdate, when you got the ocvImg, convert it to grayscale
  • call mJavaDetector.detectMultiScale() to fill a MatOfRect faces;
berak gravatar imageberak ( 2013-07-25 11:46:57 -0600 )edit

This works great! However, there is a huge lag between the view output and the camera input. What would you recommend to reduce this? Thanks in advance!

aliavci gravatar imagealiavci ( 2015-03-08 16:39:24 -0600 )edit
0

answered 2013-06-27 04:30:00 -0600

up! I also want to know.

edit flag offensive delete link more

Question Tools

Stats

Asked: 2013-06-26 17:11:40 -0600

Seen: 2,426 times

Last updated: Jun 28 '13