📄 connarea.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 + -