C++ 图像处理(十五) 快速的距离变换

快速的距离变换

原理:

代码:

/*      快速的距离变换
 *  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;
    }
}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值