首页 文章详情

Python 图像处理—使用 Scikit-Image 进行斑点检测

AI算法与图像处理 | 1121 2021-03-08 16:24 0 0 0
UniSMS (合一短信)

点击下面卡片关注AI算法与图像处理”,选择加"星标"或“置顶”

重磅干货,第一时间送达


引言


图像处理时,我们需要的最重要的技能之一就是能够识别图像中的特定部分。一张图片只有在特定的感兴趣点能够被识别和分别列出的情况下才有用。在本文中,我们将了解如何做到这一点。


让我们从导入本文所需的库开始!

import matplotlib.pyplot as pltimport numpy as npimport pandas as pdimport skimagefrom skimage.io import imread, imshowfrom skimage.color import rgb2gray, rgb2hsvfrom skimage.measure import label, regionprops, regionprops_tablefrom skimage.filters import threshold_otsufrom scipy.ndimage import median_filterfrom matplotlib.patches import Rectanglefrom tqdm import tqdm

现在让我们加载图像。

tree = imread('laughing_tree.png')imshow(tree);

我们的任务是识别和隔离图像中包含树木独特果实的部分(看起来像张开的嘴)。


首先让我们尝试看看是否有任何简单的方法来基于图像的值进行识别。让我们将图像转换为灰度,并使用 Otsu 方法。

tree_gray = rgb2gray(tree)otsu_thresh = threshold_otsu(tree_gray)tree_binary = tree_gray < otsu_threshimshow(tree_binary, cmap = 'gray');

这显然不能很好地解决这个问题,让我们尝试在几个不同阈值上进行迭代。

def threshold_checker(image):    thresholds =  np.arange(0.1,1.1,0.1)    tree_gray = rgb2gray(image)    fig, ax = plt.subplots(2, 5, figsize=(17, 10))    for n, ax in enumerate(ax.flatten()):        ax.set_title(f'Threshold  : {round(thresholds[n],2)}',                             fontsize = 16)        threshold_tree = tree_gray < thresholds[n]        ax.imshow(threshold_tree);        ax.axis('off')    fig.tight_layout()threshold_checker(tree)

我们可以看到,尽管阈值处理似乎有所帮助,但它仍然包含了我们不感兴趣的图像部分。让我们尝试另一种方法。

tree_hsv = rgb2hsv(tree[:,:,:-1])plt.figure(num=None, figsize=(8, 6), dpi=80)plt.imshow(tree_hsv[:,:,0], cmap='hsv')plt.colorbar();

如果将图像放入HSV色彩空间中,我们可以看到水果明显具有红色色调,该红色色调在图像的其他部分不存在。让我们尝试分离图像的这些部分。

lower_mask = tree_hsv [:,:,0] > 0.80upper_mask = tree_hsv [:,:,0] <= 1.00mask = upper_mask*lower_maskred = tree[:,:,0]*maskgreen = tree[:,:,1]*maskblue = tree[:,:,2]*masktree_mask = np.dstack((red,green,blue))plt.figure(num=None, figsize=(8, 6), dpi=80)imshow(tree_mask);

可以看到,除了果实,还保留了大部分的天空部分。参考上一个色相通道图像,我们可以看到这些部分在水果中也存在相同种类的红色。


为了解决这个问题,让我们检查一下图像的 Value 通道。

tree_hsv = rgb2hsv(tree[:,:,:-1])plt.figure(num=None, figsize=(8, 6), dpi=80)plt.imshow(tree_hsv[:,:,2], cmap='gray')plt.colorbar();

可以看到那些明亮区域的值非常的高,在创建mask的时候我们需要考虑这一点。

lower_mask = tree_hsv [:,:,0] > 0.80upper_mask = tree_hsv [:,:,0] <= 1.00value_mask = tree_hsv [:,:,2] < .90mask = upper_mask*lower_mask*value_maskred = tree[:,:,0] * maskgreen = tree[:,:,1] * maskblue = tree[:,:,2] * masktree_mask = np.dstack((red, green, blue))plt.figure(num=None, figsize=(8, 6), dpi=80)imshow(tree_mask);

很好!现在我们需要找到一种方法来清理图像中的小白点。为此,我们可以简单地使用 Skimage 库中的中值滤波函数。

lower_mask = tree_hsv [:,:,0] > 0.80upper_mask = tree_hsv [:,:,0] <= 1.00value_mask = tree_hsv [:,:,2] < .90mask = median_filter(upper_mask*lower_mask*value_mask, 10)red = tree[:,:,0] * maskgreen = tree[:,:,1] * maskblue = tree[:,:,2] * masktree_mask = np.dstack((red, green, blue))plt.figure(num=None, figsize=(8, 6), dpi=80)imshow(tree_mask);

可以看到,结合了中值过滤器可以使我们获得非常清晰的图像。现在我们需要标识每个,为此,我们需要使用 Skimage 中的 label 函数。

tree_blobs = label(rgb2gray(tree_mask) > 0)imshow(tree_blobs, cmap = 'tab10');

可以看到该函数标识了图像中的不同。现在的下一步是获取每个斑点的属性。为此,我们需要使用 Skimage 中的 regionprops_table 函数。

properties =['area','bbox','convex_area','bbox_area',             'major_axis_length', 'minor_axis_length',             'eccentricity']df = pd.DataFrame(regionprops_table(tree_blobs, properties = properties))

regionprops_table 函数在数据帧中为我们提供每个斑点的属性,这使我们能够轻松地操作数据。让我们使用bbox特性在图像上绘制边界框。

blob_coordinates = [(row['bbox-0'],row['bbox-1'],                     row['bbox-2'],row['bbox-3'] )for                     index, row in df.iterrows()]fig, ax = plt.subplots(1,1, figsize=(8, 6), dpi = 80)for blob in tqdm(blob_coordinates):    width = blob[3] - blob[1]    height = blob[2] - blob[0]    patch = Rectangle((blob[1],blob[0]), width, height,                        edgecolor='r', facecolor='none')    ax.add_patch(patch)ax.imshow(tree);ax.set_axis_off()

成功了!


最后,让我们从图像中切出边界框,并将其显示为自己的图像。

fig, ax = plt.subplots(1, len(blob_coordinates), figsize=(15,5))for n, axis in enumerate(ax.flatten()):    axis.imshow(tree[int(blob_coordinates[n][0]):                     int(blob_coordinates[n][2]),                      int(blob_coordinates[n][1]):                     int(blob_coordinates[n][3])]);    fig.tight_layout()

总结


了解如何进行斑点检测对于图像处理来说都是非常重要的。它可以用来将图像的不同部分分割成不同的兴趣点。虽然这是一个相对简单和直接的介绍,但希望对你哟一个启发性的认识,如何通过使用斑点检测来解决基本的图像问题。

·  END  ·


HAPPY LIFE



个人微信(如果没有备注不拉群!
请注明:地区+学校/企业+研究方向+昵称



下载1:何恺明顶会分享


AI算法与图像处理」公众号后台回复:何恺明,即可下载。总共有6份PDF,涉及 ResNet、Mask RCNN等经典工作的总结分析


下载2:终身受益的编程指南:Google编程风格指南


AI算法与图像处理」公众号后台回复:c++,即可下载。历经十年考验,最权威的编程规范!


下载3:Python视觉实战项目52讲
AI算法与图像处公众号后台回复:Python视觉实战项目即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。


觉得不错就点亮在看吧


good-icon 0
favorite-icon 0
收藏
回复数量: 0
    暂无评论~~
    Ctrl+Enter