使用我编写的函数标记图像时,与 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
我的目标是根据第一原理实现 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