- 分段传输
代码说明:
首先,图像的大小为640*480,但是图像是三通道的彩色图像,每一列都有3个小列,所以每一行的像素个数为640*3;
其次,图像的高为480,也就是有480行,这里为了避免数组过大,所以传送时每一次传送15行,一共传送480/32=15次;
然后,传送时先用ptr指针找到每一行的首地址,在对每一行的像素进行遍历,依次把每行的640*3个像素点赋值给buf数组;
.h头文件中定义BUFFER_SIZE为640*480*3/32,每一行像素为640*3,每一轮传送15行,buf的大小为640*3/15
int transmit(cv::Mat image)
{
if (image.empty())
{
printf("empty image\n\n");
return -1;
}
for (int k = 0; k < 32; k++)
{
int num1 = IMG_HEIGHT / 32 * k;
for (int i = 0; i < IMG_HEIGHT / 32; i++)
{
int num2 = i * IMG_WIDTH * 3;
uchar* ucdata = image.ptr<uchar>(i + num1);
for (int j = 0; j < IMG_WIDTH * 3; j++)
{
data.buf[num2 + j] = ucdata[j];
}
}
if (k == 31)
data.flag = 2;
else
data.flag = 1;
if (send(sockClient, (char *)(&data), sizeof(data), 0) < 0)
{
printf("send msg error: %s(errno: %d)\n", strerror(errno), errno);
return -1;
}
}
}
int receive(cv::Mat& image)
{
cv::Mat img(IMG_HEIGHT, IMG_WIDTH, CV_8UC3, cv::Scalar(0));
int needRecv = sizeof(recvbuf);
int count = 0;
extern int errno;
while (1)
{
for (int i = 0; i < 32; i++)
{
int pos = 0;
int len0 = 0;
while (pos < needRecv)
{
len0 = recv(sockConn, (char*)(&data) + pos, needRecv - pos, 0);
if (len0 < 0)
{
printf("Server Recieve Data Failed!\n");
return -1;
}
pos += len0;
}
count = count + data.flag;
int num1 = IMG_HEIGHT / 32 * i;
for (int j = 0; j < IMG_HEIGHT / 32; j++)
{
int num2 = j * IMG_WIDTH * 3;
uchar* ucdata = img.ptr<uchar>(j + num1);
for (int k = 0; k < IMG_WIDTH * 3; k++)
{
ucdata[k] = data.buf[num2 + k];
}
}
if (data.flag == 2)
{
if (count == 33)
{
image = img;
return 1;
count = 0;
}
else
{
count = 0;
i = 0;
}
}
}
}
}
- 解码传输
Mat image;
VideoCapture capture(0);
vector<uchar> data_encode;
while (1)
{
if (!capture.read(image))
break;
imencode(".jpg", image, data_encode);
int len_encode = data_encode.size();
string len = to_string(len_encode);
int length = len.length();
for (int i = 0; i < 16 - length; i++)
{
len = len + " ";
}
send(sockClient, len.c_str(), strlen(len.c_str()), 0);
char send_char[1];
for (int i = 0; i < len_encode; i++)
{
send_char[0] = data_encode[i];
send(sockClient, send_char, 1, 0);
}
char recvBuf[32];
if(recv(sockClient, recvBuf, 32, 0))
printf("%s\n", recvBuf);
}
while (1)
{
if (recv(conn, recvBuf, 16, 0))
{
for (int i = 0; i < 16; i++)
{
if (recvBuf[i]<'0' || recvBuf[i]>'9') recvBuf[i] = ' ';
}
data.resize(atoi(recvBuf));
for (int i = 0; i < atoi(recvBuf); i++)
{
recv(conn, recvBuf_1, 1, 0);
data[i] = recvBuf_1[0];
}
printf("Image recieved successfully!\n");
send(conn, "Server has recieved messages!", 29, 0);
img_decode = imdecode(data, CV_LOAD_IMAGE_COLOR);
imshow("server", img_decode);
if (waitKey(30) == 27) break;
}
}
参考链接: 1.摄像头监控视频传输实现(C++) 2.网络编程:基于TCP的socket网络传输视频(C++, python)
|