argb888与rgb888转换程序_通过相机获取bayer 图像数据转换成RGB888数据并保存
#include #include#include#include#include#include#include#include#include#include#include#include
/*位圖頭文件數據結構*/typedefstructtagBITMAPFILEHEADER {
unsignedchar bfType[2]; //位圖文件類型,必須為'B' 'M'
unsigned long bfSize; //位圖文件大小(以字節為單位)
unsigned short bfReserved1; //位圖文件保留字,必須為0
unsigned short bfReserved2; //位圖文件保留字,必須為0
unsigned long bfOffBits; //位圖數據的起始位置,以相對位圖文件頭的偏移量(單位字節)
}BITMAPFILEHEADER ; //共14Byte/*位圖信息數據結構*/typedefstructtagBITMAPINFOHEADER{
unsignedlong biSize; //本結構所占用字節數
long biWidth; //位圖寬度,以像素為單位
long biHeight; //位圖高度,以像素為單位
unsigned short biPlanes; //目標設備級別,必須為1
unsigned short biBitCount; //每個像素所需的位數,1(雙色),4(16色),8(256色),24(真彩色)
unsigned long biCompression; //位圖的壓縮類型,必須是0(示不壓縮),1(BI_RLE8壓縮類型),2(BI_RLE4壓縮類型)之一
unsigned long biSizeImage; //位圖大小以字節為單位
long biXPixPerMeter; //圖像水平分辨率,每米像素數
long biYPixPerMeter; //圖像垂直分辨率,每米像素數
unsigned long biClrUsed; //位圖實際使用的顏色表中的顏色數
unsigned long biClrImporant; //位圖顯示過程中重要的顏色數
}BITMAPINFOHEADER; //共40Byte
structbuffer {void *start;
size_t length;
};#define CLEAR(x) memset(&(x), 0, sizeof(x))
static void xioctl(int fh, int request, void *arg)
{intr;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);
}
}void saveImage(void *data,int imageWidth,intimageHeight)
{
BITMAPFILEHEADER*bitmapFileHeader;
BITMAPINFOHEADER*bitmapInfoHeader;
FILE*fp;if((fp=fopen("2345.bmp", "wb"))==NULL){
fprintf(stderr,"file cannot open\n");
exit(1);
}
bitmapFileHeader=(BITMAPFILEHEADER *)malloc(sizeof(BITMAPFILEHEADER));
bitmapInfoHeader=(BITMAPINFOHEADER *)malloc(sizeof(BITMAPINFOHEADER));
printf("%d\n",sizeof( bitmapFileHeader->bfType[2]));
bitmapFileHeader->bfType[0] = 'B';
bitmapFileHeader->bfType[1] = 'M';
bitmapFileHeader->bfReserved1 = 0x0000;
bitmapFileHeader->bfReserved2 = 0x0000;
bitmapFileHeader->bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bitmapInfoHeader->biSize = sizeof(BITMAPINFOHEADER);
bitmapInfoHeader->biWidth = (long)2592;
bitmapInfoHeader->biHeight = (long)-1944;
bitmapInfoHeader->biPlanes = 0x0001;
bitmapInfoHeader->biBitCount = 0x0018; //24位圖
bitmapInfoHeader->biCompression = 0x0000; //不壓縮
bitmapInfoHeader->biSizeImage = -bitmapInfoHeader->biWidth*bitmapInfoHeader->biHeight * 3;
bitmapInfoHeader->biXPixPerMeter = 3780; /*96dpi*/bitmapInfoHeader->biYPixPerMeter = 3780; /*96dpi*/bitmapInfoHeader->biClrUsed = 0;
bitmapInfoHeader->biClrImporant = 0;
bitmapFileHeader->bfSize = bitmapFileHeader->bfOffBits + bitmapInfoHeader->biSizeImage;
fwrite((unsignedchar *)bitmapFileHeader->bfType, 2, 1, fp);
fwrite((unsignedchar *)&bitmapFileHeader->bfSize, 4, 1, fp);
fwrite((unsignedchar *)&bitmapFileHeader->bfReserved1, 2, 1, fp);
fwrite((unsignedchar *)&bitmapFileHeader->bfReserved2, 2, 1, fp);
fwrite((unsignedchar *)&bitmapFileHeader->bfOffBits, 4, 1, fp);
fwrite((unsignedchar *)&bitmapInfoHeader->biSize, 4, 1, fp);
fwrite((unsignedchar *)&bitmapInfoHeader->biWidth, 4, 1, fp);
fwrite((unsignedchar *)&bitmapInfoHeader->biHeight, 4, 1, fp);
fwrite((unsignedchar *)&bitmapInfoHeader->biPlanes, 2, 1, fp);
fwrite((unsignedchar *)&bitmapInfoHeader->biBitCount, 2, 1, fp);
fwrite((unsignedchar *)&bitmapInfoHeader->biCompression, 4, 1, fp);
fwrite((unsignedchar *)&bitmapInfoHeader->biSizeImage, 4, 1, fp);
fwrite((unsignedchar *)&bitmapInfoHeader->biXPixPerMeter, 4, 1, fp);
fwrite((unsignedchar *)&bitmapInfoHeader->biYPixPerMeter, 4, 1, fp);
fwrite((unsignedchar *)&bitmapInfoHeader->biClrUsed, 4, 1, fp);
fwrite((unsignedchar *)&bitmapInfoHeader->biClrImporant, 4, 1, fp);
printf("white image header success\n");char *buffer=(char *)malloc(imageWidth*imageHeight*3);char *ch=(char *)data;
unsignedcharr,g,b;
union NUM{intnumber;char str[4];
}num;intk;for(int i=0,j=0;i<1944;i+=2){for(j=0;j<2592;j+=2){
r=ch[i*2592+j];
g=ch[i*2592+j+1];
b=ch[i*2592+2592+j+1];
buffer[i*2592*3+j*3+2]=b;
buffer[(i+1)*2592*3+j*3+2]=b;
buffer[i*2592*3+j*3+5]=b;
buffer[(i+1)*2592*3+j*3+5]=b;
buffer[i*2592*3+j*3+1]=g;
buffer[(i+1)*2592*3+j*3+1]=g;
buffer[i*2592*3+j*3+4]=g;
buffer[(i+1)*2592*3+j*3+4]=g;
buffer[i*2592*3+j*3]=r;
buffer[(i+1)*2592*3+j*3]=r;
buffer[i*2592*3+j*3+3]=r;
buffer[(i+1)*2592*3+j*3+3]=r;
}
}
printf("convert bayer data to rgb888 success\n");
fwrite(buffer,imageWidth*imageHeight*3,1,fp);
printf("write data to image success\n");
fclose(fp);
}int grabberandprocess(char*dev_name, int imageWidth, intimageHeight) {structv4l2_format fmt;structv4l2_buffer buf;structv4l2_requestbuffers req;enumv4l2_buf_type type;
fd_set fds;structtimeval tv;int r, fd = -1;
unsignedinti, 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);//VIDIOC_S_FMT set the video capture format
if (fmt.fmt.pix.pixelformat !=V4L2_PIX_FMT_GREY)
{
printf("Libv4l didn't accept GREY format. Can't proceed.\n");
exit(EXIT_FAILURE);
}elseprintf("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);elseprintf("set resolution OK!\n");
CLEAR(req);//亮度設置
structv4l2_control control_s;
control_s.id=V4L2_CID_BRIGHTNESS;
control_s.value=20;
ioctl(fd,VIDIOC_S_CTRL,&control_s);//曝光值
control_s.id=V4L2_CID_EXPOSURE_AUTO;
control_s.value=V4L2_EXPOSURE_MANUAL;
ioctl(fd,VIDIOC_S_CTRL,&control_s);
control_s.id=V4L2_CID_EXPOSURE_ABSOLUTE;
control_s.value=1200;
ioctl(fd,VIDIOC_S_CTRL,&control_s);//自動曝光
/*control_s.id = V4L2_CID_EXPOSURE_AUTO;
control_s.value = V4L2_EXPOSURE_APERTURE_PRIORITY;
ioctl(fd, VIDIOC_S_CTRL, &control_s);*/
//自動白平衡
control_s.id=V4L2_CID_AUTO_WHITE_BALANCE;
control_s.value=1;
ioctl(fd,VIDIOC_S_CTRL,&control_s);//手動白平衡
/*control_s.id = V4L2_CID_AUTO_WHITE_BALANCE;
control_s.value = 0;
ioctl(fd, VIDIOC_S_CTRL, &control_s);
//設置白平衡值
control_s.id = V4L2_CID_WHITE_BALANCE_TEMPERATURE;
control_s.value = 4600;
ioctl(fd, VIDIOC_S_CTRL, &control_s);*/
//對比度
control_s.id=V4L2_CID_CONTRAST;
control_s.value=32;
ioctl(fd,VIDIOC_S_CTRL,&control_s);//增益
control_s.id=V4L2_CID_GAIN;
control_s.value=0;
ioctl(fd,VIDIOC_S_CTRL,&control_s);
req.count= 3;
req.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory=V4L2_MEMORY_MMAP;
xioctl(fd, VIDIOC_REQBUFS,&req);//VIDIOC_REQBUFS request buffers
buffers= (struct 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);//read data from buffer
}
type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
xioctl(fd, VIDIOC_STREAMON,&type);//open video display function
buf.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory=V4L2_MEMORY_MMAP;
__u32 shouldused;
shouldused= imageWidth*imageHeight;do{
xioctl(fd, VIDIOC_DQBUF,&buf);//put back the data to buffer
}while(buf.bytesused !=shouldused);
saveImage(buffers[buf.index].start,imageWidth,imageHeight);
xioctl(fd, VIDIOC_QBUF,&buf);//read data from buffer
type =V4L2_BUF_TYPE_VIDEO_CAPTURE;
xioctl(fd, VIDIOC_STREAMOFF,&type);//close video display function
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);
}
總結
以上是生活随笔為你收集整理的argb888与rgb888转换程序_通过相机获取bayer 图像数据转换成RGB888数据并保存的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 开放大学MySQL形考_95至尊考试网-
- 下一篇: mysql model only_ful