0

我有一个任务,旨在从黑白图像中提取最大的对象,其中黑色是背景。我使用的是 2-pass 算法,这里有一个解释它是如何工作的链接: http://en.wikipedia .org/wiki/Connected-component_labeling#Two-pass

我的问题:1.我正在使用一个结构数组,我想将其尺寸定义为与“输入图像”相同,所以{我该怎么做}

2.我制作了一个包含两列和行数的数组作为等价表,但我不确定我是否正确,我该如何解决?

  1. 如何使用等价表“重新标记第二遍中的像素?如何编写第二遍的代码?

我的代码:

Image Image::MaxCC()
{
    Image obj;
    obj.height = height;
    obj.width = width;
    short ** original = image;
    short ** output = new short*[height];

    for (int i = 0; i < height; i++)
    {
        output[i] = new short[width];
    }
    obj.imageHeader = imageHeader;
    obj.image = output;

    //label array
    //structure 
    struct label
    {
        int lab;
        int counter;
    };

    label L[][]; //I want to use the dimensions of the input image which is obj.height and obj.width

    //Initialize 

    for (int i = 0; i <= obj.height; i++)
    {
        for (int j = 0; j <= obj.width; j++)
        {
            L[i][j].lab = 0;
            L[i][j].counter = 0;
        }
    }
     int N = 0;
     int count = 0;

     //equivlance tabel 
     int eq[100][2];
     int row = 1;
     int x = 1;
     int s;

// conditions [FIRST ITERATION]
    for (int c = 0; c < obj.width; c++)
    {
        for (int r = 0; r < obj.height; r++)
        {
            // If the pixel is balck , add no label
            if (image[r][c] == 0)
                obj.image[r][c] = 0;

            //Do the pixel's North and West neighbors have different pixel values than current pixel?
            else if (image[r - 1][c] == 0 && image[r][c - 1] == 0)
            {
                L[r][c].lab = N++;
                L[r][c].counter = count++;
                obj.image[r][c] = L[r][c].lab;

            }

            //Does the pixel to the left (West) have the same value as the current pixel?
            else if (image[r][c - 1] == image[r][c])
            {
                L[r][c - 1].counter = count++;
                obj.image[r][c] = L[r][c - 1].lab;

            }

            //Does the pixel to the left (West) have a different value and the one to the North the same value as the current pixel?
            else if (image[r - 1][c] == image[r][c] && image[r][c - 1] != image[r][c])
            {
                L[r - 1][c].counter = count++;
                obj.image[r][c] = L[r - 1][c].lab;
            }

            //Do both pixels to the North and West have the same value as the current pixel but not the same label?
            else if (image[r - 1][c] == image[r][c] && image[r][c - 1] == image[r][c] && L[r - 1][c].lab != L[r][c - 1].lab)
            {
                obj.image[r][c] = L[r - 1][c].lab;
                eq[row][1] = x;
                if (L[r - 1][c].counter << L[r][c - 1].counter)
                {
                    L[r - 1][c].counter = count++; 
                    s = L[r - 1][c].lab;

                }
                else
                {
                    L[r][c - 1].counter = count++;
                    s = L[r][c - 1].lab;
                    eq[row][2] = s;  //..
                    x++; row++;
                }
            }

        }

        //THE SECONF ITERATION ?

        //Iteration to get the maximum counter
        label max;
        int temp;

        for (int c = 0; c < obj.width; c++)
        {
            for (int r = 0; r < obj.height; c++)
            {
                temp = L[r][c].counter;
                if (temp > max.counter)
                    max.counter = temp;
            }
        }
            //iteratio to extract the bigger object
            for (int c = 0; c < obj.width; c++)
            {
                for (int r = 0; r < obj.height; c++)
                {
                    if (max.lab == L[r][c].lab)
                        obj.image[r][c] = 255;
                    else
                        obj.image[r][c] = 0;
                }
            }

    }

    return obj;

}
4

2 回答 2

1

我还为两遍算法编写了 python 代码,并查找是否有任何与您的需要相关的内容。

from PIL import Image, ImageOps
%pylab inline

import sys
import random
import numpy


def colourize(img):
    height, width = img.shape

    colors = []
    colors.append([])
    colors.append([])
    color = 1
    # Displaying distinct components with distinct colors
    coloured_img = Image.new("RGB", (width, height))
    coloured_data = coloured_img.load()

    for i in range(len(img)):
        for j in range(len(img[0])):
            if img[i][j] > 0:
                if img[i][j] not in colors[0]:
                    colors[0].append(img[i][j])
                    colors[1].append((random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)))

                ind = colors[0].index(img[i][j])
                coloured_data[j, i] = colors[1][ind]

    return coloured_img


def binarize(img_array, threshold=130):
    for i in range(len(img_array)):
        for j in range(len(img_array[0])):
            if img_array[i][j] > threshold:
                img_array[i][j] = 0
            else:
                img_array[i][j] = 1
    return img_array


def ccl4(img_array):
    ##### first pass #####
    print ("starting first pass")
    curr_label = 1;
    img_array = numpy.array(img_array)
    labels = numpy.array(img_array)

    # storing label conversions
    label_conv = []
    label_conv.append([])
    label_conv.append([])

    count = 0
    for i in range(1, len(img_array)):
        for j in range(1, len(img_array[0])):

            if img_array[i][j] > 0:
                label_x = labels[i][j - 1]
                label_y = labels[i - 1][j]

                if label_x > 0:
                    # both x and y have a label
                    if label_y > 0:

                        if not label_x == label_y:
                            labels[i][j] = min(label_x, label_y)
                            if max(label_x, label_y) not in label_conv[0]:
                                label_conv[0].append(max(label_x, label_y))
                                label_conv[1].append(min(label_x, label_y))
                            elif max(label_x, label_y) in label_conv[0]:
                                ind = label_conv[0].index(max(label_x, label_y))
                                if label_conv[1][ind] > min(label_x, label_y):
                                    l = label_conv[1][ind]
                                    label_conv[1][ind] = min(label_x, label_y)
                                    while l in label_conv[0] and count < 100:
                                        count += 1
                                        ind = label_conv[0].index(l)
                                        l = label_conv[1][ind]
                                        label_conv[1][ind] = min(label_x, label_y)

                                    label_conv[0].append(l)
                                    label_conv[1].append(min(label_x, label_y))

                        else:
                            labels[i][j] = label_y
                    # only x has a label
                    else:
                        labels[i][j] = label_x

                # only y has a label
                elif label_y > 0:
                    labels[i][j] = label_y

                # neither x nor y has a label
                else:
                    labels[i][j] = curr_label
                    curr_label += 1

                    ##### second pass #####
    print ("starting second pass")
    count = 1
    for idx, val in enumerate(label_conv[0]):

        if label_conv[1][idx] in label_conv[0] and count < 100:
            count += 1
            ind = label_conv[0].index(label_conv[1][idx])
            label_conv[1][idx] = label_conv[1][ind]

    for i in range(1, len(labels)):
        for j in range(1, len(labels[0])):

            if labels[i][j] in label_conv[0]:
                ind = label_conv[0].index(labels[i][j])
                labels[i][j] = label_conv[1][ind]

    return labels


def main():
    numpy.set_printoptions(threshold=sys.maxsize)
    # Open the image
    img = Image.open("./image1.png")

    # Threshold the image
    img = img.convert('L')
    img = ImageOps.expand(img, border=1, fill='white')
    img = numpy.array(img)
    img = binarize(img)

    

    img = ccl4(img)

    # Colour the image using labels
    coloured_img = colourize(img)

    # Show the coloured image
    coloured_img.show()
    


if __name__ == "__main__": main()
于 2021-03-03T22:08:47.430 回答
0

缺少部分代码,因此我做出以下假设:heightwidthimage类的成员Image

关于你的问题:

1.我正在使用一个结构数组,我想将其尺寸定义为与“输入图像”相同,所以{我该怎么做}

label L[][]; //I want to use the dimensions of the input image which is obj.height and obj.width

为什么不将它声明为指针的指针,就像您对输出所做的那样,即:

label ** L = new label*[height];
for (int i = 0; i < height; i++)
{
   L[i] = new label[width];
}

2.我制作了一个包含两列和行数的数组作为等价表,但我不确定我是否正确,我该如何解决?

关于不相交集数据结构,我认为数组应该能够动态增长(理论上是无限期的,所以我不会使用静态大小)。我建议你看一下,并了解一些现有的实现(这里一个在C++中,另一个在python中),然后在你理解它们之后实现你的。

编辑:我刚刚在SO上找到了另一个实现。

  1. 如何使用等价表“重新标记第二遍中的像素?如何编写第二遍的代码?

据我了解,该算法的工作原理是这样的:在第一遍中,它用一个值标记每个前景像素,但是,可能会发生部分 blob 最终包含不同的标签。在第二遍中,我们希望实现属于一个 blob 的每个像素都被标记为相同的值。

然而,在等价表中,对于每一个标签,你可以很容易地找到与其等价的最小标签,即在同一个组内。

考虑链接的 Wikipedia 文章中的示例。(尤其是第 2 步之后的表格。)在这里,如果您在第二遍中遍历图像,并找到例如值为 5 的标签,那么使用等价表,您将能够发现,它相当于标签 3(因此将所有标记为 5 的像素更改为 3)。

于 2015-01-31T18:40:01.737 回答