📄 show.cpp
字号:
// Show.cpp : implementation file
//
#include "stdafx.h"
#include "ShowBMP.h"
#include "Show.h"
#include "caminc.hpp"
#include "camio.hpp"
#include "camlink.hpp"
#include "MyModemDlg.h"
#pragma comment(lib,"camlink.lib")
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CShow
DWORD dwCounts,dwSlot;
BOOL Flag;
BOOL m_FireSignal;
CShow::CShow()
{
Flag=false;
}
CShow::~CShow()
{
}
BEGIN_MESSAGE_MAP(CShow, CWnd)
//{{AFX_MSG_MAP(CShow)
ON_WM_PAINT()
ON_WM_ERASEBKGND()
ON_WM_TIMER()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CShow message handlers
//初始化滚动位图显示控件
void CShow::InitBmpCtrl()
{
CClientDC dc(this);
//创建位图显示内存环境变量
m_dcMem.CreateCompatibleDC( &dc );
CAMLINK_InitDevice (&dwCounts,&dwSlot);
CAMLINK_StartDevice (dwSlot,7,1);
}
//根据位图名加载位图
BOOL CShow::LoadBmp(LPTSTR lpszResourceName)
{
if(m_hBmpNew != NULL )
DeleteObject(m_hBmpNew);
m_hBmpNew = SHLoadDIBitmap(lpszResourceName);
if( m_hBmpNew == NULL )
{
AfxMessageBox(_T("加载位图失败"));
return FALSE;
}
LoadBmpToCtrl();
return TRUE;
}
//根据位图资源ID加载位图
BOOL CShow::LoadBmp(UINT nIDResource)
{
if(m_hBmpNew != NULL )
DeleteObject(m_hBmpNew);
m_hBmpNew = LoadBitmap(AfxGetResourceHandle(),MAKEINTRESOURCE(nIDResource));
if( m_hBmpNew == NULL )
{
AfxMessageBox(_T("加载位图失败"));
return FALSE;
}
LoadBmpToCtrl();
return TRUE;
}
//将位图加载到控件上显示
void CShow::LoadBmpToCtrl()
{
BITMAP bmInfo; // bmp位图信息结构
CPoint pt;
//得到滚动位图显示控件大小
GetClientRect( &m_rectStaticClient );
m_rectStaticClient.NormalizeRect();
pt.x = m_rectStaticClient.left;
pt.y = m_rectStaticClient.top;
//得到位图信息,存储到bmInfo
GetObject(m_hBmpNew , sizeof(BITMAP), &bmInfo );
VERIFY(m_hBmpOld = (HBITMAP)SelectObject(m_dcMem, m_hBmpNew ) );
m_offsetX= pt.x;
m_offsetY=pt.y;
if(bmInfo.bmWidth<=m_rectStaticClient.Width())
{
if((m_rectStaticClient.Width()-bmInfo.bmWidth)==0)
m_offsetX= pt.x;
else
m_offsetX= pt.x+((m_rectStaticClient.Width()-bmInfo.bmWidth)/2);
}
if(bmInfo.bmHeight<=m_rectStaticClient.Height())
{
if((m_rectStaticClient.Height()-bmInfo.bmHeight)==0)
m_offsetY= pt.y;
else
m_offsetY= pt.y+((m_rectStaticClient.Height()-bmInfo.bmHeight)/2);
}
//更新显示
InvalidateRect(&m_rectStaticClient);
}
void CShow::OnPaint()
{
CPaintDC dc(this); // device context for painting
//显示指定位置的图片
dc.BitBlt(m_offsetX,m_offsetY,m_rectStaticClient.Width(),m_rectStaticClient.Height(),
&m_dcMem, 0, 0,SRCCOPY);
(HBITMAP)SelectObject(m_dcMem, m_hBmpOld );
DeleteObject(m_hBmpNew);
}
void CShow::OnStartTimer()
{
m_nTimer = SetTimer(1, 1, 0);
CAMLINK_InitDevice (&dwCounts,&dwSlot);
CAMLINK_StartDevice (dwSlot,7,1);
}
void CShow::OnStopTimer()
{
KillTimer(1);
CAMLINK_StopDevice(dwSlot);//现在能够说,内存不足是由于没有释放资源所致,
CAMLINK_CloseDevice(); //应加上(HBITMAP)SelectObject(m_dcMem, m_hBmpOld );
//DeleteObject(m_hBmpNew);
//需要重新插拔摄像头是由于没有停止设备
}
void CShow::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
//不断显示
const unsigned short *LOOK;
LOOK=_T("lvk.bmp");
if(Flag)
{
CAMLINK_GetDIBFile(dwSlot,(WORD)24,(WORD)320,(WORD)240,LOOK);
LoadBmp(_T("lvk.bmp"));
}
else
{
CAMLINK_GetDIBFile(dwSlot,(WORD)24,(WORD)320,(WORD)240,LOOK);
LoadBmp(_T("lvk.bmp"));
}
////
/////add lvk
BYTE* Bits;
if((Bits=new BYTE[3*320*240*8])==NULL)
{
MessageBox(_T("分配内存失败!"));
exit(1);
}
//if(CAMLINK_GetRgbBits(dwSlot,24,Bits,320,240)==NULL)
if(CAMLINK_GetRgbBits(dwSlot,24,Bits,320,240)==NULL)
MessageBox(_T("Get data is failed!"));
m_FireSignal=Detector(Bits);
if(m_FireSignal)
{
//MessageBox(_T("报警"));
::MessageBeep(0xFFFFFFFF); // Beep
::MessageBeep(0xFFFFFFFF); // Beep
::MessageBeep(0xFFFFFFFF); // Beep
CMyModemDlg::Strgsm();
//CMyModemDlg::OnBtnsenddata();
::MessageBeep(0xFFFFFFFF); // Beep
::MessageBeep(0xFFFFFFFF); // Beep
::MessageBeep(0xFFFFFFFF); // Beep
}
delete Bits;
//CAMLINK_StopDevice(dwSlot);//在加此句出现OUt of emory(不过过很常时间也会出现,
//CAMLINK_CloseDevice();//并且过一段时间就有加载位图m失败的问题,需要不断插拔摄像头。
Flag=!Flag;
CWnd::OnTimer(nIDEvent);
}
//识别算法
//火灾图像的信息量比较大,图像处理的算法比较繁琐,本系统综合考虑火焰各方面的特点,
//运用模式识别的方法(即火焰图像面积的增大,火焰形状的相似度)对火灾进行实时识别监控。
//设数字化的序列图像为fi(x,y),(x,y)为图像中各个像素点的坐标,N为连续序列图像的帧数。
//1. n幅图像被辨识出有火焰的存在。由于火焰的颜色较亮,所以我们通过火焰的颜色可以将它从整幅画面中提取出来,
//它的RGB组合比较固定,主要是有F2或F1组成。
//2. 提取出来的火焰的面积是动态变化的。这是火焰的另一个比较显著的特征,一般火灾区域的火焰都是呈慢慢扩大的趋势。
//这样我们就可以将火焰和一般的灯泡区别开来。采用的方法是连续采集n幅有火焰存在的图像,计算火焰的面积,得到一个面积序列
//,取 , 然后计算的均值 和方差 ,当相对较大时,我们就认为有火灾的存在。
//
//
BOOL CShow::Detector(BYTE *pbyTemp)
{
//变量声明部分
long k=0;
// long temp;
int CountNum=0;
//程序流程部分
for(k=0;k<=3*320*240;k=k+20)
{
if(pbyTemp[k]>20)
{
CountNum++;
}
}
//Max1=Max;
//if(Max>Max1)
// {
// return TRUE;
// }
if(CountNum>100)
return true;
else
return false;
}
/*
BOOL CShow::Detector(BYTE *pbyTemp)
{
//FILE *Temp;
long k=0x36;
long count=0;
long i=0;
long Max=0;
float fc=0;
float sum=0;
float average=0;
float tem=0;
for(k=0x36;k<=3*320*240;k=k+3)
{
i=k;
if(pbyTemp[i]==0xF||pbyTemp[i]==0xE)
{
i++;
//}
//if(pbyTemp[i]==0xF2||pbyTemp[i]==0xF1)
//{
//i++;
//}
// if(pbyTemp[i]==0xF2||pbyTemp[i]==0xF1)
//{
count++;
i=0;
}
}
if(count>=100)
{
m_Count[CountNum]=count;
CountNum++;
}
else
{
CountNum=0;
for(i=0;i<5;i++)
{
m_Count[i]=0;
}
}
if(CountNum==5)
{
for(i=2;i<5;i++)
{
if(Max<m_Count[i])
{
Max=m_Count[i];
}
}
for(i=2;i<5;i++)
{
if(Max!=m_Count[i])
{
tem=(float(m_Count[i])/float(Max));
sum=sum+tem;
}
}
average=sum/3;
for(i=2;i<5;i++)
{
if((float(Max)/float(m_Count[i]))!=1)
{
fc=fc+(float(m_Count[i])/float(Max)-average)*(float(m_Count[i])/float(Max)-average);
}
}
if(fc>=0.25)
return TRUE;
else
return FALSE;
}
return FALSE;
}
*/
///原始的识别程序
/*
BOOL CShow::Detector(BYTE *pbyTemp)
{
//long k=0x36;//在0X36之前是BMP图像的信息结构,不是数据
long k=0;
long count=0;
long i=0;
long Max=0;
float fc=0;
float sum=0;
float average=0;
float tem=0;
long m_Count[10]; //add lvk
int CountNum=0; //add lvk
//if((pbyTemp[0]=='B')&&(pbyTemp[1]=='M'))//判别是否是BMP图像
//{
for(k=0;k<=3*320*240;k=k+3)//这个For语句是用来判断从BMP图像数据开始,颜色字节中有无0xF1或0xF2(火焰颜色)
{ //因为是24位所以一个颜色值占用三个字节
i=k;
if(pbyTemp[i]==0xF2||pbyTemp[i]==0xF1)
{
i++;
}
if(pbyTemp[i]==0xF2||pbyTemp[i]==0xF1)
{
i++;
}
if(pbyTemp[i]==0xF2||pbyTemp[i]==0xF1)
{
count++;
i=0;
}
}
//m_Count[CountNum]=count;
//Temp=fopen("e:\\Counting.dat","w+");
//fwrite(&m_Count,sizeof(m_Count),1,Temp);
//fclose(Temp);
//CountNum++;
if(count>=0x100)
{
m_Count[CountNum]=count;
CountNum++;
}
else
{
CountNum=0;
for(i=0;i<10;i++)
{
m_Count[i]=0;
}
//Temp=fopen("e:\\Counting.dat","w+");
//fwrite(&m_Count,sizeof(m_Count),1,Temp);
//fclose(Temp);
}
if(CountNum==10)
{
for(i=2;i<10;i++)
{
if(Max<m_Count[i])
{
Max=m_Count[i];
}
}
for(i=2;i<10;i++)
{
if(Max!=m_Count[i])
{
tem=(float(m_Count[i])/float(Max));
sum=sum+tem;
}
}
average=sum/8;
for(i=2;i<10;i++)
{
if((float(Max)/float(m_Count[i]))!=1)
{
fc=fc+(float(m_Count[i])/float(Max)-average)*(float(m_Count[i])/float(Max)-average);
}
}
//Edit2->Text=fc;
//Temp=fopen("e:\\Counting.dat","w+");
//fwrite(&m_Count,sizeof(m_Count),1,Temp);
//fclose(Temp);
//max=FindMax(m_Count);
//WriteFlag=1;
if(fc>=0.25)
return TRUE;
else
return FALSE;
}
return FALSE;
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -