矩形区域合适边缘包括外边缘和内边缘,外边缘是指最大最小边界值;内边缘是指边缘最内点值。求取外边缘比较简单,这里只讲获取内边缘。
方法:
1、扫描图像法。
2、中心点向边界扫描,求得此时的边界点,按照四个象限求取与边界最靠近的点。
//求取矩形区域合适边缘(内边缘)
//参数说明:rectEdge,表示边缘;pBinData2,表示二值图像数据;nWidth,表示图像宽度;nHeight,表示图像高度;nSaveFlag,表示图像中边界的标记值;innerEdge,表示内边缘
void GetInnerEdge(RECT rectEdge,BYTE *pBinData2,long nWidth,long nHeight,int nSaveFlag,RECT & innerEdge)
{
LONG iMinLeft = -1,iMinTop = -1,iMinRight = 65535,iMinBottom = 65535,nX = 5,nY = 5,k = 0;
POINT ptCenter;
ptCenter.x = (rectEdge.right+rectEdge.left)/2;
ptCenter.y = (rectEdge.bottom+rectEdge.top)/2;
nX = fabs((rectEdge.right-rectEdge.left)/4);
nY = fabs((rectEdge.bottom-rectEdge.top)/4);
RECT initRegion;
initRegion.left = (ptCenter.x-nX)>=0?(ptCenter.x-nX):0;
initRegion.right = (ptCenter.x+nX)<=rectEdge.right?(ptCenter.x+nX):rectEdge.right;
initRegion.top = (ptCenter.y-nY)>=0?(ptCenter.y-nY):0;
initRegion.bottom = (ptCenter.y+nY)<=rectEdge.bottom?(ptCenter.y+nY):rectEdge.bottom;
BOOL bFindLeft = FALSE;
double d1 = 0.0,d2 = 0.0,dMax = 20;
POINT ptLeft,ptRight,ptTop,ptBottom;
LONG nOutInnerMax = 150;//内外边缘大致距离范围
BOOL bBreak = FALSE;
j = ptCenter.y;
for(i=ptCenter.x;i>=rectEdge.left;i--)
{
ioffset = j * nWidth + i;
if(pBinData2[ioffset]==nSaveFlag && (i-rectEdge.left)<nOutInnerMax)
{
bBreak = TRUE;
break;
}
}
if(bBreak)
{
ptLeft.x = i;
ptLeft.y = j;
}
else
{
ptLeft.x = rectEdge.left;
ptLeft.y = j;
}
bBreak = FALSE;
i = ptCenter.x;
for(j=ptCenter.y;j>=rectEdge.top;j--)
{
ioffset = j * nWidth + i;
if(pBinData2[ioffset]==nSaveFlag && (j-rectEdge.top)<nOutInnerMax)
{
bBreak = TRUE;
break;
}
}
if(bBreak)
{
ptTop.x = i;
ptTop.y = j;
}
else
{
ptTop.x = rectEdge.top;
ptTop.y = j;
}
bBreak = FALSE;
j = ptCenter.y;
for(i=ptCenter.x;i<=rectEdge.right;i++)
{
ioffset = j * nWidth + i;
if(pBinData2[ioffset]==nSaveFlag && (rectEdge.right-i)<nOutInnerMax)
{
bBreak = TRUE;
break;
}
}
if(bBreak)
{
ptRight.x = i;
ptRight.y = j;
}
else
{
ptRight.x = rectEdge.right;
ptRight.y = j;
}
bBreak = FALSE;
i = ptCenter.x;
for(j=ptCenter.y;j<rectEdge.bottom;j++)
{
ioffset = j * nWidth + i;
if(pBinData2[ioffset]==nSaveFlag)
{
if((rectEdge.bottom-j)<nOutInnerMax)
{
bBreak = TRUE;
break;
}
}
}
if(bBreak)
{
ptBottom.x = i;
ptBottom.y = j;
}
else
{
ptBottom.x = i;
ptBottom.y = rectEdge.bottom;
}
for(j=rectEdge.top;j<=rectEdge.bottom;j++)
{
for(i=rectEdge.left;i<rectEdge.right;i++)
{
ioffset = j * nWidth + i;
if(pBinData2[ioffset]==nSaveFlag)
{
if(i>=ptLeft.x && i<ptCenter.x && j>ptCenter.y && j<=ptBottom.y) //第3象限
{
d1 = fabs(i-ptLeft.x);
d2 = fabs(j-ptBottom.y);
if(d1<=d2)//靠近左边
{
if(iMinLeft<i && d1<dMax)
{
iMinLeft = i;
}
}
else //靠近下边
{
if(iMinBottom>j && d2<dMax)
{
iMinBottom = j;
}
}
}
else if(i>=ptLeft.x && i<ptCenter.x && j>=ptTop.y && j<ptCenter.y)//第4象限
{
d1 = fabs(i-ptLeft.x);
d2 = fabs(j-ptTop.y);
if(d1<=d2)//靠近左边
{
if(iMinLeft<i && d1<dMax)
{
iMinLeft = i;
}
}
else//靠近上边
{
if(iMinTop<j && d2<dMax)
{
iMinTop = j;
}
}
}
else if(i>ptCenter.x && i<=ptRight.x && j>=ptTop.y && j<ptCenter.y)//第1象限
{
d1 = fabs(ptRight.x-i);
d2 = fabs(j-ptTop.y);
if(d1<=d2)//靠近右边
{
if(iMinRight>i && d1<dMax)
{
iMinRight = i;
}
}
else//靠近上边
{
if(iMinTop<j && d2<dMax)
{
iMinTop = j;
}
}
}
else if(i>ptCenter.x && i<=ptRight.x && j>ptCenter.y && j<ptBottom.y)//第2象限
{
d1 = fabs(ptRight.x-i);
d2 = fabs(ptBottom.y-j);
if(d1<=d2)//靠近右边
{
if(iMinRight>i && d1<dMax)
{
iMinRight = i;
}
}
else//靠近下边
{
if(iMinBottom>j && d2<dMax)
{
iMinBottom = j;
}
}
}
else
{
continue;
}
}
}
}
innerEdge.left = (iMinLeft!=-1)?iMinLeft:rectEdge.left;
innerEdge.right = (iMinRight!=65535)?iMinRight:rectEdge.right;
innerEdge.top = (iMinTop!=-1)?iMinTop:rectEdge.top;
innerEdge.bottom = (iMinBottom!=65535)?iMinBottom:rectEdge.bottom;
}