C++通过套接字发送OpenCV图像
C++ OpenCV image sending through socket
我正在尝试使用OpenCV和套接字实现流媒体服务。服务器端加载一个给定的图像并将其发送给客户端,客户端通过套接字接收并显示它。不过,我在发送图像数据并在客户端重建图像时遇到了很多麻烦。这是我迄今为止制作的代码:
图像发送器:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
void error(const char *msg)
{
perror(msg);
exit(0);
}
int main(int argc, char *argv[])
{
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[256];
if (argc < 3) {
fprintf(stderr,"usage %s hostname portn", argv[0]);
exit(0);
}
portno = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr,"ERROR, no such hostn");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
Mat image;
image = imread(argv[3], CV_LOAD_IMAGE_COLOR);
if(! image.data ) // Check for invalid input
{
cout << "Could not open or find the image" << std::endl ;
return -1;
}
n = write(sockfd,image.data,image.total()*image.channels());
if (n < 0)
error("ERROR writing to socket");
close(sockfd);
namedWindow( "Client", CV_WINDOW_AUTOSIZE );// Create a window for display.
imshow( "Client", image );
waitKey(0);
return 0;
}
图像接收器:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
void error(const char *msg)
{
perror(msg);
exit(1);
}
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno;
socklen_t clilen;
char buffer[1024];
struct sockaddr_in serv_addr, cli_addr;
int n;
if (argc < 2) {
fprintf(stderr,"ERROR, no port providedn");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0)
error("ERROR on binding");
listen(sockfd,5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr,
&clilen);
if (newsockfd < 0)
error("ERROR on accept");
bzero(buffer,1024);
n = read(newsockfd,buffer,1023);
if (n < 0) error("ERROR reading from socket");
Mat image(690,690,CV_8UC3,*buffer);
imwrite("/home/securitas/images/prova.jpg",image);
close(newsockfd);
close(sockfd);
namedWindow( "Server", CV_WINDOW_AUTOSIZE );// Create a window for display.
imshow( "Server", image );
waitKey(0);
return 0;
}
我在客户端收到的是一张黑色图片,没有其他内容。有什么帮助吗?
获取Mat.data
并直接发送到套接字,数据顺序为BGR-BGR-BGR。。。。在接收端,假设您知道图像的大小。在接收之后,仅将接收到的缓冲器(BGR-BGR…阵列)分配给Mat
。
客户端:-
Mat frame;
frame = (frame.reshape(0,1)); // to make it continuous
int imgSize = frame.total()*frame.elemSize();
// Send data here
bytes = send(clientSock, frame.data, imgSize, 0))
服务器:-
Mat img = Mat::zeros( height,width, CV_8UC3);
int imgSize = img.total()*img.elemSize();
uchar sockData[imgSize];
//Receive data here
for (int i = 0; i < imgSize; i += bytes) {
if ((bytes = recv(connectSock, sockData +i, imgSize - i, 0)) == -1) {
quit("recv failed", 1);
}
}
// Assign pixel value to img
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;
}
}
bytes = send(clientSock, frame.data, imgSize, 0));
此语句在Visual Studio 12中出错。它说。。错误:"uchar*"类型的参数与"constchar*"类型参数不兼容在"frame.data"处。
缓冲区溢出。我不确定图像的格式和大小是否相同->你应该诚实地序列化你的Mat,就像这里一样。
Haris的回答是正确的,对我来说很有效。但是,你也可以使用更短的形式:
int imgSize = img.total()*img.elemSize();
uchar sockData[imgSize];
for (int i = 0; i < imgSize; i += bytes) {
if ((bytes = recv(connectSock, sockData +i, imgSize - i, 0)) == -1)
quit("recv failed", 1);
}
// change the last loop to below statement
Mat img(Size(HEIGHT, WIDTH), CV_8UC3, socketData);
在Microsoft Visual Studio 2012中,我在sockData[imgSize]中的imgSize下有一条红线,表示表达式必须具有常数值。然后,我将int imgSize更改为const int imgSize。它仍然向我展示了同样的问题。
Mat img = Mat::zeros(100,100, CV_8UC3);
const int imgSize = img.total()*img.elemSize();
uchar sockData[imgSize];
相关文章:
- OpenCV图像大小限制
- 如何将OpenCV图像数据从Python转换为C++?
- ROS中未定义的参考误差到OpenCV图像转换器
- C++:灰度位图标题和实时绘画+opencv图像处理
- 通过插座读取Python中的OpenCV图像
- OPENCV图像处理,向量下标超出范围
- 当摄影机参数已知时,OpenCV图像静置
- 访问linux的OpenCV-2.4.3的OPENCV图像处理库
- C OPENCV图像在Boost线程中不显示
- 图像搜索(C )中的OPENCV图像
- 在OpenCV图像中添加文本标签
- 将点云2数据转换为opencv图像
- OpenCv 图像块,大小错误
- 将opencv图像转换为gdi位图不起作用取决于图像大小
- 如何将labview图像类型转换为opencv图像类型(或Mat)
- 用C++将字节arry转换为OpenCV图像
- 嵌入OpenCV图像
- C++通过套接字发送OpenCV图像
- 为什么我在尝试将opencv图像数据指针转换为char*时出错
- OpenCV图像尺寸,而不读取整个图像