TCP/UDP发送图像数据,opencv,前面四个字节作为图像的大小

// 客户端
#include <opencv2/opencv.hpp>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>

#define HOST "127.0.0.1"
#define PORT 5000
#define BUFFER_SIZE 1024

int main() {
    // 创建TCP套接字
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == -1) {
        perror("socket");
        exit(EXIT_FAILURE);
    }

    // 连接到服务器
    sockaddr_in address;
    address.sin_family = AF_INET;
    address.sin_port = htons(PORT);
    if (inet_pton(AF_INET, HOST, &address.sin_addr) <= 0) {
        perror("inet_pton");
        exit(EXIT_FAILURE);
    }

    if (connect(sock, (sockaddr*) &address, sizeof(address)) == -1) {
        perror("connect");
        exit(EXIT_FAILURE);
    }

    // 打开视频文件
    cv::VideoCapture cap("video.mp4");
    if (!cap.isOpened()) {
        perror("cap");
        exit(EXIT_FAILURE);
    }

    // 发送视频帧
    while (true) {
        cv::Mat frame;
        cap >> frame;
        if (frame.empty()) {
            break;
        }

        // 将图像编码为JPEG格式
        std::vector<uchar> buffer;
        cv::imencode(".jpg", frame, buffer);

        // 发送图像大小  sizeof(size) = 4
        uint32_t size = buffer.size();
        int bytes_sent = send(sock, &size, sizeof(size), 0);
        if (bytes_sent == -1) {
            perror("send");
            exit(EXIT_FAILURE);
        }

        // 发送图像数据
        bytes_sent = send(sock, buffer.data(), buffer.size(), 0);
        if (bytes_sent == -1) {
            perror("send");
            exit(EXIT_FAILURE);
        }
    }

    // 清理
    cap.release();
    close(sock);

    return 0;
}

//服务端
#include <opencv2/opencv.hpp>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>

#define PORT 5000
#define BUFFER_SIZE 1024

int main() {
    // 创建TCP套接字
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == -1) {
        perror("socket");
        exit(EXIT_FAILURE);
    }

    // 绑定套接字
    sockaddr_in address;
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(PORT);

    if (bind(sock, (sockaddr*) &address, sizeof(address)) == -1) {
        perror("bind");
        exit(EXIT_FAILURE);
    }

    // 监听套接字
    if (listen(sock, 1) == -1) {
        perror("listen");
        exit(EXIT_FAILURE);
    }

    // 接受客户端连接
    sockaddr_in client_address;
    socklen_t client_address_length = sizeof(client_address);
    int client_sock = accept(sock, (sockaddr*) &client_address, &client_address_length);
    if (client_sock == -1) {
        perror("accept");
        exit(EXIT_FAILURE);
    }

    // 打开窗口以显示图像
    cv::namedWindow("image", cv::WINDOW_AUTOSIZE);

    // 接收和显示图像
    while (true) {
        // 接收图像大小
        uint32_t size;
        int bytes_received = recv(client_sock, &size, sizeof(size), 0);
        if (bytes_received == -1) {
            perror("recv");
            exit(EXIT_FAILURE);
        }

        // 接收图像数据
        std::vector<uchar> buffer(size);
        bytes_received = recv(client_sock, buffer.data(), buffer.size(), 0);
        if (bytes_received == -1) {
            perror("recv");
            exit(EXIT_FAILURE);
        }

        // 解码图像数据
        cv::Mat frame = cv::imdecode(buffer, cv::IMREAD_COLOR);

        // 显示图像
        cv::imshow("image", frame);

        // 按ESC键退出循环
        if (cv::waitKey(1) == 27) {
            break;
        }
    }

    // 清理
    cv::destroyAllWindows();
    close(client_sock);
    close(sock);

    return 0;
}

UDP发送图像数据(windows)

//send.cpp
#include <iostream>
#include <Winsock2.h>
#include <opencv2/opencv.hpp>
#include <WS2tcpip.h>
#pragma comment(lib, "ws2_32.lib")

using namespace std;
using namespace cv;
#define MAX_BUFFER_SIZE 65000
int main() {
    // 初始化Winsock
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        cerr << "WSAStartup failed." << endl;
        return 1;
    }

    // 创建UDP套接字
    SOCKET udpSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (udpSocket == INVALID_SOCKET) {
        cerr << "Failed to create UDP socket." << endl;
        WSACleanup();
        return 1;
    }

    // 设置服务器地址和端口
    sockaddr_in m_RemoteAddress;
        // 远端地址
    const char* ip = "127.0.0.1";
    int port = 8001;
    m_RemoteAddress.sin_family = AF_INET;
    m_RemoteAddress.sin_port = htons(port);


    int m_RemoteAddressLen = sizeof(m_RemoteAddress);
    inet_pton(AF_INET, ip, &m_RemoteAddress.sin_addr);
    // 打开视频文件
    VideoCapture video("C:\\Users\\mao\\Desktop\\ROV2\\1.mp4");
    if (!video.isOpened()) {
        cerr << "Failed to open video file." << endl;
        closesocket(udpSocket);
        WSACleanup();
        return 1;
    }

    

    // 初始化压缩参数
    std::vector<int> compression_params;
    compression_params.push_back(cv::IMWRITE_JPEG_QUALITY);
    compression_params.push_back(55);  // 设置JPEG压缩质量,范围0-100

    Mat frame;
    int imgSize;
    uchar buffer[MAX_BUFFER_SIZE];

    while (video.read(frame)) {
        // 将图像数据转换为字符数组
        resize(frame, frame, cv::Size(1024, 512), 0);
        // 对图像进行编码
        //imencode(".jpg", frame, buf);
        vector<uchar> encodedImage;
        imencode(".jpg", frame, encodedImage, compression_params);
        int imageSize = 0;
        imageSize = encodedImage.size();

        std::cout << "imageSize = " << imageSize << std::endl;
        // 组合图像大小和图像数据到一个数据包
        memcpy(buffer, &imageSize, sizeof(int));
        memcpy(buffer + sizeof(int), encodedImage.data(), imageSize);

        int image_size_Sent = sendto(udpSocket, (char*)buffer, sizeof(int) + imageSize, 0, (struct sockaddr*)&m_RemoteAddress, sizeof(m_RemoteAddress));
        if (image_size_Sent < 0) {
            cerr << "Error: Unable to send image size" << endl;
            break;
        }

    }

    // 关闭套接字和清理Winsock
    closesocket(udpSocket);
    WSACleanup();

    return 0;
}
//rec.cpp
#include <winsock2.h>
#include <WS2tcpip.h>
#include <iostream>
#include <opencv2/opencv.hpp>

using namespace  std;
#define MAX_BUFFER_SIZE 65000
//添加动态库的lib
#pragma comment(lib, "ws2_32.lib")

int main() {
    // socket环境
    WSADATA  wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        cout << "WSAStartup error:" << GetLastError() << endl;
        return false;
    }

    // socket对象
        // 创建UDP接收端socket
    SOCKET recvSocket = socket(AF_INET, SOCK_DGRAM, 0);
    if (recvSocket == INVALID_SOCKET) {
        cerr << "Failed to create receive socket" << endl;
        WSACleanup();
        return 1;
    }

    // 设置接收端地址
    sockaddr_in recvAddr;
    recvAddr.sin_family = AF_INET;
    recvAddr.sin_port = htons(8001);
    recvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    if (::bind(recvSocket, (sockaddr*)&recvAddr, sizeof(recvAddr)) == SOCKET_ERROR) {
        cerr << "Failed to bind receive socket" << endl;
        closesocket(recvSocket);
        WSACleanup();
        return 1;
    }

    cv::Mat receivedImage;

    while (true) {
        // 接收图像大小
        int imgSize;
        uchar buffer[MAX_BUFFER_SIZE];
        // 接收数据包
        int addrLen = sizeof(recvAddr);
        int bytesReceived = recvfrom(recvSocket, (char*)&buffer, MAX_BUFFER_SIZE, 0, (sockaddr*)&recvAddr, &addrLen);
        
        std::cout << bytesReceived << std::endl;
        if (bytesReceived > sizeof(int)) {
            // 提取图像大小
            memcpy(&imgSize, buffer, sizeof(int));

            // 提取图像数据
            vector<uchar> imageData(buffer + sizeof(int), buffer + sizeof(int) + imgSize);

            // 解码图像数据
            receivedImage = cv::imdecode(imageData, cv::IMREAD_COLOR);

            // 在这里对接收到的图像进行处理,例如显示或保存到文件
            imshow("Received Image", receivedImage);
            cv::waitKey(1);  // 等待一段时间,以便显示图像
        }
    }

    closesocket(recvSocket);
    WSACleanup();
    return true;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值