wang8953 发表于 2011-2-18 00:55:03

通过TQ2440配套的OV9650抓图源码~

刚刚做完 贡献一下
是在配套的OV9650基础上改的
算法不是很了解 找着粘了一下
流程搞的差不多 最近有进步 谢谢各位帮助过我的朋友
尤其是TQ的林工 给了我一份很有价值的文档 十分感谢!
下面贡献源码 作为回报

/*
*   TQ2440 camera test program
*
*   preview : 320x240 overlay on 320x240 16bpp LCD
*
*   TFT LCD size : 320x240
*/
#include <sys/time.h>
#include <sys/types.h>
#include <asm/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <errno.h>

#include <linux/fs.h>
#include <linux/kernel.h>
#include "videodev.h"
#include "videodev2.h"
#include <linux/fb.h>

#define PIXFMT_NUM                        5
#define INPUT_NUM                         5
#define CTRL_NUM                         100

#define V4L2_DEV_NODE                        "/dev/camera"
#define FB_DEV_NODE                        "/dev/fb/0"
#define DATA                                "/home/sky/photo"

#define WIDTH               320
#define HEIGHT                                240

//typedef struct v4l2_input    V_INPUT;
//typedef struct v4l2_format   V_FORMAT;
//typedef struct v4l2_fmtdescV_FMTDESC;
//typedef struct v4l2_queryctrl V_QRYCTRL;

typedef struct fb_var_screeninfo F_VINFO;

//文件头
struct tagBITMAPFILEHEADER{

    unsigned long bfSize;
    unsigned long bfLeft;
    unsigned long bfOffBits;

};
/*bmp图像的位图信息头*/
struct tagBITMAPINFOHEADER{
    unsigned long biSize;
    unsigned long bmpWidth;
    unsigned long bmpHeight;
    unsigned short biPlanes;
    unsigned short bicolors;
    unsigned long isCompressed;
    unsigned long biMapSize;
    unsigned long biHorizontal;
    unsigned long biVertical;
    unsigned long biusedcolors;
    unsigned long biimportcolors;
};


unsigned int x_lcd_size, y_lcd_size;
unsigned char preview_buf;


static void writebmp(int data_fd){
        int i,j,size;
        int ret;
        unsigned short buf;
        memcpy(buf, &preview_buf, 240*320*2);
        unsigned short bmp;
       
        struct tagBITMAPFILEHEADER bfhead;
        struct tagBITMAPINFOHEADER binfohead;
        size=HEIGHT*WIDTH;

       
        bfhead.bfSize=0x36+size*2;
        bfhead.bfLeft=0;
        bfhead.bfOffBits=0x36;
       
        binfohead.biSize=0x28;
        binfohead.bmpWidth=WIDTH;
        binfohead.bmpHeight=HEIGHT;
        binfohead.biPlanes=1;
        binfohead.bicolors=0x10;
        binfohead.isCompressed=0;
        binfohead.biMapSize=size*2;
        binfohead.biHorizontal=0x0b13;
        binfohead.biVertical=0x0b13;
        binfohead.biusedcolors=0;
        binfohead.biimportcolors=0;

        for(i=0;i<HEIGHT;i++)
               for(j=0;j<WIDTH;j++)
                        {
       
                        *(bmp+i*WIDTH+j)=((buf&0xf800)>>1)|((buf&0x07c0)>>1)|((buf&0x1f));
                       
                        //printf("%x\t",*(bmp+i*WIDTH+j));
                        }

        write(data_fd,"BM",2);
       
        i=write(data_fd,&bfhead,sizeof(struct tagBITMAPFILEHEADER));
        printf("Write filehead %dbytes\n",i);

        i=write(data_fd,&binfohead,sizeof(struct tagBITMAPINFOHEADER));
        printf("Write infohead %dbytes\n",i);

        i=write(data_fd,bmp,size*2);
        printf("Write bitmap %dbytes\n",i);

        lseek(data_fd,SEEK_SET,4);
       
}

static void v4l2_show_on_fb(int fd, char *fbmem, int frames)
{
        int i;
        int ret;       
       
        //while(1)
        for(i=0;i<10;i++)
                        {
                        if ((ret = read (fd, &preview_buf, WIDTH*HEIGHT*2)) < 0) {
                                perror("read");
                                return;
                        }

               
        #if 1                        //for 320*240,640*480,800*480
                        {
                        //printf("test");
                        int y;
                        for (y = 0; y < 240; y++)
                                memcpy(fbmem + x_lcd_size*2*y, preview_buf + 320*2*y, 320*2);
                                //memcpy(fbmem + x_lcd_size*2*y, preview_buf + 320*y, 320*2);
                        }
        #else                        //for 240*320
                        memcpy(fbmem, &preview_buf, 240*320*2);
        #endif

                        fflush(stdout);
        }
       
        printf("\n");
}

static unsigned int fb_grab(int fd, char **fbmem)
{
        F_VINFO modeinfo;
        unsigned int length;

        if (ioctl(fd, FBIOGET_VSCREENINFO, &modeinfo) < 0) {
                perror("FBIOGET_VSCREENINFO");
                exit (EXIT_FAILURE);
        }
        length = modeinfo.xres * modeinfo.yres * (modeinfo.bits_per_pixel >> 3);

        x_lcd_size=modeinfo.xres;             //width of tft lcd
        y_lcd_size=modeinfo.yres;             //height of tft lcd

        printf("fb memory info=xres (%d) x yres (%d), %d bpp\n",
                        modeinfo.xres, modeinfo.yres, modeinfo.bits_per_pixel);

        *fbmem = mmap(0, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
        if (*fbmem < 0) {
                perror("mmap()");
                length = 0;
        }

        return length;
}

static void fb_ungrab(char **fbmem, unsigned int length)
{
        if (*fbmem)
                munmap(*fbmem, length);
}


int main(int argc, char *argv[])
{
        int v4l2_fd = -1;
        int fb_fd = -1;
        int data_fd=-1;
        char *fbmem = NULL;
        unsigned int fb_length = 0;

        int preview_frames = 180;
        int tmp;

        printf("TQ2440 Camera Test Program, Start !\n");
        if (argc > 1) {
                if (sscanf(argv, "%d", &tmp) == 1)
                        preview_frames = tmp;
        }

        v4l2_fd = open(V4L2_DEV_NODE, O_RDWR);
        if (v4l2_fd < 0) {
                perror(V4L2_DEV_NODE);
                goto out;
        }

        fb_fd = open(FB_DEV_NODE, O_RDWR);
        if (fb_fd < 0) {
                perror(FB_DEV_NODE);
                goto out;
        }

        data_fd=open(DATA,O_CREAT|O_RDWR,0777);
        if(data_fd<0){
                perror(DATA);
                goto out;
        }
       
        fflush(stdout);
        if ((fb_length = fb_grab(fb_fd, &fbmem)) == 0)
                goto out;
        memset(fbmem, 0, fb_length);

        printf("Press Ctrl+C to stop !\n");
        fflush(stdout);

        v4l2_show_on_fb(v4l2_fd, fbmem, preview_frames);

        writebmp(data_fd);
       
        printf("\n");

out:

        if (v4l2_fd > 0)
                close(v4l2_fd);

        if(data_fd>0)
                close(data_fd);

        fb_ungrab(&fbmem, fb_length);

        return 0;
}

不支持上传BMP文档 那就不传啦~

天嵌_support1 发表于 2011-2-18 10:35:40

顶网友!!!

shufexiu 发表于 2011-2-18 10:38:45

这个必须顶的哟!!

embedsky_lhh 发表于 2011-2-18 11:14:09

:)

wang8953 发表于 2011-2-18 11:45:19

谢谢各位版主~

uboard 发表于 2011-2-18 13:43:58

天嵌的人很负责,网友们也有这样的精神!很喜欢。

lkcumt 发表于 2011-2-24 19:29:06

楼主很犀利,我也在弄,楼主有QQ号吗,留下我加一下,向你讨论一下:)

dk56 发表于 2011-2-25 16:09:14

楼主,那份很有价值的文档能分享一下吗?

wang8953 发表于 2011-3-2 13:10:43

本帖最后由 wang8953 于 2011-3-2 13:14 编辑

7# lkcumt
你留下QQ 我加你吧~

这个是有价值的资料 不能直接在TQ2440上用的。 改一下宏定义 可以抓取屏幕的图像,只不过是镜像图像。左右相反的。 有问题的留言吧~

wang8953 发表于 2011-3-2 13:12:34

这个是有价值的资料。不能直接用在TQ2440上。需要修改。但是如果简单改一下宏定义的话 可以直接抓取屏幕上的图像 只不过需要镜像调整。
有问题继续留言吧~

machoe 发表于 2011-3-2 13:55:14

好帖 收藏了

gankeliang 发表于 2011-3-11 10:01:55

楼主,好人啊,我的QQ是283299176,可以加下到时向你请教下,我最近也在做摄像头。

gankeliang 发表于 2011-3-11 10:03:44

楼主可以加下么?283299176,谢谢了

wjjontheway 发表于 2011-3-14 16:23:47

感谢楼主分享了啊

guoyin 发表于 2011-3-14 20:18:40

感谢楼主!!!
页: [1] 2 3
查看完整版本: 通过TQ2440配套的OV9650抓图源码~