v4l_fb.c

V4L fb.c

int deviceHandle = 0;   
int i; // temporary counter    
struct video_capability capability;   
struct video_channel queryChannel;   
struct video_channel selectedChannel;   
struct video_window captureWindow;   
struct video_picture imageProperties;   
struct video_mbuf memoryBuffer;   
struct video_mmap* mmaps;   
char* memoryMap;   
int channelNumber = 0;   
int width = 320;   
int height = 240;   
int depth;   
int palette;   
int bufferIndex;   
int fbfd = 0;   
struct fb_var_screeninfo vinfo;   
struct fb_fix_screeninfo finfo;   
struct fb_cmap chen_fb_cmap;   
long int screensize = 0;   
char *fbp = 0;   
int x = 0, y = 0;   
long int location = 0;   
typedef unsigned char BYTE;   
BYTE m_pData[240][320];   
int gwidth;   
int gheight;   
int gcount;   
int GetSeg(int *x, int len);   
void ErosionLin(int s[][20],int sm,int sn,int x[][320],int xm,int xn,int y[][320]);   
void DilationLin(int s[][20],int sm,int sn,int x[][320],int xm,int xn,int y[][320]);   
void CloseLin(int s[][20],int sm,int sn,int x[][320],int xm,int xn,int y[][320],int z[][320]);   
int CountBySeg(int x[][320], long row, long col);   
void OnResult();   
void gray(char *data,int width,int height);   
static int write_file(char *data, int width, int height);   
int GetSeg(int *x, int len)   
{   
    int i,temp,sum;   
    for(i=0;i<len-1;i++)   
    {   
        temp = x[i] * x[i+1];   
        if(temp==1)   
            x[i] = 0;   
    }   
    sum = 0;   
    for(i=0;i<len;i++)   
        sum = sum + x[i];   
    return sum;   
}   
void ErosionLin(int s[][20],int sm,int sn,int x[][320],int xm,int xn,int y[][320]){   
        int i0,j0,i,j;   
        int sum0,sum;   
        for(i0=0;i0<xm;i0++)   
        for(j0=0;j0<xn;j0++){      
            y[i0][j0]=0;   
        }   
        sum0=0;   
        for(i=0;i<sm;i++)   
        for(j=0;j<sn;j++){   
            sum0=sum0+s[i][j];   
        }   
        for(i0=0;i0=xm-sm;i0++)   
        for(j0=0;j0=xn-sn;j0++){   
            sum=0;   
            for(i=0;i<sm;i++)   
                for(j=0;j<sn;j++){   
                    sum=sum+s[i][j]*x[i0+i][j0+j];   
                }   
            if(sum==sum0)   
                y[i0+sm/2][j0+sn/2]=1;   
        }   
    }   
   
void DilationLin(int s[][20],int sm,int sn,int x[][320],int xm,int xn,int y[][320]){   
        int i0,j0,i,j;   
        int sum;   
        for(i0=0;i0<xm;i0++)   
            for(j0=0;j0<xn;j0++){   
                y[i0][j0]=0;   
                }   
        for(i0=0;i0=xm-sm;i0++)   
            for(j0=0;j0=xn-sn;j0++){   
                sum=0;   
                for(i=0;i<sm;i++)   
                    for(j=0;j<sn;j++){   
                        sum=sum+s[i][j]*x[i0+i][j0+j];   
                    }   
                if(sum>0)   
                y[i0+sm/2][j0+sn/2]=1;         
               }   
}   
void CloseLin(int s[][20],int sm,int sn,int x[][320],int xm,int xn,int y[][320],int z[][320]){         
        DilationLin(s,sm,sn,x,xm,xn,y);   
        ErosionLin(s,sm,sn,y,xm,xn,z);   
    }   
int CountBySeg(int x[][320],long row, long col)   
{   
    int y[240][320];   
    int * z;   
    int i,j,j1,k;          
    int sum,count,seg;   
    for(i=0;i<row;i++)   
        for(j=0;j<col;j++)   
            y[i][j] = x[i][j];   
    for(i=0;i<row;i++)   
        y[i][0]=y[i][col-1] = 0;   
    for(j=0;j<col;j++)   
        y[0][j]=y[row-1][j] = 0;   
    z =(int*)malloc(sizeof(int)*col);   
    count = 0;             
    for(i=1;i<row-1;i++)   
    {   
        j = 1;   
        while(j<col-1)   
        {//while 1                  
            if(y[i][j]==1)   
            {   
                sum = 1;   
                j1 = j + 1;   
                while(y[i][j1])   
                {   
                    sum++;   
                    j1++;   
                }   
                for(k=0;k<sum+2;k++)   
                    z[k] = y[i-1][j+k-1];   
                seg = GetSeg(z,sum+2);   
                count = count + 1 - seg;                       
                j = j + sum;   
            }   
                j++;   
        }          
    }   
    free(z);   
        gcount=count;   
    return count;   
}   
void OnResult()   
{   
    int count,i,j;   
    int  temp1[240][320],temp2[240][320];   
        int xx[240][320];   
        int s1[20][20];   
        int s2[20][20];   
    for(i=0; i<5; i++)   
        for(j=0; j<5; j++)   
            s1[i][j]=1;   
    for(i=0; i<20; i++)   
        for(j=0; j<20; j++)   
            s2[i][j]=1;   
    for(i=0; i<240; i++)   
        for(j=0; j<320; j++)   
        {   
            xx[i][j] = m_pData[i][j];   
        }   
    CloseLin(s1,5,5,xx,240,320,temp1,temp2);   
    ErosionLin(s2,10,10,temp2,240,320,temp1);   
    count=CountBySeg(temp1,gheight,gwidth);   
    return;   
}   
void gray(char *data,int width,int height)   
  {   
    int k=0;   
    long i,j;   
    gheight=height;   
    gwidth=width;   
    for ( i=0; i<height; i++)   
    {   
      for ( j=0; j<width; j++)   
      {   
        m_pData[i][j]= data[k] *0.114   
                               +data[k+1] * 0.587   
                               +data[k+2] * 0.299;   
        if(m_pData[i][j]>50)   
          m_pData[i][j]=1;   
        else   
          m_pData[i][j]=0;   
        k+=3;   
      }   
    }   
  }   
   
static int write_file(char *data, int width, int height)   
{   
    gray(data,width,height);   
    OnResult();   
    return 0;   
}   
char* NextFrame()   
{   
        // send a request to begin capturing to the currently indexed buffer    
        if (ioctl (deviceHandle, VIDIOCMCAPTURE, &mmaps[bufferIndex]) == -1)   
        {       // capture request failed    
        }   
        // move bufferIndex to the next frame    
        ++ bufferIndex;   
        if (bufferIndex == memoryBuffer.frames)   
        {       // bufferIndex is indexing beyond the last buffer    
                // set it to index the first buffer    
                bufferIndex = 0;   
        }   
        // wait for the currently indexed frame to complete capture    
        if (ioctl (deviceHandle, VIDIOCSYNC, &mmaps[bufferIndex]) == -1)   
        {       // sync request failed    
        }   
        // return the address of the frame data for the current buffer index    
        return (memoryMap + memoryBuffer.offsets[bufferIndex]);   
}   
int main()   
{   
        // open the device    
        char * videodeviceName = "/dev/v4l/video0";   
        deviceHandle = open (videodeviceName, O_RDWR);   
        if (deviceHandle == -1)   
        {       // could not open device    
                printf("Could not open device %s\n",videodeviceName);   
        // printf ("Could not open device %s - %s\n", videodeviceName, strerror[errno]);    
                return -1;   
        }   
        // get device capabilities    
        if (ioctl (deviceHandle, VIDIOCGCAP, &capability) == -1)   
        {       // query failed    
                printf ("could not obtain device capabilities\n");   
                return -1;   
        }   
        if ((capability.type & VID_TYPE_CAPTURE) == 0)   
        {       // this device cannot capture video to memory, exit    
                printf ("this device cannot capture video to memory\n");   
                return -1;   
        }   
        // enumerate and print out the channels    
        printf ("Select a channel:\n");   
        i = 0;   
        while (i  capability.channels)   
        {   
                queryChannel.channel = i;   
                if (ioctl (deviceHandle, VIDIOCGCHAN, &queryChannel) != -1)   
                {       // ioctl success, queryChannel contains information about this channel    
                        printf ("%d. %s\n", queryChannel.channel, queryChannel.name);   
                }   
                ++ i;   
        }   
        // have the user select a channel    
        printf (": ");   
        fflush (stdout);   
        scanf ("%d", &channelNumber);   
        // set the selected channel    
        selectedChannel.channel = channelNumber;   
        selectedChannel.norm = VIDEO_MODE_NTSC;   
        if (ioctl (deviceHandle, VIDIOCSCHAN, &selectedChannel) == -1)   
        {       // could not set the selected channel    
                printf ("Could not set channel #%d\nNot a fatal error.", channelNumber);   
        }   
        // set the desired width and height    
        //if ((capability.type & VID_TYPE_SCALES) != 0)    
        //{       // supports the ability to scale captured images    
                // have the user enter a desired width    
                printf ("Enter the desired width (e.g. 320): ");   
                fflush (stdout);   
                scanf ("%d", &width);   
                printf ("Enter the desired height (e.g. 240): ");   
                fflush (stdout);   
                scanf ("%d", &height);   
                captureWindow.x = 0;   
                captureWindow.y = 0;   
                captureWindow.width = width;   
                captureWindow.height = height;   
                captureWindow.chromakey = 0;   
                captureWindow.flags = 0;   
                captureWindow.clips = 0;   
                captureWindow.clipcount = 0;   
                if (ioctl (deviceHandle, VIDIOCSWIN, &captureWindow) == -1)   
                {       // could not set window values for capture    
                        printf ("Could not set desired dimensions\nNot a fatal error.\n");   
                }   
        //}    
        // retrieve the actual width and height of the capturing images    
        if (ioctl (deviceHandle, VIDIOCGWIN, &captureWindow) == -1)   
        {       // could not obtain specifics of capture window    
                printf ("Could not obtain capture window dimensions.\n");   
        }   
        width = captureWindow.width;   
        height = captureWindow.height;   
        printf ("Capturing dimensions are : %d, %d\n", width, height);   
        // request that we capture to 24bit RGB    
        // get image properties    
        if (ioctl (deviceHandle, VIDIOCGPICT, &imageProperties) != -1)   
        {       // successfully retrieved the default image properties    
                // the following values are for requesting 24bit RGB    
                imageProperties.depth = 24;   
                imageProperties.palette = VIDEO_PALETTE_RGB24;   
                if (ioctl (deviceHandle, VIDIOCSPICT, &imageProperties) == -1)   
                {       // failed to set the image properties    
                        printf ("Could not set the video depth and palette.\nPerhaps not a fatal error.\n");   
                }   
        }   
        // verify that the requested capture pixel depth and palette succeeded    
        if (ioctl (deviceHandle, VIDIOCGPICT, &imageProperties) == -1)   
        {       // failed to retrieve default image properties    
                printf ("Failed to retrieve the video depth and palette.\n");   
                return -1;   
        }   
        depth = imageProperties.depth;   
        palette = imageProperties.palette;   
        if ((depth != 24) || (palette != VIDEO_PALETTE_RGB24))   
        {       // not a format our program supports    
                printf ("Format is not 24bit RGB.\n");   
                return -1;   
        }   
        printf ("Capture depth is %dbit RGB\n",depth);   
        // obtain memory about capture space    
        if (ioctl (deviceHandle, VIDIOCGMBUF, &memoryBuffer) == -1)   
        {       // failed to retrieve information about capture memory space    
                printf ("Failed to retrieve information about MMIO space.\n");   
                return -1;   
        }   
        // obtain memory mapped area    
        memoryMap = (char*)mmap (0, memoryBuffer.size, PROT_READ | PROT_WRITE, MAP_SHARED, deviceHandle, 0);   
        if ((int)memoryMap == -1)   
        {       // failed to retrieve pointer to memory mapped area    
                printf ("Failed to obtain MMIO space.\n");   
                return -1;   
        }   
        // allocate structures    
        mmaps = (struct video_mmap*)(malloc (memoryBuffer.frames * sizeof (struct video_mmap)));   
          
        //****************    
        //add by chenfu 2005.01.26    
        //****************    
        //open framebuffer    
       /*int fbfd = 0;   
        struct fb_var_screeninfo vinfo;   
        struct fb_fix_screeninfo finfo;   
    struct fb_cmap chen_fb_cmap;   
        long int screensize = 0;   
        char *fbp = 0;   
        int x = 0, y = 0;   
        long int location = 0;*/   
            // Open the file for reading and writing    
        fbfd = open("/dev/fb/0", O_RDWR);   
        if (!fbfd) {   
                printf("Error: cannot open framebuffer device.\n");   
                exit(1);   
        }   
        printf("The framebuffer device was opened successfully.\n");   
         // Get fixed screen information    
        if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) {   
                printf("Error reading fixed information.\n");   
                exit(2);   
        }   
        // Get variable screen information    
        if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {   
                printf("Error reading variable information.\n");   
                exit(3);   
        }   
        vinfo.bits_per_pixel=12;   
    if(ioctl(fbfd, FBIOPUT_VSCREENINFO, &vinfo)){   
            printf("The dfdfdfdfdfdfdfdfdfdfu\n");   
        }      
                // printf("The framebuffer set not  .chenfu\n");    
        // Get variable screen information    
        if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {   
                printf("Error reading variable information.\n");   
                exit(3);   
        }   
        printf("    the chenfu framebuffe is %dx%d, %dbpp    \n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel );   
       /*if (ioctl(fbfd, FBIOGETCMAP, &chen_fb_cmap)) {  
                printf("Error  CHENFU variable information.\n");  
                exit(4);  
         }*/   
    //    printf("the CHENFU CMAP %d\n",*chen_fb_cmap.red);    
            // Figure out the size of the screen in bytes    
        //screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;    
    screensize = vinfo.xres * vinfo.yres*1.5;   
            // Map the device to memory    
        fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,fbfd, 0);   
        if ((int)fbp == -1) {   
                printf("Error: failed to map framebuffer device to memory.\n");   
                exit(4);   
        }   
            printf("The framebuffer device was mapped to memory successfully.\n");   
   
        //the next is to capture     
        //start capture    
        // fill out the fields    
        i = 0;   
        while (i  memoryBuffer.frames)   
        {   
                mmaps[i].frame = i;   
                mmaps[i].width = width;   
                mmaps[i].height = height;   
                mmaps[i].format = palette;   
                ++ i;   
        }   
        // request capture to each buffer except the last one    
        i = 0;   
        while (i  (memoryBuffer.frames-1))   
        {   
                if (ioctl (deviceHandle, VIDIOCMCAPTURE, &mmaps[i]) == -1)   
                {    
                    // capture request failed}    
                ++ i;   
        }   
        // set our index to the last buffer    
        bufferIndex = memoryBuffer.frames-1;   
        // capture and write out ten frames    
        printf ("Capture is ready;now start to captur images.\n");   
        while (1)   
        {                char* frame = NextFrame();       
        write_file(frame, 320, 240);   
        int index=0;   
        for ( y = 0; y  240; y++ )   
            for ( x = 0; x <160; x++ ) {   
                        index = index +2;    
                location =(x+ vinfo.xoffset) * 3 + (y+vinfo.yoffset) * finfo.line_length;   
                *(fbp + location) = (frame[index*3+2]&0xF0)|((frame[index*3+1]&0xF0)>>4);   
                *(fbp + location+1) = (frame[index*3]&0xF0)|((frame[(index+1)*3+2]&0xF0)>>4);   
                                *(fbp + location+2) = (frame[(index+1)*3+1]&0xF0)|((frame[(index+1)*3]&0xF0)>>4);   
        }   
        if((gcount>=0)&&(gcount=9))   
            drawNum(gcount);   
        else   
            drawNum(0);   
    }   
        // free the video_mmap structures    
        free (mmaps);   
        // unmap the capture memory    
        munmap (memoryMap, memoryBuffer.size);   
       // close the device    
        close (deviceHandle);   
        return 0;   
}  



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值