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 - 套接字接收到的失真图像的主要内容,如果未能解决你的问题,请参考以下文章
如何拆分接收到的 boost asio udp 套接字联合数据报