映美精相机拍照(bayer转rgb)获取彩色图片
映美精官网程序想交叉编译到板子上是,交叉编译gstreamer 总出错,然后从网上寻找相机拍照源码,找到了这个http://www.ithao123.cn/content-8845848.html
black.cpp程序源码:
#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> 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); 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); } 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); struct v4l2_control control_s; //自动曝光 control_s.id=V4L2_CID_EXPOSURE_AUTO; control_s.value=V4L2_EXPOSURE_APERTURE_PRIORITY; ioctl(fd,VIDIOC_S_CTRL,&control_s); printf("自动曝光:%d==%d",V4L2_EXPOSURE_APERTURE_PRIORITY,control_s.value); //自动白平衡 /* control_s.id=V4L2_CID_AUTO_WHITE_BALANCE; control_s.value=1; ioctl(fd,VIDIOC_S_CTRL,&control_s); printf("自动白平衡:1==%d",control_s.value);*/ //色调 control_s.id=V4L2_CID_HUE; control_s.value=100; ioctl(fd,VIDIOC_S_CTRL,&control_s); printf("色调:%d==%d\n",100,control_s.value); //设置白平衡 struct v4l2_control control_s5; control_s5.id = V4L2_CID_AUTO_WHITE_BALANCE; control_s5.value = 0; ioctl(fd, VIDIOC_S_CTRL, &control_s5); ioctl(fd, VIDIOC_S_CTRL, &control_s5); control_s5.id = V4L2_CID_WHITE_BALANCE_TEMPERATURE; control_s5.value =4600; ioctl(fd, VIDIOC_S_CTRL, &control_s5); printf("白平衡:4600==%d\n",control_s5.value); 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) { imageWidth = atoi(argv[1]); imageHeight = atoi(argv[2]); } char device[]="/dev/video0"; grabberandprocess(device,imageWidth, imageHeight); }
编译命令: g++ black.cpp -o black -lopencv_core -lopencv_imgproc -lopencv_highgui
映美精相机只能设置图片格式为grey,彩色相机的话采集到的图像格式是bayer格式的灰度图像,所以如果想保存成彩色图片的话需要进行色彩空间的转换。我是使用的opencv 库函数进行了转换。不过转换出来的图像会发黄。对图像保存方式以及读取不了解,有待解决
以下为bayertorgb.cpp程序源码:
#include <opencv/cv.h> #include <opencv2/highgui.hpp> #include <iostream> using namespace std; using namespace cv; int main( int argc, char** argv ) { if(argc != 2) { printf("useage: %s <imagefile>\n ", argv[0]); return -1; } char* imageName = argv[1]; Mat image; /* CV_LOAD_IMAGE_ANYDEPTH CV_LOAD_IMAGE_COLOR CV_LOAD_IMAGE_GRAYSCALE */ image = imread( imageName, 0); if( !image.data ) { printf( " No image data \n " ); return -1; } Mat gray_image; cvtColor( image, gray_image, CV_BayerGR2RGB);//CV_BayerBG2BGR);//CV_BayerRG2BGR);//CV_BayerRG2RGB);//CV_BayerGB2BGR);//CV_BayerGB2BGR); //CV_BayerGR2RGB);//CV_BayerGR2RGB yellow);//CV_BayerGB2RGB) green; imwrite( "Image.jpg", gray_image ); //imwrite("Image3.bmp",gray_image); /*namedWindow( imageName, CV_WINDOW_AUTOSIZE ); namedWindow( "Gray image", CV_WINDOW_AUTOSIZE ); imshow( imageName, image ); imshow( "Gray image", gray_image ); waitKey(0);*/ return 0; }
浙公网安备 33010602011771号