Union-Find 알고리즘을 이용하여 영역 분할 과정이다. 각각의 픽셀에서 4방향으로 연결된 픽셀이 속한 영역 merge 할 수 있는지를 시도한다. merge 조건은 현재 픽셀의 그레이 값과 인접 영역의 평균 그레이 값의 차이가 주어진 임계값보다 작은 경우다.

$$\tt \text{merge 조건: }\quad | 그레이 값- \text{인접 영역 평균값}| < threshold$$

컬러 영상의 경우에는 RGB 채널에 조건을 부여하거나 gray level만 이용해서 판단할 수 있다. root node 수만큼의 분할 영역이 만들어지고, 임계값이 클수록 분할된 각 영역의 사이즈가 커진다.  

gray = 0.2989 * r + 0.5870 * g + 0.1140 * b ;

같은 평균 픽셀값을 가지고 있더라도 4-방향으로 서로 연결된 영역이 아니면 합병되지 못하고 서로 다른 영역으로 남는다. 이를 하나의 영역으로 만들려면 분할된 영역을 다시 검사를 하는 과정이 필요하다. 자세한 과정은 Statistical Region Merge(SRM) 알고리즘(kipl.tistory.com/98)에 잘 구현이 되어 있다.

struct Universe {
    int n;
    std::vector<int> sizes;
    std::vector<int> sums;
    std::vector<int> parent;
    Universe(int n, BYTE *image) {
        this->n = n;
        parent.resize(n, -1);  // all nodes are root;
        sizes.resize(n, 1); 
        sums.resize(n);
        for (int i = 0; i < n; i++)
            sums[i] = image[i];
    }
    int FindCompress (int node) { // find root node;
        if ( parent[node] < 0 ) return node;	 // root-node;
        else  return parent[node] = FindCompress (parent[node]);
        // 찾음과 동시에 depth을 줄인다;   
    }
    int Find(int node) { // find root;
        while (parent[node] >= 0) node = parent[node];
        return node;
    }
    bool Predicate(int root1, int root2, int thresh) {
        double diff = double(sums[root2]) / sizes[root2] 
                      - double(sums[root1]) / sizes[root1];
        return fabs(diff) < thresh;
    }
    void Merge(int root1, int root2) {
        sums[root2]  += sums[root1];
        sizes[root2] += sizes[root1];
        parent[root1] = root2;			 // r2 트리로 합병함;
    }
};
// root 노드는 분할영역의 픽셀 갯수와 픽셀 값의 합을 저장한다.
// 처음 각 픽셀이 root 이고, 픽셀 갯수는 1, 픽셀값은 자신의 픽셀값을 저장;
BOOL UnionFindAverage(BYTE *image, int width, int height, int thresh) {
    Universe *UF = new Universe(width * height, image);
    // 4-connectivity:
    // 첫행; LEFT 픽셀이 속한 영역의 평균값과 차이가 thresh 내이면 left로 합병;
    for ( int x = 1; x < width; x++ ) {
        int left = UF->FindCompress (x - 1);
        int curr = UF->FindCompress (x);
        if (UF->Predicate(curr, left, thresh))
            UF->Merge(curr, left);
    }
    //Flatten(y=0);
    for (int x = 0; x < width; x++) UF->FindCompress(x);
    for ( int y = 1, pos = y * width; y < height; y++ ) {
        // x = 0; TOP 픽셀이 속학 영역과 합병 체크;
        int up   = UF->FindCompress (pos - width);
        int curr = UF->FindCompress (pos);
        if (UF->Predicate(curr, up, thresh))
            UF->Merge(curr, up);
        pos++;
        // TOP-LEFT 픽셀 영역과 합병 체크;
        for ( int x = 1; x < width; x++, pos++ ) {
            int left = UF->FindCompress(pos - 1);
            int curr = UF->FindCompress(pos);
            // left와 합병이 되면 left가 up과 합병이 되는지 확인;
            if (UF->Predicate(curr, left, thresh)) {
                UF->Merge(curr, left);
                curr = left;
            }
            int up = UF->FindCompress (pos - width);
            if ((curr != up) && (UF->Predicate(curr, up, thresh))) 
                UF->Merge(curr, up);
        }
        // Flatten(y>0)
        for (int x = 0; x < width; x++) UF->FindCompress(x + y * width);
    }

    // 평균 이미지 생성;
    for ( int k = width*height; k-->0;) {
        int root = UF->Find(k);
        int avg = int(double(UF->sums[root]) / UF->sizes[root] + 0.5);
        image[k] = avg > 255 ? 255 : avg;
    }
    delete UF;
    return TRUE;
};

네이버 블로그 이전
statistical region merge 알고리즘을 적용한 결과

 
 
 
 
728x90

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

Octree Quantization  (0) 2021.01.12
Median-Cut 컬러 양자화  (0) 2021.01.12
Multilevel Otsu Thresholding  (0) 2021.01.09
Binary Image에서 Convex Hull  (0) 2021.01.06
Kuwahara Filter  (2) 2020.12.28
Posted by helloktk
,

http://www.lix.polytechnique.fr/~nielsen/tpami04-nn.pdf

Abstract—This paper explores a statistical basis for a process often described in computer vision: image segmentation by region merging following a particular order in the choice of regions. We exhibit a particular blend of algorithmics and statistics whose segmentation error is, as we show, limited from both the qualitative and quantitative standpoints. This approach can be efficiently approximated in linear time/space, leading to a fast segmentation algorithm tailored to processing images described using most common numerical pixel attribute spaces. The conceptual simplicity of the approach makes it simple to modify and cope with hard noise corruption, handle occlusion, authorize the control of the segmentation scale, and process unconventional data such as spherical images. Experiments on gray-level and color images, obtained with a short readily available C-code, display the quality of the segmentations obtained. 

인간은 영상을 보면 매우 쉽게 비슷한 픽셀 값을 갖는 영역으로 분리해서 인식을 한다. 우리가 보는 영상이 여러 개의 균일한 영역으로 나누어진 기본 영상에 랜덤 노이즈가 추가되어 만들어졌다고 생각해보자. 영상의 픽셀 값이 기본 영상의 픽셀 값에 일정 구간(Q)에서 값을 취하는 랜덤 변수가 더해져서 만들어졌다고 보면, 영상에서 다른 두 영역($R, R'$)의 픽셀 평균값의 차이 $(\overline{R}-\overline{R'})$와 기본 영상에서 랜덤 변수에 의한 통계적 기댓값의 차이 $(E(\overline{R}-\overline{R'}))$는 주어진 $0 < δ < 1$ 에 다음식을 만족함을 보일 수 있다.

따라서, 두 영역 $R$과 $R'$에 대해서 우변의 값이 이 부등식을 만족하지 않으면 두 영역은 하나로 인식될 수 있다.

 

#region count = 576; 많은 영역이 1픽셀로 구성이 되었있다;
#region count > 1 = 302;
#region count > 2 = 222;
#region count > 3 = 179;
#region count > 4 = 140;

 

 

728x90

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

RANSAC: Ellipse Fitting  (1) 2012.10.07
Autofocus Algorithm  (0) 2012.06.03
Local Histogram Equalization  (0) 2012.03.10
2차원 Savitzky-Golay Filters 응용  (0) 2012.02.28
webcam용 QR code detector  (0) 2012.02.19
Posted by helloktk
,