📄 alarmsystemview.cpp
字号:
// at this point we have our thresholding value
// debug code to display thresholding values
if ( vvv & 1 )
fprintf(stderr,"# OTSU: thresholdValue = %d gmin=%d gmax=%d\n",
thresholdValue, gmin, gmax);
np=NULL;
delete np;
return(thresholdValue);
}
void CAlarmSystemView::area(IplImage *pImage,int *area)
{
int temp=0;
unsigned char *imageData=(uchar *)pImage->imageData;
for(int i=top;i<=bottom;i++)
for(int j=left;j<=right;j++)
if(imageData[WIDTH*i+j]==0)//计算黑点数目
temp++;
*area=temp;
}
void CAlarmSystemView::color_bright(double *bright,double *color)
{
//首先将原图转换为hsv格式
cvCvtColor(pFrame,HSV,CV_BGR2HSV); //经测试原图是bgr格式
pimageData=(uchar *)pFrImg->imageData; //二值图为单通道
unsigned char *lpimageDataHSV=(uchar *)HSV->imageData; //HSV图为三通道
unsigned char *lpSrcEr=NULL;
unsigned char *lpSrcHSV=NULL;
double bright_value_sum=0.0;
double color_value_sum=0.0;
int aimNum=0;
for(int i=top;i<=bottom;i++)
for(int j=left;j<=right;j++)
{
lpSrcEr=pimageData+(i*WIDTH+j);
if(*lpSrcEr==0)
{
lpSrcHSV=lpimageDataHSV+(i*WIDTH+j)*3; // HSV的H值
bright_value_sum+=*(lpSrcHSV+2); // HSV的V值
color_value_sum+=*lpSrcHSV; // HSV的H值
aimNum++;
}
}
*bright=bright_value_sum/aimNum;
*color=color_value_sum/aimNum;
lpimageDataHSV=NULL;
lpSrcEr=NULL;
lpSrcHSV=NULL;
delete lpimageDataHSV;
delete lpSrcEr;
delete lpSrcHSV;
/*
CString a;
a.Format("%d,%f,%f",aimNum,*color,*bright);
MessageBox(a);
*/
}
int CAlarmSystemView::isChange()
{
pimageData=(uchar *)pFrImg->imageData;
int num=0; //统计变化的像素点数
for(int i=0;i<HEIGHT;i++)
for(int j=0;j<WIDTH;j++)
{
if(*(pimageData+i*WIDTH+j)>15)
num++;
}
pimageData=NULL;
delete pimageData;
fprintf(log,"变化的像素点数为%d\r\n",num);
return num;
}
void CAlarmSystemView::SharpAngle(int *angle_num,CvPoint AnglePointPosition[10])
{
unsigned char *lpSrc;
int i,j,m;
// 中间变量
int DirectSum; //边界扫描的方向数目计数
int tempW; //扫描中的像素列中间变量
int tempH; //扫描中的像素行中间变量
int Count=0; //扫描到的连续目标白点计数
int AngleSum=0;
//用于尖角顶点判定条件(起始扫描点设为左、右两个边界点,左右可以重合为一个点)
int FindTopPoint1=1; // 条件一:首先必须是顶点(尖或广义平尖角,即该点上方无目标白点)
int FindTopPoint2=1; // 条件二:如果是广义平尖角即同一行有几个连续的目标白点,则这个连续目标白点个数必须小于阈值
//尖角顶点的起始点和结束点下标
int TopPointFirst, TopPointEnd;
//左右边界交点下标(横坐标)及其相隔点数
int ColumnL, ColumnR, BounderSpaceNum;
//尖角左右边界交点的纵坐标,及尖角高度(用这两个条件判断尖角)
int RowSumL,RowSumR; //左右边界方向,扫描的行数
//用标记法跟踪扫描的5个方向
int Direction[5][2]={{0,-1},{1,-1},{1,0},{1,1},{0,1}}; // 注意扫描图像时从上往下进行
pimageData=(uchar *)pFrImg->imageData;
int PlainAngleThreshold=WIDTH*5/100; //平尖角阈值,现在设为整幅图宽度的5%
for(j=top;j<bottom;j++)
{
i=0;
while(i<WIDTH)
{
Count=1;
lpSrc=pimageData+(j*WIDTH+i);
if(*lpSrc==0)//当前点为目标黑点
{
//当尖角处于图像最上端边界时,单独处理
if(j==0)
{
FindTopPoint1=1;
TopPointFirst=i;
}
else //一般位置尖角判断
{
for(m=-4;m<=4;m++) //看当前目标黑点上方小区域是否也为目标黑点
{
if( 0<=(i+m)<WIDTH ) //防止地址越界
{
lpSrc=pimageData+((j-1)*WIDTH+i+m);
if(*lpSrc==0) break; //若当前检测点上方小区域有目标黑点,则非尖角顶点,退出顶点检测
}
}
if(m<=4)
FindTopPoint1=0; //尖角顶点判定条件1为非
else
{
FindTopPoint1=1;
TopPointFirst=i; //找到一个尖角顶点,起始点
}
}
}
else FindTopPoint1=0;
if(FindTopPoint1) //若尖角顶点判定条件1为真(即找到顶点起始点),则进行条件2判断
{
while(0<=(i+Count)<WIDTH) //统计到一行的最右端即可
{
// if(0<=(j*lWidth+i+Count)<lWidth) //防止地址越界
{
lpSrc=pimageData+(j*WIDTH+i+Count);
if(*lpSrc==0) Count++; //count统计同行连续黑点数目
else break;
}
}
if(Count<PlainAngleThreshold) //若当前检测点同行的连续目标黑点个数<阈值8时,则判定该处是:广义平尖角
{ //反之,尖角顶点判定条件2为非
FindTopPoint2=1;
TopPointEnd=TopPointFirst+Count-1;//尖角顶点的右端点
}
else FindTopPoint2=0;
}
/*****************************以上为尖角顶点检测***************************/
//若找到尖角顶点(狭义或广义平尖角:多个连续目标黑点且个数和<8),则进行左下和右下边界扫描
if(FindTopPoint1 && FindTopPoint2)
{
ColumnL=TopPointFirst; ColumnR=TopPointEnd;//左右向下扫描的列起始点坐标
//从ColumnL开始进行左下边界扫描
RowSumL=0;
while(RowSumL<6) //向下扫描,检测0,1,2,3,4,5共6行(实质是设定尖角的高度为6)
{
DirectSum=0; //每行扫描时扫描起始方向数置0
while(1)
{
tempH=j+RowSumL+Direction[DirectSum][0];
tempW=ColumnL+Direction[DirectSum][1];
if( (0<=tempW<WIDTH) && (0<=tempH<HEIGHT) )//地址有效
{
lpSrc=pimageData+(tempH*WIDTH+tempW);
if(*lpSrc==0) //尖角周围有目标黑点
{
if(Direction[DirectSum][0]>0) //表示扫描到的目标边界点与前一点非同行
{
RowSumL++; //则RowSumL++,以扫描下一行
ColumnL=tempW; //记录下一行扫描时左边界起始点列坐标
break;//表示若本次扫描找到隔行边界点,则退出本行扫描以进入下一行扫描
}
else ColumnL=tempW;
}
else
DirectSum++; //进行下一个方向扫描
}
else //地址无效,直接进入到下一个方向扫描
{
DirectSum++;//进行下一个方向扫描,注意原扫描点的行列坐标不变
}
//若跟踪扫描的5个方向全部扫描完还没有找到边界黑点,则认为该处轮廓不规则,
//不存在尖角,退出小循环,并置ColumnL=0以用于后续尖角判断(左右边界距离)
if(DirectSum>4)
{
ColumnL=0; break; //退出while(1)
}
} //while(1)结束
if(DirectSum>4) break; //退出大循环
}
/*******************以上为从左顶点向左下扫描进行边界检测*********************/
//从ColumnR开始进行右下边界扫描
RowSumR=0;
while(RowSumR<6) //向下扫描,检测0,1,2,3,4共5行
{
DirectSum=4; //每行扫描时扫描起始方向数置4
while(1)
{
tempH=j+RowSumR+Direction[DirectSum][0];
tempW=ColumnR+Direction[DirectSum][1];
if( (0<=tempW<WIDTH) && (0<=tempH<HEIGHT) )//地址有效
{
lpSrc=pimageData+(tempH*WIDTH+tempW);
if(*lpSrc==0) //此方向点为目标黑点
{
if(Direction[DirectSum][0]>0) //表示扫描到的目标边界点与前一点非同行
{
RowSumR++; //则RowSum++,以扫描下一行
ColumnR=tempW; //记录下一行扫描时右边界起始点列坐标
break;//表示若本次扫描找到隔行边界点,则退出本行扫描以进入下一行扫描
}
else ColumnR=tempW;
}
else
{
DirectSum--;//进行下一个方向扫描,注意原扫描点的行列坐标不变
}
}
else
DirectSum--; //地址无效,直接进行下一方向扫描
//若跟踪扫描的5个方向全部扫描完还没有找到边界黑点,则认为该处轮廓不规则,
//不存在尖角,退出小循环,并置ColumnL=0以用于后续尖角判断(左右边界距离)
if(DirectSum<0)
{
ColumnR=0; break; //退出while(1)
}
} //while(1)结束
if(DirectSum<0) break; //退出大循环
}
/*******************以上为从右顶点向右下扫描进行边界检测*********************/
// 计算左右边界点之间的象素个数,即距离
BounderSpaceNum=ColumnR-ColumnL-1;
// 尖角判断和数目统计
if( BounderSpaceNum>=0 && BounderSpaceNum<10 )
{
if(AngleSum>0) //不是第一个尖角,判断是不是毛刺
{
int dis=abs(i-AnglePointPosition[AngleSum-1].x);
if(dis>8) //去除毛刺尖角,因为毛刺导致尖角重复计算,原先设为3
{
AnglePointPosition[AngleSum].x=i; //若为平尖角,x为左边起始点
AnglePointPosition[AngleSum].y=j;
AngleSum++;
}
}
else //发现的第一个尖角,直接存储
{
AnglePointPosition[AngleSum].x=i; //若为平尖角,x为左边起始点
AnglePointPosition[AngleSum].y=j;
AngleSum++;
}
}
}
//转当前行的下一象素点检测
i=i+Count;
} //当前行的所有象素点检测完毕(while(i))
} //整个目标矩形区域的所有行均检测完毕(while(j))
*angle_num=AngleSum;
pimageData=NULL;
lpSrc=NULL;
delete pimageData;
delete lpSrc;
}
void CAlarmSystemView::AnglePointDisplay(IplImage* pImage)
{
for(int i=0;i<m_SharpAngleNum;i++)
{
fprintf(log,"(%d,%d)\r\n",AnglePointPosition[i].x,AnglePointPosition[i].y);
cvCircle(pFrImg,AnglePointPosition[i],5,CV_RGB(255,0,0),1);
cvNamedWindow("Erzhi",1);
cvShowImage("Erzhi",pImage);
}
}
BOOL CAlarmSystemView::connection()
{
///////////////////////创建socket连接
WSADATA wsaData;
WORD WINSOCK_VERSION=MAKEWORD(2,0);
if(WSAStartup(WINSOCK_VERSION,&wsaData))//调用windows Sockets Dll
{
MessageBox("Winsock无法初始化",NULL,MB_OK);
return FALSE;
}
m_hClientSocket=socket(AF_INET,SOCK_STREAM,0);
if(m_hClientSocket==INVALID_SOCKET)
{
MessageBox("无法创建客户端socket!");
return FALSE;
}
m_sockClientAddr.sin_family=AF_INET;//使用TCP/IP协议
m_sockClientAddr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
m_sockClientAddr.sin_port=htons((u_short)5342);
int nConnect=connect(m_hClientSocket,(LPSOCKADDR)&m_sockClientAddr,sizeof(m_sockClientAddr)); //请求连接
if(nConnect==SOCKET_ERROR)
{
MessageBox("连接失败!");
return FALSE;
}
else
{
MessageBox("连接成功!");
return TRUE;
}
}
void CAlarmSystemView::RunningAvg()
{
//更新背景
cvRunningAvg(pFrameMat, pBkMat, 0.5, 0);
cvConvert(pBkMat, pBkImg);
cvFlip(pBkImg,pBkImg,0);
cvFlip(pFrImg,pFrImg_copy,0);
cvShowImage("video",pFrame);
cvShowImage("front",pFrImg_copy);
cvShowImage("back",pBkImg);
//如果有按键事件,则跳出循环
//此等待也为cvShowImage函数提供时间完成显示
//等待时间可以根据CPU速度调整
cvWaitKey(50);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -