前言
在用电子显微镜拍摄玻片成像的过程中,我们会得到很多张图像,如果说我们希望从图像中得到我们想要的信息,我们应该先想办法拿到图像的关键信息,也就是找出一张图像中,哪一些部分对我们是重要的,哪一些部分对我们是不重要的。
而我们描述一个图像最好的办法就是拿到图像的颜色信息,根据图像的颜色信息对图像进行处理,但是图像可能会有很多种区域的颜色,这里我们只考虑灰度图像的颜色直方图。
我们能够根据一张图像的颜色直方图,标记出图像的重点部分颜色信息,并且将这些重点部分的颜色信息快速的初步标记出来,并且区分出重点信息和非重点信息。从而从这张图像中获取对我们有价值的信息。
1. 读取浮点数图像
from skimage import io
from matplotlib import pyplot as plt
import numpy as np
# 01.读取图像
img = io.imread("../resource/image.png")
# 图像窗口名称
plt.figure("Image")
# 指定显示图片
plt.imshow(img)
# 开启坐标轴
plt.axis('on')
# 图像坐标轴
plt.title('image')
# 显示图片
plt.show()
2. 显示图像直方图
plt.hist(img.ravel(), 100, (0,255))
plt.show()
从上面的图像中我们可以看到,我们按照正常人类的思维是不能够从这张直方图中得到我们想要的东西的,也就是说我们不好针对这个直方图来分割这张图像。所以我们要对这个颜色直方图进行一点处理,让我们能够明显的根据直方图来区分出这张图片中的背景和前景。
3. 对图片进行直方图均衡化,更好的分割分割背景和前景
eq_img = exposure.equalize_adapthist(img)
plt.figure("exposure")
# 指定显示图片
plt.imshow(eq_img)
# 开启坐标轴
plt.axis('on')
# 图像坐标轴
plt.title('exposure')
# 显示图片
plt.show()
# 重新绘制直方图
plt.hist(eq_img.flat, 100, (0.,1))
plt.show()
从上面直方图均衡化过后的图片,我们可以很容易的区分出背景和前景,其中图像在0.6之前的部分为前景,也就是我们需要标注出来的部分,在0.6之后的部分为背景,也就是我们可以舍弃出去的部分
4. 分离前景和背景,并标注显示
现在我们已经能够根据图像的灰度值大致判断出了图像的背景和前景,现在我们需要做的,就是根据我们人眼断定的背景和前景,手动的将图片重要信息给分离出来
这里我们使用skimage.segmentation的randomwalker来进行简单的标记分割操作,我们会将直方图灰度值小于0.6的部分打上标签1,并且标注其为红色,直方图灰度值大于0.6的部分打上标签2,并且标注其为绿色【标签1为前景,标签2为背景】
可以注意到,我们的背景基本上很干净,因为在实际绘制颜色之前,我还对背景执行了开闭操作,去除了在绿色背景中可能存在的杂色斑点。
完整代码
from skimage import io,exposure,img_as_float
from matplotlib import pyplot as plt
from skimage.segmentation import random_walker
from scipy import ndimage as nd
import numpy as np
# 01.读取图像
img = img_as_float(io.imread("../resource/image.png",3))
# 图像窗口名称
plt.figure("Image")
# 指定显示图片
plt.imshow(img)
# 开启坐标轴
plt.axis('on')
# 图像坐标轴
plt.title('image')
# 显示图片
plt.show()
# 展示原始的颜色直方图
plt.hist(img.ravel(), 100, (0,1))
plt.show()
# # 对图片进行去噪
# sigma_est = np.mean(estimate_sigma(img))
# denoise_img = denoise_nl_means(img, h=1.15 * sigma_est, fast_mode=True, patch_size=5, patch_distance=3,channel_axis=2)
#
# plt.figure("denoise")
# # 指定显示图片
# plt.imshow(denoise_img)
# # 开启坐标轴
# plt.axis('on')
# # 图像坐标轴
# plt.title('denoise')
# # 显示图片
# plt.show()
#
eq_img = exposure.equalize_adapthist(img)
plt.figure("exposure")
# 指定显示图片
plt.imshow(eq_img)
# 开启坐标轴
plt.axis('on')
# 图像坐标轴
plt.title('exposure')
# 显示图片
plt.show()
# 重新绘制直方图
plt.hist(eq_img.ravel(), 100, (0.,1))
plt.show()
print(img.shape)
# 创建层叠标记画布
markers = np.zeros(img.shape, dtype=np.uint)
markers[ (eq_img < 0.6)] = 1
markers[(eq_img >= 0.6)] = 2
labels = random_walker(eq_img, markers, beta=10, mode='bf')
segm1 = (labels == 1)
segm2 = (labels == 2)
all_segments = np.zeros((eq_img.shape[0], eq_img.shape[1], 3))
segm1_closed = nd.binary_closing(segm1, np.ones((3,3)))
segm2_closed = nd.binary_closing(segm2, np.ones((3,3)))
all_segments_cleaned = np.zeros((eq_img.shape[0], eq_img.shape[1], 3))
all_segments_cleaned[segm1_closed] = (1,0,0)
all_segments_cleaned[segm2_closed] = (0,1,0)
plt.figure("colored")
# 指定显示图片
plt.imshow(all_segments_cleaned)
# 开启坐标轴
plt.axis('on')
# 图像坐标轴
plt.title('colored')
# 显示图片
plt.show()