配置

这里采用的是 VS2017
之前写过一个Python的版本
https://blog.csdn.net/a19990412/article/details/80930725

  • 首先得先下载一下opencv,然后简单配置一下。别担心,这个步骤操作就点击下三下鼠标就好了(但是如果是想换一个安装路径什么的,可能会多一点点的 不过基本上非常简单。)
  • 根据https://blog.csdn.net/a19990412/article/details/79768775 就可以完成配置了。
  • 如果遇到问题了,请务必在评论取留言,或者是私信我。是看不出对方是什么qq头像之类的,没必要担心,我也认不出是谁。

文章目录

  • 配置
  • 实现
  • 代码解释
    • 解释下服务端的代码
    • 解释下客户端的代码
    • 图片和网络数据的转换工作
      • 从Mat到数据包
  • 运行方法
    • IP地址获取

实现

服务器代码(就是那个用有摄像头的那个电脑要运行的代码

  • 要把下面这个代码中的
  • sockAddr.sin_addr.S_un.S_addr = inet_addr("192.168.199.222");
  • 192.168.199.222换成有摄像头的电脑自己的ip地址(不用担心 怎么获得ip地址,在最后,我会说了,其实非常简单的。
  • 关闭这个文件的话,我这里只是设置了强制更新的。没有设置自己关掉的方法。
#include "opencv2/opencv.hpp"
#include <WinSock2.h>
#include <Windows.h>
#pragma comment (lib, "ws2_32.lib")  //加载 ws2_32.dll
#pragma warning(disable : 4996)//待传输图像默认大小为 640*480,可修改
#define IMG_WIDTH 640   // 需传输图像的宽
#define IMG_HEIGHT 480  // 需传输图像的高
//默认格式为CV_8UC3
#define BUFFER_SIZE IMG_WIDTH*IMG_HEIGHT*3/32
using namespace cv;struct sentbuf{char buf[BUFFER_SIZE];int flag;
};
sentbuf data;
void sendMat(SOCKET sockClient, Mat image);int main(int, char**)
{VideoCapture cap(0); // open the default cameraif (!cap.isOpened())  // check if we succeededreturn -1;Mat frame;//初始化 DLLWSADATA wsaData;::WSAStartup(MAKEWORD(2, 0), &wsaData);//创建套接字SOCKET servSock = ::socket(AF_INET, SOCK_STREAM, 0);//绑定套接字sockaddr_in sockAddr;sockAddr.sin_family = AF_INET;sockAddr.sin_addr.S_un.S_addr = inet_addr("192.168.199.222");sockAddr.sin_port = htons(1234);::bind(servSock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR));//进入监听状态listen(servSock, 5);//接收客户端请求SOCKADDR clntAddr;int nSize = sizeof(SOCKADDR);SOCKET clntSock = accept(servSock, (SOCKADDR*)&clntAddr, &nSize);std::cout << "linked\n";for (;;){cap >> frame; // get a new frame from camerasendMat(clntSock, frame);}// the camera will be deinitialized automatically in VideoCapture destructor//关闭套接字closesocket(clntSock);closesocket(servSock);//终止 DLL 的使用WSACleanup();return 0;
}
void sendMat(SOCKET sockClient, Mat image) {for (int k = 0; k < 32; k++) {int num1 = IMG_HEIGHT / 32 * k;for (int i = 0; i < IMG_HEIGHT / 32; i++) {int num2 = i * IMG_WIDTH * 3;uchar* ucdata = image.ptr<uchar>(i + num1);for (int j = 0; j < IMG_WIDTH * 3; j++) {data.buf[num2 + j] = ucdata[j];}}if (k == 31)data.flag = 2;elsedata.flag = 1;send(sockClient, (char *)(&data), sizeof(data), 0);}
}

客户端代码(就是那个要看摄像头内容的电脑要运行的代码

  • 注意: 要把下面的代码中ip地址换成上面的那个有摄像头的电脑的ip地址
  • 就是修改下面的这个代码
  • addr.sin_addr.S_un.S_addr = inet_addr("192.168.199.222");
  • 把这个192.168.199.222换一下就好了~
  • 关闭这个文件的话,我这里只是设置了强制更新的。没有设置自己关掉的方法(毕竟为了代码短,其实可以在任务管理器上,强制关闭)。
#include <opencv2/opencv.hpp>
#include <WinSock2.h>
#include <Windows.h>
#pragma comment (lib, "ws2_32.lib")
#pragma warning(disable : 4996)
using namespace cv;//待传输图像默认大小为 640*480,可修改
#define IMG_WIDTH 640   // 需传输图像的宽
#define IMG_HEIGHT 480  // 需传输图像的高
//默认格式为CV_8UC3
#define BUFFER_SIZE IMG_WIDTH*IMG_HEIGHT*3/32
struct recvbuf
{char buf[BUFFER_SIZE];int flag;
};
recvbuf data_recv;
Mat recieveMat(SOCKET sockServer);
int main() {//初始化 DLLWSADATA data;WORD w = MAKEWORD(2, 0);::WSAStartup(w, &data);// 创建套接字SOCKET s;s = ::socket(AF_INET, SOCK_STREAM, 0);// 构造ip地址sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_addr.S_un.S_addr = inet_addr("192.168.199.222");addr.sin_port = htons(1234);std::cout << "connecting\n";::connect(s, (sockaddr*)&addr, sizeof(addr));std::cout << "linked\n";while (true) {Mat frame = recieveMat(s);if (frame.data) imshow("Camera", frame);if (waitKey(1) >= 0)break;}::closesocket(s);::WSACleanup();}Mat recieveMat(SOCKET sockServer) {Mat img(IMG_HEIGHT, IMG_WIDTH, CV_8UC3, cv::Scalar(0));int needRecv = sizeof(recvbuf);int count = 0;for (int i = 0; i < 32; i++) {int pos = 0;int len0 = 0;while (pos < needRecv) {len0 = recv(sockServer, (char*)(&data_recv) + pos, needRecv - pos, 0);pos += len0;}count = count + data_recv.flag;int num1 = IMG_HEIGHT / 32 * i;for (int j = 0; j < IMG_HEIGHT / 32; j++) {int num2 = j * IMG_WIDTH * 3;uchar* ucdata = img.ptr<uchar>(j + num1);for (int k = 0; k < IMG_WIDTH * 3; k++) {ucdata[k] = data_recv.buf[num2 + k];}}if (data_recv.flag == 2) {if (count == 33) {return img;}else {count = 0;i = 0;}}}
}

代码解释

解释下服务端的代码

  • 服务端的代码,就是指运行在有摄像头的那个电脑的代码。
  • 一开始的三行都是导入头文件。(如果你之前配置好了opencv这里就是没有问题的
  • 第四行,导入了一个winsock的包,这个包,是为了使用网络通信技术
  • 之后,就是定义了几个常量(IMG_WIDTH,IMG_HEIGHT,BUFFER_SIZE)就是定义了几个数而已。
  • using namespace cv; 是使用opencv的名空间(这个意思就是说,使用什么作为关键字符,比如,之前cout,这是个关键字,但是,这个的名空间是std
  • 之后创建一个结构体,这个你可以参照Python中的类的概念。(如果你也没学过类的话,就把这个理解为一个盒子(然后,我们在这个盒子里面放东西),以后定义新的元素的时候(像以前定义int,double之类的东西的时候,这里就直接定义一个)
  • 所以说,在定义完的下面就有一行,写着sentbuf data;
  • 之后的话,就是写了一个函数的声明(定义放在了下面)。原因这里要跟Python区别一下。 Python的话,函数放在一个文件里,那就是可以找到的,但是c++不一样,就是必须要在函数调用之前就有了才能调用的。
  • 但是这样写就会很丑,所以我这里才会先写一个函数声明,最后再写函数定义
  • 进入到main函数(注意到,有些时候我是写了参数的int, char**。但是实际上,没区别的。。
  • VideoCapture是一个摄像头类
  • 然后,来确定一下,是否是打开的,如果是打开的,就是继续。
  • Mat(其实是一个矩阵)在这里是为了存一个图(这个矩阵不是二维的,其实是三维的,还多加了一堆东西的
  • 之后的,什么初始化DLL之类的。没关系,反正我也记不住。
  • 但是这个,都很简单的,大致流程copy一下就好了。
  • 重点在那个换ip地址的(是的,我现在还没告诉你怎么看ip地址)
  • accept(servSock, (SOCKADDR*)&clntAddr, &nSize); 函数,必须在,有其他ip地址来连接到这个上面之后,才会继续,否则,整个代码就会一直定在这。(所以,后面输出了那个linked 的时候,才表示连接成功了)
  • 一直到for(;;)就是创建一个无限循环,一直在读取摄像头的图片,然后用那个函数给发出去。
  • 最后的关闭什么的 都是套路,顺着来就好了。

解释下客户端的代码

  • 就是那个看另外一个电脑摄像头信息的电脑运行的代码。
  • 讲道理,前面都是基本一模一样的。
  • 区别在于std::cout << "connecting\n";之后,使用的是connect函数,表示创立连接,并且,整个连接,就是通过s这个SOCKET来完成通信。
  • 同样是,如果没连上就会一直停在这个,所以,后面输出的话,就会表示已经连上了。
  • 然后while (true) 同样是一种无限循环的表示方法一样。
  • 还是通过,先读取一个图片,然后再展示出来。

图片和网络数据的转换工作

  • 之前一直没讲这个,其实这个才是难点。
  • 之前的结构体中,我们除了放了一个char*之外,我们还放了一个int作为标签。(作用为:记录当前这个包是不是这个图片的最后一个包
  • 做上面这样的处理的原因是,电脑发数据的时候,一次性不能发太大大数据,所以,就只能这样了。

从Mat到数据包

  • 每个图片分32个包来发出去。
  • img.ptr<uchar>(j + num1);这个()内的数字,表示的是第多少行。(这里不妨假设为二维的,三维只是因为有彩色的)
  • uchar其实跟char也没太的区别,就是变成了没有符号的char而已。
  • 本质上,就是通过Mat函数本身的ptr(这是个指针(可以这么理解)来定位到一个串,直接丢给字符串数组就好了。)
  • *3表示的是有三通道

反过来的操作是类似的。这里就做多描述了。

运行方法

  • 一个电脑运行服务端代码(要求有摄像头)
  • 一个电脑运行客户端代码(没有要求)
  • 两台电脑在同一个局域网下(可以是连着同一个wifi的两台机器。(也可以是连着同一个路由器的两台电脑))

  • 我测试过了。测试环境是
  • 服务端:Win10 + VS2017+ 摄像头
  • 客户端:Win10 + VS2017

IP地址获取

  • win键+R
  • 出来运行框。把那个输入框(只有一个)的内容换成cmd,敲回车
  • 出现一个黑框框
  • 输入 ipconfig 敲回车

  • 如果这台电脑是通过台式链接的

  • 如果这台电脑是wifi链接的

  • 就找这个带有WLAN字样的IPv4地址


  • 这样的运行出来的东西就是可以用的啦~
  • 希望能帮到你

摄像头监控视频传输实现(C++)相关推荐

  1. 使用flask获取树莓派摄像头监控视频

    目录 1.安装flask库 2.使用flask打开网页传输视频 2.1 在树莓派终端桌面上,新建一个flask文件夹 2.2 在flask文件夹里面,新建一个template文件夹和app.py文件 ...

  2. 海康摄像头监控视频播放详解

    2019.12.09 更新(重要!!!) 一,此博文及对应代码写于2018年初,基于海康SDK V5.3.3.2版本(当时最新版本),只适用于2019年前海康监控设备:(海康监控产品更新换代,旧版SD ...

  3. [转]GStreamer资料(摄像头采集,视频保存,远程监控)DVR

    http://blog.csdn.net/wzwxiaozheng/archive/2010/12/26/6099397.aspx GStreamer资料整理(包括摄像头采集,视频保存,远程监控,流媒 ...

  4. GStreamer资料(摄像头采集,视频保存,远程监控)DVR

    转载自:http://blog.chinaunix.net/uid-10747583-id-282761.html http://blog.csdn.net/wzwxiaozheng/archive/ ...

  5. 从零搭建树莓派远程监控小车,udp视频传输,qt上位机

    目录 前言 一.材料准备 二.连线方式 三.软件编程 软件编程主要有一下几个方面 (1)树莓派视频传输 (2)esp8266代码 (3)上位机编程 四.总结 前言 最近刚准备完期末机器人驱动的课设,本 ...

  6. 使用手机摄像头实现视频监控实时播放

    使用手机摄像头实现视频监控实时播放 一.概述 视频监控实时播放的原理与目前较为流行的直播是一致的,所以采用直播的架构实现视频监控实时播放,流程图如下: #mermaid-svg-mUiqq5ywjTx ...

  7. 如何实现摄像头监控数据实时存储及传输?

    我们今天接到一个需求电话,是用户打电话向我们咨询方案,具体场景是这样的:需要用户对某个场景的监控数据进行访问,也就是监控摄像头拍摄到的,外网用户在我们的网站上都能看到,难点是怎么把摄像头监控的数据进行 ...

  8. 视频监控远程传输方案

    一.市场需求和产品瓶颈的尴尬局面 远程视频传输 早期对于集成厂商来说需要解决太多的技术问题,还要购买昂贵的网络产品,高难度的技术调试门槛.国内的一线大厂开发了云平台,这样就造成了集成厂商的可选择性很小 ...

  9. Android 手机采集摄像头视频 socket 视频传输实时传播

    这里搜集了两种实现Android 手机采集摄像头视频 socket 视频传输实时传播的方法,两种都可以使用. 第一种如下: 1.通过客户端socket请求,服务端接受到请求后,获取socket的输出流 ...

最新文章

  1. Windbg学习 (0x0013) 扩展命令-SOS
  2. stl中各种容器的自定义比较函数
  3. 简单工厂模式(Simple Factory)
  4. UML 中各种图形重要性的排行
  5. S3c2440A平台HIVE注册表+binfs的实现
  6. ZOJ3944People Counting暴力/枚举
  7. 设计世界上最小的 Arduino!
  8. ios之JavaScript
  9. 蓝桥杯代码测评使用指南
  10. “kuangbin带你飞”专题计划——专题一:简单搜索
  11. SQL注入语句(详细)
  12. MongoDB下载、安装和配置教程
  13. 深入理解二进制 算法必备底层知识
  14. Java扫码点餐小程序源码 SaaS系统源码 微信、支付宝扫码点餐小程序源代码
  15. linux下解压文件丢失文件,Linux下解压文件
  16. 百度离线地图开发,node实现地图瓦片下载
  17. 关于trunk的几个端口模式
  18. 0x000000f怎么修复 win10_0xc000000f修复引导win10步骤
  19. Javascript获取元素的xpath
  20. ACM:nbsp;polya定理+hashnbsp;数论题nbsp;pojnbsp;3…

热门文章

  1. linux桌面卷积文件删除不掉,Linux 删除文件夹和文件的命令(强制删除包括非空文件)...
  2. Linux----bond技术及mode模式详解
  3. 2021年塔式起重机司机免费试题及塔式起重机司机模拟试题
  4. What's ASM?
  5. 制作多重启动光盘——启动易(EasyBoo…
  6. 遗传算法中的种群长度及范围有什么用
  7. Powershell下载文件的三种方法
  8. 我唱出心里话时眼泪会流,要是怕难过抱住我手。
  9. 外汇里面马丁格尔交易系统的交易原理是什么?(汇友必入区)
  10. 史上最全最实用HBuilder快捷键大全