有一段时间没更新了。。。深表遗憾啊!最近接手了一个新的项目,基本上都是从头开始写源代码,所以进度慢效率也一般。新项目的第一个模块就是关于usb采集视频数据的,目前基本完成了对本模块的代码编写。在此总结一下心路历程(默认你对ndk linux命令 和 jni有一定的认识)。

http://blog.csdn.net/mirkerson/article/details/50764314#reply 这个是我刚接触usb相机对我有极大帮助的文章,里面也有相应的源码。对相机的操作是通过底层的C实现的,ndk-build编译成库,Android通过jni进行调用,主要说一下在此期间遇到的一些问题吧

1 .怎么跑起来的?
下载好的源码是在Android Studiod上面的运行的,本人习惯了eclipse所以直接将代码改成了自己需要的(看个人的习惯),同时 我连接设备是通过无线的方式(这么高大上你竟然不知道。。。),保证电脑和设备在同一个网段,在电脑cmd下运行 adb connect 设备的IP 回车即可(期间出现过一个问题 死后连不上 后来是你的设备开发者选项开了吗?) 连接成功之后 cmd下接着运行 adb shell 回车进入设备 ,接着执行cd /dev 到dev目录下执行ls -l 插上相机会出现videoX(X代表一个数字,如果前面有一个类似的设备那么X就是1,这个数字很重要,因为它代表的是哪一个相机),usb相机作为一种即插即用的设备,需要赋予权限的。如果直接运行程序,安装什么的都是顺利的,会报一个 Permit…什么的错误,熟悉linux系统的应该知道是权限问题,所以在命令行执行 chmod 777 /dev/videoX 就可以了。

如果报一个busy什么的,应该是你选择的相机资源被占用了,你应该选择你信插上的相机,根据刚才的相机数字修改代码CameraPreview里面的private int cameraId=X; 现在应该是可以跑起来的(可能我运气好吧,手上的相机支持 V4L2_PIX_FMT_YUYV格式吧),如果还是无法运行,报一个VIDIOC_S_FMT的错误,接着往下看吧。。。

2 .相机的格式支持
接下来的操作涉及的是底层c和ndk-build这块(java代码少 ,我也没有遇到java这块的问题)。出现上述的问题是因为c代码写好了支持的帧格式是 V4L2_PIX_FMT_YUYV ,而你的相机刚好不支持,所以会报错。c里面的那些函数不懂的话可以自行百度,网上有人说的很清楚。解决这个问题首先需要了解你的相机支持什么样的格式,在这里我贴上自己总结的几种打印方法,直接看java logcat的输出就可以了。

//打印设备支持的图像帧格式
1.方法一
struct v4l2_fmtdesc fmtdesc;
CLEAR(fmtdesc);
fmtdesc.index=0;
fmtdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
LOGE("Support format:\n");
while(ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc)!=-1)
{LOGE("\t%d.%s\n",fmtdesc.index+1,fmtdesc.description);fmtdesc.index++;
}2.方法二
int ret;
ret = ioctl(fd, VIDIOC_G_FMT, &fmt);LOGI("pixelformat is '%c%c%c%c'\n",fmt.fmt.pix.pixelformat & 0xFF,  (fmt.fmt.pix.pixelformat >> 8) & 0xFF, (fmt.fmt.pix.pixelformat >> 16) & 0xFF,  (fmt.fmt.pix.pixelformat >> 24) & 0xFF);
LOGI("fmt.fmt.pix.field is %d", fmt.fmt.pix.field);

知道支持就可以直接设置了,当然你的程序还是一样的不可以运行,因为后面的处理函数还是针对YUYV格式的,我只和接触了一个相机只支持mjpeg的格式,源代码

void processimage (const void *p)
{yuyv422toABGRY((unsigned char *)p);
}

也没法处理相机采集的数据,如果你还感兴趣 接着来

3 . mjpeg的解压缩
由于采集的数据是不相同的所以就需要重新写处理函数,把yuyv422toABGRY((unsigned char *)p);改成我们的想要的就可以,其他的可以不需要进行大的改动。首先相机采集的一帧jpeg格式的数据大小是 width*height*2(打印出来计算一下就会知道),jpeg是一种压缩封装的格式,使用的话就需要进行解压缩,解压缩之后的大小是width*height*3 这些对于数据的存储很重要。解压缩的话 http://blog.sina.com.cn/s/blog_643634b80101hzi8.html 这篇文章有很大的帮助(对代码的结构也有很大的帮助,我相信你看了也会按照他的方法在自己项目的jni根目录下新建一个jpeg的目录),我当时就是先下载了libjpeg的源码然后根据这篇文章把用到的C文件一个个拷贝到我的项目文件夹下重新编译成功的。编译通过之后jpeg解压缩需要的函数就有了,接下来就是如何在ImageProc.c里面进行改写了, 在v4l2读出的帧中找到SOF0(Start Of Frame 0),插入个huffman表就可以用libjpeg解码成rgb。可以参考mjpg-streamer中input_uvc目录下的代码,或者我刚调试好的 :https://github.com/joeshang/joycar/blob/master/module/v4l2_camera/decoder_mjpeg.c 只需要一下3个函数,用于解压缩就可以了

is_huffman(unsigned char *buf)decoder_jpeg_decompress(unsigned char *out_buf, unsigned char *jpeg_buf,
int jpeg_size)static void decoder_mjpeg_decode(这里我改了一点unsigned char *out_buf, unsigned char *in_buf,
int buf_size)

这些size就是我之前说的大小 你对号入座就可以。期间还会有一些乱七八糟的问题我也记不清楚了,编译说缺什么你需要在ImageProc.h里面添加相关的声明(前提你需要懂一点C),问题最多的是decoder_jpeg_decompress这个函数,这个可以网上搜索jpeg解压缩,千篇一律都一样的,说的很清楚,应该可以搞定。
如果搞定了,我再给你一个测试程序

//将jpeg图像刘保存成本地.jpg图片
FILE *fp = NULL;
char str[1000];
sprintf(str, "/sdcard/img/test%d.jpg", img_index++);
fp = fopen(str, "w");
if(fp != NULL)
{fwrite(buffers[buf.index].start, 1,buffers[buf.index].length, fp);
//buffers[buf.index].length换成buf.bytesused就行了sync();fclose(fp);
}

这个是检测相机获取的jpeg格式的数据对不对,可以直接保存为本地图片,方便检查

//将rgb24数据保存为bmp
int jjk = 0;
//width:图像宽; height:图像高;rgbbuf:图像RGB数据;fileName:保存文件名;
void MySaveBmp(unsigned char *rgbbuf,int width,int height) {
LOGI(" ......from MySaveBmp.....");
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih;
/* Magic number for file. It does not fit in the header structure due to alignment requirements, so put it outside */
unsigned short bfType=0x4d42;
bfh.bfReserved1 = 0;
bfh.bfReserved2 = 0;
bfh.bfSize = 2+sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)+width*height*3;
bfh.bfOffBits = 0x36;  bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biWidth = width;
bih.biHeight = height;
bih.biPlanes = 1;
bih.biBitCount = 24;
bih.biCompression = 0;
bih.biSizeImage = 0;
bih.biXPelsPerMeter = 5000;
bih.biYPelsPerMeter = 5000;
bih.biClrUsed = 0;
bih.biClrImportant = 0;  char str[1000];
sprintf(str, "/sdcard/img/test%d.bmp",jjk);
// ffp = fopen(sstr, "w");
//sprintf(str, "/sdcard/img/test0018.bmp");
FILE *file = fopen(str, "wb");
if (!file)
{  printf("Could not write file\n");  return;
}
/*Write headers*/
fwrite(&bfType,sizeof(bfType),1,file);
fwrite(&bfh,sizeof(bfh),1, file);
fwrite(&bih,sizeof(bih),1, file);
fwrite(rgbbuf,IMG_WIDTH*IMG_WIDTH*3,1,file);  jjk++;fclose(file);

}
//以下是.h文件的相关声明

typedef struct                       /**** BMP file header structure ****/  {  unsigned int   bfSize;           /* Size of file */
unsigned short bfReserved1;      /* Reserved */
unsigned short bfReserved2;      /* ... */
unsigned int   bfOffBits;        /* Offset to bitmap data */
} BITMAPFILEHEADER;typedef struct                       /**** BMP file info structure ****/
{
unsigned int   biSize;           /* Size of info header */
int            biWidth;          /* Width of image */
int            biHeight;         /* Height of image */
unsigned short biPlanes;         /* Number of color planes */
unsigned short biBitCount;       /* Number of bits per pixel */
unsigned int   biCompression;    /* Type of compression to use */
unsigned int   biSizeImage;      /* Size of image data */
int            biXPelsPerMeter;  /* X pixels per meter */
int            biYPelsPerMeter;  /* Y pixels per meter */
unsigned int   biClrUsed;        /* Number of colors used */
unsigned int   biClrImportant;   /* Number of important colors */
} BITMAPINFOHEADER;

解压缩之后得到的是rgb的数据了,具体的我没有深究是什么格式的,直接用上面的代码检测。如果解压缩得到得到的数据需要显示出来的话 接着来吧。。。

4 .数据的显示
得到的unsigned char *out_buf就是解压好的数据了,显示有两种方式:
可以直接把数据返回给java端 java端将数据转换为bmp格式在显示出来,也可以把数据在c层处理为int *rgb的数组,像源代码一样返回给java bitmap数据,怎么样都是很简单的啦。代码都有,稍作分析就可以

我支持第二张方式,不然第一种方式的延迟绝对会让你的老板不满意。。。

总结

这就是我开发相机模块遇到的一些问题啦,我是站在自己的立场上。首先有些问题时间长我已经记不住了,其次说的也有点啰嗦,最后没有考虑到你的立场等。如果有问题的话欢迎留言,我看的一定回复 大家一起交流学习一下!我是Mr.小艾

usb相机的经验总结相关推荐

  1. 【GStreamer 】2-ubuntu v4l2-ctl 查看USB 相机基本参数

    v4l2是Video4linux2的简称,是linux中关于视频设备的内核驱动,在Linux中,视频设备是设备文件,可以像访问普通文件一样对其进行读写,摄像头设备文件位置是/dev/video0.V4 ...

  2. Ubuntu下如何获取usb相机的PID/VID并打开指定的相机

    项目需求控制和打开两个USB摄像头,并且根据相机的PID和VID来打开指定的相机,来区分主副相机,在Windows下可以通过AForge.Video.DirectShow库来实现,但是Ubuntu下没 ...

  3. 一款支持大恒相机、IDS相机、普通USB相机和机械手的标定工具

    最近做了一款相机的标定软件,可以用来标定本软件支持的相机和机械手坐标系的关系.目前软件支持的相机有大恒USB相机,IDS的uEye网口相机,普通的USB相机.其中镜面靶标其实就是一种特定规则形状的标定 ...

  4. 海康工业相机USB相机问题排查思路—Windows 系统

    海康机器视觉Visionmaster-缺失检测 ​第一步骤:固件版本 a) 查看相机固件版本 b) 若较老建议升级成最新固件后再测试异常是否消失. 注意切勿跨大版本升级: 第二步骤:驱动排查 查看客户 ...

  5. VM下虚拟机连接usb相机后电脑蓝屏重启问题

    系列文章目录 VM下虚拟机连接usb相机后重启问题 ros系统的安装 系列文章目录 一.问题描述 二.解决办法 一.问题描述 在VM虚拟机下连接摄像头设备到虚拟机后 打开虚拟机,并且切换usb1.1时 ...

  6. Cognex VisionPro连接USB相机的两种品牌

    1.Imaging USB相机 Imageingicextaik,安装这个Imaging官方提供的软件后就可以直接通过VP连接Imaging品牌的USB相机了. 同时附上下载地址 https://do ...

  7. Nvdia Jetson 上CSI相机和USB相机使用对比

    1. 优缺点对比 USB相机: · 优:很容易整合,内核支持标准UVC协议 · 优:可以做很多的离线的图像工作(曝光控制,帧率等). · 优:提供输入/中断功能,可为您节省计算应用程序时间(例如,在新 ...

  8. labview实现USB相机图像采集并拍照存储

    实现功能 首先放上我目前设计出来的程序框图 然后附上前面板 所设计程序实现的功能为: 对图像进行实时采集(未设置延时): 点击拍照实现图片拍照并存储. 我事先设置了存储路径,因此存储得到的照片就保存在 ...

  9. 【GStreamer 】5-5-总结USB相机转RTSP网络视频流-推流usb摄像头JPEG

    我们使用gstreamer-rtsp-server ,实现了USB相机转RTSP网络流的基本功能,之前很多篇都讲了如何实现,这一次我们集中精力解决之前的一些问题. 文章[GStreamer ]5-4- ...

最新文章

  1. 大庆东风中学高考成绩查询2021年,2021年大庆中考成绩和分数线什么时候公布(附查询入口)...
  2. CSRF 1 (转)
  3. 计算机二级aoa软件_国产软件WPS进入全国计算机二级考试 明年3月实施
  4. vmstat使用简介各种linux命令使用
  5. Python中几个有趣的函数
  6. (转)Spring4.2.5+Hibernate4.3.11+Struts1.3.8集成方案一
  7. 很喜欢的一首歌曲《Take me to your heart》
  8. [Vue warn]: Error in render: “TypeError: Cannot read properties of undef
  9. 计算二叉树的叶子结点个数
  10. was日志报检测到cpu饥饿
  11. Idea Java开发必备插件
  12. ant design table列表 合并列单元格
  13. IDL学习——调用enviTask对高分2号影像进行预处理
  14. HTTP 状态码,404,301,505网络状态码详细说明
  15. OpenBmc开发13:添加传感器(fan)
  16. CentOS7 防火墙开放端口配置
  17. PostgreSQL中计算百分位数和中位数
  18. 那些年用过的音乐软件
  19. Scrapy框架的学习(一)
  20. 广东省数字经济促进条例 (征求意见稿)

热门文章

  1. 树莓派学习笔记(九)树莓派Linux内核开发
  2. ARM64+树莓派4b+JLINK仿真器实验环境搭建指南
  3. 在线音频巨头的新角逐与新平衡
  4. Linux 下固态硬盘恢复误删除文件
  5. 【入门】(二)相机标定、矩阵求解、相机位姿势估计
  6. 一篇文章,中文发完英文发,算“一稿多投”吗?
  7. 用Python发一个高逼格的朋友圈【附代码】
  8. AP: Oracle EBS AP INVOICE TAX 税码计算规则(ZT)
  9. 深度学习【使用pytorch实现基础模型、优化算法介绍、数据集的加载】
  10. 玩转NVIDIA Jetson AGX Xavier(1)--- jetson是什么