OpenCV - 套接字接收到的失真图像

Posted

技术标签:

【中文标题】OpenCV - 套接字接收到的失真图像【英文标题】:OpenCV - Socket Received Distorted Image 【发布时间】:2014-03-13 11:38:48 【问题描述】:

我有发送者和接收者。当我在同一台计算机上尝试时,接收器正确接收图像,但在另一台计算机上执行发送器时,接收器接收到失真图像。其他正确接收(整数、字符数组...)

接收者:

char sockData[record.imageSize];
bytes_received = recv(new_sd, sockData, record.imageSize, 0);

cv::Mat img = cv::Mat::zeros(height,width,CV_8UC1);
memcpy(img.data, sockData, record.imageSize);

std::vector<int> compression_params;
compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);
compression_params.push_back(3);

customerFacePath << id << ".png";
cv::imwrite(customerFacePath.str().c_str(),img,compression_params);

发件人:

rec.imageSize = av.mImg.total()*av.mImg.elemSize();
bytes_sent = send(socketfd, av.mImg.data, rec.imageSize, 0);

这里是扭曲的图像,

顶部只有一小部分是正确的。我该如何解决这个问题?

【问题讨论】:

在此处查看答案***.com/questions/20314524/… 可能会有所帮助。 将您的recv 放入一个循环中,直到收到所有字节。 【参考方案1】:

在TCP 中,数据不需要以相同的结构(作为一个块)发送和接收。使用 TCP 发送的数据可以在接收时拆分为多个数据包或从多个数据包组合。这种修改可以发生在您的计算机和目标计算机之间的任何位置(即在路由器中)。

还值得注意的是recv 不会等到所有缓冲区都被填满。它尽可能多地获取并返回它收到的大小。结果可能会发生以下执行:

关于发送部分:

int sent = send(socket, bufPtr, 100, 0);
std::cout << "Bytes sent: " << sent << std::endl;

输出:

发送的字节数:15

在接收部分:

int received = recv(socket, bufPtr, 100, 0);
std::cout << "Bytes received: " << received << std::endl;

输出:

收到的字节数:5

TCP on Wikipedia

您必须确保使用某种数据包结构接收所有数据。即

2-byte packetId | 4-byte packetLength | variable-byte packetData

通常在同一台机器上发送/接收不会修改数据包,因此您的代码可以正常工作。另一方面,发送到远程端点时,Nagle's algortihm 等协议功能会发挥作用来修改您的数据。

不要禁用 nagle 来解决问题,因为它仍然不能保证数据包不会被修改。这就是 TCP 的工作原理。它是一个流协议

您可以使用UDP,数据包作为块发送和接收,无需对该协议进行修改。但是 UDP 缺少对数据正确传递的验证,更不用说检查数据是否传递了。

UDP on Wikipedia

【讨论】:

以上是关于OpenCV - 套接字接收到的失真图像的主要内容,如果未能解决你的问题,请参考以下文章

如何获取刚刚从套接字接收到的缓冲区的长度?

想要渲染通过 React 中的套接字接收到的数据

如何将数据从 Python 异步套接字服务器发送到子进程?

如何拆分接收到的 boost asio udp 套接字联合数据报

套接字编程c ++ windows,看不到从服务器接收到的消息[关闭]

调整大小时Python OpenCV图像打乱[重复]