您的位置:首页 > 运维架构 > Linux

linux下摄像头抓图源码

2013-11-23 14:22 351 查看
/****************************************************/

/* */

/* v4lgrab.h */

/* */

/****************************************************/

#ifndef __V4LGRAB_H__

#define __V4LGRAB_H__

#define WIDTHBYTES(i) ((i+31)/32*4)

#include <stdio.h>

//typedef enum { FALSE = 0, TRUE = 1, O67

//#define SWAP_HL_WORD(x) {(x) = ((x)<<8) | ((x)>>8);}

//#define SWAP_HL_DWORD(x) {(x) = ((x)<<24) | ((x)>>24) | (((x)&0xff0000)>>8) | (((x)&0xff00)<<8);}

#define FREE(x) if((x)){free((x));(x)=NULL;}

typedef unsigned char BYTE;

typedef unsigned short WORD;

typedef unsigned long DWORD;

typedef struct tagBITMAPFILEHEADER{

WORD bfType; // the flag of bmp, value is "BM"

DWORD bfSize; // size BMP file ,unit is bytes

DWORD bfReserved1; // 0

DWORD bfReserved2; //0

DWORD bfOffBits; // must be 54

}BITMAPFILEHEADER;

typedef struct tagBITMAPINFOHEADER{

DWORD biSize; // must be 0x28

DWORD biWidth; //

DWORD biHeight; //

WORD biPlanes; // must be 1

WORD biBitCount; //

DWORD biCompression; //

DWORD biSizeImage; //

DWORD biXPelsPerMeter; //

DWORD biYPelsPerMeter; //

DWORD biClrUsed; //

DWORD biClrImportant; //

}BITMAPINFOHEADER;

typedef struct tagRGBQUAD{

BYTE rgbBlue;

BYTE rgbGreen;

BYTE rgbRed;

BYTE rgbReserved;

}RGBQUAD;

#if defined(__cplusplus)

extern "C" { /* Make sure we have C-declarations in C++ programs */

#endif

//if successful return 1,or else return 0

int openVideo();

int closeVideo();

//data 用来存储数据的空间, size空间大小

void getVideoData(unsigned char *data, int size);

#if defined(__cplusplus)

}

#endif

#endif //__V4LGRAB_H___

//-------------------------------------------------------------------------------

/****************************************************/

/* */

/* v4lgrab.c */

/* */

/****************************************************/

#include <unistd.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <stdio.h>

#include <sys/ioctl.h>

#include <stdlib.h>

#include <linux/types.h>

#include <linux/videodev.h>

#include "v4lgrab.h"

#define TRUE 1

#define FALSE 0

#define FILE_VIDEO "/dev/video0"

#define IMAGEWIDTH 640
#define IMAGEHEIGHT 480

static int fd;

static struct video_capability cap;

static struct video_window win;

static struct video_picture vpic;

static struct video_mmap mapbuf;

int openVideo()

{

//Open video device

fd = open(FILE_VIDEO, O_RDONLY);

if (fd < 0) {

perror(FILE_VIDEO);

return (FALSE);

}

//Get capabilities

if (ioctl(fd, VIDIOCGCAP, &cap) < 0) {

perror("VIDIOGCAP");

printf("(" FILE_VIDEO " not a video4linux device?)\n");

close(fd);

return (FALSE);

}

printf("devicename -->%s\n",cap.name);
printf("devicetape -->%d\n",cap.type);
printf("channels -->%d\n",cap.channels);
printf("maxwidth -->%d\n",cap.maxwidth);
printf("maxheith -->%d\n",cap.maxheight);
printf("minwidth -->%d\n",cap.minwidth);
printf("minheith -->%d\n",cap.minheight);

//Get the video overlay window

if (ioctl(fd, VIDIOCGWIN, &win) < 0) {

perror("VIDIOCGWIN");

close(fd);

return (FALSE);

}

//Set the video overlay window

win.width = IMAGEWIDTH;

win.height = IMAGEHEIGHT;

if(ioctl(fd, VIDIOCSWIN, &win) <0) {

perror("VIDIOCSWIN");

close(fd);

return (FALSE);;

}

//Get picture properties

if (ioctl(fd, VIDIOCGPICT, &vpic) < 0) {

perror("VIDIOCGPICT");

close(fd);

return (FALSE);

}

//mapbuf.width=600;
//mapbuf.height=480;

if (cap.type & VID_TYPE_MONOCHROME) {

} else {

vpic.depth=32;
//常用的颜色深度是1位、8位、24位和32位。1位有两个可能的数值:0或1。较大的颜色深度(每像素信息的位数更多)意味着数字图像具有较多的可用颜色和较精确的颜色表示
vpic.palette=VIDEO_PALETTE_RGB24;
vpic.brightness=5000;//3000-12000比较合适
vpic.colour=65535;
vpic.whiteness=65535;//65-65535差别不大
if(ioctl(fd, VIDIOCSPICT, &vpic) < 0) {

printf("Unable to find a supported capture format.\n");

return (FALSE);

}

}

return (TRUE);

}

int closeVideo()

{

if(fd != -1) {

close(fd);

return (TRUE);

}

return (FALSE);

}

void getVideoData(unsigned char *data, int size)

{

size = read(fd, data, size);

}

//-------------------------------------------------------------------------------

/****************************************************/

/* */

/* temp_get.c */

/* */

/****************************************************/

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <linux/types.h>
#include <linux/videodev.h>
#include "v4lgrab.h"

#define BMP "image2.bmp"

#define IMAGEWIDTH 640
#define IMAGEHEIGHT 480

int main(int argc, char ** argv)

{

FILE * fp;

BITMAPFILEHEADER bf;

BITMAPINFOHEADER bi;

unsigned char * buffer;

int i;

fp = fopen(BMP, "wb");

if(!fp){

perror(BMP);
exit(1);

}

if(openVideo() == -1) {

return(-1);

}

//Set BITMAPINFOHEADER

bi.biSize = 40;

bi.biWidth = IMAGEWIDTH;

bi.biHeight = IMAGEHEIGHT;

bi.biPlanes = 1;

bi.biBitCount = 24;

bi.biCompression = 0;

bi.biSizeImage = WIDTHBYTES(bi.biWidth * bi.biBitCount) * bi.biHeight;

bi.biXPelsPerMeter = 0;

bi.biYPelsPerMeter = 0;

bi.biClrUsed = 0;

bi.biClrImportant = 0;

//Set BITMAPFILEHEADER

bf.bfType = 0x4d42;

bf.bfSize = 54 + bi.biSizeImage;

bf.bfReserved1 = 0;

bf.bfReserved2 = 0;

bf.bfOffBits = 54;

buffer = malloc(bi.biSizeImage);

if (!buffer) {

printf("Out of memory.\n");

exit(1);

}

for(i=0; i<20; i++)

getVideoData(buffer, bi.biSizeImage);

fwrite(&bf, 14, 1, fp);

fwrite(&bi, 40, 1, fp);

fwrite(buffer, bi.biSizeImage, 1, fp);

printf("get bmp form video\t[OK]\n");

fclose(fp);

closeVideo();

return 0;

}

//------------------------------------------------------------------------------
网上摘录下来的,经过了调试修改.在gcc4.1 arm-linux-gcc-3.4.1 编译通过.
在s3c2410 pc上可以正常运行.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: