图像细化

由于最近项目需要,粗略的研究了一下不同的细化算法。https://www.cnblogs.com/mikewolf2002/p/3327318.html 这位大哥的博客里面有一系列的细化算法,还附带原理,可以看看。

我这里就贴一下不同细化算法的结果图吧

Rosenfeld

 

ZhangSuen

 

Thining-Algorithm

Pavlidis

Linear Skeletons from Square Cupboards

最后一个是我自己理解后修改的代码:

满足的条件可以总结为:

(1)为前景点

(2)为边界点

(3)端点不能删

(4)孤立点不能删

(5)连通性不变

(6)先从边缘删

附一下代码:

    //8邻域的偏移量
    int offset[9][2] = { {0,0},{1,0},{1,-1},{0,-1},{-1,-1},
    {-1,0},{-1,1},{0,1},{1,1} };
    //四邻域的偏移量
    int n_odd[8] = { 1,  3,  5,  7 };
    int px, py;
    int b[9];                      //3*3格子的灰度信息
    int condition[6];              //1-6个条件是否满足
    int counter;                   //移去像素的数量
    int i, x, y, copy, sum;

    int width, height;
    width = n_X;
    height = n_Y;
    double *img = outline_childs;
    int step = n_X;
    do
    {

        counter = 0;

        for (y = 0; y < height; y++)
        {

            for (x = 0; x < width; x++)
            {

                //前面标记为删除的像素,我们置其相应邻域值为-1
                for (i = 0; i < 9; i++)
                {
                    b[i] = 0;
                    px = x + offset[i][0];
                    py = y + offset[i][1];
                    if (px >= 0 && px < width &&    py >= 0 && py < height)
                    {
                        // printf("%d\n", img[py*step+px]);
                        if (img[py*step + px] >0)
                        {
                            b[i] = 1;
                        }
                        else if (img[py*step + px] == -1)
                        {
                            b[i] = -1;
                        }
                    }
                }
                for (i = 0; i < 6; i++)
                {
                    condition[i] = 0;
                }

                //条件1,是前景点
                if (b[0] == 1) condition[0] = 1;

                //条件2,是边界点
                sum = 0;
                for (i = 0; i < 4; i++)
                {
                    sum = sum + 1 - abs(b[n_odd[i]]);
                }
                if (sum >= 1) condition[1] = 1;

                

                //条件3, 端点不能删除
                //端点不是只有等于1才是端点
                sum = 0;
                for (i = 1; i <= 8; i++)
                {
                    if(b[i]>0)
                    sum = sum + /*abs*/(b[i]);
                }
                if (sum >= 4) condition[2] = 1;

                if (sum == 2)
                {
                    if ((b[4] == 1 && b[3] == 1) || (b[2] == 1 && b[3] == 1)
                        || (b[4] == 1 && b[5] == 1) || (b[5] == 1 && b[6] == 1)
                        || (b[6] == 1 && b[7] == 1) || (b[7] == 1 && b[8] == 1)
                        || (b[8] == 1 && b[1] == 1) || (b[1] == 1 && b[2] == 1))
                        condition[2] = 0;
                    else
                        condition[2] = 1;
                }
                if (sum == 3)
                {
                    if ((b[4] == 1 && b[3] == 1&& b[2] == 1 )
                        || (b[4] == 1 && b[5] == 1 && b[6] == 1)
                        || (b[6] == 1 && b[7] == 1 && b[8] == 1)
                        || (b[8] == 1 && b[1] == 1 && b[2] == 1))
                        condition[2] = 0;
                    else
                        condition[2] = 1;
                }

                //条件4, 孤立点不能删除
                sum = 0;
                for (i = 1; i <= 8; i++)
                {
                    if (b[i] == 1) sum++;
                }
                if (sum >=2) condition[3] = 1;

                //条件5, 连通性检测
                if (func_nc8(b) == 1) condition[4] = 1;

                //条件6,宽度为2的骨架只能删除1边
                sum = 0;
                for (i = 1; i <= 8; i++)
                {
                    if (b[i] != -1)
                    {
                        sum++;
                    }
                    else
                    {
                        copy = b[i];
                        b[i] = 0;
                        if (func_nc8(b) == 1) sum++;
                        b[i] = copy;
                    }
                }
                if (sum == 8) condition[5] = 1;

                if (condition[0] && condition[1] && condition[2] && condition[3] && condition[4] && condition[5])
                {
                    img[y*step + x] = -1; //可以删除,置位GRAY,GRAY是删除标记,但该信息对后面像素的判断有用
                    counter++;
                    //printf("----------------------------------------------\n");
                    //PrintMat(dst);
                }
            }
        }

        if (counter != 0)
        {
            for (y = 0; y < height; y++)
            {
                for (x = 0; x < width; x++)
                {
                    if (img[y*step + x] == -1)
                        img[y*step + x] = 0;

                }
            }
        }

    } while (counter != 0);

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值