/*HoughTransform参数说明:
HoughTransform(
Uchar* input, 输入边缘图像
IO_INFO* ioInfo, 输出:ioInfo->cirX 、ioInfo->cirY 、ioInfo->cladRadius
int halfWidth, 圆心可能区域半宽(10像素)
int rowSize, 行数
int colSize 列数
)
return -1检测圆失败,return 0检测圆成功
*/
static int HoughTransform(Uchar* input, IO_INFO* ioInfo, int halfWidth, int rowSize, int colSize)
{
int* circleCenterDistribute = (int*)malloc(NUMBER_OF_RADIUS * rowSize * colSize * sizeof(int));
memset(circleCenterDistribute, 0, NUMBER_OF_RADIUS * rowSize * colSize * sizeof(int));
//int circleCenterDistribute[NUMBER_OF_RADIUS][NUMBER_OF_ROWS][NUMBER_OF_COLUMNS] = {};
int rMin = int(estimatedRadius - NUMBER_OF_RADIUS * 0.5); //查找最小半径
//int rMax = estimatedRadius + NUMBER_OF_RADIUS*0.5 - 1; //查找最大半径
int xCoordinate = 0; //圆心X坐标
int yCoordinate = 0; //圆心Y坐标
float angleStep = 0.2f * PI; //角度步长
//圆心可能区域的半宽,限制圆心范围进行搜索
int xMin = preCenterX - halfWidth;
int xMax = preCenterX + halfWidth;
int yMin = preCenterY - halfWidth;
int yMax = preCenterY + halfWidth;
//霍夫变换的坐标范围
int Xmin = xMin - estimatedRadius;
int Xmax = xMax + estimatedRadius;
int Ymin = yMin - estimatedRadius;
int Ymax = yMax + estimatedRadius;
if (Xmin<0)
{
Xmin = 0;
}
if (Xmax > colSize - 1)
{
Xmax = colSize - 1;
}
if (Ymin < 0)
{
Ymin = 0;
}
if (Ymax > rowSize - 1)
{
Ymax = rowSize - 1;
}
// 霍夫变换
for (int k = 0; k < NUMBER_OF_RADIUS; k++)
{
for (int i = Ymin; i <= Ymax; i++)
{
for (int j = Xmin; j <= Xmax; j++)
{
for (float angle = 0; angle < 2 * PI; angle += angleStep)
{
if (input[i * colSize + j] > 0)//边缘
{
xCoordinate = (int)roundf(j - (k + rMin)*cosf(angle));
yCoordinate = (int)roundf(i - (k + rMin)*sinf(angle));
//根据开始粗略估计圆心位置(preCenterY,preCenterX),限制圆心范围
if ((xCoordinate >= 0) && (xCoordinate >= xMin) && (xCoordinate < colSize) && (xCoordinate < xMax)
&& (yCoordinate >= 0) && (yCoordinate >= yMin) && (yCoordinate < rowSize) && (yCoordinate < yMax))
{
//circleCenterDistribute[k][yCoordinate][xCoordinate] += 1;
circleCenterDistribute[k * rowSize * colSize + yCoordinate* colSize + xCoordinate] += 1;
}
}
}
}
}
}
//寻找圆心
int MaxValue = 0;
for (int k = 0; k < NUMBER_OF_RADIUS; k++)
{
for (int i = yMin; i < yMax; i++)
{
for (int j = xMin; j < xMax; j++)
{
if (circleCenterDistribute[k * rowSize * colSize + i * colSize + j] > MaxValue)
{
//MaxValue = circleCenterDistribute[k][i][j];
MaxValue = circleCenterDistribute[k * rowSize * colSize + i * colSize + j];
ioInfo->cirY = i;
ioInfo->cirX = j;
ioInfo->cladRadius = rMin + k;
}
}
}
}
//通过计算边缘在霍夫圆上的点数,判断是否正确检测到圆
int wide = OFF_BORDER_WIDTH;
float halfWidth = 1;//圆的半宽(0.5(400+)or 1(580+))
int numberOfCirpoints = 0;
for (int i = wide; i < rowSize - wide; i++)
{
for (int j = wide; j < colSize - wide; j++)
{
if (input[i * colSize + j]>0)
{
int d = (i - ioInfo->cirY) * (i - ioInfo->cirY) + (j - ioInfo->cirX) * (j - ioInfo->cirX);//点到圆心距离的平方
if (((ioInfo->cladRadius - halfWidth) * (ioInfo->cladRadius - halfWidth) <= d ) & (d <= (ioInfo->cladRadius + halfWidth) * (ioInfo->cladRadius + halfWidth)))
{
numberOfCirpoints = numberOfCirpoints + 1;
}
}
}
}
if (numberOfCirpoints<NUMBER_OF_CIRPOINT)//判断检测圆是否成功
{
printf("HoughTransform: Detection circle failed");
free(circleCenterDistribute);
circleCenterDistribute = NULL;
return -1;
}
free(circleCenterDistribute);
circleCenterDistribute = NULL;
return 0;
}
Hough变换求圆心位置
猜你喜欢
转载自blog.csdn.net/u013297911/article/details/88057622
今日推荐
周排行