我想计算一个二进制图像中六边形单元的百分比(例如,具有6个相邻单元的单元数量/总单元数量),并生成如下所示的彩色编码图像。
我已经尝试了下面的python代码,但是我没有得到正确的输出。例如,如您所见,二进制图像中的红色单元格有4、5、6或7个相邻单元格,但计算错误,因为它们有3、4和6个相邻单元格。
附上了一个二进制图像及其输出的示例。
import sys
import json
import cv2
import os
import scipy.io
import numpy as np
from scipy.ndimage import measurements, morphology
from skimage import measure
import time
def cells_measurements(path, orig_image, color="yellow", size=3,
pixel_sz=0.00104167):
size = int(size)
im = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
_, im = cv2.threshold(im, 127, 255, cv2.THRESH_BINARY)
labeled_image, num_of_cells = measurements.label(255 - im)
props = measure.regionprops(labeled_image)
number_of_cells = len(props)
colored_image = np.pad(cv2.cvtColor(~im, cv2.COLOR_GRAY2BGR), ((1, 1),(1, 1), (0, 0,)), mode='constant',constant_values=0)
colors = [[0, 0, 128], [0, 0, 255], [0, 128, 255], [0, 255, 255],[128,255, 128], [255, 255, 0], [255, 128, 0],[255, 0, 0]]
count_hex = 0
labels = np.unique(labeled_image)
for l in labels[1:]:
i_temp = (labeled_image == l).astype(float) * 255
i_temp = cv2.dilate(i_temp, np.ones((3, 3)), iterations=2) - i_temp
i_temp2 = np.copy(labeled_image)
i_temp2[i_temp == 0.] = 0
adjacent = len(np.unique(i_temp2)) - 1
if adjacent == 6:
count_hex += 1
cv2.floodFill(colored_image, None, (int(cell_center_all[l - 1][1]),
int(cell_center_all[l - 1][0])), colors[min(adjacent, 7)])
hexagonal_cells = (count_hex / num_of_cells) * 100
colored_image = np.pad(colored_image, ((0, 0), (0, 75), (0, 0)),
'constant', constant_values=255)
for i in range(8):
step = colored_image.shape[0] // 8
colored_image[i * step:+(i + 1) * step, -60:-35] = colors[7 - i]
colored_image[i * step, -60:-35] = 0
colored_image[(i + 1) * step, -60:-35] = 0
colored_image[i * step:(i + 1) * step, -60] = 0
colored_image[i * step:(i + 1) * step, -35] = 0
cv2.putText(colored_image, str(7 - i), (colored_image.shape[1] -
30, 5 + i * step + step // 2), cv2.FONT_HERSHEY_DUPLEX, 0.5, 0)
color_path = 'Labeled Images/' + fn + "_color.png"
cv2.imwrite(color_path, colored_image)
Auto_Cells_Pleomorphism = []
Mask_Path = 'generated_samples_masks/'
Original_img_path = 'TestingSet/enhanced_imgs/'
# please note that the "mask" image is the result of the segmentation
algorithm which I will provide today
# Loop over images
for i in range(1, 640):
filename = str(i) + '.png'
print(filename)
Masks_Path = os.path.join(Mask_Path, filename)
Original_image = os.path.join(Original_img_path, filename)
[hexagonal_cells] = cells_measurements(Masks_Path, Original_image,
color="yellow", size=3)
Auto_Cells_Pleomorphism.append(round(hexagonal_cells))
正如你所看到的,二进制图像有一些模糊的边缘。我如何提高他们的可见性?
发布于 2020-04-09 17:53:02
一种方法是使用分水岭算法进行分割。
点击此处阅读相关信息:
https://scikit-image.org/docs/dev/auto_examples/segmentation/plot_watershed.html
https://www.pyimagesearch.com/2015/11/02/watershed-opencv/
你可以看看有没有更好的many other segmentation algorithms (例如Felsenszwalb's algorithm)。Here是三种算法的简单比较,您可以很容易地扩展此示例,以查看它们在数据集上的比较情况。
一旦你有了所有元素(多边形)的轮廓,你就可以使用它们来创建一个“完整的地图”(识别所有单元和它们的邻居,没有洞,没有未知的元素),以确保你没有遗漏任何单元。您可以将其称为单元的拓扑。
有一件事可能会有帮助,那就是从分水岭算法返回的多边形中创建“更清晰”的多边形。
你可能不得不
这就是所谓的“修复,修复,简化网格”。它本身就是一个主题,当然也有工具可以做到这一点。您可以阅读与Python相关的项目here、here或here。
一旦完成,你只需计算边缘,创建一个所有相邻单元的列表,并交叉检查所有相邻单元是否被检测到。
这个算法不是开箱即用的,你必须改进和调整它,直到它起作用。
https://stackoverflow.com/questions/61125888
复制