При маркировке изображения с помощью функции, которую я написал, я не получаю тот же результат по сравнению с функцией skimage measure.label - PullRequest
0 голосов
/ 01 июля 2019

Моя цель - реализовать функцию 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]]

Таким образом, если кто-то может указать мне правильное направление относительно того, что я делаю неправильно, это будет очень цениться.

1 Ответ

0 голосов
/ 02 июля 2019

Итак, после нескольких попыток я наконец-то кодировал что-то, что работает. Я следовал алгоритму «Один компонент за раз», изложенному в: [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

...