• 6199阅读
  • 2回复

[分享]基于S3C2410编写摄像头应用程序的参考资料 [复制链接]

上一主题 下一主题
离线keisuo
 

只看楼主 倒序阅读 楼主  发表于: 2007-05-10
— 本帖被 XChinux 执行加亮操作(2008-07-19) —
收集的一些资料,大家共享吧!========================================================================用servfox一个小程序做服务端,传出来到你的电脑连续显示,效果不错!http://mxhaard.free.fr/spcaserv.html=======================================================================还有一个类似:spcacathttp://www.macsat.com/macsat/content/view/36/30/=======================================================================德国人做的抓图程序:vgrabbjhttp://vgrabbj.gecius.de/=======================================================================其它的编程经验:问题1:linux支持的设像头驱动太少,现在我们只找到ov511的驱动,也就是说并不是每一个设像头都能在linux下用.问题2:以前我们是用v4l一写的,可以正确读取图像,现在2.6内核是v4l二,我们写的程序读出来显现的不正确,源代码大概是这样的:        Mywidth = 176;Myheight = 144;tmp = (uchar *)malloc(Mywidth * Myheight *3);buffer = (uchar *)malloc(Mywidth * Myheight *4);device_fd = open("/dev/video0", O_RDONLY);static struct video_window vidwin;vidwin.width = Mywidth;vidwin.height = Myheight;ioctl(device_fd, VIDIOCSWIN, &vidwin);read(device_fd, tmp, Mywidth*Myheight*3);for(int i = 0; i < 176 * 144; ++i){  buffer[4*i] = tmp[3*i];//first bit is blue  buffer[4*i + 1] = tmp[3*i + 1];//second bit is green  buffer[4*i + 2] = tmp[3*i + 2] ;//third bit is red  buffer[4*i + 3] = 130;//forth bit}//后面这此是用QT库写的,意思是将buffer的内容转为image再转为pixmap,然后显示出来QImage img(buffer, Mywidth, Myheight, 32, NULL, 0, QImage::LittleEndian); QPixmap pic;pic.convertFromImage(img);PixmapVideo->setPixmap(pic);====================================Content 1.驱动 2.应用程序书写 1.驱动    Linux-2.4.18默认带有ov511摄像头的驱动,在USB设备中选中,并激活video选项,即可对ov511支持。 2.应用程序书写    这是一个在MiniGui下的程序,可以用QVFB模拟,可以可以在板子上跑,效果还可以。 v4l.h /* * w3v4l.h * * Copyright (C) 1998 - 2000 Rasca, Berlin * EMail: thron@gmx.de * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __W3V4L_H__ #define __W3V4L_H__ class CV4L{ public: CV4L(); CV4L(char *szDevName); ~CV4L(); bool init(int channel, int width, int height); unsigned char *Read(); void destroy(); private: char *szDevName; bool initialized; unsigned char *m_Buff; int m_BuffSize; int fdVideo; int m_Width, m_Height; int m_MapSize; }; #endif v4l.cpp /* * v4l.c * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/ioctl.h> #include <sys/mman.h> #include <linux/types.h> #include <string.h> #include <linux/videodev.h> #include "v4l.h" /* v4l_init() * function: init the video device * references: *    dev: device name. *    input: channel number of video_channel structure. *    width: width value of video_window structure *    height: height value of video_window structure */ bool CV4L::init(int channel, int width, int height) { int fd; struct video_capability vid_caps; struct video_mbuf vid_mbuf; struct video_channel vid_chnl; // open the video device fd = open (szDevName, O_RDWR); if (fd == -1) { perror (szDevName); return false; } fdVideo = fd; // get video_capability structrue if (ioctl (fd, VIDIOCGCAP, &vid_caps) == -1) { perror ("ioctl (VIDIOCGCAP)"); return false; } // get the buffer information in video_mbuf structure // if can't use mmap() if (ioctl (fd, VIDIOCGMBUF, &vid_mbuf) == -1) { struct video_window vid_win; m_MapSize = 0; // set video window information if (ioctl(fd, VIDIOCGWIN, &vid_win) != -1) { vid_win.width = width; vid_win.height= height; ioctl (fd, VIDIOCSWIN, &vid_win); } } else { m_MapSize = vid_mbuf.size; m_BuffSize = m_MapSize; } #ifdef DEBUG printf ("%s: mbuf.size=%d\n", __FILE__, vid_mbuf.size); #endif if (channel > -1) { vid_chnl.channel = channel; if (ioctl (fd, VIDIOCGCHAN, &vid_chnl) == -1) { perror ("ioctl (VIDIOCGCHAN)"); } else { vid_chnl.channel = channel; if (ioctl (fd, VIDIOCSCHAN, &vid_chnl) == -1) { perror ("ioctl (VIDIOCSCHAN)"); } } } if (m_MapSize > 0) { m_Buff = (unsigned char *)mmap (0,m_MapSize, PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); if ((unsigned char *) -1 == (unsigned char *)m_Buff) { perror ("mmap()"); close (fd); return false; } } else { m_BuffSize = width * height * 3; m_Buff = (unsigned char *)malloc (m_BuffSize); } m_Width = width; m_Height = height; return true; } unsigned char *CV4L::Read() { struct video_mmap vid_mmap; if (m_MapSize == 0) { printf (__FILE__": reading image .. \n"); if (read (fdVideo, (void *)m_Buff, m_BuffSize) <= 0) { free (m_Buff); return (0); } } else { vid_mmap.format = VIDEO_PALETTE_RGB565;  //VIDEO_PALETTE_RGB24; vid_mmap.frame = 0; vid_mmap.width = m_Width; vid_mmap.height= m_Height; if (ioctl (fdVideo, VIDIOCMCAPTURE, &vid_mmap) == -1) { perror ("ioctl (VIDIOCMCAPTURE)"); return (0); } if (ioctl (fdVideo, VIDIOCSYNC, &vid_mmap) == -1) { perror ("ioctl (VIDIOCSYNC)"); return (0); } } return m_Buff; } void CV4L::destroy() { if (fdVideo >= 0) { if (m_MapSize == 0) free (m_Buff); else munmap (m_Buff, m_MapSize); close (fdVideo); } } CV4L::CV4L() { // } CV4L::CV4L(char *_szDevName) { szDevName = (char *)malloc(strlen(_szDevName)+1); strcpy(szDevName, _szDevName); //init(0, int width, int height); // } CV4L::~CV4L() { destroy(); } video.cpp /* ** $Id: helloworld.c,v 1.7 2003/06/13 07:15:49 weiym Exp $ ** ** Listing 2.1 ** ** helloworld.c: Sample program for MiniGUI Programming Guide **      The first MiniGUI application. ** ** Copyright (C) 2003 Feynman Software. ** ** License: GPL */ #include <stdio.h> #include <minigui/common.h> #include <minigui/minigui.h> #include <minigui/gdi.h> #include <minigui/window.h> #include <string.h> #include <malloc.h> #include "v4l.h" #define VID_W 320 #define VID_H 240 static BITMAP bmp; CV4L *cVid;  //"/dev/video0" unsigned char *buf;    static int count = 0;    static int xdir = -3;    static int ydir = -3;    static int x = 1;    static int y = 11; /*bool SwitchBuf24ToBmp16(unsigned char *buf24, PBITMAP pBmp) { myBmp.bits = buf24; //ExpandMyBitmap (HDC_SCREEN, &bmp, &myBmp, rgb, 0); printf ("bmp.bmType = %i\n", bmp.bmType); printf ("bmp.bmBitsPerPixel = %i\n", bmp.bmBitsPerPixel); printf ("bmp.bmBytesPerPixel = %i\n", bmp.bmBytesPerPixel); printf ("bmp.bmAlpha = %i\n", bmp.bmAlpha); printf ("bmp.bmColorKey = %i\n", bmp.bmColorKey); printf ("bmp.bmWidth = %i\n", bmp.bmWidth); printf ("bmp.bmHeight = %i\n", bmp.bmHeight); printf ("bmp.bmPitch = %i\n", bmp.bmPitch); printf ("bmp.bmBits = %i\n", bmp.bmBits); printf ("bmp.bmAlphaPixelFormat = %i\n", bmp.bmAlphaPixelFormat); return true; }*/ void FillBitmap(BITMAP *bmp) { bmp->bmType = 0; bmp->bmBitsPerPixel = 16; bmp->bmBytesPerPixel = 2; bmp->bmAlpha = 0; bmp->bmColorKey = 0; bmp->bmWidth = VID_W; bmp->bmHeight = VID_H; bmp->bmPitch = VID_W*2; bmp->bmBits = NULL; bmp->bmAlphaPixelFormat = NULL; } void FillMyBitmap(PMYBITMAP my_bmp) { my_bmp->flags = MYBMP_RGBSIZE_3 | MYBMP_TYPE_BGR | MYBMP_FLOW_DOWN; my_bmp->frames = 1; my_bmp->depth = 24; my_bmp->alpha = 0; my_bmp->reserved[0] = 0; my_bmp->reserved[1] = 0; my_bmp->transparent = 0; my_bmp->w = 240; my_bmp->h = 180; my_bmp->pitch = 240*3; my_bmp->size = 240*180*3; my_bmp->bits = NULL; } static int HelloWinProc(HWND hWnd, int message, WPARAM wParam, LPARAM lParam) {    HDC hdc;    RECT rc;    switch (message) {        case MSG_PAINT:            hdc = BeginPaint (hWnd);            if (bmp.bmBits)                FillBoxWithBitmap (hdc, 0, 0, bmp.bmWidth, bmp.bmHeight, &bmp);            SetBkColor (hdc, RGB2Pixel (hdc, 0xFF, 0xFF, 0xFF));            SetBkMode (hdc, BM_TRANSPARENT);            SetTextColor (hdc, RGB2Pixel (hdc, 0xFF, 0x00, 0x00));            rc.left = 0;            rc.top = 0;            rc.right = 300;            rc.bottom = 60;            TextOut (hdc, 0, 0, "??????");    if (x >= VID_W || x <=0)    {                xdir = 0 - xdir;    }    if (y >= VID_W || y <=10)    {                ydir = 0 - ydir;    }        x += xdir;    y += ydir;    TextOut (hdc, x, y, "kdf");            Rectangle (hdc, 0, 0, bmp.bmWidth, bmp.bmHeight);            /*FillBoxWithBitmap (hdc, 100, 0, 200, 200, &bmp);            Rectangle (hdc, 100, 0, 300, 200);            FillBoxWithBitmapPart (hdc, 0, 200, 400, 200, 0, 0, &bmp, 10, 10);            Rectangle (hdc, 0, 200, 400, 400);*/            EndPaint (hWnd, hdc);            return 0;        case MSG_CREATE:            /*if (LoadBitmap (HDC_SCREEN, &bmp, "bkgnd.bmp"))                return -1;*/            return 0;        case MSG_CLOSE:            UnloadBitmap (&bmp);            DestroyMainWindow (hWnd);            PostQuitMessage (hWnd);            return 0;    }    return DefaultMainWinProc(hWnd, message, wParam, lParam); } int MiniGUIMain (int argc, const char* argv[]) {    MSG Msg;    HWND hMainWnd;    MAINWINCREATE CreateInfo; #ifdef _LITE_VERSION    SetDesktopRect(0, 0, 1024, 768); #endif    CreateInfo.dwStyle = WS_VISIBLE | WS_BORDER | WS_CAPTION;    CreateInfo.dwExStyle = WS_EX_NONE;    CreateInfo.spCaption = "Hello, world";    CreateInfo.hMenu = 0;    CreateInfo.hCursor = GetSystemCursor(0);    CreateInfo.hIcon = 0;    CreateInfo.MainWindowProc = HelloWinProc;    CreateInfo.lx = 0;    CreateInfo.ty = 0;    CreateInfo.rx = VID_W;    CreateInfo.by = VID_H;    CreateInfo.iBkColor = COLOR_lightwhite;    CreateInfo.dwAddData = 0;    CreateInfo.hHosting = HWND_DESKTOP;        hMainWnd = CreateMainWindow (&CreateInfo);        if (hMainWnd == HWND_INVALID)        return -1;    ShowWindow(hMainWnd, SW_SHOWNORMAL);    //////////////////////////////////////////////////////////////    // 1. Create my video class CV4L.    cVid = new CV4L("/dev/video0");        //////////////////////////////////////////////////////////////    // 2. Init the video device with channel and map size.    if (cVid->init(0, VID_W, VID_H) == false)        return -1;    //FillMyBitmap(&myBmp);    FillBitmap(&bmp);    //////////////////////////////////////////////////////////////    // 3. Read the data from video device.    if (buf = cVid->Read ())    {        bmp.bmBits = buf;        //InvalidateRect ();        SendMessage (hMainWnd, MSG_PAINT, 0, 0);    }    while (true)    {        if (!HavePendingMessage (hMainWnd))        {            if (!GetMessage (&Msg, hMainWnd))                break;            TranslateMessage (&Msg);            DispatchMessage (&Msg);        } else {            //////////////////////////////////////////////////////////////            // 3. Read the data from video device.            if (buf = cVid->Read ())            {                bmp.bmBits = buf;                SendMessage (hMainWnd, MSG_PAINT, 0, 0);            } else {                // if Buffer is Null, vedeo device have pluged out.                PostQuitMessage (hMainWnd);            } /* end of read video buffer */        } /* end of HavePendingMessage() */    } /* end of while */    //////////////////////////////////////////////////////////////    // 4. destroy the CV4L class, and release resources.    cVid->destroy ();    UnloadBitmap (&bmp);    //free (bmp.bmBits);    MainWindowThreadCleanup (hMainWnd);    return 0; } #ifndef _LITE_VERSION #include <minigui/dti.c> #endif 把这些代码添加到miniugi-1.3.3的helloworld程序中去编译一下就可以了,也可以用如下命令 g++ -o video -I/minigui/include -L/minigui/lib video.cpp v4l.cpp
离线keisuo

只看该作者 1楼 发表于: 2007-05-10
最近又在搞摄像头的东西。被搞死了。。。上述代码在minigui中是单线程跑的,虽然是在消息空闲的时候进行图像获取的,但实际效果无论是pc还是板子上那些控件都是不能操作的。因此我改了个多线程的。

/*
** $Id: button.c,v 1.7 2003/08/15 11:12:18 weiym Exp $
**
** Listing 7.1
**
** button.c: Sample program for MiniGUI Programming Guide
**    Usage of BUTTON control.
**
** Copyright (C) 2003 Feynman Software.
**
** License: GPL
*/

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <memory.h>

#include <pthread.h>

#include <minigui/common.h>
#include <minigui/minigui.h>
#include <minigui/gdi.h>
#include <minigui/window.h>
#include <minigui/control.h>

#include "v4l.h"

//#define IDC_STATIC      100

#define IDC_WINMAIN_KAISHIJISHI    101
#define IDC_WINMAIN_DINGSHISHEDING  102
#define IDC_WINMAIN_KAISHIJIANCE    103
#define IDC_WINMAIN_XUANZEKU    104
#define IDC_WINMAIN_NONGDUZHI    105
#define IDC_WINMAIN_KANGSHENGSULEIXING 106
#define IDC_WINMAIN_LEBAL    107
#define IDC_WINMAIN_GUANJI    108

int NumerWin(void);
int TypeWin(void);
void StartTimer(void);
void StopTimer(void);

/* Global Variable */
char gszTypeName[100] = "绿霉素";
int giWaitTime = 12;
bool gbTimerStart = false;
HWND ghWnd = NULL;

/* v4l */
#define V4L_DEV "/dev/video0"
#define VID_W 320
#define VID_H 240
static BITMAP bmp;
static BITMAP small_bmp;
static unsigned char small_buf[240*180*2];
CV4L *cVid;  //"/dev/video0"
unsigned char *buf;
pthread_t vid_tid = 0;

char strBuf[100];

static CTRLDATA CtrlYourTaste[] =
{
    {
        "button",
        WS_VISIBLE | BS_DEFPUSHBUTTON | WS_TABSTOP,
        6, 236, 71, 32,
        IDC_WINMAIN_KAISHIJISHI,
        "开始记时",
        0
    },
    {
        "button",
        WS_VISIBLE | BS_DEFPUSHBUTTON | WS_TABSTOP,
        85, 236, 71, 32,
        IDC_WINMAIN_DINGSHISHEDING,
        "定时设定",
        0
    },
    {
        "button",
        WS_VISIBLE | BS_DEFPUSHBUTTON | WS_TABSTOP,
        162, 236, 71, 32,
        IDC_WINMAIN_KAISHIJIANCE,
        "开始检测",
        0
    },
    {
        "button",
        WS_VISIBLE | BS_DEFPUSHBUTTON | WS_TABSTOP,
        6, 273, 71, 32,
        IDC_WINMAIN_XUANZEKU,
        "选择库",
        0
    },
    {
        "button",
        WS_VISIBLE | BS_DEFPUSHBUTTON | WS_TABSTOP,
        85, 273, 71, 32,
        IDC_WINMAIN_GUANJI,
        "结束",
        0
    },
    {
        "static",
        WS_VISIBLE | WS_TABSTOP,
        14, 185, 124, 25,
        IDC_WINMAIN_LEBAL,
        "检测结果",
        0
    },
    {
        "static",
        WS_VISIBLE | WS_TABSTOP,
        120, 185, 100, 25,
        IDC_WINMAIN_NONGDUZHI,
        "3.1415",
        0
    },
    {
        "static",
        WS_VISIBLE | WS_TABSTOP,
        14, 211, 150, 25,
        IDC_STATIC,
        "抗生素类型",
        0
    },
    {
        "static",
        WS_VISIBLE | WS_TABSTOP,
        120, 211, 100, 25,
        IDC_WINMAIN_KANGSHENGSULEIXING,
        "绿霉素",
        0
    },
};

static DLGTEMPLATE DlgYourTaste =
{
    WS_BORDER | WS_CAPTION,
    WS_EX_NONE,
    0, -23, 240, 344,
    "",
    0, 0,
    sizeof(CtrlYourTaste)/sizeof(CTRLDATA), NULL,
    0
};

void SetTimer(void)
{
NumerWin();
}

void BeginDetect(void)
{
// 停止线程,取得图片
if (vid_tid != 0)
{
  pthread_cancel(vid_tid);
  vid_tid = 0;
  printf("Video Stoped!\n");
}

/* 进行图像检测 */

/* 显示结果 */
SetDlgItemText(ghWnd, IDC_WINMAIN_LEBAL, "检测结果");
sprintf(strBuf, "%f", 3.1415926);
SetDlgItemText(ghWnd, IDC_WINMAIN_NONGDUZHI, strBuf);

}

void ChooseType(void)
{
TypeWin();
}

void FillBitmap(BITMAP *bmp, int w, int h, int bpp, unsigned char *pBuf)
{
bmp->bmType = 0;
bmp->bmBitsPerPixel = 8*bpp;
bmp->bmBytesPerPixel = bpp;
bmp->bmAlpha = 0;
bmp->bmColorKey = 0;
bmp->bmWidth = w;
bmp->bmHeight = h;
bmp->bmPitch = w*2;
bmp->bmBits = pBuf;
bmp->bmAlphaPixelFormat = NULL;
}

void *__VideoThreadProc(void *arg)
{
printf("Thread Start\n");
//////////////////////////////////////////////////////////////
// 3. Read the data from video device.
while (vid_tid != 0)
{
  if (buf = cVid->Read ())
  {
  bmp.bmBits = buf;
  SendMessage (ghWnd, MSG_PAINT, 0, 0);
  }
}
printf("Thread End\n");
pthread_exit(0);
}

static int DialogBoxProc2 (HWND hDlg, int message, WPARAM wParam, LPARAM lParam)
{
    HDC hdc;

ghWnd = hDlg;

    switch (message) {
    case MSG_INITDIALOG:
        {
  hdc = GetDC(hDlg);
  Rectangle (hdc, 0, 0, 100, 100);
  //Rectangle (hdc, 0, 0, bmp.bmWidth, bmp.bmHeight);
  /*if (LoadBitmap (HDC_SCREEN, &bmp, "save.bmp"))
  {
    return 0;
  }*/
  ReleaseDC(hdc);
        }
        break;
    case MSG_PAINT:
            hdc = BeginPaint (hDlg);

            if (small_bmp.bmBits != NULL)
  {
    ScaleBitmap (&small_bmp, &bmp);
                FillBoxWithBitmap (hdc, 0, 0, small_bmp.bmWidth, small_bmp.bmHeight, &small_bmp);
  }
            Rectangle (hdc, 0, 0, small_bmp.bmWidth, small_bmp.bmHeight);

            EndPaint (hDlg, hdc);
            break;
    case MSG_USER:
  SetDlgItemText(hDlg, IDC_WINMAIN_LEBAL, "剩余时间");
  sprintf(strBuf, "%d分%d秒", wParam, lParam);
  SetDlgItemText(hDlg, IDC_WINMAIN_NONGDUZHI, strBuf);
  printf("剩余时间:%s\n", strBuf);
  break;
    case MSG_USER+1:
  printf("时间到\n", wParam, lParam);
  SetDlgItemText(hDlg, IDC_WINMAIN_KAISHIJISHI, "开始记时");
  gbTimerStart = false;
  EnableWindow(GetDlgItem(hDlg, IDC_WINMAIN_DINGSHISHEDING), true);
  EnableWindow(GetDlgItem(hDlg, IDC_WINMAIN_KAISHIJIANCE), true);
  if (vid_tid == 0)
  {
  printf("Video Begin!\n");
  pthread_create(&vid_tid, NULL, &__VideoThreadProc, (void *) NULL);
  printf("tid = %d\n", vid_tid);
  }
  break;
    case MSG_COMMAND:
        switch (wParam) {
  case IDC_WINMAIN_KAISHIJISHI:
    if (gbTimerStart)
    {
    SetDlgItemText(hDlg, IDC_WINMAIN_KAISHIJISHI, "开始记时");
    EnableWindow(GetDlgItem(hDlg, IDC_WINMAIN_DINGSHISHEDING), true);
    EnableWindow(GetDlgItem(hDlg, IDC_WINMAIN_KAISHIJIANCE), true);
    gbTimerStart = false;
    StopTimer();
    }
    else
    {
    SetDlgItemText(hDlg, IDC_WINMAIN_KAISHIJISHI, "停止计时");
    EnableWindow(GetDlgItem(hDlg, IDC_WINMAIN_DINGSHISHEDING), false);
    EnableWindow(GetDlgItem(hDlg, IDC_WINMAIN_KAISHIJIANCE), false);
    gbTimerStart = true;
    StartTimer();
    }
    break;
  case IDC_WINMAIN_DINGSHISHEDING:
    SetTimer();
    break;
  case IDC_WINMAIN_KAISHIJIANCE:
    BeginDetect();
    break;
  case IDC_WINMAIN_XUANZEKU:
    ChooseType();
    SetDlgItemText(hDlg, IDC_WINMAIN_KANGSHENGSULEIXING, gszTypeName);
    break;
  case IDC_WINMAIN_GUANJI:
    if (vid_tid != 0)
    {
    pthread_cancel(vid_tid);
    vid_tid = 0;
    printf("Video Stoped!\n");
    }
    EndDialog (hDlg, wParam);
    //exit(0);
    break;
        }
        break;
       
    }
   
    return DefaultDialogProc (hDlg, message, wParam, lParam);
}

void sig_int(int signo)
{
if (vid_tid != 0)
{
  pthread_cancel(vid_tid);
  vid_tid = 0;
  printf("Video Stoped!\n");
}
    //cVid->destroy ();
    UnloadBitmap (&bmp);
printf("Stoped!\n");
exit(0);
}

int MiniGUIMain (int argc, const char* argv[])
{
#ifdef _LITE_VERSION
    SetDesktopRect(0, 0, 1024, 768);
#endif
   
signal(SIGINT, sig_int);

    //////////////////////////////////////////////////////////////
    // 1. Create my video class CV4L.
    cVid = new CV4L("/dev/video0");
   
    //////////////////////////////////////////////////////////////
    // 2. Init the video device with channel and map size.
    if (cVid->init(0, VID_W, VID_H) == false)
        return -1;

    //FillMyBitmap(&myBmp);
    FillBitmap(&bmp, VID_W, VID_H, 2, NULL);
memset(small_buf, 0xFF, 240*180*2);
    FillBitmap(&small_bmp, VID_H, 180, 2, small_buf);
    //////////////////////////////////////////////////////////////
    // 3. Read the data from video device.
    if (buf = cVid->Read ())
    {
        bmp.bmBits = buf;
    }

    DlgYourTaste.controls = CtrlYourTaste;
   
    DialogBoxIndirectParam (&DlgYourTaste, HWND_DESKTOP, DialogBoxProc2, 0L);

    //cVid->destroy ();
    UnloadBitmap (&bmp);
    exit(0);
}

#ifndef _LITE_VERSION
#include <minigui/dti.c>
#endif

/*Timer.cpp*/


#include <stdio.h>
#include <stdlib.h>

#include <unistd.h>  /* UNIX standard function definitions */ /* sleep() */

#include <sys/time.h> /* timeval{} for select() */
#include <time.h>  /* timespec{} for pselect() */

#include <pthread.h>

#include <minigui/common.h>
#include <minigui/minigui.h>
#include <minigui/gdi.h>
#include <minigui/window.h>
#include <minigui/control.h>

#define IDC_WINMAIN_GUANJI    107

pthread_t timer_tid;

extern HWND ghWnd;
extern int giWaitTime;

void *__TimerThreadProc(void *arg)
{
int i, j;

for (i=giWaitTime-1; i>=0; i--)
{
  for (j=59; j>=0; j--)
  {
  SendMessage(ghWnd, MSG_USER, i, j);
  sleep(1);
  }
}
SendMessage(ghWnd, MSG_USER+1, i, j);
pthread_exit(0);
return(NULL);
}

void StartTimer(void)
{
pthread_create(&timer_tid, NULL, &__TimerThreadProc, (void *) NULL);
}

void StopTimer(void)
{
pthread_cancel(timer_tid);
}


    程序的大致思路是这样的:先开个线程,做定时器(也可以用minigui中MSG_TIMER消息来做),定时到一定时候发送自定义消息,启动图像获取线程。在图像获取线程中获取图像后发送paint消息进行绘制。

    但是我发现摄像头在pc上用没有问题,在2410下用有花斑。这个问题有可能是处理器处理能力的问题,也可能是用了多线程以后的问题,因为原先花斑没这么多。

    立宇太的工程师不知道有没有遇到这个问题。。。
离线lixiangnew
只看该作者 2楼 发表于: 2008-11-07
我直接写显存,也可以实现,也有花斑。
快速回复
限100 字节
 
上一个 下一个