关于网络图像传输,网上大多数都是基于像素访问进行传输,传输的大小是图像的分辨率以及他的通道数,一般普通摄像头拍摄到图像大小的分辨率是640480,也就是说单通道灰度图像,一次要传输的数据量大小是640480=307200个字节,如果是彩色3通道那就是604803 = 921600个字节。90万的字节对网络资源的消耗是非常大,采用这种方式进行网络图像传输,容易造成视频的卡顿,所以不建议采用像素的访问进行传输。
Openc提供了imencode和imdecode两个函数,将图像进行二进制编码。https://docs.opencv.org/3.0-beta/modules/imgcodecs/doc/reading_and_writing_images.html这个是opencv官网对于图像读写的API做出了相应的介绍。我们先看一下imencode。
关于imencode与imdecode
C++: bool imencode(const String& ext, InputArray img, vector& buf, const vector& params=vector())
参数:
ext-定义输出文件格式的扩展名
img-需要被编码的图像
buf-输出的缓存区,类型是vector
parms-被编码的格式和压缩率,类型是vector
prams目前支持以下参数:
JPEG,它的压缩率范围(cv_imwrite_jpeg_quality)从0到100(越大越好)。默认值是95。100为没有压缩。
对于WEBP来说,它的压缩范围(cv_imwrite_webp_quality)从1到100(越大越好)。默认情况下(不含任何参数)和质量在100以上,则使用无损压缩。
png,可以压缩级别(cv_imwrite_png_compression)从0到9。更高的值意味着更小的尺寸和更长的压缩时间。默认值是3。
PPM、PGM、或PBM,它可以是一个二进制格式的标志(cv_imwrite_pxm_binary),0或1。默认值是1。
然后看一下imdecode
C++: Mat imdecode(InputArray buf, int flags)
C++: Mat imdecode(InputArray buf, int flags, Mat* dst)
buf-输入解压的buf
flags-和imread()的flags是一样的
CV_LOAD_IMOSE_COLOR-如果设置,始终将图像转换为彩色图像
CV_LOAD_IMAGE_GRAYSCALE如果设置,始终将图像转换为灰度图像
dst -解码矩阵的可选输出占位符。不填则是NULL。
关于图像传输
图像传输利用socket套接字进行传输,有两种协议,这个是TCP协议一个是UDP协议。对于两种协议的采用哪种,我个人觉得UDP会更好一些。UDP不需要建立握手环节,在某些工程下减少了一些资源的开销。相反TCP协议需呀建立握手后才可以通信,一旦因为网络不好或者网络断开,就需要重新连接,需要一些时间和精力去处理这些琐事,同时也会消耗系统的资源。在网络不好时UDP存在的现象,无非使视频卡顿,而TCP则需重新连接。所以选择UDP是一个非常好的选择。
以下是UDP协议下利用imencode和imdecode的网络视频传输
接收端:
#define _CRT_SECURE_NO_WARNINGS
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include
#include
#include
#include
#pragma comment(lib,"WS2_32.lib")
using namespace cv;
using namespace std;
enum
{
PORT = 0x1234
};
int main(int argc, char** argv)
{
WSADATA wsaData;
WSAStartup(0x01, &wsaData); //创建初始化句柄
SOCKET m_sockClient;
if ((m_sockClient = socket(AF_INET, SOCK_DGRAM, 0)) < 0) //创建socket句柄,采用UDP协议
{
printf("create socket error: %s(errno: %d)\n", strerror(errno), errno);
return -1;
}
sockaddr_in m_servaddr;
memset(&m_servaddr, 0, sizeof(m_servaddr)); //初始化结构体
m_servaddr.sin_family = AF_INET; //设置通信方式
m_servaddr.sin_port = htons(PORT); //设置端口号
bind(m_sockClient, (sockaddr*)&m_servaddr, sizeof(m_servaddr));//绑定套接字
Mat image;
char buf[65536];
while (true)
{
std::vector decode;
int n = recv(m_sockClient, buf, sizeof(buf), 0);//接受缓存
int pos = 0;
while (pos < n)
{
decode.push_back(buf[pos++]);//存入vector
}
buf[n] = 0;
image = imdecode(decode, CV_LOAD_IMAGE_COLOR);//图像解码
imshow("image", image);
waitKey(30);
}
return 0;
}
发送端:
#ifdef _WIN32
#define _CRT_SECURE_NO_WARNINGS
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include
#pragma comment(lib,"WS2_32.lib")
#else
#include //Linux系统下网络通讯的头文件集合
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#endif
#include
#include
#include
using namespace cv;
using namespace std;
enum
{
PORT = 0X4321
};
int main(int argc, char** argv)
{
#ifdef _WIN32
WSADATA wsaData;
WSAStartup(0x01, &wsaData); //创建初始化句柄
#endif
int m_sockClient;
if ((m_sockClient = socket(AF_INET, SOCK_DGRAM, 0)) < 0) //创建socket句柄,采用UDP协议
{
printf("create socket error: %s(errno: %d)\n", strerror(errno), errno);
return -1;
}
sockaddr_in m_servaddr;
memset(&m_servaddr, 0, sizeof(m_servaddr)); //初始化结构体
m_servaddr.sin_family = AF_INET; //设置通信方式
m_servaddr.sin_port = htons(PORT); //设置端口号
bind(m_sockClient, (sockaddr*)&m_servaddr, sizeof(m_servaddr));//绑定端口号
VideoCapture capture(0);//打开摄像头
Mat image;
while (true)
{
capture >> image;//读入图片
if (image.empty()) //如果照片为空则退出
{
printf("empty image\n\n");
return -1;
}
std::vector data_encode;
std::vector quality;
quality.push_back(CV_IMWRITE_JPEG_QUALITY);
quality.push_back(50);//进行50%的压缩
imencode(".jpg", image, data_encode,quality);//将图像编码
char encodeImg[65535];
int nSize = data_encode.size();
for (int i = 0; i < nSize; i++)
{
encodeImg[i] = data_encode[i];
}
m_servaddr.sin_addr.s_addr = inet_addr("192.168.1.102");
m_servaddr.sin_port = htons(0x1234);//设置需要发送的IP和端口号
sendto(m_sockClient, encodeImg, nSize, 0, (const sockaddr*)& m_servaddr, sizeof(m_servaddr));
memset(&encodeImg, 0, sizeof(encodeImg)); //初始化结构体
}
return 0;
}
相关源码可以在此处下载:http://download.csdn.net/download/qq_37406130/10161435