⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gtk_cam.c

📁 gtk实现的图像采集的示例程序。
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <strings.h>#include <stdio.h>#include <unistd.h>#include <sys/types.h>#include <sys/mman.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/ioctl.h>#include <time.h>#include <gtk/gtk.h>#include <errno.h>#include <stdlib.h>#include "grab-ng.h"#include "dh-ioctl.h"//#define __YUV422_CAP__    //采用YUV格式采集int TOP = 0, LEFT = 0; //窗体起始坐标int COLS = 768, ROWS = 288;  //采集窗体的大小int frame = 0;int send_num = 0;int bt8x8_handle = 0; //设备句柄unsigned char *card0_buf = NULL;  //硬件采集到的原始图像数据指针unsigned char *card0_dest_buf = NULL; //经过格式转换后的图像数据指针char title[256];int g_err_num = 0;int global_frames = 0;  //用来计算FPSint capture_flag = 0;  //preview采集控制参数int overlay_flag = 0; //overlay采集控制参数int b_current = 0, c_current = 0, s_current = 0, h_current = 0; //用来存取图像亮度对比度等参数GtkObject *b_adj, *c_adj, *s_adj, *h_adj;time_t stTime;GtkWidget *main_win;GtkWidget *status;GtkWidget *darea;GtkWidget *label;gdouble gtk_adjustment_get_value (GtkAdjustment * adjustment);int send_expose (void);void on_darea_expose (GtkWidget * widget);gint configure_event (GtkWidget * widget);static void overlay_display (void);//打开设备void open_dev (void){	int rc;	card0_dest_buf = (unsigned char *) malloc (768 * 576 * 3); //申请存放处理后图像数据的内存空间	bt8x8_handle = dh_OpenVideo (0); //打开设备	if (bt8x8_handle < 0)	{		printf (dh_GetErrInfo ());		free (card0_dest_buf);		exit (-1);	}#ifdef	__YUV422_CAP__	rc = dh_MSetCaptureNorm (bt8x8_handle, COLS, ROWS, VIDEO_YUYV); //YUV格式采集#else	rc = dh_MSetCaptureNorm (bt8x8_handle, COLS, ROWS, VIDEO_BGR24); //BGR格式采集#endif	if (rc < 0)	{		printf (dh_GetErrInfo ());	}	if (dh_SetVideoSource (bt8x8_handle, VIDEO_SOURCE_COMPOSITE0) < 0)	//设置源路为复合视频1	{		printf (dh_GetErrInfo ());	}	if (dh_SetVideoStandard (bt8x8_handle, VIDEO_MODE_PAL) < 0)	//设置源路制式为PAL制	{		printf (dh_GetErrInfo ());	}//default value	dh_SetBrightness (bt8x8_handle, 65535 / 2);	dh_SetContrast (bt8x8_handle, 65535 / 2);	dh_SetSaturation (bt8x8_handle, 65535 / 2);	dh_SetHue (bt8x8_handle, 65535 / 2);}/*---------------------------菜单要调用的函数(callback)---------------------------------*///菜单项preview要调用的函数static void preview_display (void){	time (&stTime);	g_err_num = 0;		//采集之前判断是否有视频信号输入	if (!dh_IsVideoOn (bt8x8_handle))	{		printf ("Video source not ready.\n");		return;	}		//如果正在overlay采集,先停止overlay采集	if (overlay_flag)		overlay_display ();		//由capture_flag判断开始采集还是停止采集	if (capture_flag == 0)	{		capture_flag = 1;		//如果窗体大小变化,每次采集前得重新设置采集参数#ifdef	__YUV422_CAP__		dh_MSetCaptureNorm (bt8x8_handle, COLS, ROWS, VIDEO_YUYV);#else		dh_MSetCaptureNorm (bt8x8_handle, COLS, ROWS, VIDEO_BGR24);#endif		dh_MStartCapture (bt8x8_handle, 4); //发往内存循环采集命令,使用4个缓冲区		gtk_timeout_add (10, (GtkFunction) send_expose, NULL); //每10秒调用一次函数send_expose()	}	else	{		capture_flag = 0;		dh_MStopCapture (bt8x8_handle); //停止往内存循环采集	}}//定时器调用的函数,实现连续采集显示int send_expose (void){	if (capture_flag == 1)	{		//返回采集完成当前帧的指针,同时发出采集下帧的命令		card0_buf = dh_MGetNextFrame (bt8x8_handle);		if (NULL == card0_buf)		{			printf ("card0_buf is NULL.\n");			//如果采集错误,重启采集			dh_MStopCapture (bt8x8_handle);			dh_MStartCapture (bt8x8_handle, 4);			g_err_num++;		}		else		{			on_darea_expose (darea); //调用此函数实现图像显示			//释放内存,否则循环采集无法进行下去			if (dh_MReleaseBuf (bt8x8_handle) < 0)			{				printf (dh_GetErrInfo ());			}		}	}	return 1;}//菜单项overlay调用的函数:往屏幕采集static voidoverlay_display (void){	int wx, wy;	wx = TOP + 4;	wy = LEFT + 56;		//采集之前判断是否有视频信号输入	if (!dh_IsVideoOn (bt8x8_handle))	{		printf ("Video source not ready.\n");		return;	}		gtk_widget_set_uposition (main_win, TOP, LEFT);	if (overlay_flag == 0)	{		//如果正在preview采集,先停下来		if(capture_flag)		{			capture_flag = 0;			dh_MStopCapture (bt8x8_handle);		}				//开始overlay采集		dh_OStartCapture (bt8x8_handle, COLS, ROWS, wx, wy);		overlay_flag = 1;	}	else	{			//停止overlay采集		dh_OStopCapture (bt8x8_handle);		overlay_flag = 0;	}}//菜单项grab调用的的函数抓单帧static void grab_one_display (void){	int i;	time (&stTime);	g_err_num = 0;		//如果正在preview采集,先停下来	if (capture_flag == 1)		preview_display ();	//stop capture	//如果正在overlay采集,先停下来	if (overlay_flag)		overlay_display ();	//采集之前判断是否有视频信号输入	if (!dh_IsVideoOn (bt8x8_handle))	{		printf ("Video source not ready.\n");		return;	}//for(;;)      //死循环抓单帧采集,用来测试性能	{				card0_buf = dh_MCaptureOne (bt8x8_handle);  //正常抓单帧或单场采集,FPS最高8帧/秒		//card0_buf = dh_MFastCaptureOne(bt8x8_handle);   //快速抓单帧或单场采集,FPS可达到16帧/秒				//dh_MSnapOne(bt8x8_handle);		//card0_buf = dh_MGetSnapOneStatus(bt8x8_handle);				if (NULL == card0_buf)		{			printf (dh_GetErrInfo ());			g_err_num++;		}		else		{			on_darea_expose (darea);   //调用此函数实现图像显示									//释放内存,否则循环采集无法进行下去,如果是快速采集则无需调用此函数			if (dh_MReleaseBuf (bt8x8_handle) < 0)			{				printf (dh_GetErrInfo ());			}		}	}	gtk_statusbar_push (GTK_STATUSBAR (status), 1, "Grab a picture");	g_message ("Grab a picture!\n");}//此函数用来显示图像和计算FPSvoid on_darea_expose (GtkWidget * widget){	static time_t init, end;	static int frames;	if (!frames)	{		time (&init);	}	if (!card0_buf)	{		return;	}	gdk_threads_enter ();		//转换成24位RGB#ifdef __YUV422_CAP__	yuv422_to_rgb24 (card0_dest_buf, card0_buf, COLS * ROWS);#else	redblue_swap (card0_dest_buf, card0_buf, COLS * ROWS);#endif	//显示图像	gdk_draw_rgb_image (widget->window, widget->style->white_gc, 0, 0,			    COLS, ROWS, GDK_RGB_DITHER_NORMAL,			    card0_dest_buf, COLS * 3);	gdk_threads_leave ();	frames++;	time (&end);	if (end - init >= 1)	{		global_frames = frames;		frames = 0;		sprintf (title, "RTime=%d,FPS %d,Err=%d",			 (int) (end - stTime), global_frames, g_err_num);		gtk_statusbar_push (GTK_STATUSBAR (status), 1, title);		fprintf (stderr, "%s\n", title);	}}//退出程序static void exit_program (void){	int rc = 0;	capture_flag = 0;	//退出程序前先释放buf	if (NULL != card0_buf)	{		rc = dh_MReleaseBuf (bt8x8_handle);		if (rc == 0)			card0_buf = NULL;	}	free (card0_dest_buf);	dh_CloseVideo (bt8x8_handle);//关闭设备句柄	gtk_main_quit ();}//菜单项option->SourceInput调用下列函数static void set_ch_video0 (){	dh_SetVideoSource (bt8x8_handle, VIDEO_SOURCE_COMPOSITE0);	g_message ("use VIDEO_SOURCE_COMPOSITE0.\n");}static voidset_ch_video1 (void){	dh_SetVideoSource (bt8x8_handle, VIDEO_SOURCE_COMPOSITE1);	g_message ("use VIDEO_SOURCE_COMPOSITE1.\n");}static voidset_ch_video2 (void){	dh_SetVideoSource (bt8x8_handle, VIDEO_SOURCE_COMPOSITE2);	g_message ("use VIDEO_SOURCE_COMPOSITE2.\n");}static voidset_ch_video3 (void){	dh_SetVideoSource (bt8x8_handle, VIDEO_SOURCE_SVIDEO);	g_message ("use VIDEO_SOURCE_SVIDEO.\n");}//菜单项option->SourceNorm调用下列函数static voidset_norm_pal (void){	dh_SetVideoStandard (bt8x8_handle, VIDEO_MODE_PAL);	g_message ("change source norm to PAL.\n");}static voidset_norm_ntsc (void){	dh_SetVideoStandard (bt8x8_handle, VIDEO_MODE_NTSC);	g_message ("change source norm to NTSC.\n");}static voidset_norm_secam (void){	dh_SetVideoStandard (bt8x8_handle, VIDEO_MODE_SECAM);	g_message ("change source norm to SECAM.\n");}static voidclick_ok (GtkWidget * widget, gpointer window){	dh_GetBrightness (bt8x8_handle, &b_current);	dh_GetContrast (bt8x8_handle, &c_current);	dh_GetSaturation (bt8x8_handle, &s_current);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -