首页
社区
课程
招聘
[旧帖] [求助]C语言写一个摄像头拍照的程序遇挫 0.00雪花
发表于: 2012-5-19 10:14 1721

[旧帖] [求助]C语言写一个摄像头拍照的程序遇挫 0.00雪花

2012-5-19 10:14
1721
想用C语言写一个摄像头拍照的程序遇挫,不知道各位高手有没有写过类此的程序,给小弟提供个思路,或者源码都可以。
就一个功能:摄像头拍下一张相片保存下来
用OpenCV写的,移植到别人的电脑上就不能执行了,怎么回事???难道还少东西么

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 0
支持
分享
最新回复 (9)
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
过来支持了,,呵呵
2012-5-19 14:46
0
雪    币: 44
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
头文件
#ifndef _VIDEOCAP_H
#define _VIDEOCAP_H

#include <Vfw.h>
#include <Windows.h>

#pragma comment(lib,"vfw32.lib")

class CVideoCap
{
public:
	CVideoCap();
	~CVideoCap();

public:
	//初始化设备
	BOOL			 Initialize();	
	BOOL			 IsWebCam();
	//获取每帧图像DIB格式
	LPBYTE			 GetDIB( LPCTSTR lpPath );
	void			 YUV2_RGB( BYTE *YUV2buff, BYTE *RGBbuff, DWORD dwYUVSize );
	BITMAPINFOHEADER *Getbmi();
	static LRESULT CALLBACK capErrorCallback( HWND hWnd, int nID, LPCTSTR lpsz );
	static LRESULT CALLBACK FrameCallbackProc( HWND hWnd, LPVIDEOHDR lpVHdr );
public:
	BOOL		m_bIsConnected;
	BOOL		m_bIsCapture;
	BITMAPINFO	*m_lpbmi;
	LPBYTE		m_lpDIB;
	HWND		m_hWnd;
	HWND		m_hWndCap;
	LPCTSTR		m_Path;
	BOOL		m_bInit;
};

#endif	//end of VideoCap.h


源文件
#include "stdafx.h"
#include "VideoCap.h"

///*********************************** format char to int ***********************************/
//	for ( int i = 0; i < 8; i ++ )
//	{
//		if ( yuv[in +i] >= '0' && yuv[in + i] <= '9' )
//		{
//			yuv[in + i] = yuv[in + i] - '0'; 
//		}
//		else
//		{
//			yuv[in + i] = (yuv[in + i] - 'a') + 10;
//		}
//	}
//
///*********************************** format int to char ***********************************/
//	for ( int i = 0; i < 3; i++ )
//	{
//		if ( ((pixed_24[i] / 16) >= 0) && ((pixed_24[i] / 16) <= 9) )
//			rgb[OUT++] = pixed_24[i] / 16 + '0';
//		else
//			rgb[OUT++] = pixed_24[i] / 16 - 10 + 'a';
//
//		if ( ((pixed_24[i] % 16) >= 16) && pixed_24[i] % 16 <= 9 )
//			rgb[OUT++] = pixed_24[i] % 16 + '0';
//		else
//			rgb[OUT++] = pixed_24[i] % 16 - 10 + 'a';
//	}


//注意RGB的缓冲区得是YUV2的1.5倍,因为一个YUV2包含两个像素, 所以需要两个RGB像素表示
void CVideoCap::YUV2_RGB( BYTE *YUY2buff, BYTE *RGBbuff, DWORD dwYUVSize )
{	
	//整型算法
	//	要用整型运算代替浮点运算,当然是要用移位的办法了,我们可以很容易得到下列算法:

	//u = YUVdata[UPOS] - 128;
	//v = YUVdata[VPOS] - 128;

	//rdif = v + ((v * 103) >> 8);
	//invgdif = ((u * 88) >> 8) +((v * 183) >> 8);
	//bdif = u +( (u*198) >> 8);

	//r = YUVdata[YPOS] + rdif;
	//g = YUVdata[YPOS] - invgdif;
	//b = YUVdata[YPOS] + bdif;


	int R, G, B;
	int Y, U, Y1, V;
	int rdif, invgdif, bdif;

	BYTE *poriYUV2buff = YUY2buff;
	BYTE *poriRGBbuff = RGBbuff;

	DWORD	pos = 0;
	for ( DWORD j = 0; j < dwYUVSize; j += 4 )
	{
		//1. 获取Y U V 数值, 
		//YUV2格式的排列是Y0,V0,Y1,U0,  Y2,V2,Y3,U2 

		Y  = *(YUY2buff++);
		U  = *(YUY2buff++);
		Y1 = *(YUY2buff++);
		V  = *(YUY2buff++);

		//2. 计算 R G B 值
		U -= 128;
		V -= 128;

		rdif	= V + ((V * 103) >> 8);
		invgdif = ((U * 88) >> 8) + ((V * 183) >> 8);
		bdif	= U +( (U * 198) >> 8);

		R = Y + rdif;
		G = Y - invgdif;
		B = Y + bdif;


		//3. 溢出处理
		if ( R > 255 )  R = 255; if ( R < 0 ) R = 0;
		if ( G > 255 )  G = 255; if ( G < 0 ) G = 0;
		if ( B > 255 )  B = 255; if ( B < 0 ) B = 0;


		//4. 输出 R G B
		*(RGBbuff++) = (byte)R;
		*(RGBbuff++) = (byte)G;
		*(RGBbuff++) = (byte)B;

		*(RGBbuff++) = (byte)R;
		*(RGBbuff++) = (byte)G;
		*(RGBbuff++) = (byte)B;
	}

	YUY2buff = poriYUV2buff;
	RGBbuff = poriRGBbuff;
}


CVideoCap::CVideoCap()
{
	m_bInit = FALSE;
	m_bIsConnected = FALSE;
	m_bIsCapture = FALSE;
	m_lpbmi = NULL;
	m_lpDIB = NULL;

	if ( ! IsWebCam() || m_bIsConnected )
		return;
	m_hWnd = CreateWindow( _T("#32770"), _T(""), WS_POPUP, 0, 0, 0, 0, NULL, NULL, NULL, NULL );
	m_hWndCap = capCreateCaptureWindow( 
		_T("CVideoCap"),
		WS_CHILD | WS_VISIBLE,
		0,
		0,
		0,
		0,
		m_hWnd,
		0);
}

CVideoCap::~CVideoCap()
{
	if ( m_bIsConnected )
	{
		capCaptureAbort( m_hWndCap );
		capSetCallbackOnError( m_hWndCap, NULL );
		capSetCallbackOnFrame( m_hWndCap, NULL );
		capDriverDisconnect( m_hWndCap );

		if ( m_lpbmi )
			delete [] m_lpbmi;
		if ( m_lpDIB )
			delete [] m_lpDIB;
		m_bIsConnected = FALSE;
	}
	CloseWindow( m_hWnd );
	CloseWindow( m_hWndCap );
}

LRESULT CALLBACK CVideoCap::capErrorCallback( HWND hWnd, int nID, LPCTSTR lpsz )
{
	return -1;
}

LRESULT CALLBACK CVideoCap::FrameCallbackProc( HWND hWnd, LPVIDEOHDR lpVHdr )
{
	try
	{
		CVideoCap *pThis = (CVideoCap *)capGetUserData( hWnd );
		if ( pThis != NULL )
		{
			memcpy( pThis->m_lpDIB, lpVHdr->lpData, pThis->m_lpbmi->bmiHeader.biSizeImage );
			InterlockedExchange( (LPLONG)&(pThis->m_bIsCapture), FALSE );
			
			if ( pThis->m_Path != NULL )
				capFileSaveDIB( hWnd, pThis->m_Path );
		}
	}
	catch(...){}
	return 0;
}

BOOL CVideoCap::IsWebCam()
{
	if ( m_bIsConnected )
		return FALSE;

	BOOL bRet = FALSE;

	char lpszName[100], lpszVer[50];
	for ( int i = 0; i < 10 && !bRet; i++ )
	{
		bRet = capGetDriverDescription( i, lpszName, sizeof(lpszName), lpszVer, sizeof(lpszVer) );
	}
	return bRet;
}

LPBYTE CVideoCap::GetDIB( LPCTSTR lpPath )
{
	if ( lpPath != NULL )
		m_Path = lpPath;
	if ( !m_bInit )
	{
		Initialize();
	}

	m_bIsCapture = TRUE;
	capGrabFrameNoStop( m_hWndCap );
	while( m_bIsCapture == TRUE )
		Sleep( 100 );

	return m_lpDIB;
}

BITMAPINFOHEADER *CVideoCap::Getbmi()
{
	return &(m_lpbmi->bmiHeader);
}

BOOL CVideoCap::Initialize()
{
	//CAPTUREPARMS	gCapTureParms;
	CAPDRIVERCAPS	gCapDriverCaps;
	DWORD			dwSize;

	if ( !IsWebCam() )
		return FALSE;

	int i;
	for ( i = 0; i < 10; i++ )
	{
		if ( capDriverConnect( m_hWndCap, i ) )
			break;
	}
	if ( i == 10 )
		return FALSE;

	dwSize = capGetVideoFormatSize( m_hWndCap );
	capSetUserData( m_hWndCap, this );
	
	capSetCallbackOnError( m_hWndCap, capErrorCallback );
	if ( ! capSetCallbackOnFrame( m_hWndCap, FrameCallbackProc ) )
	{
		return FALSE;
	}
	m_lpbmi = (BITMAPINFO *)new BYTE[dwSize];

	capGetVideoFormat( m_hWndCap, m_lpbmi, dwSize );
	m_lpDIB = new BYTE[m_lpbmi->bmiHeader.biSizeImage];

	capDriverGetCaps( m_hWndCap, &gCapDriverCaps, sizeof(CAPDRIVERCAPS) );

	capOverlay( m_hWndCap, FALSE );
	capPreview( m_hWndCap, TRUE );
	capPreviewScale( m_hWndCap, FALSE );

	m_bIsConnected = TRUE;

	m_bInit = TRUE;
	return TRUE;
}
2012-5-19 16:27
0
雪    币: 8
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
啊,原来出了ffmpeg,还有vfw库啊!
2012-5-19 20:20
0
雪    币: 47
活跃值: (31)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
也可以试试OpenCV啊
2012-5-19 22:03
0
雪    币: 239
活跃值: (41)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
大侠,我想用C语言,而不是C++,可否用C语言写一个呢
2012-5-20 01:15
0
雪    币: 239
活跃值: (41)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
想过用OpenCV,可是不知道从何下手啊,今天还有一天,再做不出来就得换程序啦!!!
2012-5-20 01:17
0
雪    币: 44
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
把类名去掉就是C的了,难道你没看出来吗?我把函数放在类里只是为了方便管理。代码都是C风格的,没有用到C++特性。
2012-5-20 07:28
0
雪    币: 239
活跃值: (41)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
可是我看着好像有继承啊,C里面应该没继承吧,可否把修改好的C代码给出来呢
2012-5-20 11:35
0
雪    币: 44
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
哪有继承?我就是把API封装了下。
2012-5-20 13:13
0
游客
登录 | 注册 方可回帖
返回
//