映美精相机拍照(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;
}

 

posted on 2016-11-02 17:04  Just_Boy  阅读(1569)  评论(0)    收藏  举报