📄 mainfrm.cpp
字号:
{
CDC *pDC = NULL;
CView *pView = NULL;
LOGPALETTE *pLGPal = NULL;
BYTE Palbuf[2048];
int i = 0;
pDC = GetDC();
if (pDC != NULL) {
m_nScreenWidth = pDC->GetDeviceCaps(HORZRES);
m_nScreenHeight = pDC->GetDeviceCaps(VERTRES);
m_nScreenBits = pDC->GetDeviceCaps(PLANES) * pDC->GetDeviceCaps(BITSPIXEL);
pLGPal = (LOGPALETTE *)Palbuf;
pLGPal->palVersion = 0x300;
pLGPal->palNumEntries = 256;
for (i = 0; i < pLGPal->palNumEntries; i++){
pLGPal->palPalEntry[i].peRed = (BYTE)i + 10;
pLGPal->palPalEntry[i].peGreen = (BYTE)i + 10;
pLGPal->palPalEntry[i].peBlue = (BYTE)i + 10;
pLGPal->palPalEntry[i].peFlags = 0; //PC_NOCOLLAPSE;
}
m_hPalette = ::CreatePalette(pLGPal);
ReleaseDC(pDC);
pDC = NULL;
}
m_pBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
m_pBmpInfo->bmiHeader.biWidth = 0;
m_pBmpInfo->bmiHeader.biHeight = 0;
m_pBmpInfo->bmiHeader.biPlanes = 1;
m_pBmpInfo->bmiHeader.biBitCount = 0;
m_pBmpInfo->bmiHeader.biCompression = BI_RGB;
m_pBmpInfo->bmiHeader.biSizeImage = 0;
m_pBmpInfo->bmiHeader.biXPelsPerMeter = 0;
m_pBmpInfo->bmiHeader.biYPelsPerMeter = 0;
m_pBmpInfo->bmiHeader.biClrUsed = 0;
m_pBmpInfo->bmiHeader.biClrImportant = 0;
for (i = 0; i < 256; i++){
m_pBmpInfo->bmiColors[i].rgbBlue = (BYTE)i;
m_pBmpInfo->bmiColors[i].rgbGreen = (BYTE)i;
m_pBmpInfo->bmiColors[i].rgbRed = (BYTE)i;
m_pBmpInfo->bmiColors[i].rgbReserved = 0;
}
}
void CMainFrame::InitHVDevice()
{
if(m_hhv == NULL) return;
//get the max size of the output window
int nBuffSize = 0;
HVSTATUS status = HVGetDeviceInfo(m_hhv, DESC_RESOLUTION, NULL,&nBuffSize);
if( !HV_SUCCESS(status))
return;
BYTE *pbContext = new BYTE[nBuffSize];
DWORD *pdContext = (DWORD *)(pbContext);
status = HVGetDeviceInfo(m_hhv, DESC_RESOLUTION, pdContext,&nBuffSize);
m_nMaxWidth = *(pdContext + 2 * m_Resolution);
m_nMaxHeight = *(pdContext + 2* m_Resolution + 1);
int nMaxWidMd0 = *(pdContext + 2*RES_MODE0);
int nMaxHeiMd0 = *(pdContext + 2*RES_MODE0 +1);
delete []pbContext;
int size = sizeof(HVTYPE);
HVTYPE type;
HVGetDeviceInfo(m_hhv,DESC_DEVICE_TYPE, &type, &size);
if(type == HV2001UCTYPE || type == HV1301UCTYPE)
{
m_bIsSnapSpeedSprted = TRUE; //本摄像机是否支持设置采集速度
m_bIsBlkSizeSprted = TRUE; //本摄像机是否支持设置取得消隐取值范围
}
HVSetResolution(m_hhv, m_Resolution);
HVSetSnapMode(m_hhv, m_SnapMode);
HVSetOutputWindow(m_hhv, 0, 0, m_nMaxWidth, m_nMaxHeight);
if(m_bIsSnapSpeedSprted)
HVSetSnapSpeed(m_hhv,m_SnapSpeed);
HVSetBlanking(m_hhv,m_nHBlanking,m_nVBlanking);
for (int i = 0; i < 4; i++){
HVAGCControl(m_hhv, RED_CHANNEL + i, m_lGain[i]);
}
//设置曝光时间
SetExposureTime(m_nMaxWidth,m_lTintUpper,m_lTintLower);
HVADCControl(m_hhv, ADC_BITS, m_lADCLevel);
//初始化查找表
SetLutTable(m_dRatioR,m_dRatioG,m_dRatioB);
//allocate the memeor accord to the resolution fo RES_MODE0
m_pImageBuffer = new BYTE[nMaxWidMd0 * nMaxHeiMd0 * 3];
if (m_pImageBuffer) {
FillMemory(m_pImageBuffer, nMaxWidMd0 * nMaxHeiMd0 * 3, 0xff);
}
m_pRawBuffer = new BYTE[nMaxWidMd0 * nMaxHeiMd0 ];
if (m_pRawBuffer) {
FillMemory(m_pRawBuffer, nMaxWidMd0 * nMaxHeiMd0 , 0xff);
}
m_pPatternBuf = new int [nMaxWidMd0 * nMaxHeiMd0 ];
if (m_pPatternBuf) {
FillMemory(m_pPatternBuf, nMaxWidMd0 * nMaxHeiMd0*sizeof(int) , 0x00);
}
m_pBadPixelBuf = new BYTE[nMaxWidMd0 * nMaxHeiMd0 ];
if (m_pBadPixelBuf) {
FillMemory(m_pBadPixelBuf, nMaxWidMd0 * nMaxHeiMd0 , 0xff);
}
}
//根据卡的其他参数设置曝光时间
//其他的参数如摄像机时钟频率,消隐值都取默认值,
//参数:
//nWindWidth:当前图像宽度
//lTintUpper:曝光时间的分子, lTintUpper/lTintLower 组成实际的曝光时间
//lTintLower:曝光时间的分母,lTintUpper/lTintLower 组成实际的曝光时间
void CMainFrame::SetExposureTime(int nWindWidth,long lTintUpper,long lTintLower)
{
int size = sizeof(HVTYPE);
HVTYPE type;
HVGetDeviceInfo(m_hhv,DESC_DEVICE_TYPE, &type, &size);
//When outputwindow changes, change the exposure
//请参考曝光系数转换公式
long lClockFreq = (m_SnapSpeed == HIGH_SPEED)? 24000000:12000000;
int nOutputWid = nWindWidth;
double dExposure = 0.0;
double dTint = max((double)lTintUpper/(double)lTintLower,MY_ZERO);
if(type == HV1300UCTYPE || type == HV1301UCTYPE)
{
if(type == HV1300UCTYPE)
lClockFreq = 24000000; //HV1300UCTYPE 暂不支持更改摄像机时钟频率
long lTb = m_nHBlanking;
lTb -= 10;
if(lTb <= 0) lTb =0;
dExposure = (dTint* lClockFreq + 180.0)/((double)nOutputWid + 244.0 + lTb);
}
else
{
if(type == HV2000UCTYPE)
lClockFreq = 24000000; //HV1300UCTYPE 暂不支持更改摄像机时钟频率
long lTb = m_nHBlanking;
lTb += 36;
if(lTb <= 0) lTb =0;
dExposure = (dTint* lClockFreq + 180.0)/((double)nOutputWid + 305.0 + lTb) + 1;
}
if (dExposure > 16383)
dExposure = 16383;
HVAECControl(m_hhv, AEC_EXPOSURE_TIME, (long)dExposure);
}
//设置行消隐和场消隐,
//因为这个时候会影响曝光时间,所以同时要设置曝光时间
void CMainFrame::SetBlanking(int nHBlanking,int nVBlanking)
{
DWORD pBlankSize[4];
int nBufSize = 0;
int nHmin = -9;
int nVmin = -9;
int nHmax = 1930;
int nVmax = 1930;
if(m_bIsBlkSizeSprted)
{
HVGetDeviceInfo(m_hhv,DESC_DEVICE_BLANKSIZE,NULL,&nBufSize);
HVGetDeviceInfo(m_hhv,DESC_DEVICE_BLANKSIZE,pBlankSize,&nBufSize);
//得到消隐的边界值
nHmin = (int)pBlankSize[0];
nVmin = (int)pBlankSize[1];
nHmax = (int)pBlankSize[2];
nVmax = (int)pBlankSize[3];
}
nHBlanking = max(min(nHmax,nHBlanking),nHmin);
nVBlanking = max(min(nVmax,nVBlanking),nVmin);
m_nHBlanking = nHBlanking;
m_nVBlanking = nVBlanking;
HVSetBlanking(m_hhv,nHBlanking,nVBlanking);
SetExposureTime(GetOutputWinWdith(),m_lTintUpper,m_lTintLower);
}
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
InitParamFromINI();
InitSystemInfo();
//如果是黑白图像,需要创建查找表的映射文件
if(m_ImageMode == HV_BW && m_pLutMapping == NULL)
{
char lpStrExePath[MAX_PATH];
GetModuleFileName(NULL,lpStrExePath,MAX_PATH);
CString strPath = CString(lpStrExePath);
CString m_strFilePath = strPath.Left(strPath.ReverseFind('\\')) + "\\YUVLut.dat";
m_pLutMapping = CreateLutMapFile(m_strFilePath);
}
HVSTATUS status = BeginHVDevice(1, &m_hhv);
HV_MESSAGE(status);
if (HV_SUCCESS(status)){
InitHVDevice();
}
HVTYPE type;
int nSize = sizeof(HVTYPE);
status = HVGetDeviceInfo(m_hhv, DESC_DEVICE_TYPE, &type,&nSize);
if ( ! HV_SUCCESS(status)) {
m_strDeviceType = "HVDevice";
}
else{
switch(type) {
case HV1300UCTYPE:
m_strDeviceType = "HV1300UC";
break;
case HV2000UCTYPE:
m_strDeviceType = "HV2000UC";
break;
case HV1301UCTYPE:
m_strDeviceType = "HV1301UC";
break;
default:
break;
}
}
return 0;
}
void CMainFrame::OnClose()
{
// TODO: Add your message handler code here and/or call default
if (m_bSnapping) {
SendMessage(WM_COMMAND, ID_VIEW_SNAP);
}
SaveParamToINI();
EndHVDevice(m_hhv);
CFrameWnd::OnClose();
}
void CMainFrame::OnViewColor()
{
// TODO: Add your command handler code here
m_ImageMode = HV_COLOR;
}
void CMainFrame::OnUpdateViewColor(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck( m_ImageMode == HV_COLOR);
}
void CMainFrame::OnViewBw()
{
// TODO: Add your command handler code here
m_ImageMode = HV_BW;
if(m_pLutMapping == NULL)
{
char lpStrExePath[MAX_PATH];
GetModuleFileName(NULL,lpStrExePath,MAX_PATH);
CString strPath = CString(lpStrExePath);
CString m_strFilePath = strPath.Left(strPath.ReverseFind('\\')) + "\\YUVLut.dat";
m_pLutMapping = CreateLutMapFile(m_strFilePath);
}
}
void CMainFrame::OnUpdateViewBw(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck( m_ImageMode == HV_BW);
}
void CMainFrame::OnViewConversionBg()
{
// TODO: Add your command handler code here
m_Layout = BAYER_BG;
}
void CMainFrame::OnUpdateViewConversionBg(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck( m_Layout == BAYER_BG);
}
void CMainFrame::OnViewConversionGb()
{
// TODO: Add your command handler code here
m_Layout = BAYER_GB;
}
void CMainFrame::OnUpdateViewConversionGb(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_Layout == BAYER_GB);
}
void CMainFrame::OnViewConversionGr()
{
// TODO: Add your command handler code here
m_Layout = BAYER_GR;
}
void CMainFrame::OnUpdateViewConversionGr(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_Layout == BAYER_GR);
}
void CMainFrame::OnViewConversionRg()
{
// TODO: Add your command handler code here
m_Layout = BAYER_RG;
}
void CMainFrame::OnUpdateViewConversionRg(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_Layout == BAYER_RG);
}
void CMainFrame::OnViewAdjust()
{
// TODO: Add your command handler code here
CAdjustDlg dlg;
if (dlg.DoModal() == IDOK){
}
}
void CMainFrame::OnViewSnap()
{
// TODO: Add your command handler code here
HVSTATUS status = STATUS_OK;
if (m_bSnapping) {
status = HVCloseSnap(m_hhv);
m_bSnapping = FALSE;
Invalidate(TRUE);
}
else{
if(m_pImageBuffer && m_pRawBuffer){
HVSTATUS status = HVOpenSnap(m_hhv, SnapCallback, this);
if (HV_SUCCESS(status)) {
//只定义一个缓冲区,
BYTE * ppBuffer[1];
ppBuffer[0] = m_pRawBuffer;
status = HVStartSnap(m_hhv,ppBuffer, 1);
if ( ! HV_SUCCESS(status))
{
HVCloseSnap(m_hhv);
}
else{
m_bSnapping = TRUE;
m_dwStart = ::GetTickCount();
m_dwCount = 0;
}
}
HV_MESSAGE(status);
}
}
}
void CMainFrame::OnUpdateViewSnap(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetCheck(m_bSnapping);
}
int CALLBACK CMainFrame::SnapCallback(HV_SNAP_INFO *pInfo)
{
CMainFrame *pFrame = (CMainFrame *)(pInfo->pParam);
ASSERT(pFrame);
pFrame->SendMessage(WM_CHANGE_SNAP, 0, 0);
return 1;
}
LRESULT CMainFrame::OnSnapMessage(WPARAM wParam, LPARAM lParam)
{
float fps = 0;
CString strTitle;
ShowImage();
m_dwCount++;
fps = (float)(m_dwCount * 1000) / (::GetTickCount() - m_dwStart + 1);
strTitle.Format("%s Viewer [%d x %d] %f(fps)", m_strDeviceType,
m_pBmpInfo->bmiHeader.biWidth, m_pBmpInfo->bmiHeader.biHeight, fps);
SetWindowText(strTitle);
return 1;
}
void CMainFrame::DecodeImage()
{
if (m_ImageMode == HV_COLOR) {
m_pBmpInfo->bmiHeader.biBitCount = 24;
CSize Size;
Size.cx = m_pBmpInfo->bmiHeader.biWidth;
Size.cy = m_pBmpInfo->bmiHeader.biHeight;
//每两帧处理一次
if(m_ConversionType != BAYER2RGB_NEIGHBOUR)
{
static int nTemp = 1;
if(nTemp%2 ==0 )
{
nTemp =1;
return;
}
else
nTemp = 2;
}
if(m_bIsToGetBadPixel)
{
DetectDeadPixel(m_pRawBuffer,m_pBadPixelBuf,m_nMaxWidth,m_nMaxHeight);
m_bIsToGetBadPixel = FALSE;
/*得到坏点位置后,恢复原来采集窗口*/
//在设置输出窗口前,停止采集
if (m_bSnapping)
{
HVStopSnap(m_hhv);
}
HVSTATUS status = HVSetOutputWindow(m_hhv,
m_rcOutputWindow.left,
m_rcOutputWindow.top,
m_rcOutputWindow.Width(),
m_rcOutputWindow.Height()
);
//在设置输出窗口后,开始采集
if (m_bSnapping)
{
//只定义一个缓冲区,
BYTE * ppBuffer[1];
ppBuffer[0] = m_pRawBuffer;
status = HVStartSnap(m_hhv,ppBuffer,1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -