发新话题
打印

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

取消高亮

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

收集的一些资料,大家共享吧!
========================================================================
用servfox一个小程序做服务端,传出来到你的电脑连续显示,效果不错!
http://mxhaard.free.fr/spcaserv.html
=======================================================================
还有一个类似:spcacat
http://www.macsat.com/macsat/content/view/36/30/
=======================================================================
德国人做的抓图程序:vgrabbj
http://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:ittleEndian);
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

[此贴子已经被作者于2006-6-5 17:36:50编辑过]

TOP

艾。。。我大学时候的东西也被拿出来了,代码还是乱了点。。。。

注意,这个代码只能用在OV511这一类输出bmp格式的摄像头上。目前市面上占主导地位的中芯微的芯片的摄像头是输出jpeg格式的,不能用这段代码。在PC机器上已经吧中芯微的摄像头用起来了,板子上编译通过,取得图片数据,没显示出来。但是驱动不是很稳定。可能是我做的方法上有些不对。

可以参考这篇文章
http://www.gnome-cn.org/resources/blog/lonestar/blogentry.2005-05-05.6150799324

TOP

感谢deven对这个主题的关注!

顶楼文章都是分别从一些个论坛转载,匆忙之中没有注明作者和出处,抱歉、抱歉...

TOP

    最近又在搞摄像头的东西。被搞死了。。。上述代码在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下用有花斑。这个问题有可能是处理器处理能力的问题,也可能是用了多线程以后的问题,因为原先花斑没这么多。

    立宇太的工程师不知道有没有遇到这个问题。。。

TOP

设信号量,同步线程.

TOP

发新话题