通过二值图像查找边界
代码:
//pImgData为输入的二值图像
void TrackBoundary(unsigned char *pImgData, int nImgWidth, int nImgHeight)
{
//存储外边界
unsigned char *pBoudary = new unsigned char[nImgWidth * nImgHeight];
memset(pBoudary, 0, nImgWidth * nImgHeight * sizeof(unsigned char));
int i, j, k;
int direction[8][2] = {-1, -1, 0, -1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 1, -1, 0}; //从左上角像素开始,逆时针判断
for(i = 1; i < nImgHeight - 1; i++)
{
for(j = 1; j < nImgWidth - 1; j++)
{
if(pImgData[i * nImgWidth + j] > 0)
{
for(k = 0; k < 8; k++)
{
int ii = i + direction[k][0];
int jj = j + direction[k][1];
if(pImgData[ii * nImgWidth + jj] == 0)
pBoudary[ii * nImgWidth + jj] = 255;//通过查找白色区域周围是否有黑色区域来确定是否为边界
}
}
}
}
//存储去除小边界后的边界图像
unsigned char *pFinalBoundary = new unsigned char[nImgWidth * nImgHeight];
memset(pFinalBoundary, 0, nImgWidth * nImgHeight * sizeof(unsigned char));
//存储搜寻标识
unsigned char *pSearchFlag = new unsigned char[nImgWidth * nImgHeight];
memset(pSearchFlag, 0, nImgWidth * nImgHeight * sizeof(unsigned char));
for(i = 1; i < nImgHeight - 1; i++)
{
for(j = 1; j < nImgWidth - 1; j++)
{
if(pBoudary[i * nImgWidth + j] > 0 && pSearchFlag[i * nImgWidth + j] == 0)
Search(pBoudary, pFinalBoundary, pSearchFlag, nImgWidth, nImgHeight, i, j);
}
}
memcpy(pImgData, pFinalBoundary, nImgWidth * nImgHeight * sizeof(unsigned char));
if(pBoudary != NULL)
{
delete[] pBoudary;
pBoudary = NULL;
}
if(pFinalBoundary != NULL)
{
delete[] pFinalBoundary;
pFinalBoundary = NULL;
}
if(pSearchFlag != NULL)
{
delete[] pSearchFlag;
pSearchFlag = NULL;
}
}
对边界进行搜索,剔除小的边界
代码:
//其中vector<BoundaryPoint> BounVector;在全局中定义,BounVector是一个全局变量
void Search(unsigned char *pImgData, unsigned char *pFinalBoundary, unsigned char *pSearchFlag, int nImgWidth, int nImgHeight, int row, int col)
{
BoundaryPoint BPoint;
BPoint.x = col;
BPoint.y = row;
BounVector.push_back(BPoint);
pSearchFlag[row * nImgWidth + col] = 1;
int direction[8][2] = {-1, -1, 0, -1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 1, -1, 0}; //从左上角像素开始,逆时针判断
bool bIsStop = false;
for(int k = 0; k < 8; k++)
{
int ii = row + direction[k][0];
int jj = col + direction[k][1];
if((ii < 0) || (jj < 0) || (ii > nImgHeight - 1) || (jj > nImgWidth - 1))
continue;
if(pImgData[ii * nImgWidth + jj] > 0 && pSearchFlag[ii * nImgWidth + jj] == 0)
{
Search(pImgData, pFinalBoundary, pSearchFlag, nImgWidth, nImgHeight, ii, jj);
bIsStop = true;
}
}
if(bIsStop == false)
return;
if(!BounVector.empty())
{
if(BounVector.size() < 50)
{
BounVector.clear();
return;
}
for(int z = 0; z < BounVector.size(); z++)
{
pFinalBoundary[BounVector[z].y * nImgWidth + BounVector[z].x] = 255;
}
BounVector.clear();
}
}