从Camera frame Android获取Mat对象以获取OpenCV

时间:2014-05-18 15:03:06

标签: android sockets opencv mat

我正在开发一个基于OpenCV4Android提供的教程2的Android应用程序。我想要实现的是当我触摸手机的屏幕(onTouch())时获取相机框架的Mat对象。我想修改代码,以便将图像存储为Mat而不是手机内存中的jpeg文件。垫子将进一步处理。

我是否需要参与onCameraFrame()功能? 任何指导将不胜感激。我对Android开发和OpenCV也很陌生。

注意:我使用的是Android 4.2.2和OpenCV2.4.8。

修改

修改onTouch()onCameraFrame()功能后,这些是代码段:

public Mat onCameraFrame(CvCameraViewFrame inputFrame) {

        Mat img = inputFrame.rgba();

        if(touched) {
            int imgsize = (int) (img.total()*img.channels());
            byte[] data = new byte[imgsize];
            img.get(0,0,data);
            int col = img.cols();
            int row = img.rows();
            Toast.makeText(this, "size:"+imgsize+" row:"+row+" col:"+col, Toast.LENGTH_SHORT).show();

            StartSocket(row, col, imgsize, data);

            touched = false;
        }

        return img;
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        Log.i(TAG,"onTouch event"); 
        touched = true;
        return true;
    }

我所做的基本上是将Mat对象转换为名为ByteArray的{​​{1}},并通过套接字将其与其他信息一起发送到服务器。当我尝试发送文本文件时,套接字可以作为一个单独的项目工作,所以我相信它没有任何问题。

我没有data[]因为我直接在我的设备上运行应用程序。

2 个答案:

答案 0 :(得分:1)

如果你想从相机处理图像,是的,你需要onCameraFrame()方法,因为它提供你的图像

public class MyActivity extends Activity implements CvCameraViewListener2,OnTouchListener {
    boolean touched=false;
    public boolean onTouch(View v, MotionEvent event) {
         touched = true;
         return true;
    }
    public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
        Mat rgba = inputFrame.rgba();
        if ( touched ) {
            // do some processing on rgba Mat
            touched = false;
        }
        return rgba;
    }
}

答案 1 :(得分:1)

我找到了问题的解决方案。当然,如果没有@berak的帮助,我就不会这样做。从LogCat我发现失败是由于线程问题。所以我将以下几行从onTouch()移到StartSocket()函数:

int imgsize = (int) (img.total()*img.channels());
            byte[] data = new byte[imgsize];
            img.get(0,0,data);
            int col = img.cols();
            int row = img.rows();
            Toast.makeText(this, "size:"+imgsize+" row:"+row+" col:"+col, Toast.LENGTH_SHORT).show();

我会将相关的代码段放在这里,以便其他人可以使用它。

public class Tutorial3Activity extends Activity implements CvCameraViewListener2, OnTouchListener {

    static TextView msgReceived;
    String serverMsg = "";

    boolean touched = false;

    public Mat onCameraFrame(CvCameraViewFrame inputFrame) {

        Mat image = inputFrame.rgba();

        if(touched) {
            StartSocket(image); 
            touched = false;
        }

        return image;
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        Log.i(TAG,"onTouch event"); 
        touched = true;

        return true;
    }

    private void StartSocket(final Mat img) {
        Thread t = new Thread(new Runnable(){

            @Override
            public void run() {
                try {
                    final int imgsize = (int) (img.total()*img.channels());
                    byte[] data = new byte[imgsize];
                    img.get(0,0,data);
                    final int col = img.cols();
                    final int row = img.rows();

                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(getBaseContext(), "size:"+imgsize+" row:"+row+" col:"+col, Toast.LENGTH_SHORT).show();
                        }
                    });

                    //--- SEND IMAGE TO SERVER ---//
                    Socket s = new Socket ("192.168.1.25", 6000);

                    DataOutputStream dout = new DataOutputStream(s.getOutputStream());
                    dout.writeInt(col);
                    dout.writeInt(row);
                    dout.writeInt(imgsize);
                    dout.write(data);

                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(getBaseContext(), "Dout written", Toast.LENGTH_SHORT).show();
                        }
                    });

                    dout.flush();
                                        dout.close();
                    s.close(); //close socket

                    } catch (UnknownHostException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            });

            t.start();
    }