流式摄像机帧

时间:2017-11-22 14:11:25

标签: android image

我正在尝试编写一个Android应用程序,通过相机将从第一台设备拍摄的图像流式传输到另一台使用WiFi Direct的设备。

我设法连接两个设备,并从手机图库交换图像,但我无法直接从相机交换图像。

开始编辑

要使用OpenCV模块获取相机帧,我的mainActivity扩展了CvCameraViewListener。

这应该是我得到我的框架的课程:

public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
    appData.image_got++;
    myInputFrame = inputFrame.rgba();
   // if(myInputFrame != null){Log.e("on camera frame","input frame");}
    timestampQ.push(System.currentTimeMillis());
    byte[] img  = Mat2Byte(myInputFrame);
    return myInputFrame;
}

应将Mat转换为字节的类

public byte[] Mat2Byte(Mat img){
    int total_bytes = img.cols() * img.rows() * img.channels();
    byte[] return_byte = new byte[total_bytes];
    img.get(0, 0, return_byte);
    return return_byte;
}

编辑结束

这是应该发送获得的帧的代码:

Thread myThread = new Thread(){
    @Override
    public void run(){
        while (appData.image_got <= 0) {
            Log.d(TAG, "Waiting for image");
            try {
                Thread.sleep(1000);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        int image_got_local = -1;
        mOpenCvCameraView.turnFlashOn();
        mOpenCvCameraView.setFrameRate(30000, 30000);           //We are trying to get 30FPS constant rate
        while(keep_thread_running & !myThread.isInterrupted()){

            //We will wait till a new frame is received
            while(image_got_local == appData.image_got){
                //Sleeping part may lead to timing problems
                try {
                    Thread.sleep(11);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }

            appData.frameSz = myInputFrame.size();

            ArrayList<Mat> img_comp = new ArrayList<Mat>(3);
            Core.split(myInputFrame, img_comp);

            if(myInputFrame == null) {Log.e("main thread","input frame is null");}
            //Get the red component of the image
            Mat myMat = img_comp.get(0);

            byte[] byte_img = Mat2Byte(myMat);
            if(byte_img == null)Log.e("main thread","byte_img is null");
            conta = conta +1;

            try
            {
                if (byte_img !=null){
                    Socket socket = new Socket();
                    int port = 8988;
                    try
                    {
                        socket.bind(null);
                        socket.connect((new InetSocketAddress(OwnerIp, port)));
                        OutputStream stream = socket.getOutputStream();
                        InputStream is = null;
                        try
                        {
                            is = new ByteArrayInputStream(byte_img);
                            Log.e("main thread","input stream not null: " + is.toString());
                        }
                        catch (Exception e){Log.e("main thread","byte array input stream " +
                                "exception: " + e.getMessage());}
                        DeviceDetailFragment.copyFile(is, stream);
                        Log.d("main thread", "Client: Data written");
                    }
                    catch (Exception e){Log.e("main thread","connect or bind exception: "
                    + e.getMessage());}
                    finally {
                        if (socket != null) {
                            if (socket.isConnected()) {
                                try {
                                    socket.close();
                                } catch (IOException e) {
                                    // Give up
                                    Log.e("file transfer service","exception socket close: " +
                                            e.getMessage());
                                }
                            }
                        }
                    }
                }
            }
            catch(Exception e ){Log.e("main thread","exception: " + e.getMessage());}

            appData.frameAv = getMatAvg(myMat);

            //We cannot access UI objects from background threads, hence need to pass this data to UI thread
            Message uiMessage = mHandler.obtainMessage(1,appData);
            uiMessage.sendToTarget();

            handleInputData(appData.frameAv);
            image_got_local = appData.image_got;

        }
    }
};

这是代码,在应该读取所​​获得的帧的另一个应用程序上:

public class FileServerAsyncTask extends AsyncTask<String, String, String> {

    private Context mFilecontext;
    private String Extension, Key;
    private File EncryptedFile;
    private long ReceivedFileLength;
    private int PORT;

    public FileServerAsyncTask(Context context, int port) {
        this.mFilecontext = context;
        handler = new Handler();
        this.PORT = port;

    }

    @Override
    protected String doInBackground(String... params) {

        try {
            ServerSocket serverSocket = new ServerSocket(8988);
            Log.d(WiFiDirectActivity.TAG, "Server: Socket opened");
            Socket client = serverSocket.accept();
            Log.d(WiFiDirectActivity.TAG, "Server: connection done");
            final File f = new File(Environment.getExternalStorageDirectory() + "/"
                    + getContext().getPackageName() + "/wifip2pshared-" + System.currentTimeMillis()
                    + ".jpg");

            File dirs = new File(f.getParent());
            if (!dirs.exists())
                dirs.mkdirs();
            f.createNewFile();

            Log.d(WiFiDirectActivity.TAG, "server: copying files " + f.toString());
            InputStream inputstream = client.getInputStream();

            Message msg = Message.obtain();
            msg.what = 1;
            try
            {
                // send the images to the image view through handler
                Bitmap bitmap = BitmapFactory.decodeStream(inputstream);
                if(bitmap!=null) {
                    Bundle b = new Bundle();
                    b.putParcelable("bitmap", bitmap);
                    msg.setData(b);
                    messageHandler.sendMessage(msg);
                }
                else Log.e("dev deta fragm","bitmap is null");
            }
            catch (Exception e)
            {
                Log.e("device detail fragment","stream not decoded into bitmap with" +
                        "exception:   " + e.toString());
            }

            copyFile(inputstream, new FileOutputStream(f));
            serverSocket.close();
            return f.getAbsolutePath();
        } catch (IOException e) {
            Log.e(WiFiDirectActivity.TAG, e.getMessage());
            return null;
        }
    }

    @Override
    protected void onPostExecute(String result) {
        if (result!=null) {

            /**
             * To initiate socket again we are initiating async task
             * in this condition.
             */
            FileServerAsyncTask FileServerobj = new FileServerAsyncTask(getContext(),
                    FileTransferService.PORT);
            Log.e("on post execute", "file server obj: " + FileServerobj.toString());
            if (FileServerobj != null) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                    FileServerobj.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, new String[]{null});
                    Log.e("Post Execute", "FileServerobj.execute on executor");

                } else

                {
                    FileServerobj.execute();
                    Log.e("Post Execute", "FileServerobj.execute");
                }
            }
        }
    }

    @Override
    protected void onPreExecute() {
        if(imageView == null){
            imageView = new ImageView(mFilecontext);
        }
    }
}

我对自己做错了什么的想法?我认为问题在于我发送帧的字节表示然后是:

Bitmap bitmap = BitmapFactory.decodeStream(inputstream);

不会以合适的图像转换它。

如果我以正确的方式发布问题,请与我们联系。

2 个答案:

答案 0 :(得分:1)

int total_bytes = img.cols() * img.rows() 

如果它有像​​素的cols和row,并且你可以单独获取每个像素,你可以设置一个Bitmap并填充它的像素。

然后将位图压缩为ByteArrayOutputStream为jpg或png并转换为字节数组。

像现在一样发送字节数组。

答案 1 :(得分:0)

将Mat帧转换为png我设法在设备之间流式传输图像。我发布了更正的代码(如果我不应该告诉我,我将删除它)。

Thread myThread = new Thread(){
    @Override
    public void run(){
        while (appData.image_got <= 0) {
            Log.d(TAG, "Waiting for image");
            try {
                Thread.sleep(1000);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        int image_got_local = -1;
        mOpenCvCameraView.turnFlashOn();
        mOpenCvCameraView.setFrameRate(30000, 30000);           //We are trying to get 30FPS constant rate
        while(keep_thread_running & !myThread.isInterrupted()){

            //We will wait till a new frame is received
            while(image_got_local == appData.image_got){
                //Sleeping part may lead to timing problems
                try {
                    Thread.sleep(11);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }

            appData.frameSz = myInputFrame.size();

            ArrayList<Mat> img_comp = new ArrayList<Mat>(3);
            Core.split(myInputFrame, img_comp);

            if(myInputFrame == null) {Log.e("main thread","input frame is null");}
            //Get the red component of the image
            Mat myMat = img_comp.get(0);

            /******************************************************************************/
            Bitmap bmp = null;
            try {
                bmp = Bitmap.createBitmap(myMat.cols(), myMat.rows(), Bitmap.Config.ARGB_8888);
                org.opencv.android.Utils.matToBitmap(myMat,bmp);
            } catch (Exception e) {
                Log.e(TAG, e.getMessage());
            }

            myMat.release();


            FileOutputStream out = null;

            String filename = "frame" + conta + ".png";
            conta = conta +1;

            File sd = new File(Environment.getExternalStorageDirectory() + "/frames");
            boolean success = true;

            if (!sd.exists()) {
                success = sd.mkdir();
            }
            if (success) {
                File dest = new File(sd, filename);

                try {
                    out = new FileOutputStream(dest);
                    Log.e("main thread","file written: " + out.toString());
                    bmp.compress(Bitmap.CompressFormat.PNG, 100, out); // bmp is your Bitmap instance
                    // PNG is a lossless format, the compression factor (100) is ignored

                    try
                    {
                        if (dest !=null){
                            Socket socket = new Socket();
                            int port = 8988;
                            try
                            {
                                socket.bind(null);
                                socket.connect((new InetSocketAddress(OwnerIp, port)));
                                OutputStream stream = socket.getOutputStream();
                                InputStream is = null;

                                try
                                {
                                    {
                                        if(dest!=null) {
                                            is = new FileInputStream(dest);
                                            Log.e("main thread", "input stream not null: " + is.toString());
                                        }
                                    }
                                }
                                catch (Exception e){Log.e("main thread", "exception: "+ e.getMessage());}

                                DeviceDetailFragment.copyFile(is, stream);
                                Log.d("main thread", "Client: Data written");
                            }
                            catch (Exception e){Log.e("main thread","connect or bind exception: "
                                    + e.getMessage());}
                            finally {
                                if (socket != null) {
                                    if (socket.isConnected()) {
                                        try {
                                            socket.close();
                                        } catch (IOException e) {
                                            // Give up
                                            Log.e("file transfer service","exception socket close: " +
                                                    e.getMessage());
                                        }
                                    }
                                }
                            }
                        }
                    }
                    catch(Exception e ){Log.e("main thread","exception: " + e.getMessage());}

                } catch (Exception e) {
                    e.printStackTrace();
                    Log.e(TAG, e.getMessage());
                } finally {
                    try {
                        if (out != null) {
                            out.close();
                            Log.e(TAG, "OK!!");
                        }
                    } catch (IOException e) {
                        Log.e(TAG, e.getMessage() + "Error");
                        e.printStackTrace();
                    }
                }
            }
            else {
                Log.e("main thread","file dest is null");
            }

            /****************************************************************************/

            appData.frameAv = getMatAvg(myMat);

            //We cannot access UI objects from background threads, hence need to pass this data to UI thread
            Message uiMessage = mHandler.obtainMessage(1,appData);
            uiMessage.sendToTarget();

            handleInputData(appData.frameAv);
            image_got_local = appData.image_got;

        }
    }
};

再次感谢greenapps。