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

📄 hvstorebmpdlg.cpp

📁 Led识别与统计系统,基于DELPHI 7.0下
💻 CPP
字号:
// HVStoreBmpDlg.cpp : implementation file
//

#include "stdafx.h"
#include "HVStoreBmp.h"
#include "HVStoreBmpDlg.h"

#include "..\..\inc\HVDAILT.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

//定义自己的0
#define  MY_ZERO 0.000000001
#include "..\..\inc\Raw2Rgb.h"


//const
const int DeviceNum = 1;
const HV_RESOLUTION Resolution = RES_MODE0;
const HV_SNAP_MODE SnapMode = CONTINUATION;
const HV_BAYER_LAYOUT Layout = BAYER_GR;
const HV_BAYER_CONVERT_TYPE ConvertType = BAYER2RGB_NEIGHBOUR;
const long Gain = 8;
const long ExposureTint_Upper = 60;
const long ExposureTint_Lower = 1000;

const long ShutterDelay = 0;
const long ADCLevel = ADC_LEVEL2;
const int XStart = 0;
const int YStart = 0;
const int Width = 800;
const int Height = 600;


/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CHVStoreBmpDlg dialog

CHVStoreBmpDlg::CHVStoreBmpDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CHVStoreBmpDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CHVStoreBmpDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CHVStoreBmpDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CHVStoreBmpDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CHVStoreBmpDlg, CDialog)
	//{{AFX_MSG_MAP(CHVStoreBmpDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(ID_SAVE_BMP, OnSaveBmp)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CHVStoreBmpDlg message handlers

BOOL CHVStoreBmpDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CHVStoreBmpDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CHVStoreBmpDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}



// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CHVStoreBmpDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}




void CHVStoreBmpDlg::OnSaveBmp() 
{
	// TODO: Add your control notification handler code here
	
	HVSTATUS status = STATUS_OK;
	HHV hhv = NULL;

	/*
	 *	初始化所有成员变量,同时打开数字摄像机
	 */

	//	打开数字摄像机 1,返回状态值
	status = BeginHVDevice(DeviceNum, &hhv);
	//	检验函数执行状态,如果失败,则返回错误状态消息框
	HV_VERIFY(status);

	
	/*
	 *	初始化数字摄像机硬件状态,用户也可以在其他位置初始化数字摄像机,
	 *	但应保证数字摄像机已经打开,建议用户在应用程序初始化时,
	 *	同时初始化数字摄像机硬件。
	 */

	//	设置数字摄像机分辨率
	HVSetResolution(hhv, Resolution);		

	//	采集模式,包括 CONTINUATION(连续)、TRIGGER(外触发)
	HVSetSnapMode(hhv, SnapMode);

	//  设置各个分量的增益
	for (int i = 0; i < 4; i++){
		HVAGCControl(hhv, RED_CHANNEL + i, Gain);
	}
	
	//	设置曝光时间
	SetExposureTime(hhv,Width,ExposureTint_Upper,ExposureTint_Lower);
	//  设置ADC的级别
	HVADCControl(hhv, ADC_BITS, ADCLevel);
	
	/*
	 *	视频输出窗口,即视频输出范围,输出窗口取值范围必须在输入窗口范围以内,
	 *  视频窗口左上角X坐标和窗口宽度应为4的倍数,左上角Y坐标和窗口高度应为2的倍数
	 *	输出窗口的起始位置一般设置为(0, 0)即可。
	 */
	HVSetOutputWindow(hhv, XStart, YStart, Width, Height);

	/*
	 *	分配原始图像缓冲区,一般用来存储采集图像原始数据
	 *  一般图像缓冲区大小由输出窗口大小和视频格式确定。
	 */
	BYTE *pRawBuffer = new BYTE[Width * Height];
	ASSERT(pRawBuffer);

	/*
		分配Bayer转换后图像数据缓冲
	*/
	BYTE *pImageBuffer = new BYTE[Width * Height * 3];
	ASSERT(pImageBuffer);

	//	分配BITMAPINFO缓冲 
	BYTE *pInfoBuffer = new BYTE[sizeof(BITMAPINFO)];
	ASSERT(pInfoBuffer);

	/*
	 *	初始化BITMAPINFO 结构,此结构在保存bmp文件、显示采集图像时使用
	 */
	//	m_pBmpInfo即指向m_chBmpBuf缓冲区,用户可以自己分配BTIMAPINFO缓冲区	
	BITMAPINFO *pBmpInfo				= (BITMAPINFO *)pInfoBuffer;	
	pBmpInfo->bmiHeader.biSize			= sizeof(BITMAPINFOHEADER);
	// 	图像宽度,一般为输出窗口宽度
	pBmpInfo->bmiHeader.biWidth			= Width;
	//	图像宽度,一般为输出窗口高度
	pBmpInfo->bmiHeader.biHeight		= Height;
	//	图像位深度,数字摄像机采集的原始数据为8位,Bayer转换后为24位
	pBmpInfo->bmiHeader.biBitCount		= 24;
	//	以下设置一般相同,对于低于8位的位图,还应设置相应的位图调色板
	pBmpInfo->bmiHeader.biPlanes		= 1;
	pBmpInfo->bmiHeader.biCompression	= BI_RGB;
	pBmpInfo->bmiHeader.biSizeImage		= 0;
	pBmpInfo->bmiHeader.biXPelsPerMeter	= 0;
	pBmpInfo->bmiHeader.biYPelsPerMeter	= 0;
	pBmpInfo->bmiHeader.biClrUsed		= 0;
	pBmpInfo->bmiHeader.biClrImportant	= 0;
		
	// 	采集1帧图像到内存,采集完成后停止
	BYTE *ppBuf[1];
	ppBuf[0] = pRawBuffer;
	status = HVSnapShot(hhv, ppBuf,1);
	HV_VERIFY(status);

	if (HV_SUCCESS(status)) {
		//	将原始图像数据进行Bayer转换,转换后为24位。
		//同时将原始数据进行上下翻转

		//颜色查找表
		BYTE pLutR[256] ;
		BYTE pLutG[256] ;
		BYTE pLutB[256] ;
		for(int i=0;i<256;i++)
		{
			pLutR[i] = i;
			pLutG[i] = i;
			pLutB[i] = i;
		}		
		ConvertBayer2Rgb(pImageBuffer,pRawBuffer,Width,Height,ConvertType,pLutR,pLutG,pLutB,true,Layout);
		
		/*	
		 *	以下保存BMP文件设置基本相同
		 */
		CFileDialog dlg(FALSE , "*.bmp", NULL ,OFN_OVERWRITEPROMPT|OFN_HIDEREADONLY, "Bitmap Files(*.bmp)|*.bmp", this);
		if (dlg.DoModal() == IDOK) {
			BITMAPFILEHEADER bfh	= {0};
			DWORD dwImageSize		= 0;
			DWORD dwBytesRead		= 0;
			BOOL bRVal				= TRUE;

			dwImageSize		=  Width * Height * 3;	//计算图像大小,由视频输出窗口和视频格式确定

			bfh.bfType		= (WORD)'M' << 8 | 'B';			//定义文件类型
			bfh.bfOffBits	= sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);	//定义文件头大小

			bfh.bfSize		= bfh.bfOffBits + dwImageSize;		//文件大小

			HANDLE hFile = ::CreateFile(dlg.GetPathName(),
										GENERIC_WRITE ,
										0,
										NULL,
										CREATE_ALWAYS,														FILE_ATTRIBUTE_NORMAL,
										NULL
										);
			if (hFile == INVALID_HANDLE_VALUE) {
				bRVal = FALSE;
			}
			else{
				::WriteFile(hFile, &bfh, sizeof(BITMAPFILEHEADER), &dwBytesRead, NULL );
				::WriteFile(hFile, pBmpInfo, sizeof(BITMAPINFOHEADER), &dwBytesRead, NULL );
				::WriteFile(hFile, pImageBuffer, dwImageSize, &dwBytesRead, NULL );
				
				CloseHandle(hFile);
			}
		}
	}

	delete []pRawBuffer;	
	delete []pImageBuffer;	
	delete []pInfoBuffer;

	//	关闭数字摄像机1
	status = EndHVDevice(hhv);
	HV_VERIFY(status);
	
}
//根据卡的其他参数设置曝光时间
//其他的参数如摄像机时钟频率,消隐值都取默认值,
//参数:
//nWindWidth:当前图像宽度
//lTintUpper:曝光时间的分子, lTintUpper/lTintLower 组成实际的曝光时间
//lTintLower:曝光时间的分母,lTintUpper/lTintLower 组成实际的曝光时间
void CHVStoreBmpDlg::SetExposureTime(HHV hhv,int nWindWidth,long lTintUpper,long lTintLower)
{
	int size = sizeof(HVTYPE);
	HVTYPE type;
	HVGetDeviceInfo(hhv,DESC_DEVICE_TYPE, &type, &size);	
	
	//When outputwindow changes, change the exposure 
	//请参考曝光系数转换公式
	long lClockFreq = 24000000; 
	int nOutputWid = nWindWidth;
	double dExposure = 0.0;
	double dTint = max((double)lTintUpper/(double)lTintLower,MY_ZERO);
	if(type == HV1300UCTYPE || type == HV1301UCTYPE)	
	{
		long lTb = 0;
		dExposure = (dTint* lClockFreq + 180.0)/((double)nOutputWid + 244.0 + lTb);
	}
	else
	{		
		long lTb = 0;
		dExposure = (dTint* lClockFreq + 180.0)/((double)nOutputWid + 305.0 + lTb) + 1 ;
	}
	
	if (dExposure > 16383) 
		dExposure = 16383;
	HVAECControl(hhv, AEC_EXPOSURE_TIME, (long)dExposure);
	
}

⌨️ 快捷键说明

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