UDP/TCP和OpenCV的实时视频传输(On Linux)

这篇具有很好参考价值的文章主要介绍了UDP/TCP和OpenCV的实时视频传输(On Linux)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. UDP 传输视频

client.cpp

#include <unistd.h>//Linux系统下网络通讯的头文件集合
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <malloc.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <stdarg.h>
#include <fcntl.h>
#include <fcntl.h>
#include <iostream>
#include <opencv2/opencv.hpp>  
#include <opencv2/imgproc/imgproc.hpp> 
using namespace cv;
using namespace std;

enum
{
	PORT = 8888
};
int main(int argc, char** argv)
{

	int m_sockClient;
	if ((m_sockClient = socket(AF_INET, SOCK_DGRAM, 0)) < 0)    //创建socket句柄,采用UDP协议
	{
		printf("create socket error: %s(errno: %d)\n", strerror(errno), errno);
		return -1;
	}
	sockaddr_in m_servaddr;
	memset(&m_servaddr, 0, sizeof(m_servaddr));  //初始化结构体
	m_servaddr.sin_family = AF_INET;           //设置通信方式
	m_servaddr.sin_port = htons(PORT);         //设置端口号
        m_servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
	//m_servaddr.sin_port = htons(8888);//设置需要发送的IP和端口号

	bind(m_sockClient, (sockaddr*)&m_servaddr, sizeof(m_servaddr));//绑定端口号
	VideoCapture capture(cv::String("/home/zhy/Documents/Perception/camera_data/tmp.mp4"));//打开摄像头
	Mat image;
	while (true)
	{
		capture >> image;//读入图片
		if (image.empty())    //如果照片为空则退出
		{
			printf("empty image\n\n");
			return -1;
		}

		std::vector<uchar> data_encode;
		std::vector<int> quality;
		quality.push_back(CV_IMWRITE_JPEG_QUALITY);
		quality.push_back(30);//进行50%的压缩
		imencode(".jpg", image, data_encode,quality);//将图像编码

		//char encodeImg[426672];

		int nSize = data_encode.size();
                
                unsigned char *encodeImg = new unsigned char[nSize];

                printf("%d\n", nSize);

		for (int i = 0; i < nSize; i++)
		{
			encodeImg[i] = data_encode[i];
		}
                
		
		sendto(m_sockClient, encodeImg, nSize, 0, (const sockaddr*)& m_servaddr, sizeof(m_servaddr));
		memset(&encodeImg, 0, sizeof(encodeImg));  //初始化结构体
	}
	return 0;
}

server.cpp

#include <unistd.h>//Linux系统下网络通讯的头文件集合
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <malloc.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <stdarg.h>
#include <fcntl.h>
#include <fcntl.h>
#include <iostream>
#include <opencv2/opencv.hpp>  
#include <opencv2/imgproc/imgproc.hpp> 


using namespace cv;
using namespace std;

enum
{
	PORT = 8888
};
int main(int argc, char** argv)
{
	
	int m_sockClient;
	if ((m_sockClient = socket(AF_INET, SOCK_DGRAM, 0)) < 0)    //创建socket句柄,采用UDP协议
	{
		printf("create socket error: %s(errno: %d)\n", strerror(errno), errno);
		return -1;
	}
	sockaddr_in m_servaddr;
	memset(&m_servaddr, 0, sizeof(m_servaddr));  //初始化结构体
	m_servaddr.sin_family = AF_INET;           //设置通信方式
	m_servaddr.sin_port = htons(PORT);         //设置端口号
        m_servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
        int len = sizeof(m_servaddr);

	bind(m_sockClient, (sockaddr*)&m_servaddr, sizeof(m_servaddr));//绑定套接字
	Mat image;
	unsigned char buf[426672];

        struct sockaddr_in addr_client;


	while (true)
	{
		std::vector<uchar> decode;

		int n = recvfrom(m_sockClient, buf, sizeof(buf), 0,(struct sockaddr *)&addr_client, (socklen_t *)&len);//接受缓存
		int pos = 0;
		while (pos < n)
		{
			decode.push_back(buf[pos++]);//存入vector
		}
		buf[n] = 0;
		image = imdecode(decode, CV_LOAD_IMAGE_COLOR);//图像解码
		imshow("image", image);
		waitKey(30);
	}
	return 0;
}

2. TCP传输视频

TCP协议通信的一般步骤:

客户端:

1、创建一个socket,用函数socket();

2、设置socket属性,用函数setsockopt();* 可选
  3、绑定IP地址、端口等信息到socket上,用函数bind();* 可选
  4、设置要连接的对方的IP地址和端口等属性;
  5、连接服务器,用函数connect();
  6、收发数据,用函数send()和recv(),或者read()和write();
  7、关闭网络连接;

服务器端:

   1、创建一个socket,用函数socket(); 
2、设置socket属性,用函数setsockopt(); * 可选
  3、绑定IP地址、端口等信息到socket上,用函数bind();
  4、开启监听,用函数listen();
  5、接收客户端上来的连接,用函数accept();
  6、收发数据,用函数send()和recv(),或者read()和write();
  7、关闭网络连接;
  8、关闭监听;

udp视频传输,udp,tcp/ip,opencv

 文章来源地址https://www.toymoban.com/news/detail-778754.html

采集与发送:

SocketMatTransmissionClient.h

#ifndef SOCKETMATTRANSMISSIONCLIENT_H
#define SOCKETMATTRANSMISSIONCLIENT_H


#include "opencv2/opencv.hpp"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

using namespace cv;

//待传输图像默认大小为 640*480,可修改
#define IMG_WIDTH 1920	// 需传输图像的宽
#define IMG_HEIGHT 1200	// 需传输图像的高
#define PACKAGE_NUM 2
//默认格式为CV_8UC3
#define BUFFER_SIZE IMG_WIDTH*IMG_HEIGHT*3/PACKAGE_NUM

struct sentbuf
{
    char buf[BUFFER_SIZE];
    int flag;
};

class SocketMatTransmissionClient
{
public:
    SocketMatTransmissionClient(void);
    ~SocketMatTransmissionClient(void);

private:
    int sockClient;
    struct sentbuf data;

public:

    // 打开socket连接
    // params :	IP		服务器的ip地址
    //			PORT	传输端口
    // return : -1		连接失败
    //			1		连接成功
    int socketConnect(const char* IP, int PORT);


    // 传输图像
    // params : image 待传输图像
    // return : -1		传输失败
    //			1		传输成功
    int transmit(cv::Mat image);


    // 断开socket连接
    void socketDisconnect(void);
};

#endif // SOCKETMATTRANSMISSIONCLIENT_H

  socketmattransmissionclient.cpp

#include "socketmattransmissionclient.h"

SocketMatTransmissionClient::SocketMatTransmissionClient(void)
{
}


SocketMatTransmissionClient::~SocketMatTransmissionClient(void)
{
}


int SocketMatTransmissionClient::socketConnect(const char* IP, int PORT)
{
    struct sockaddr_in    servaddr;

    if ((sockClient = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        printf("create socket error: %s(errno: %d)\n", strerror(errno), errno);
        return -1;
    }

    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(PORT);
    /*创建客户端套接字--IPv4协议,面向连接通信,TCP协议*/
    if (inet_pton(AF_INET, IP, &servaddr.sin_addr) <= 0)
    {
        printf("inet_pton error for %s\n", IP);
        return -1;
    }
    /*将套接字绑定到服务器的网络地址上*/
    if (connect(sockClient, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
    {
        printf("connect error: %s(errno: %d)\n", strerror(errno), errno);
        return -1;
    }
    else
    {
        printf("connect successful!\n");
    }
}


void SocketMatTransmissionClient::socketDisconnect(void)
{
    close(sockClient);
}

int SocketMatTransmissionClient::transmit(cv::Mat image)
{
    if (image.empty())
    {
        printf("empty image\n\n");
        return -1;
    }

    if(image.cols != IMG_WIDTH || image.rows != IMG_HEIGHT || image.type() != CV_8UC3)
    {
        printf("the image must satisfy : cols == IMG_WIDTH(%d)  rows == IMG_HEIGHT(%d) type == CV_8UC3\n\n", IMG_WIDTH, IMG_HEIGHT);
        return -1;
    }

    for(int k = 0; k < PACKAGE_NUM; k++)
    {
        int num1 = IMG_HEIGHT / PACKAGE_NUM * k;
        for (int i = 0; i < IMG_HEIGHT / PACKAGE_NUM; 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 == PACKAGE_NUM - 1)
            data.flag = 2;
        else
            data.flag = 1;

        if (send(sockClient, (char *)(&data), sizeof(data), 0) < 0)
        {
            printf("send image error: %s(errno: %d)\n", strerror(errno), errno);
            return -1;
        }
    }
}

main.cpp

#include "socketmattransmissionclient.h"
#include <opencv2/opencv.hpp>

int main()
{
    SocketMatTransmissionClient socketMat;
    if (socketMat.socketConnect("127.0.0.1", 6666) < 0)
    {
        return 0;
    }

    cv::VideoCapture capture(cv::String("/home/zhy/Documents/Perception/camera_data/tmp.mp4"));
    cv::Mat image;
   

    while (1)
    {
        if (!capture.isOpened())
           return 0;
        capture >> image;

        if (image.empty())
            return 0;

        socketMat.transmit(image);
    }

    socketMat.socketDisconnect();
    return 0;
}

CMakeLists.txt

# cmake needs this line
cmake_minimum_required(VERSION 2.8)

# Define project name
project(image_client_TCP)

# Find OpenCV, you may need to set OpenCV_DIR variable
# to the absolute path to the directory containing OpenCVConfig.cmake file
# via the command line or GUI
find_package(OpenCV REQUIRED)

# If the package has been found, several variables will
# be set, you can find the full list with descriptions
# in the OpenCVConfig.cmake file.
# Print some message showing some of them
message(STATUS "OpenCV library status:")
message(STATUS "    version: ${OpenCV_VERSION}")
message(STATUS "    libraries: ${OpenCV_LIBS}")
message(STATUS "    include path: ${OpenCV_INCLUDE_DIRS}")

if(CMAKE_VERSION VERSION_LESS "2.8.11")
  # Add OpenCV headers location to your include paths
  include_directories(${OpenCV_INCLUDE_DIRS})
endif()

# Declare the executable target built from your sources
add_executable(main main.cpp socketmattransmissionclient.cpp)

# Link your application with OpenCV libraries
target_link_libraries(main ${OpenCV_LIBS})

接收与显示:
SocketMatTransmissionServer.h

#ifndef SOCKETMATTRANSMISSIONSERVER_H
#define SOCKETMATTRANSMISSIONSERVER_H


#include "opencv2/opencv.hpp"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

using namespace cv;

#define PACKAGE_NUM 2

#define IMG_WIDTH 1920
#define IMG_HEIGHT 1200

#define BLOCKSIZE IMG_WIDTH*IMG_HEIGHT*3/PACKAGE_NUM

struct recvBuf
{
    char buf[BLOCKSIZE];
    int flag;
};


class SocketMatTransmissionServer
{
public:
    SocketMatTransmissionServer(void);
    ~SocketMatTransmissionServer(void);
    int sockConn;
private:
    struct recvBuf data;

    int needRecv;
    int count;

public:

    // 打开socket连接
    // params :	PORT	传输端口
    // return : -1		连接失败
    //			1		连接成功
    int socketConnect(int PORT);


    // 传输图像
    // params : image	待接收图像
    //		image	待接收图像
    // return : -1		接收失败
    //			1		接收成功
    int receive(cv::Mat& image);


    // 断开socket连接
    void socketDisconnect(void);
};

#endif // SOCKETMATTRANSMISSIONSERVER_H

接收与显示:
SocketMatTransmissionServer.h

#ifndef SOCKETMATTRANSMISSIONSERVER_H
#define SOCKETMATTRANSMISSIONSERVER_H


#include "opencv2/opencv.hpp"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

using namespace cv;

#define PACKAGE_NUM 2

#define IMG_WIDTH 1920
#define IMG_HEIGHT 1200

#define BLOCKSIZE IMG_WIDTH*IMG_HEIGHT*3/PACKAGE_NUM

struct recvBuf
{
    char buf[BLOCKSIZE];
    int flag;
};


class SocketMatTransmissionServer
{
public:
    SocketMatTransmissionServer(void);
    ~SocketMatTransmissionServer(void);
    int sockConn;
private:
    struct recvBuf data;

    int needRecv;
    int count;

public:

    // 打开socket连接
    // params :	PORT	传输端口
    // return : -1		连接失败
    //			1		连接成功
    int socketConnect(int PORT);


    // 传输图像
    // params : image	待接收图像
    //		image	待接收图像
    // return : -1		接收失败
    //			1		接收成功
    int receive(cv::Mat& image);


    // 断开socket连接
    void socketDisconnect(void);
};

#endif // SOCKETMATTRANSMISSIONSERVER_H

socketmattransmissionserver.cpp

#include "socketmattransmissionserver.h"

SocketMatTransmissionServer::SocketMatTransmissionServer(void)
{
}


SocketMatTransmissionServer::~SocketMatTransmissionServer(void)
{
}


int SocketMatTransmissionServer::socketConnect(int PORT)
{
    int server_sockfd = socket(AF_INET,SOCK_STREAM, 0);

    struct sockaddr_in server_sockaddr;
    server_sockaddr.sin_family = AF_INET;
    server_sockaddr.sin_port = htons(PORT);
    server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);

    if(bind(server_sockfd,(struct sockaddr *)&server_sockaddr,sizeof(server_sockaddr))==-1)
    {
        perror("bind");
        return -1;
    }

    if(listen(server_sockfd,5) == -1)
    {
        perror("listen");
        return -1;
    }

    struct sockaddr_in client_addr;
    socklen_t length = sizeof(client_addr);

    sockConn = accept(server_sockfd, (struct sockaddr*)&client_addr, &length);
    if(sockConn<0)
    {
        perror("connect");
        return -1;
    }
    else
    {
        printf("connect successful!\n");
        return 1;
    }

    close(server_sockfd);
}


void SocketMatTransmissionServer::socketDisconnect(void)
{
    close(sockConn);
}

int SocketMatTransmissionServer::receive(cv::Mat& image)
{
    int returnflag = 0;
    cv::Mat img(IMG_HEIGHT, IMG_WIDTH, CV_8UC3, cv::Scalar(0));
    needRecv = sizeof(recvBuf);
    count = 0;
    memset(&data,0,sizeof(data));

    for (int i = 0; i < PACKAGE_NUM; i++)
    {
        int pos = 0;
        int len0 = 0;

        while (pos < needRecv)
        {
            len0 = recv(sockConn, (char*)(&data) + pos, needRecv - pos, 0);
            if (len0 < 0)
            {
                printf("Server Recieve Data Failed!\n");
                break;
            }
            pos += len0;
        }

        count = count + data.flag;

        int num1 = IMG_HEIGHT / PACKAGE_NUM * i;
        for (int j = 0; j < IMG_HEIGHT / PACKAGE_NUM; 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.buf[num2 + k];
            }
        }

        if (data.flag == 2)
        {
            if (count == PACKAGE_NUM + 1)
            {
                image = img;
                returnflag = 1;
                count = 0;
            }
            else
            {
                count = 0;
                i = 0;
            }
        }
    }
    if(returnflag == 1)
        return 1;
    else
        return -1;
}

main.cpp

#include "socketmattransmissionserver.h"

int main()
{
    SocketMatTransmissionServer socketMat;
    if (socketMat.socketConnect(6666) < 0)
    {
        return 0;
    }

    cv::Mat image;
    while (1)
    {
        if(socketMat.receive(image) > 0)
        {
            cv::imshow("",image);
            cv::waitKey(30);
        }
    }

    socketMat.socketDisconnect();
    return 0;
}

udp视频传输,udp,tcp/ip,opencv

udp视频传输,udp,tcp/ip,opencv 

 

到了这里,关于UDP/TCP和OpenCV的实时视频传输(On Linux)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 08-linux网络管理-nc命令(TCP|UDP网络联通测试,文件传输,带宽测试)

    - 监听TCP端口(默认) 说明: -l 启动监听模式(作为服务器监听指定端口) -v 显示信息和错误 - 监听UDP端口 说明: -u UDP模式 - 链接TCP端口 - 链接UDP端口 说明: -z 链接不传输数据 - 接收数据重定向 - 上传数据 检查本地服务器是和 10.10.239.65的80端口是否能建立TCP链接。 如上

    2024年01月24日
    浏览(46)
  • 传输层协议: TCP 、UDP

    TCP在数据传输前,先要进行链接测试(三次握手),如果测试通过才会发送真实数据。     TCP将若干字节构成一个分组,叫报文段     TCP报文封装在IP数据报中;    面向连接,慢    稳定;   1 TCP报文的首部格式                源端口号:为发送方进程对应的端口号  

    2024年02月04日
    浏览(39)
  • 传输层(TCP/UDP)协议

    TCP(Transmission Control Protocol)传输控制协议 IP(Internet Protocol)因特网互联协议 TCP/IP是一个Protocol Stack,包括TCP、IP、UDP、ICMP、RIP、TELNET、FTP、SMTP、ARP等许多协议,叫TCP/IP只是因为其中使用并且最具代表性的是这两个协议。 1.工作在传输层 2.面向连接协议 3.全双工协议 4.半关

    2024年04月15日
    浏览(42)
  • 传输层协议----UDP/TCP

    传输层的作用就是负责数据能够从发送端传输到接收端. 正文开始! 端口号(Port)标识了一个主机上进行通信的不同的应用程序; 在TCP/IP协议中中,用\\\"源IP\\\",“源端口号”,“目的IP”,“目的端口号”,\\\"协议号\\\"这样的一个五元组来标识一个通信(在Linux中可以通过netstat -n查看) 0~1023:知

    2023年04月08日
    浏览(40)
  • 传输层--TCP/UDP协议

    目录 一、TCP/UDP协议介绍 1、UDP(User Datagram Protocol)--用户数据报协议 1.1 UDP报文格式  1.2 UDP协议的特性 2、TCP(Transmission Control Protocol )--传输控制协议 2.1 TCP报文格式 2.2 TCP协议的特性 2.3 TCP三次握手 2.4 四次挥手  三、TCP和UDP的区别 四、telnet协议--telnet协议--远程管理协议 UDP是无

    2024年02月21日
    浏览(41)
  • TCP 和 UDP 的区别、TCP 是如何保证可靠传输的?

    先来介绍一些osi七层模型 分为应用层、表示层、会话层、运输层、网络层、链路层、物理层。 应用层(数据):确定进程之间 通信的性质 以及满足用户需要以及提供网络和用户应用,为应用程序提供服务,DNS,HTTP,HTTPS,DHCP,FTP,POP3(Post Office Protocol)、SMTP(Simple Mail Transfer P

    2024年02月11日
    浏览(39)
  • 网络原理(四):传输层协议 TCP/UDP

    目录 应用层 传输层 udp 协议  端口号 报文长度(udp 长度) 校验和 TCP 协议 确认应答 超时重传 链接管理 滑动窗口 流量控制 拥塞控制 延时应答 捎带应答 总结 我们第一章让我们对网络有了一个初步认识,第二章和第三章我们通过代码感受了网络通信程序。 而本章的 通信原

    2023年04月27日
    浏览(53)
  • 计网传输层协议:UDP和TCP

    🍂 程序员在应用层要做的事情 在网络通信的过程中, 应用层描述了应用程序如何理解和使用网络中的通信数据, 和程序员打交道最多的就是应用层了, 针对不同的业务场景, 很多时候程序员需要去自定义应用层协议, 自定义协议主要需要完成下面的两件事情: 结合业务场景和需

    2024年02月02日
    浏览(46)
  • 网络传输层协议:UDP和TCP

    端口号(Port)标识了一个主机上进行通信的不同的应用程序; 在TCP/IP协议中, 用 \\\"源IP\\\", \\\"源端口号\\\", \\\"目的IP\\\", \\\"目的端口号\\\", \\\"协议号\\\" 这样一个五元组来标识一个通信(可以通过 netstat -n查看);  0 - 1023: 知名端口号, HTTP, FTP, SSH 比特科技 等这些广为使用的应用层协议, 他们的端口号

    2024年02月15日
    浏览(50)
  • 网络传输层协议详解(TCP/UDP)

    目录 一、TCP协议 1.1、TCP协议段格式  1.2、TCP原理  确认应答机制 超时重传机制 (安全机制) 连接管理机制(安全机制)  滑动窗口  流量控制(安全机制)  拥塞控制  延迟应答(效率机制) 捎带应答(效率机制)  ​编辑面向字节流(粘包问题)  缓冲区  TCP异常情况  二、UDP协议

    2024年02月06日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包