如何将字节数组转换为从套接字接收的Mat?
我的客户端应用程序将发送像这样的彩色图像数据
Mat frame; //colour image
int imgSize = frame.total()*frame.elemSize();
int bytes = send(clientSock, frame.data, imgSize, 0));//write to the socket
服务器将接收
等数据 char sockData[imgSize];
Mat img;
for (int i = 0; i < imgSize; i += bytes) {
bytes = recv(connectSock, sockData +i, imgSize - i, 0));
}
// Write to mat
for (int i = 0; i < img.rows; i++) {
for (int j = 0; j < img.cols; j++) {
(img.row(i)).col(j) = (uchar)sockData[((img.cols)*i)+j];
}
}
我在接收器处得到扭曲的图像。我的代码有问题吗? 在此先感谢.......
答案 0 :(得分:3)
如果您有彩色图像,您可以使用3个uchar通道进行数学运算,因此请更改以下代码:
for (int i = 0; i < img.rows; i++) {
for (int j = 0; j < img.cols; j++) {
(img.row(i)).col(j) = (uchar)sockData[((img.cols)*i)+j];
}
}
用这个:
int baseIndex = 0;
for (int i = 0; i < img.rows; i++) {
for (int j = 0; j < img.cols; j++) {
img.at<cv::Vec3b>(i,j) = cv::Vec3b(sockData[baseIndex + 0],
sockData[baseIndex + 1],
sockData[baseIndex + 2]);
baseIndex = baseIndex + 3;
}
}
也许这应该有用。
答案 1 :(得分:1)
我使用下面的代码解决了这个问题。
int ptr=0;
for (int i = 0; i < img.rows; i++) {
for (int j = 0; j < img.cols; j++) {
img.at<cv::Vec3b>(i,j) = cv::Vec3b(sockData[ptr+0],sockData[ptr+1],sockData[ptr+2]);
ptr=ptr+3;
}
}
答案 2 :(得分:1)
这不起作用吗?
cv::Mat frame(img.rows, img.cols, CV_8UC3, sockData);
只需用正确的图像格式替换CV_8UC3:
CV_<bit-depth>{U|S|F}C(<number_of_channels>)
请参阅https://docs.opencv.org/2.4/modules/core/doc/basic_structures.html
编辑:还有第5个附加字段可用。每行的字节数(如果有几个填充字节)。今天使用V4L2时,我成功使用了这个cv :: Mat构造函数:
v4l2_format camera_format = ...; // see https://linuxtv.org/downloads/v4l-dvb-apis/uapi/v4l/vidioc-g-fmt.html#description
cv::Mat mat(camera_format.fmt.pix.height,
camera_format.fmt.pix.width,
CV_8UC3,
raw_data_ptr,
camera_format.fmt.pix.bytesperline);
答案 3 :(得分:1)
添加到Michele答案,还可以使用MatIterator来解决这个问题。
cv::Mat m;
m.create(10, 10, CV_32FC3);
// This is the socket data.
float *array = (float *)malloc( 3*sizeof(float)*10*10 );
cv::MatIterator_<cv::Vec3f> it = m.begin<cv::Vec3f>();
for (unsigned i = 0; it != m.end<cv::Vec3f>(); it++ ) {
for ( unsigned j = 0; j < 3; j++ ) {
(*it)[j] = *(array + i );
i++;
}
}
Now you have a float cv::Mat. In case of 8 bit, simply change float to uchar and Vec3f to Vec3b and CV_32FC3 to CV_8UC3