图像的种子算法之c++实现(qt + 不调包)

1.基本原理

    相互连通且颜色相近的像素集合可以被看成图像的区域,而区域填充就是将每一块图像区域用指定颜色填充,填充的算法有很多种,但今天的猪脚是种子算法。在使用种子算法的时候,我们要注意两点,第一点:连通像素的搜索分为四方向和八方向,根据应用自己选择就行;第二点:边界判断,如果填充过程遇到某点的像素值和基准像素值差距太大,就可以视该点位边界像素。

    种子算法的实现过程:

    1)选取一个起始种子点,获取基准颜色,将种子点压入栈

    2)从栈中取一个像素,依次对该像素的左右连通像素进行填充,并在填充过程中判断每个填充位置的上下两行中的相邻像素是否需要填充,将需要填充的相邻像素压入栈

    3)对栈中的像素进行检查,去除已被填充的像素

    4)重复第2、3步,直到栈为空。

2.代码实现(代码是我以前自学图像处理时写的,代码很粗糙没做任何优化,但很好理解

//种子算法
QImage* MainWindow::FillArea(QImage* image,int* pos, int color,int delta)
{
    int stack[9999];
    int sk = 0;
    int stk = 0;
    int x =pos[0];
    int y =pos[1];
    int x1,y1;
    unsigned char flagBuf[image->width()][image->height()];
    memset(flagBuf,0,sizeof(unsigned char)*image->width()*image->height());
    QImage* newImage = new QImage(image->height(),image->width(),QImage::Format_ARGB32);
    QColor color1;
    QColor color2;
    color1 = QColor(image->pixel(x,y));
    unsigned nowColor[3];
    nowColor[0] = color1.red();
    nowColor[1] = color1.green();
    nowColor[2] = color1.blue();
    stack[sk] = x;
    stack[sk + 1] = y;
    sk+=2;
    while(sk > 0)
    {
        sk-=2;
        int *tempStack = new int [9999];
        int*pos = new int[2];
        pos[0] = stack[sk];
        pos[1] = stack[sk+1];

        x1 = pos[0];
        y1 = pos[1];
        stk = 0;
        newImage->setPixel(x1,y1,qRgb(color,color,color));
        flagBuf[x1][y1] = 1;
        for(int step = -1; step<=1; step+=2)
        {
            x1 = pos[0] + step;
            y1 = pos[1];
            while(x1>=0 && x1 < image->width())
            {
                color2 = QColor(image->pixel(x1,y1));
                if(abs(color2.red() - nowColor[0])<delta && abs(color2.green() - nowColor[1])<delta && abs(color2.blue() - nowColor[2])<delta)
                {
                    image->setPixel(x1,y1,qRgb(color,color,color));
                    flagBuf[x1][y1] = 1;
                    color2 = QColor(image->pixel(x1,y1-1));
                    if(y1>0 && flagBuf[x1][y1 -1] == 0 && abs(color2.red() - nowColor[0])<delta && abs(color2.green() - nowColor[1])<delta && abs(color2.blue() - nowColor[2])<delta)
                    {
                        tempStack[stk]=x1;
                        tempStack[stk +1] = y1-1;
                        stk +=2;
                    }
                    color2 = QColor(image->pixel(x1,y1+1));
                    if(y1<image->height() - 1 && flagBuf[x1][y1+1] == 0 && abs(color2.red() - nowColor[0])<delta && abs(color2.green() - nowColor[1])<delta && abs(color2.blue() - nowColor[2])<delta)
                    {
                        tempStack[stk]=x1;
                        tempStack[stk +1] = y1+1;
                        stk +=2;
                    }
                    x1+=step;
                }
                else
                    break;
            }
         }
        tempStack[stk]=-1;
        int k =0;
        for(int i = 0;i<sk;i+=2)
        {
            x = stack[i];
            y= stack[i+1];
            if(flagBuf[x][y] == 0)
            {
                stack[k] = stack[i];
                stack[k+1] = stack[i+1];
                k+=2;
            }
        }
        sk = k;
        int i = 0;
        while(tempStack[i]!=-1)
        {
            stack[sk]=tempStack[i];
            stack[sk+1]=tempStack[i+1];
            sk+=2;
            i+=2;
        }
    }
    return image;
}

3.参考资料

    数字图像处理——技术详解与Visual C++实践(左飞等著),写代码与写博客的时间相差两年,至于还参考其他的资料不,我已经忘记了,如若需要,我可以补上去

发布了138 篇原创文章 · 获赞 141 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/u013289254/article/details/101224177
今日推荐