接着上个月写的一篇发送IplImage结构的来说,因为Socket发送结构的部分上一篇写过了,所以不再多写了。
CvMat的结构如下:
typedef struct CvMat
{
int type;
int step;
/* for internal use only */
int* refcount;
int hdr_refcount;
union
{
uchar* ptr;
short* s;
int* i;
float* fl;
double* db;
} data;
#ifdef __cplusplus
union
{
int rows;
int height;
};
union
{
int cols;
int width;
};
#else
int rows;
int cols;
#endif
}
CvMat;
这里其实和传送IpIlmage一样,需要先传送CvMat的header。需要特别说明的是,CvMat中的矩阵元素的类型和IplImage是不一样的,有可能是uchar,short,float或者double。所以在接受的过程中可能需要知道它的type。使用以下代码:
int a_type = CV_MAT_TYPE(mat->type);
CV_MAT_TYPE是core文件夹下的types_c.h里定义的一个宏。用这个宏可以将CvMat的type转换成诸如CV_8UC1之类的参数,并且以此确定CvMat的类型。
另外在利用cvCreateMatHeader这个函数中需要特别注意,它创建的CvMat的step和正常读一幅图片读出来的CvMat是不一样的。
以下是利用Socket传送一个CvMat的代码,这里指定CvMat为CV_32FC1,其中HDRLEN_CVMAT等于sizeof(CvMat)
BOOL SendCvMat(CvMat* source, SOCKET s)
{
int ret, count, datalen, total;
char *index;
char buffer[BUFF_SIZE + 5];
hdr_data datainfo;
index = (char *)source->data.ptr;
count = 0;
ret = ::send(s, (char *)source, HDRLEN_CVMAT, 0);
datalen = BUFF_SIZE;
total = source->step * source->height;
while (ret > 0)
{
datainfo.data_len = datalen;
ret = ::send(s, (char *)&datainfo, HDRLEN_DATA, 0);
memcpy(buffer, index, datalen);
ret = ::send(s, (char *)&buffer, datalen, 0);
if (datalen < BUFF_SIZE)
break;
count += datalen;
index += datalen;
if (count > total - BUFF_SIZE)
datalen = total - count;
}
datainfo.data_len = -1;
ret = ::send(s, (char *)&datainfo, HDRLEN_DATA, 0);
return TRUE;
}
以下是接受一个CvMat的代码
CvMat* RcvCvMat(SOCKET s)//just for 32-bit float
{
CvMat header;
CvMat *mat;
float *databuf;//so each element of databuf consists of two chars
char *index;
int ret;
hdr_data datainfo;
char buffer[BUFF_SIZE + 5];
ret = ::recv(s, (char *)&header, HDRLEN_CVMAT, 0);
mat = cvCreateMatHeader(header.rows, header.cols, header.type);
mat->step = header.step;
databuf = new float[mat->height * mat->step];
mat->data.fl = databuf;
index = (char *)databuf;
ret = ::recv(s, (char *)&datainfo, HDRLEN_DATA, 0);
while(ret > 0 && datainfo.data_len != -1){
receivedata(buffer, datainfo.data_len, s);
memcpy(index, buffer, datainfo.data_len);
index += datainfo.data_len;
receivedata((char *)&datainfo, HDRLEN_DATA, s);
}
return mat;
}