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

📄 connarea.cpp

📁 用于系统跟踪的程序
💻 CPP
字号:
#include "stdafx.h"
#include "ConnArea.h"
#include "aglrothim.h"
 #pragma warning(disable : 4996)

//填充颜色的迭代函数
void FillColorAlpha(IplImage* img,int x,int y,int a,int &CountPixel)
{
	if(x<=1 ||y<=1 || x>=img->width-1  || y>= img->height-1 || CountPixel>CONTENTPOINTMAXNUMBER ) 
		return;

	CountPixel++;
	if((unsigned char)(*(img->imageData+(img->width*y+x)*4+0))==255) 
	{
		if(a!=255 && CountPixel<CONTENTPOINTMAXNUMBER)
		{
			(*(img->imageData+(img->width*y+x)*4+3))=a;
			(*(img->imageData+(img->width*y+x)*4+1))=a;
			(*(img->imageData+(img->width*y+x)*4+0))=0;
			FillColorAlpha(img,x-1,y,a,CountPixel);
			FillColorAlpha(img,x+1,y,a,CountPixel);
			FillColorAlpha(img,x,y-1,a,CountPixel);
			FillColorAlpha(img,x,y+1,a,CountPixel);
			FillColorAlpha(img,x-1,y-1,a,CountPixel);
			FillColorAlpha(img,x-1,y+1,a,CountPixel);
			FillColorAlpha(img,x+1,y-1,a,CountPixel);
			FillColorAlpha(img,x+1,y+1,a,CountPixel);
		}
	}
}
ConnArea::ConnArea(){
		wx=0;
		wy=0;
		x0=0;
		y0=0;
		Index=0;
		X=0;
		Y=0;
		groupID=-1;
		UsedTime=0;
		//ptLeftTop.x=0;
		//ptLeftTop.y=0;
		//ptRightBottom.x=0;
		//ptRightBottom.y=0;
		//BorderpointsCount=0;
		PointCount=0; 
 
		type=NotIndentify;

		NearConnAreaIndex1=0;
		NearConnAreaIndex2=0;
	 
		SquareID[0]=-1;
		SquareID[1]=-1;
		SquareID[2]=-1;
		SquareID[3]=-1;
		SquareCount=0;
		posX=NOTVALUE;
		posY=NOTVALUE;
		posZ=NOTVALUE;


		ptT.x=100000;
		ptT.y=100000;
		ptB.x=-10000;
		ptB.y=-10000;
		ptL.x=100000;
		ptL.y=100000;
		ptR.x=-10000;
		ptR.y=-10000;

		isUseForCompute=false;
		isUsed=false;
		FirstPoint.x=-1;
		FirstPoint.y=-1;

	};	
//清理数据
void ConnArea::Clear()
{
	X=-1000;
	Y=-1000;
	wx=0;
	wy=0;
	x0=0;
	y0=0;
	Index=0;
 
	groupID=-1;
	UsedTime=0;
	//ptLeftTop.x=0;
	//ptLeftTop.y=0;
	//ptRightBottom.x=0;
	//ptRightBottom.y=0;
	//BorderpointsCount=0;
	PointCount=0; 
 
	type=NotIndentify;

	NearConnAreaIndex1=0;
	NearConnAreaIndex2=0;


	SquareID[0]=-1;
	SquareID[1]=-1;
	SquareID[2]=-1;
	SquareID[3]=-1;
	SquareCount=0;


	ptT.x=100000;
	ptT.y=100000;
	ptB.x=-10000;
	ptB.y=-10000;
	ptL.x=100000;
	ptL.y=100000;
	ptR.x=-10000;
	ptR.y=-10000;
	isUseForCompute=false;
	isUsed=false;
	FirstPoint.x=-1;
	FirstPoint.y=-1;
}

//绘制边界
void ConnArea::drawBorder(IplImage* img,int r,int g,int b)
{

	//for(int i=0;i<this->BorderpointsCount;i++)
	//{
	//	 (*(img->imageData+0+3*(img->width*(this->Borderpoints[i].y)+(this->Borderpoints[i].x))))=r;	
	//	 (*(img->imageData+1+3*(img->width*(this->Borderpoints[i].y)+(this->Borderpoints[i].x))))=g;	
	//	 (*(img->imageData+2+3*(img->width*(this->Borderpoints[i].y)+(this->Borderpoints[i].x))))=b;	
	//}
	
}
//绘制直线,从起点到终点
void ConnArea::drawLine(IplImage* img,int r,int g,int b,int a)
{
	cvLine( img,  ptBegin, ptEnd, cvScalar(r,g,b,a), 3, 8, 0 );

	CvPoint pt1,pt2;
	pt1.x=ptBegin.x-5;
	pt1.y=ptBegin.y;
	pt2.x=ptBegin.x+5;
	pt2.y=ptBegin.y;
	cvLine(img,pt1,pt2,cvScalar(r,g,b,a), 1, 4, 0 );

	pt1.x=ptBegin.x;
	pt1.y=ptBegin.y-5;
	pt2.x=ptBegin.x;
	pt2.y=ptBegin.y+5;
	cvLine(img,pt1,pt2,cvScalar(r,g,b,a), 1, 4, 0 );

	CvFont font;
	cvInitFont(&font,10,0.4,0.4,0.2,0, 8 );
	char  info[80];
	 
	//显示每个点的编号
	sprintf((char *)info,"%d", Index); 
	//绘制点的位置
	//cvPutText(img,info, pt1,&font, CV_RGB(255,255,0));

}


//绘制十字点
void ConnArea::drawALLCross(IplImage* img,int r, int g,int b)
{
	//for(int i=0;i<PointCount;i++)
	//{
	//	CvPoint pt1,pt2;
	//	pt1.x=Points[i].x-5;
	//	pt1.y=Points[i].y;
	//	pt2.x=Points[i].x+5;
	//	pt2.y=Points[i].y;
	//	cvLine(img,pt1,pt2,CV_RGB(r,g,b), 1, 4, 0 );

	//	pt1.x=Points[i].x;
	//	pt1.y=Points[i].y-5;
	//	pt2.x=Points[i].x;
	//	pt2.y=Points[i].y+5;
	//	cvLine(img,pt1,pt2,CV_RGB(r,g,b), 1, 4, 0 );

	//	CvFont font;
	//	cvInitFont(&font,10,0.4,0.4,0.2,0, 8 );
	//	char  info[80];

	//	//显示每个点的编号
	//	sprintf((char *)info,"%d", Index); 
	//	//绘制点的位置
	//	cvPutText(img,info, pt1,&font, CV_RGB(r,g,b));
	//}
}
//绘制十字点
void ConnArea::drawCross(IplImage* img,int r, int g,int b)
{
	CvPoint pt1,pt2;
	pt1.x=(int)(X-5);
	pt1.y=(int)Y;
	pt2.x=(int)(X+5);
	pt2.y=(int)Y;
	cvLine(img,pt1,pt2,CV_RGB(r,g,b), 1, 4, 0 );

	pt1.x=(int)X;
	pt1.y=(int)(Y-5);
	pt2.x=(int)X;
	pt2.y=(int)(Y+5);
	cvLine(img,pt1,pt2,CV_RGB(r,g,b), 1, 4, 0 );

 
	cvLine(img,ptBegin,ptEnd,CV_RGB(r,255-g,b), 1, 4, 0 );
	
	//cvLine(img,ptL,ptR,CV_RGB(r,g,b), 1, 4, 0 );


	CvFont font;
	cvInitFont(&font,2,0.3,0.3,0.1,0, 8 );
	char  info[80];
	 

 
	//显示每个点的编号
	//sprintf((char *)info,"%3.0f,%3.0f,%3.0f", this->posX,this->posY,this->posZ); 
	sprintf((char *)info,"%3.0f", this->posX); 
	for(int i=-1;i<=1;i++)
	{
		for(int j=-1;j<=1;j++)				
		{
			pt2.x=pt1.x+i;
			pt2.y=pt1.y+j;
			cvPutText(img,info, pt2,&font, CV_RGB(255,255,255));
		}
	}
	cvPutText(img,info, pt1,&font, CV_RGB(r,g,b));


	pt1.y=pt1.y+10;
	sprintf((char *)info,"(%3.0f,%3.0f)", this->X, this->Y); 
	for(int i=-1;i<=1;i++)
	{
		for(int j=-1;j<=1;j++)				
		{
			pt2.x=pt1.x+i;
			pt2.y=pt1.y+j;
			//cvPutText(img,info, pt2,&font, CV_RGB(255,255,255));
		}
	}

	//cvPutText(img,info, pt1,&font, CV_RGB(r,g,b));
	
}



void ConnArea::drawALLAlpha(IplImage* img,int a)
{
	int CountPixel=0;
	try
	{
		FillColorAlpha(img,FirstPoint.x,FirstPoint.y,a,CountPixel);
	}catch( char * str )
	{
				
	}
	//for(int i=0;i<this->PointCount-1;i++)
	//{
	//	 (*(img->imageData+0+3*(img->width*(this->Points[i].y)+(this->Points[i].x))))=r;	
	//	 (*(img->imageData+1+3*(img->width*(this->Points[i].y)+(this->Points[i].x))))=g;	
	//	 (*(img->imageData+2+3*(img->width*(this->Points[i].y)+(this->Points[i].x))))=b;	
	//}
}

//判断区域是否靠近图像边界
bool ConnArea::isNearBorder(int imgWidth,int imgHeight,int DistanceToBorder)
{
 
	if(ptL.x <DistanceToBorder || ptT.y<DistanceToBorder || ptR.x>imgWidth-DistanceToBorder || ptB.y>imgHeight-DistanceToBorder)
		return true;
		 
	
	return false;
}
//判断区域是否靠近图像边界
bool ConnArea::isCenterNearBorder(int imgWidth,int imgHeight,int DistanceToBorder)
{
	if(X <DistanceToBorder || Y<DistanceToBorder || X>imgWidth-DistanceToBorder || Y>imgHeight-DistanceToBorder)
		return true;
		 
	
	return false;
}
//判断两个区域是否靠近
bool ConnArea::isNear(ConnArea area,int Distance,CvPoint& pt1,CvPoint& pt2)
{
	double D=0;
	bool returnValue=false;

	if(abs(area.X-X)<Distance && abs(area.Y-Y)<Distance)
	{
		pt1.x=(int)X;
		pt1.y=(int)Y;
		pt2.x=(int)area.X;
		pt2.y=(int)area.Y;

		returnValue=true;
		goto returnproc;
	}
	if(abs(area.ptL.x-ptR.x)<Distance && abs(area.ptL.y - ptR.y)<Distance)
	{
		pt1.x=area.ptL.x;
		pt1.y=area.ptL.y;
		pt2.x=ptR.x;
		pt2.y=ptR.y;

		returnValue=true;
		goto returnproc;
	}
	if(abs(area.ptR.x-ptL.x)<Distance && abs(area.ptR.y - ptL.y)<Distance)
	{
		pt1.x=area.ptR.x;
		pt1.y=area.ptR.y;
		pt2.x=ptL.x;
		pt2.y=ptL.y;

		returnValue=true;
		goto returnproc;
	}



	if(abs(area.ptT.x-ptB.x)<Distance && abs(area.ptT.y - ptB.y)<Distance)
	{
		pt1.x=area.ptT.x;
		pt1.y=area.ptT.y;
		pt2.x=ptB.x;
		pt2.y=ptB.y;
		returnValue=true;
		goto returnproc;
	}
	if(abs(area.ptB.x-ptT.x)<Distance && abs(area.ptB.y - ptT.y)<Distance)
	{
		pt1.x=area.ptB.x;
		pt1.y=area.ptB.y;
		pt2.x=ptT.x;
		pt2.y=ptT.y;
		returnValue=true;
		goto returnproc;
	}

	//if(abs(area.X-ptT.x)+abs(area.Y-ptT.y)<Distance)
	//{
	//	returnValue=true;
	//	goto returnproc;
	//}
	//if(abs(area.X-ptT.x)+abs(area.Y-ptT.y)<Distance)
	//{
	//	returnValue=true;
	//	goto returnproc;
	//}
returnproc:
	return returnValue;



	////两个区域都是点
	//if(!isLine && !area.isLine)
	//{
	//	D=getDistance(X,Y,area.X,area.Y);
	//}

	////当前区域是点,被监测区域是线
	//if(!isLine && area.isLine)
	//{
	//	double D1=getDistance(X,Y,area.ptBegin.x,area.ptBegin.y);
	//	double D2=getDistance(X,Y,area.ptEnd.x,area.ptEnd.y);
	//	if(D1>=D2)
	//	{
	//		D=D2;
	//	}
	//	else
	//	{
	//		D=D1;
	//	}
	//}
	//
	////当前区域是线,被监测区域是点
	//if(isLine && !area.isLine)
	//{
	//	double D1=getDistance(ptBegin.x,ptBegin.y,area.X,area.Y);
	//	double D2=getDistance(ptEnd.x,ptEnd.y,area.X,area.Y);
	//	if(D1>=D2)
	//	{
	//		D=D2;
	//	}
	//	else
	//	{
	//		D=D1;
	//	}
	//}
	////两个区域都是线
	//if(isLine && area.isLine)
	//{
	//	double D1=getDistance(ptBegin.x ,ptBegin.y,area.ptBegin.x,area.ptBegin.y);
	//	double D2=getDistance(ptBegin.x,ptBegin.y,area.ptEnd.x,area.ptEnd.y);
	//	double D3=getDistance(ptEnd.x ,ptEnd.y,area.ptBegin.x,area.ptBegin.y);
	//	double D4=getDistance(ptEnd.x,ptEnd.y,area.ptEnd.x,area.ptEnd.y);

	//	if(D1<=D2 && D1<=D3 && D1<=D4)
	//	{
	//		D=D1;
	//	}
 //		if(D2<=D1 && D2<=D3 && D2<=D4)
	//	{
	//		D=D2;
	//	}
	//	if(D3<=D1 && D3<=D2 && D3<=D4)
	//	{
	//		D=D3;
	//	}
	//	if(D4<=D1 && D4<=D2 && D4<=D3)
	//	{
	//		D=D4;
	//	}
	//}
	//if(D<Distance)
	//{
	//	return true;
	//}else
	//{
	//	return false;
	//}
}


//绘制点和信息
void DrawLine(IplImage  *img,double k, double b,bool isTurnXY)
{
	CvPoint pt1,pt2;
	if(!isTurnXY)
	{
		pt1.x=0;
		pt1.y=(int)(k*pt1.x+b);
		pt2.x=(int)(img->width);
		pt2.y=(int)(k*pt2.x+b);
	}
	else
	{
		pt1.y=0;
		pt1.x=(int)(k*pt1.y+b);
		pt2.y=(int)(img->width);
		pt2.x=(int)(k*pt2.y+b);
	}
	cvLine(img,pt1,pt2,CV_RGB(255,0,0), 1, 4, 0 ); 
}

//判断点是否在线上
bool ConnArea::isPointOnLine(ConnArea P,int DistanceToLine,int combinePointLinDistance,int combineDistance)
{
	//----------------------------//
	//if(P.isLine)return false; isLine 已经被type取代
	//if(!isLine)return false;

	double k=0;
	double b=0;
	bool isTurnXY=false;
	double D=0;


	if(abs(wx)>=abs(wy))
	{
		getKB(wx,wy,x0,y0,k,b);
		isTurnXY=false;
		D=getDistanceToLine(P.X,P.Y,k,b);
	}
	else
	{	
		getKB(wy,wx,y0,x0,k,b);
		isTurnXY=true;
		D=getDistanceToLine(P.Y,P.X,k,b);
	}
	if(D>=DistanceToLine)
	{
		return false;
	}else
	{
		double D0=0;
		double D1=getDistance(P.X ,P.Y,ptBegin.x,ptBegin.y);
		double D2=getDistance(P.X ,P.Y,ptEnd.x,ptEnd.y);
		if(D1>=D2)
		{
			D0=D2;
		}
		else
		{
			D0=D1;
		}


		if(D0>combinePointLinDistance)
		{
			return false;
		}else
		{
			return true;
		}
	}
}

 //增加连同区域内部点
void ConnArea::addPoints(int count,CvPoint* NewPoints)
{
	//for(int i=0;i<count;i++)
	//{
	//	if(i+PointCount<CONTENTPOINTMAXNUMBER)
	//	{
	//		Points[i+PointCount].x=NewPoints[i].x;
	//		Points[i+PointCount].y=NewPoints[i].y;
	//	}
	//}
	//if(count+PointCount<CONTENTPOINTMAXNUMBER)
	//{
	//	PointCount=count+PointCount;
	//}
	//else
	//{
	//	PointCount=CONTENTPOINTMAXNUMBER;
	//}
}

 //增加连同区域边界点
void ConnArea::addBorderPoints(int count,CvPoint* NewPoints)
{
	//for(int i=0;i<count;i++)
	//{
	//	if(i+BorderpointsCount<BORDERPOINTMAXNUMBER)
	//	{
	//		Borderpoints[i+BorderpointsCount].x=NewPoints[i].x;
	//		Borderpoints[i+BorderpointsCount].y=NewPoints[i].y;
	//	}
	//}
	//if(count+BorderpointsCount<BORDERPOINTMAXNUMBER)
	//{
	//	BorderpointsCount=count+BorderpointsCount;
	//}
	//else
	//{
	//	BorderpointsCount=BORDERPOINTMAXNUMBER;
	//}
}

//刷新直线参数,进行直线拟和
void ConnArea::refreshLine(int LineLength)
{

	if(X<0 || Y<0)
	{
		type=NotIndentify;
		return;
	}
	x0=(float)X;
	y0=(float)Y;

	int l=0;
	if(abs(ptB.y - ptT.y)>abs(ptR.x-ptL.x))
	{
		wx=(float)(ptB.x-ptT.x);
		wy=(float)(ptB.y-ptT.y);
		ptBegin=ptB;
		ptEnd=ptT;
		l=abs(ptB.y - ptT.y)+abs(ptB.x - ptT.x);
	}else
	{
		wx=(float)(ptR.x-ptL.x);
		wy=(float)(ptR.y-ptL.y);
		ptBegin=ptR;
		ptEnd=ptL;
		l=abs(ptR.x-ptL.x)+abs(ptR.y-ptL.y);
	}
	if(l>LineLength)
	{
		
		type=Line;
	}
	else
	{
		type=Point;
	}
 

}

//

//合并连同区域
void ConnArea::combineConnArea(ConnArea area,int LineLength)
{



	if(area.ptT.y<ptT.y)
	{
		ptT.x=area.ptT.x;
		ptT.y=area.ptT.y;
	}
	if(area.ptB.y>ptB.y)
	{
		ptB.x=area.ptB.x;
		ptB.y=area.ptB.y;
	}
	if(area.ptL.x<ptL.x)
	{
		ptL.x=area.ptL.x;
		ptL.y=area.ptL.y;
	}
	if(area.ptR.x>ptR.x)
	{
		ptR.x=area.ptR.x;
		ptR.y=area.ptR.y;
	}

	//X=(ptL.x+ptR.x+ptT.x+ptB.x)/4;
	//Y=(ptL.y+ptR.y+ptT.y+ptB.y)/4;
	
	X=(X*PointCount+area.X*area.PointCount)/(area.PointCount+PointCount);
	Y=(Y*PointCount+area.Y*area.PointCount)/(area.PointCount+PointCount);
	PointCount=area.PointCount+PointCount; 
	
	
	//addPoints(area.PointCount,area.Points);
	//addBorderPoints(area.BorderpointsCount,area.Borderpoints);
	////X=(X*PointCount+area.X*area.PointCount)/(PointCount+area.PointCount);
	////Y=(Y*PointCount+area.Y*area.PointCount)/(PointCount+area.PointCount);
	//refreshLine(LineLength);
}


//合并连同区域
int ConnArea::Scan(IplImage* img,int way)
{
	bool	isFinish=false;
	double	Xscan=0;
	double	Yscan=0;
	int		i=0;
	double	xStep=0;
	double	yStep=0;
	int		returnValue=-1;

	if(wy==0 && wx==0)return 0;
	while(!isFinish)
	{
		
		//获取r,g,b中b的值
		//(*(img->imageData+(img->width*y+x)*4+3))=0;
		//(*(img->imageData+(img->width*y+x)*4+2))=0;
		//(*(img->imageData+(img->width*y+x)*4+1))=0;
		//(*(img->imageData+(img->width*y+x)*4+0))=255;

	 
		if(abs(wx)>abs(wy))
		{
			xStep=i;
			yStep=i*wy/wx;
		}else
		{
			xStep=i*wx/wy;
			yStep=i;
		}

		Xscan=X+xStep;
		Yscan=Y+yStep; 
		i=i+way;
 
		if(Xscan<=1 || Xscan>=img->width-1 || Yscan<=1 || Yscan>=img->height-1)
		{
			returnValue=-1;	
			isFinish=true;
			goto endloop;
		}
		unsigned char color=(unsigned char)(*(img->imageData+(img->width*(int)Yscan+(int)(Xscan))*4+3));
		//绘制扫描线
		//(*(img->imageData+(img->width*(int)Yscan+(int)(Xscan))*4+1))=255;
		if(color>0 && color!=255  && color!=Index)
		{
			returnValue=color;	
			isFinish=true;
			goto endloop;
		}
		 
		 
	}	
	 endloop:

	//绘制//////////////////////////////////////////
	//CvPoint pt1;
	//pt1.x=X;
	//pt1.y=Y;
	//CvPoint pt2;
	//pt2.x=Xscan;
	//pt2.y=Yscan;
	//cvLine(img,pt1,pt2,CV_RGB(0,255,0), 1, 8, 0 );

	//CvFont font;
	//cvInitFont(&font,10,0.4,0.4,0.2,0, 8 );
	//char  info[80];
	// 
	////显示每个点的编号
	//sprintf((char *)info,"%d", returnValue); 
	////绘制点的位置
	//cvPutText(img,info, pt2,&font, CV_RGB(100,255,0));
	////////////////////////////////////////////////
	return returnValue;
}

//获得相邻区域编号
void ConnArea::getNearConnAreaIndex(IplImage* img)
{
	NearConnAreaIndex1=Scan(img,-1);
	NearConnAreaIndex2=Scan(img,1);
}

⌨️ 快捷键说明

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