快速的距离变换
原理:
代码:
/* 快速的距离变换
* QImage &image 输入图像
* QImage &otpImage 输出图像
* int distant_modle 距离计算模型 1 表示 欧几里德距离
* 2 表示 曼哈顿距离(City Block Distance)
* 3 表示 象棋格距离(Chessboard Distance)
*/
void Fast_Distance_transform(QImage &image,QImage &otpImage,int distance_modle)
{
int width = image.width();
int height = image.height();
int all_size = width * height; //图像的大小
int i,j,n; //遍历用的
int x,y;
int p1[4][2] = {{0,-1},{-1,-1},{-1,0},{-1,1}};
int p2[4][2] = {{1,-1},{1,0},{1,1},{0,1}};
int curr_index; //当前的指针
int grey;
float distance;
float d;
float dx[4];
float d_min = 10000;
Init_Image(otpImage,0);
QVector<int> mask(all_size);
QVector<float> dist_mask(all_size);
for(i = 1; i < height-1; i++)
{
for(j = 1; j < width-1; j++)
{
curr_index = i * width + j;
mask[curr_index] = (qGray(image.pixel(j,i)) > 2) ? 1 : -1;
dist_mask[curr_index] = (qGray(image.pixel(j,i)) > 2) ? 1 : -1;
}
}
//前向遍历
for(i = 1; i<height-1; i++)
{
for(j = 1; j<width-1; j++)
{
curr_index = i * width + j;
if(mask[curr_index] == 1)
{
d = dist_mask[curr_index];
for(n = 0; n<4; n++)
{
y = i + p1[n][0];
x = j + p1[n][1];
curr_index = y * width + x;
dx[n] = dist_mask[curr_index] + Fast_Distance_Modle(x,y,j,i,distance_modle);
if(dx[n] < d_min)
{
d_min = dx[n];
}
}
distance = fmax(d,d_min);
dist_mask[curr_index] = distance;
}
}
}
//后向遍历
for(i = height-2; i>0; i--)
{
for(j = width-2; j>0; j--)
{
curr_index = i * width + j;
if(mask[curr_index] == 1)
{
d = dist_mask[curr_index];
for(n = 0; n<4; n++)
{
y = i + p2[n][0];
x = j + p2[n][1];
curr_index = y * width + x;
dx[n] = dist_mask[curr_index] + Fast_Distance_Modle(x,y,j,i,distance_modle);
if(dx[n] < d_min)
{
d_min = dx[n];
}
}
distance = fmax(d,d_min);
dist_mask[curr_index] = distance;
if(distance>255)
{
grey = 255;
}else {
grey = distance + 0.5;
}
otpImage.setPixel(j,i,qRgb(grey,grey,grey));
}
}
}
}
距离计算模式;
//距离计算模式
float Fast_Distance_Modle(int x1,int y1,int x2,int y2,int modle)
{
float x,y;
switch (modle) {
//欧式距离
case 1:
x = (x1-x2)*(x1-x2);
y = (y1-y2)*(y1-y2);
return sqrtf(x+y);
break;
//城市距离
case 2:
x = fabs(x1 - x2);
y = fabs(y1 - y2);
return fmax(x,y);
break;
//棋盘距离
case 3:
return fabs(x1-x2)+fabs(y1-y2);
break;
default:
return 0;
break;
}
}