打造pc端和Android端的远程视频监控系统

标签: PYTHON c# java android
16人阅读 评论(1) 收藏 举报

第一篇博客献给java和c#

最近做比赛需要远程视频接入pc端和安卓端,于是就有了本文。

首先,我们使用一块嵌入式板搭载摄像头,嵌入式板我由于比赛用的是Intel的upboard,当然也可以使用树莓派。

第一步:我们在树莓派上安装好系统,然后在terminal中输入ifconfig得到树莓派的内网ip地址。

第二步:我选用python写一个获取摄像头图片及服务端的脚本。以下是代码(python代码是搬运的,哈哈):

读取摄像头的代码:

#-*- coding: cp936 -*-
import cv2
import time
import socket
from PIL import Image
import StringIO

# 获取电脑自带摄像头,若用usb摄像头则把0改为1
cap = cv2.VideoCapture(0)
# 调整采集图像大小为640*480
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)

# 这里的HOST对应树莓派的IP地址(自己输入ifconfig查),端口号自己随便定一个即可,但注意后面的程序中要保持统一
HOST="192.168.1.105"
PORT=15023
# 连接服务器
sock =socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST,PORT))

while True:
    # 获取一帧图像
    ret, img = cap.read()
    # 如果ret为false,表示没有获取到图像,退出循环
    if ret is False:
        print("can not get this frame")
        continue    

    # 将opencv下的图像转换为PIL支持的格式
    pi = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    buf = StringIO.StringIO()# 缓存对象
    pi.save(buf, format='JPEG')# 将PIL下的图像压缩成jpeg格式,存入buf中
    jpeg = buf.getvalue()# 从buf中读出jpeg格式的图像
    buf.close()
    sock.sendall(jpeg )# 通过socket传到服务器
    # time.sleep(0.2)

sock.close()

然后是服务器代码:

# -*- coding: cp936 -*-
import socket
import time


sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(("192.168.1.105",15023))# 注意bind的这里,IP地址和端口号都要与前面的程序中一样
sock.listen(2)# 监听端口

# 等待数据源端连接
src, src_addr = sock.accept()
print "Source Connected by", src_addr

# 等待目标端连接
dst, dst_addr = sock.accept()
print "Destination Connected by", dst_addr

while True:
    msg = src.recv(1024 *1024)
    if not msg:
        break
    try:
        dst.sendall(msg)
    except Exception as ex:
        dst, dst_addr = sock.accept()
        print "Destination Connected Again by", dst_addr
    except KeyboardInterrupt:
        print "Interrupted"
        break

src.close()
dst.close()
sock.close()

以上代码有一个问题尚未解决,就是无法完全关闭摄像头进程,需要在杀第一个代码进程后再开一次再杀。。。

第三步就是我们的pc端了:

pc端我采用的是wpf界面来显示视频画面,代码由于夹杂着其他功能就不贴了。只是说一下重点部分,主要是多线程上的问题。在wpf中,ui线程没有办法直接在非主线程中直接更新,需要用控件的Invoke方法,如:

                this.picbox.Dispatcher.Invoke(new Action(() =>
                {
                    BitmapFrame frame = BitmapFrame.Create(bmpimg);
                    this.picbox.Source = frame;
                }));

其中注意BitmapFrame,只有这个玩意才能跨线程更新,而BitmapImage是不行的。

最后是安卓端:

package rosclient.pc.com.test;

import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.widget.ImageView;
import android.os.Handler;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;

public class MainActivity extends AppCompatActivity {
    BufferedReader br = null;
    OutputStream os = null;
    Bitmap bmp=null;
    private ImageView imageView = null;
    private static final int COMPLETED = 0;
    Socket socket = null;

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

        Thread t1=new Thread(socketRun);
        t1.start();
    }

    private void showTip(final String tip) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(MainActivity.this, tip, Toast.LENGTH_SHORT).show();
            }
        });
    }

    Runnable socketRun=new Runnable() {
        @Override
        public void run() {

            try {
                // 创建socket
                socket = new Socket("192.168.1.105", 15023);
                socket.setReceiveBufferSize(1024*1024);
            }catch (Exception e) {

                showTip("Error:" + e);
            }
            while (true)
            {
                try{
                    InputStream in = socket.getInputStream();
                    bmp=BitmapFactory.decodeStream(in);
                }catch (Exception e) {

                    showTip("Error:" + e);
                }
                Message msg=new Message();
                msg.what=0;
                msg.obj=bmp;
                handle.sendMessage(msg);
            }
            }
    };
    private Handler handle = new Handler() {
        public void handleMessage(Message msg) {
                switch (msg.what) {
                    case 0:
                        Bitmap bmp = (Bitmap) msg.obj;
                        if (bmp != null) {
                            imageView = (ImageView) findViewById(R.id.imageView1);
                            imageView.setImageBitmap(bmp);
                        }
                        break;
                }
        };
    };
    public Bitmap getimg()
    {
        if(socket.isConnected())
        {
            try{
                InputStream in = socket.getInputStream();
                bmp=BitmapFactory.decodeStream(in);
            }catch (Exception e) {

                showTip("Error:" + e);
            }
        }
        return bmp;
    }
}

不过要记得在manifest里给网络权限。

其中我遇到的问题首先是无法在主线程中使用网络,所以必须开另一个线程去socket连接,但是控件又不允许在非主线程中更新,所以要使用Handler方法

    private Handler handle = new Handler() {
        public void handleMessage(Message msg) {
                switch (msg.what) {
                    case 0:
                        Bitmap bmp = (Bitmap) msg.obj;
                        if (bmp != null) {
                            imageView = (ImageView) findViewById(R.id.imageView1);
                            imageView.setImageBitmap(bmp);
                        }
                        break;
                }
        };
    };
以上就完成了,撒花!!!!



查看评论

一种基于Android智能手机的远程视频监控的设计

          android手机h.264嵌入式操作系统网络多线程 一种基于Android智能手机的远程视频监控的设计[图] 摘要:为了实现移动视频监控,提出...
  • yuanyuan_186
  • yuanyuan_186
  • 2014-11-29 21:16:09
  • 1948

手机移动终端与PC进行音视频聊天和监控的开发

针对目前市场需求,越来愈多的用户在系统中需要添加视频聊天、音频聊天和视频监控的要求,至于在平台的需求上,各种各样。       有的人只需要PC对PC的视频聊天或监控;有的人需要PC对手机或平板...
  • u014247193
  • u014247193
  • 2014-03-20 16:20:57
  • 541

基于Android手机的远程视频监控系统

系统代码如下: 一、android手机客户端 (1)AndroidManifest.xml文件。添加camera和socket权限,并设置了程序开始执行的activity、 ...
  • yelin042
  • yelin042
  • 2017-10-17 08:30:13
  • 584

实现Android手机(服务端)与PC(客户端)实现通信

本文在此基础上做了一些修改:http://blog.csdn.net/wufenglong/article/details/5778862   我主要是要通过在PC端发送命令控制手机作出相应的反应,...
  • zhou0707
  • zhou0707
  • 2012-03-13 15:07:57
  • 8822

android 远程视频监控系统

http://www.cnblogs.com/feifei1010/archive/2012/08/31/2664939.html 基本过程是Android作为socket客户端将采集到的每一帧...
  • haoaoo
  • haoaoo
  • 2016-09-29 14:34:57
  • 1606

移动端与PC端的测试差异性

移动端和PC测试的差异性
  • jinyuji7
  • jinyuji7
  • 2017-11-02 14:59:44
  • 175

PC端所有的屏幕的尺寸

  • github_36629330
  • github_36629330
  • 2016-12-01 22:51:51
  • 988

基于H.264的远程视频监控

有兴趣的留言一起研究     开始做自己的毕业设计了,希望这个暑假能把毕业设计搞完,下学期就去找工作,希望能早到一份好工作。回到正题,经过几天的摸索对H.264远程监控有了一定的认识,特别是图像...
  • qinjinghua2012
  • qinjinghua2012
  • 2015-01-21 00:45:14
  • 1472

pc端web前端开发

1. var navigatorName = “Microsoft Internet Explorer”; //判断是否是ie浏览器 if (navigator.appName == nav...
  • u013018357
  • u013018357
  • 2015-11-23 19:33:58
  • 856

基于VCpp远程视频监控系统

  • 2013年04月26日 10:51
  • 3.22MB
  • 下载
    个人资料
    等级:
    访问量: 16
    积分: 10
    排名: 251万+
    文章分类
    文章存档
    最新评论