映美精黑白相机在linux平台上的使用(一)

看了好多强文,自己也想像别人一样记录下自己所做的一些工作。在此分享给大家,有错误还请指教!


下面是我用映美精相机在树莓派上的一点摸索。其实也叫不上摸索了,就是照着映美精官网上的指导,一步一步调通而已。闲话不多说了。


首先是按照https://github.com/TheImagingSource/tiscamera/wiki/Raspberry-PI-start上的介绍,在树莓派上装上相机的驱动。但我今天只是完成到,在/dev目录下有video*设备就没再往下了。接着就是运用v4l2来操作相机采集图片,并使用openCV保存采集到的图片。源码如下:


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <linux/videodev2.h>
#include <libv4l2.h>
#include <libv4l1.h>
#include <opencv2/core/core.hpp>  
#include <opencv2/imgproc/imgproc.hpp>  
#include <opencv2/highgui/highgui.hpp>  
#include <opencv/cv.h>


/*
*  A program to capture image via the tis camera.
*  scut Guangzhou #3CITA109
*  2015.5.7
*/


struct buffer {
void   *start;
size_t length;
};


int improcess(void* bstart, __u32 bytesused, int imageWidth, int imageHeight)
{
IplImage* img = cvCreateImageHeader(cvSize(imageWidth,imageHeight), IPL_DEPTH_8U, 1);
// printf("0x%x\n",img->imageData);
// img->imageData=(char*)bstart;
cvSetData(img, bstart, imageWidth);
printf("0x%x\n",img->imageData);
cvSaveImage("single.png", img, 0);
printf("Image is saved!\n");
return 0;
}

#define CLEAR(x) memset(&(x), 0, sizeof(x))

static void xioctl(int fh, int request, void *arg)
{
int r;
do {
r = ioctl(fh, request, arg);
} while (r == -1 && ((errno == EINTR) || (errno == EAGAIN)));

if (r == -1) {
fprintf(stderr, "error %d, %s\n", errno, strerror(errno));
exit(EXIT_FAILURE);
}
}


int grabberandprocess(char*dev_name, int imageWidth, int imageHeight) {
struct v4l2_format              fmt;
struct v4l2_buffer              buf;
struct v4l2_requestbuffers      req;
enum v4l2_buf_type              type;
fd_set                          fds;
struct timeval                  tv;
int                             r, fd = -1;
unsigned int                    i, n_buffers;
struct buffer                   *buffers;


fd = open(dev_name, O_RDWR | O_NONBLOCK, 0);
if (fd < 0) {
perror("Cannot open device");
exit(EXIT_FAILURE);
}


/* struct v4l2_fmtdesc fmtdesc; 
fmtdesc.index=0; 
fmtdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE; 
printf("Support format:\n"); 
while(ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc)!=-1) 

printf("\t%d.%s\n",fmtdesc.index+1,fmtdesc.description); 
fmtdesc.index++; 

*/
CLEAR(fmt);
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = imageWidth;
fmt.fmt.pix.height = imageHeight;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_GREY;
fmt.fmt.pix.field = V4L2_FIELD_ANY;
xioctl(fd, VIDIOC_S_FMT, &fmt);
if (fmt.fmt.pix.pixelformat != V4L2_PIX_FMT_GREY)
{
printf("Libv4l didn't accept GREY format. Can't proceed.\n");
exit(EXIT_FAILURE);
}
// else
// printf("set GREY OK!\n");
if ((fmt.fmt.pix.width != imageWidth) || (fmt.fmt.pix.height != imageHeight))
printf("Warning: driver is sending image at %dx%d\n", fmt.fmt.pix.width, fmt.fmt.pix.height);
// else
// printf("set resolution OK!\n");

CLEAR(req);
req.count = 3;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
xioctl(fd, VIDIOC_REQBUFS, &req);


buffers = (buffer*)calloc(req.count, sizeof(*buffers));
for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
CLEAR(buf);

buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = n_buffers;

xioctl(fd, VIDIOC_QUERYBUF, &buf);

buffers[n_buffers].length = buf.length;
buffers[n_buffers].start = mmap(NULL, buf.length,
PROT_READ | PROT_WRITE, MAP_SHARED,
fd, buf.m.offset);

if (MAP_FAILED == buffers[n_buffers].start) {
perror("mmap");
exit(EXIT_FAILURE);
}
xioctl(fd, VIDIOC_QBUF, &buf);
}
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
xioctl(fd, VIDIOC_STREAMON, &type);

buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;

__u32 shouldused;
shouldused = imageWidth*imageHeight;
do{
xioctl(fd, VIDIOC_DQBUF, &buf);
}while(buf.bytesused != shouldused);

improcess(buffers[buf.index].start, buf.bytesused, imageWidth, imageHeight);

xioctl(fd, VIDIOC_QBUF, &buf);
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
xioctl(fd, VIDIOC_STREAMOFF, &type);
for (i = 0; i < n_buffers; ++i) 
{
munmap(buffers[i].start, buffers[i].length);
}
close(fd);
return 0;
}

int main(int argc, char **argv) {
int imageWidth = 2592;
int imageHeight = 1944;
if (argc == 3) {
//printf("Usage: ./webcam [outputImageWidth] [outputImageHeight]\nE.g. ./webcam 1920 1280\n");
imageWidth = atoi(argv[1]);
imageHeight = atoi(argv[2]);
}
char device[]="/dev/video0";
grabberandprocess(device,imageWidth, imageHeight);
}


在树莓派上编译的Makefile

CC = g++
TARGET = tisgrabber
SRCS = tisgrabber.cpp
OBJS = $(SRCS:.cpp=.o)
DLIBS = -lopencv_core -lopencv_imgproc -lopencv_highgui
$(TARGET):$(OBJS)
$(CC) -o $@ $^ $(DLIBS)  
clean:
rm -rf $(TARGET) $(OBJS)  
%.o:%.cpp
$(CC) -o $@ -c $<  


接下来计划加上qt5编的界面,显示采集到的图片和视屏。(待续)


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值