使用我编写的函数标记图像时,与 skimage measure.label 函数相比,我没有获得相同的结果

When labelling an image using a function I wrote, I don't obtain the same result compared to the skimage measure.label function

我的目标是根据第一原理实现 skimage measure.label 功能。我想这样做以获得带标签的图像。

一共有三个函数。第一个 "ccl" 遍历每个像素,检查之前是否访问过该像素并设置适当的标签值。第二个函数 "check_neighbours" 查看所有周围的像素,以比较它们是否构成图像中同一标签的一部分。它还确定哪些值是相关的。最后一个函数 "join_neighbours" 用于连接相关的部分。

import cv2
import numpy as np
from skimage import measure
from skimage.filters import threshold_otsu

bgr_image=cv2.imread('filename')
gray_image = np.dot(bgr_image[..., :3], [0.114, 0.587, 0.299])
threshold = threshold_otsu(gray_image)
binary_image = gray_image > threshold

def check_neighbours(i, j, label,label_image,image,row,col):
    label_image[i,j] = label
    positions=[[i+1, j], [i-1, j],[i-1, j-1], [i + 1, j + 1],[i-1, j +1], [i + 1, j-1],[i, j+1], [i, j-1]]
    for pos in positions:
        if pos[0]>=0 and pos[0]<row and pos[1]>=0 and pos[1]<col and label_image[pos[0],pos[1]]>0 and image[pos[0],pos[1]] == 1:
            if label_image[pos[0],pos[1]] != label_image[i,j]:
                neighbours=sorted([label_image[pos[0],pos[1]],label_image[i,j]])
                if not neighbours in dup and not neighbours[::-1] in dup:
                    dup.append(neighbours)
        if pos[0]>=0 and pos[0]<row and pos[1]>=0 and pos[1]<col and image[pos[0],pos[1]] == 1:
            label_image[pos[0],pos[1]]=label
    return label_image

def ccl(image):
    row, col = image.shape
    count=0
    label_image=np.asarray(np.zeros((row,col)), np.uint8)
    for i in range(row):
        for j in range(col):
            if image[i,j] == 1:
                if label_image[i,j]>0:
                    label = label_image[i,j]
                else:
                    label=count+1
                    count=label
                label_image=check_neighbours(i, j, label, label_image,image, row, col)
    return label_image

def join_neighbours(image):
    row, col = image.shape
    for q in dup:
        for i in range(row):
            for j in range(col):
                if image[i,j]==q[1]:
                    image[i,j]=q[0]
    return image





#labelling image
dup=[]
print("Theirs")
print(measure.label(binary_image))
print()
print("Mine")
print(join_neighbours(ccl(binary_image)))

test_image=np.asarray([[True,True,True,True,False],[True,False,False,False,False],[False,False,False,True,True],[False,False,False,True,False],[True,False,False,True,True],[True,False,False,True,True],[True,False,False,True,False],[True,False,False,True,False],[True,False,False,True,False],[True,False,False,False,False],[True,False,True,False,True],[True,False,True,True,True]])

#labelling test data
dup=[]
print("Theirs")
print(measure.label(test_image))
print()
print("Mine")
print(join_neighbours(ccl(test_image)))

当我用小数据集测试函数时,输出与 measure.label 函数相同,但是,当我测试图像时,我似乎没有得到相同的输出。

Image:

measure.label output:
[[  0   0   0 ...   7   7   7]
 [  0   0   0 ...   7   7   7]
 [  0   0   0 ...   7   7   7]
 ...
 [  0   0   0 ... 107 107 107]
 [  0   0   0 ... 107 107 107]
 [  0   0   0 ... 107 107 107]]

My output:
[[ 0  0  0 ...  8  8  8]
 [ 0  0  0 ...  8  8  8]
 [ 0  0  0 ...  8  8  8]
 ...
 [ 0  0  0 ... 36 36 36]
 [ 0  0  0 ... 36 36 36]
 [ 0  0  0 ... 36 36 36]]


Test data:
test_image=[[True,True,True,True,False],[True,False,False,False,False],[False,False,False,True,True],[False,False,False,True,False],[True,False,False,True,True],[True,False,False,True,True],[True,False,False,True,False],[True,False,False,True,False],[True,False,False,True,False],[True,False,False,False,False],[True,False,True,False,True],[True,False,True,True,True]]

measure.label output:
[[1 1 1 1 0]
 [1 0 0 0 0]
 [0 0 0 2 2]
 [0 0 0 2 0]
 [3 0 0 2 2]
 [3 0 0 2 2]
 [3 0 0 2 0]
 [3 0 0 2 0]
 [3 0 0 2 0]
 [3 0 0 0 0]
 [3 0 4 0 4]
 [3 0 4 4 4]]

My output:
[[1 1 1 1 0]
 [1 0 0 0 0]
 [0 0 0 2 2]
 [0 0 0 2 0]
 [3 0 0 2 2]
 [3 0 0 2 2]
 [3 0 0 2 0]
 [3 0 0 2 0]
 [3 0 0 2 0]
 [3 0 0 0 0]
 [3 0 4 0 4]
 [3 0 4 4 4]]

因此,如果有人能指出我做错的正确方向,将不胜感激。

所以经过几次尝试,我终于编写了一些可行的代码。我遵循了 "One component at a time" 中列出的算法:[https://en.wikipedia.org/wiki/Connected-component_labeling][1].

我得到的代码如下所示:

Python

def check_neighbours(queue,label,labelled_image,image,row,col):
    while queue:
        temp_value=queue.pop()
        i,j=temp_value
        positions=[[i+1, j], [i-1, j],[i-1, j-1], [i + 1, j + 1],[i-1, j +1], [i + 1, j-1],[i, j+1], [i, j-1]]
        for pos in positions:
            if pos[0]>=0 and pos[0]<row and pos[1]>=0 and pos[1]<col and image[pos[0],pos[1]]==1 and labelled_image[pos[0],pos[1]]==0:
                labelled_image[pos[0],pos[1]]=label
                queue.append([pos[0],pos[1]])
    return labelled_image

def ccl(image):
    row, col = image.shape
    label=1
    queue=[]
    labelled_image=np.asarray(np.zeros((row,col)), np.uint8)
    for i in range(row):
        for j in range(col):
            if image[i,j] == 1 and labelled_image[i,j]==0:
                labelled_image[i,j]=label
                queue.append([i,j])
                labelled_image=check_neighbours(queue,label,labelled_image,image,row,col)
                label+=1
    return labelled_image