적용 예는 http://kipl.tistory.com/1         

std::vector<int> sort_pixels(std::vector<BYTE> &img,   std::vector<int> &sorted) ;

// img의 픽셀 위치를 gray값이 커지는 순서로 정렬하고, cumulative histogram chist를 반함함.

// chist은 sorted img에서 특정한 gray값을 갖는 픽셀이 포함된 위치 구간을 알 수 있게 한다.

// 8-way connectivity case only;
// last update: 2024-7-22;
#define MASK -2
#define WSHED 0
#define INIT -1
#define RANGE(i,j,h,w) (((i)>=0) && ((j)>=0) && ((i)<h) && ((j)<w))
// main procedure;
int watershed8(std::vector<BYTE> &img, int width, int height, 
               std::vector<int*> &lab)
{
    int cur_label = 0 ;
    std::queue<int> q;
    std::vector<int> dmap(img.size(), 0);  
    std::vector<int> sorted(img.size());
    std::vector<int> chist = sort_pixels(img, sorted); 
    int hmin = -1, hmax = 255;
    while (!chist[++hmin]);
    while (chist[--hmax]==chist[255]); hmax++; 
    // prepare label image;
    for (int y = 0; y < height; y++)
        for (int x = 0; x < width; x++) lab[y][x] = INIT;
    //
    int *plab = lab[0]; //1-dim representative of label image
    for (int h = hmin; h <= hmax; h++) {
        int *bin_left = &sorted[0] + (h==0 ? 0: chist[h-1]);
        int *bin_right = &sorted[0] + chist[h];
        for (int *curr = bin_left; curr < bin_right; curr++) {
            int pos = *curr;
            plab[pos]=MASK;      
            int x=pos % width;
            int y=pos / width;      
            for (int k=-1;k<=1;k++)
                for (int m=-1;m<=1;m++) 
                    if (RANGE(y+k, x+m, height, width)) 
                        if ((k!=0) || (m!=0))
                            if ((lab[y+k][x+m]>0) || (lab[y+k][x+m]==WSHED)) {
                                q.push(pos);
                                dmap[pos]=1;
                                k=1; break;
                            }
        }      

        int cur_dist=1;
        q.push(-1);
        while (1) {
            int pos = q.front(); q.pop();
            if (pos==-1) {
                if (q.empty()) break;
                else {
                    q.push(-1);
                    cur_dist++;
                    pos = q.front(); q.pop();
                }
            }
            int x=pos % width;
            int y=pos / width;
            for (int k=-1;k<=1;k++)
                for (int m=-1;m<=1;m++) {
                    if (RANGE(y+k, x+m, height, width)) 
                        if ((k!=0) || (m!=0)) {
                            int nn = (y+k)*width + (x+m);// nearest neightbor;
                            if ((dmap[nn]<cur_dist) && ((plab[nn]>0) || (plab[nn]==WSHED))) { 
                                if (plab[nn]>0) {
                                    if ((plab[pos]==MASK) || (plab[pos]==WSHED))
                                        plab[pos]=plab[nn];
                                    else if(plab[pos]!=plab[nn])
                                        plab[pos]=WSHED;
                                }
                                else if(plab[pos]==MASK) plab[pos]=WSHED;
                            } else if((plab[nn]==MASK) && (dmap[nn]==0)) {
                                dmap[nn]=cur_dist+1;
                                q.push(nn);
                            }
                        }
                }
        }  // end while(1)	    	  
        for (int *curr = bin_left; curr < bin_right; curr++) {
            int pos = *curr;
            dmap[pos]=0;	
            if (plab[pos]==MASK) {
                cur_label++;
                q.push(pos);
                plab[pos] = cur_label;
                while (!q.empty()) {
                    int pos1=q.front(); q.pop();
                    int x=pos1 % width;
                    int y=pos1 / width;
                    for (int k=-1;k<=1;k++)
                        for (int m=-1;m<=1;m++)
                            if (RANGE(y+k, x+m, height, width)) 
                                if ((k!=0) || (m!=0)) {
                                    int nn = (y+k)*width + (x+m);
                                    if (plab[nn]==MASK) {
                                        q.push(nn);
                                        plab[nn]=cur_label;
                                    }
                                }
                }
            }
        }
    }  //endfor h    	    	
    
    // convert the result(labeled rgns + boundary) to a suitable form;
    mark_boundary8(lab, width, height);
    return cur_label;
}

 

 

 
 
728x90

'Image Recognition' 카테고리의 다른 글

Blur Detection  (0) 2010.05.25
Savitzky-Golay Smoothing Filter  (2) 2010.03.24
Retinex 알고리즘  (11) 2010.02.03
Gaussian Mixture Model & KMeans  (4) 2010.01.30
Image Morphing  (0) 2010.01.24
Posted by helloktk
,