• 6510阅读
  • 3回复

用网络查看usb摄像头的图像 [复制链接]

上一主题 下一主题
离线keisuo
 

只看楼主 正序阅读 楼主  发表于: 2007-05-10
— 本帖被 XChinux 执行加亮操作(2008-07-19) —
用网络查看usb摄像头的图像    



最近要把那个usb摄像头简单做成一个网络摄像头
板子里的服务端暂时用的c,客户端用的qt

现在的传输方式是:
两个线程,一个负责采集图像数据,然后转换格式压缩成jpeg文件,一个320*240的图片平均4k,如果图像鲜明会多一点。另一个线程负责建立

socket然后传输图像数据,图像数据首先传输这帧图像的大小,blocksize,然后传输图像数据,在这个连接上不停地循环发送
客户端就进行接受显示就行了,没什么问题

采集图像的处理大致如下:
convmap = malloc ( 320 * 240 * bytes );

v4l_yuv420p2rgb (convmap, map + grab_buf.offsets[frame], 320, 240, bytes * 8);
//map + grab_buf.offsets[frame]为usb摄像头采集的一帧图像地址,convmap为处理后的格式地址
out = fopen ("grab.jpeg", "wb");
if (!out) {
perror ("grab.jpeg");
return 1;
}

put_image_jpeg (out, convmap, 320, 240, 50, 4);//用libjpeg处理后压缩存为grab.jpeg文件
free(convmap);
fclose(out);

在数据发送线程程序如下:

while(1)
{
//判断grab.jpeg是否存在,存在则用rename改名然后传输,防止在传输过程中图片数据被采集线程修改
while( stat("grab.jpeg", &buf) < 0)
{
// perror("stat");
usleep(40000);
}

if( (fd = rename("grab.jpeg","temp.jpeg")) < 0)
perror( "rename" );
if( (fd = stat("temp.jpeg",&buf)) < 0 )
perror("stat temp.jpeg");

printf("buf.size=%d\n",buf.st_size);
//发送此帧图片的blocksize,new_fd为socket文件描述符
if( (fd = send( new_fd, &buf.st_size, sizeof(off_t), 0 )) < 0 )
perror("send blocksize");
//发送图片数据
if( (fd = open( "temp.jpeg", O_RDONLY )) < 0 )
perror("open img");
while( ( nread = read( fd, buff, MAXDATASIZE ) ) > 0 )
{

if( send( new_fd, buff, nread, 0 ) == -1 )
perror( "send\n" );
}
close( fd );

}//不关闭socket继续发送数据

这段程序在我的pc机上测试没有问题,昨天测试了一夜数据传输都没有错,只不过在有时候blocksize为0,我估计原因是在采集线程fopen之后还没来得及写数据就被我rename了,还没时间测试,今天早上出来的路上想起的这个原因,晚上回去看看,将while( stat("grab.jpeg", &buf) < 0)改为while( (stat("grab.jpeg", &buf) < 0) && (buf.st_size == 0) )
但在我的板子上采集问题就大了,传输的blocksize总为0或者4096,也就是当temp.jpeg的大小不为4096的时候stat得到的值为0,如果大小为4096又正确。我在板子上采集的同时写了个小程序每隔一秒钟stat temp.jpeg然后输出大小的值又正确不总是4096是正常值,所以就迷惑了
我不知道4096是个什么特殊的值,并且有个问题就是用libjpeg库压缩的时候如果得到的size为4096时是一帧不完整的图像,其他都是好的,也还没有时间去分析

用rename是为了文件互斥,用信号量应该好一些不过我暂时不会,所以昨天找到rename这个函数作为权宜之计,有时间再来研究信号量什么的

还有几个问题想问一下
1.在一般的网络条件下,我先发送的数据应该会先到基本不会数据错误吧。因为我没有加任何校验位什么的,这个如果有必要再来研究。我们校园网网络条件好,昨天测试了一夜没有出问题
2.有没有什么提高效率的方式?我在这个版本之前写的是一个socket传送一帧图像然后在client显示,在板子上采集时可以看到图像就是比较慢,大约只有3fps,现在一个socket上一直不停地传送就是为了试验效率的,结果遇到了这个问题。现在我感觉是在图像压缩和转换上花费的时间多,准备找时间去买一个支持RGB格式的摄像头,然后可以省掉v4l_yuv420p2rgb这步,不过需要移植驱动了,所以一直没有去做。由于编程经验很有限,也刚涉及编程领域,所以请大家多多指教
多谢
[ 此贴被XChinux在2008-07-19 20:26重新编辑 ]
离线morriszy

只看该作者 3楼 发表于: 2011-03-16
07年的帖子,好遥远哦,我刚毕业,呵呵,不知道楼主啊玩Qt了,楼主能分享一下你的代码吗?
VS2010+Qt4.7.0
离线morriszy

只看该作者 2楼 发表于: 2011-03-16
这么好的帖子,居然没人顶啊!
VS2010+Qt4.7.0
离线htyoung

只看该作者 1楼 发表于: 2007-05-10
2^12=4096
另外这个问题到 qt embebed可能会得到更多的响应
***
QT5
***
快速回复
限100 字节
 
上一个 下一个