python图形模块_使用Python的scikit-image模块进行图像分割

在本文中,我们将详细讨论scikit-image,这是一个基于Python的图像处理库。

Scikit-image

031432ek9y3yntk8ei6n3t.jpg

scikit-image.org

Scikit-image是一个专用于图像处理的Python包。

安装

scikit-image可以按如下方式安装:pip install -U scikit-image(Linux and OSX)

pip install scikit-image(Windows)

# For Conda-based distributions

conda install scikit-image

031432a76j81q128glgug0.jpg

Python中的图像概述

在继续进行图像分割技术之前,我们必须熟悉scikit image生态系统以及它如何处理图像。从skimage库导入GrayScale图像

skimage数据模块包含一些内置的示例数据集,这些数据集通常以jpeg或png格式存储。from skimage import data

import numpy as np

import matplotlib.pyplot as plt

image = data.binary_blobs()

plt.imshow(image, cmap='gray');

031432lppqcsckydqzqvj6.jpg

031433lpxfx0f81xv4avdm.jpg路从skimage库导入彩色图像from skimage import data

import numpy as np

import matplotlib.pyplot as plt

image = data.astronaut()

plt.imshow(image);

031433keep0i72gzcfw4e7.jpg

031433qx33i1pp1x27d3z0.jpg路从外部源导入图像# The I/O module is used for importing the image

from skimage import data

import numpy as np

import matplotlib.pyplot as plt

from skimage import io

image = io.imread('skimage_logo.png')

plt.imshow(image);

031433obo8jrbj3eojbe3b.jpg

031433epplaeir24iccryc.jpg路加载多个图像images = io.ImageCollection('../images/*.png:../images/*.jpg')

print('Type:', type(images))

images.files

031433hrx1q29l4xqobisi.jpg

Out[]: Type: 保存图像#Saving file as ‘logo.png’

io.imsave('logo.png', logo)

031433hmmcemk4m4mbmb6n.jpg

图像分割

现在我们有了关于scikit-image的概念,让我们来深入了解图像分割的细节。图像分割本质上是将数字图像分割成多个部分,以简化和/或将图像的表示形式转换成更有意义和更容易分析的东西的过程。

在本文中,我们将把分割过程看作有监督和无监督算法的组合。

031433vgqamrdqvm6ajy3a.jpg

scikit-image库中提供了一些分段算法

监督分割:一些先验知识,可能来自人类输入,用于指导算法。

无监督分割:无需先验知识。这些算法尝试自动将图像细分为有意义的区域。用户仍然可以调整某些设置以获得所需的输出。

让我们从最简单的算法Thresholding开始。

阈值

这是通过选择高于或低于特定阈值的像素来从背景中分割对象的最简单方法。当我们打算从背景中分割对象时,这通常很有用。

让我们在预装了scikit-image数据集测试一下。

导入Python库import numpy as np

import matplotlib.pyplot as plt

import skimage.data as data

import skimage.segmentation as seg

import skimage.filters as filters

import skimage.draw as draw

import skimage.color as color

031433bfv7t2rfcc020c7k.jpg

图片text = data.page()

image_show(text)

031433npjzzhjsuln7xzek.jpg

这个图像有点暗,但也许我们仍然可以选择一个值,无需任何高级算法就能给出合理的分割。现在,为了帮助我们选择该值,我们将使用直方图。

直方图是显示图像中不同强度值下的像素数量的图形。简单地说,直方图是一种图形,其中x轴表示图像中的所有值,而y轴表示这些值的频率。fig, ax = plt.subplots(1, 1)

ax.hist(text.ravel(), bins=32, range=[0, 256])

ax.set_xlim(0, 256);

031434xkxp3oqe9ixg3zhl.jpg

031434a7l2yl9cj2k4jdcs.jpg

我们的例子恰好是一个8位图像,所以我们在x轴上总共有256个可能的值。我们观察到像素的浓度比较淡(0:黑色,255:白色)。这很可能是我们的文字背景。一个理想的分割直方图应该是双峰的,并且是完全分离的,这样我们就可以在中间选择一个数字。现在,让我们尝试制作一些基于简单阈值的分割图像。

监督阈值

由于我们将自己选择阈值,我们称之为监督阈值。text_segmented = text > (value concluded from histogram i.e 50,70,120 )

image_show(text_segmented);

031434pfp20h112m6p34ph.jpg

031434dm0ezuz60eqqii4u.jpg

上:text> 50 | 中:text> 70 | 下:text> 120

我们没有得到任何理想的结果,因为左边的阴影会产生问题。让我们现在尝试使用无监督阈值处理。

无监督阈值

Scikit-image有许多自动阈值处理方法,在选择最佳阈值时无需输入。一些方法是:otsu, li, local.text_threshold = filters.threshold_ # Hit tab with the cursor after the underscore to get all the methods.

image_show(text < text_threshold);

031434nz996jcqam7mr29q.jpg

031434a9925zpb22e9g259.jpg

上:otsu 下:li

对于local,我们还需要指定block_size。Offset有助于优化图像以获得更好的结果。text_threshold = filters.threshold_local(text,block_size=51, offset=10)

image_show(text > text_threshold);

031434z1zi23me3w1w4hbx.jpg

031434p0b2k6nuufkko620.jpg

local thresholding

这很好,在很大程度上消除了噪声区域。

监督分割

阈值处理是一个非常基本的分割过程,在高对比度图像中无法正常工作,我们需要更高级的工具。

对于本节,我们将使用免费提供的示例图像,并尝试使用监督分割技术对头部进行分割。# import the image

from skimage import io

image = io.imread('girl.jpg')

plt.imshow(image);

031434zfgu7qx2aa6979wp.jpg

031435yicmc18u2x2z16xy.jpg路在对图像进行任何分割之前,使用一些过滤器去噪是一个好主意。

但是,在我们的例子中,图像不是很嘈杂,所以我们会照原样。下一步将使用rgb2gray将图像转换为灰度。image_gray = color.rgb2gray(image)

image_show(image_gray);

031435w44quv4ea5gve4gl.jpg

031435c8rl6b26ll4ik68l.jpg

我们将使用两种完全不同原理的分割方法。

活动轮廓分割

活动轮廓分割也称为snakes,使用用户定义的轮廓或线进行初始化,然后该轮廓慢慢收缩。

对于我们的示例图像,让我们在人的头部周围画一个圆来初始化snake。def circle_points(resolution, center, radius):

"""

Generate points which define a circle on an image.Centre refers to the centre of the circle

"""

radians = np.linspace(0, 2*np.pi, resolution)

c = center[1] + radius*np.cos(radians)#polar co-ordinates

r = center[0] + radius*np.sin(radians)

return np.array([c, r]).T

# Exclude last point because a closed path should not have duplicate points

points = circle_points(200, [80, 250], 80)[:-1]

031435tnkpopnenma11bab.jpg

上述计算计算圆周边上的点的x和y坐标。既然我们已经给出了200的分辨率,它将计算200个这样的点。fig, ax = image_show(image)

ax.plot(points[:, 0], points[:, 1], '--r', lw=3)

031435s9upydtd9jstyj7y.jpg

031435c4tcdcj07z0d4d3s.jpg

然后,算法通过将闭合曲线拟合到脸部的边缘来从人的图像的其余部分分割人的面部。snake = seg.active_contour(astronaut_gray, points)

fig, ax = image_show(image)

ax.plot(points[:, 0], points[:, 1], '--r', lw=3)

ax.plot(snake[:, 0], snake[:, 1], '-b', lw=3);

031435d46u2xz72q2vvvoq.jpg

031435qah9vojtlt21oj3t.jpg

我们可以调整调用的参数alpha和 beta。较高的alpha值会使这条snake收缩得更快,而beta会让snake变得更加平滑。snake = seg.active_contour(image_gray, points,alpha=0.06,beta=0.3)

fig, ax = image_show(image)

ax.plot(points[:, 0], points[:, 1], '--r', lw=3)

ax.plot(snake[:, 0], snake[:, 1], '-b', lw=3);

031435q09c2i28i7b282b8.jpg

031435io643ko4948nh0p4.jpg

随机游走分割

在这种方法中,用户交互地给少量像素标上标签,这些像素被称为标签。然后想象每个未标记的像素释放一个random walker,然后可以确定一个random walker从每个未标记的像素开始并到达其中一个预先标记的像素的概率。将每个像素分配给计算概率最大的标签,可以得到高质量的图像分割。

我们将重用前面示例中的种子值。我们可以做不同的初始化,但为了简单起见,我们还是用圆吧。image_labels = np.zeros(image_gray.shape, dtype=np.uint8)

随机游走算法期望标签图像作为输入。所以我们将有一个更大的圆圈,包括人的整个脸部和另一个靠近脸部中间的小圆圈。indices = draw.circle_perimeter(80, 250,20)#from here

image_labels[indices] = 1

image_labels[points[:, 1].astype(np.int), points[:, 0].astype(np.int)] = 2

image_show(image_labels);

031436vsc9skn89ao830du.jpg

031436j5s5sfj7bd8kp4bb.jpg

现在,让我们使用Random Walker,看看会发生什么。image_segmented = seg.random_walker(image_gray, image_labels)

# Check our results

fig, ax = image_show(image_gray)

ax.imshow(image_segmented == 1, alpha=0.3);

031436wnt77ja5h7m5sjtd.jpg

031436hnsnxd7ni2dxj9jn.jpg

看起来不像我们想要的边缘。为了解决这种情况,我们可以调优beta参数,直到得到所需的结果。经过多次尝试,3000的值工作得相当好。image_segmented = seg.random_walker(image_gray, image_labels, beta = 3000)

# Check our results

fig, ax = image_show(image_gray)

ax.imshow(image_segmented == 1, alpha=0.3);

031436x6ytcyy6gy4yjg36.jpg

031436qi6z50ncmmesna8y.jpg

这就是监督分割,我们必须提供特定的输入,也必须调整特定的参数。

无监督分割

无监督分割不需要先验知识。考虑这样的图像,该图像太大以致不能同时考虑所有像素。在这种情况下,无监督分割可以将图像分割成几个子区域,所以不是数百万像素,而是数十到数百个区域。让我们来看看这两种算法:

SLIC(简单线性迭代聚类)

SLIC算法实际上使用了一种名为K-Means的机器学习算法。它接收图像的所有像素值并尝试将它们分离到给定数量的子区域中。

SLIC以彩色工作,因此我们将使用原始图像。image_slic = seg.slic(image,n_segments=155)

我们所做的只是将我们找到的每个子图像或子区域设置为该区域的平均值,这使得它看起来不像随机分配的颜色拼凑而更像一个图像被分解成类似的区域。# label2rgb replaces each discrete label with the average interior color

image_show(color.label2rgb(image_slic, image, kind='avg'));

031436j3mdg6g2h4l3uxh0.jpg

031436bt6na3f58djflst8.jpg

我们已将此图像从512 * 512 = 262,000像素缩小到155个区域。

Felzenszwalb

该算法还使用了一种称为最小生成树聚类的机器学习算法。Felzenszwaib没有告诉我们图像将被分割成的聚类的确切数量。它会运行并生成它认为适合于图像上给定的缩放因子的任意多的聚类。image_felzenszwalb = seg.felzenszwalb(image)

image_show(image_felzenszwalb);

031436q3x48d64358lx81x.jpg

031436jsw5sapuuook54ab.jpg

这里有很多区域。我们来计算唯一区域的数量。np.unique(astronaut_felzenszwalb).size

3368

现在让我们使用区域平均值重新着色它们,就像我们在SLIC算法中所做的那样。image_felzenszwalb_colored = color.label2rgb(image_felzenszwalb, image, kind='avg')

image_show(image_felzenszwalb_colored);

031436qg8829zmesa0jgxz.jpg

现在我们得到了更小的区域。如果我们想要更少的区域,我们可以改变scale参数,或者从这里开始并将它们组合起来。这种方法有时被称为over-segmentation。

031437n8i4knnshrr4im4m.jpg

这看起来更像是一张图片,它基本上只是减少了颜色数量。要再次组合它们,您可以使用区域邻接图(RAG)。

结论

图像分割是图像处理中的一个非常重要的步骤。它是一个活跃的研究领域,应用范围从计算机视觉到医学图像,交通和视频监控。Python以scikit-image的形式提供了一个强大的库,其中包含大量用于图像处理的算法。它是免费和不受限制的,背后有一个活跃的社区。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 您可以通过以下步骤安装scikit-image: 1. 打开命令行窗口或终端。 2. 输入以下命令安装pip(如果您已经安装了pip,请跳过此步骤): ``` python -m ensurepip --default-pip ``` 3. 输入以下命令安装scikit-image: ``` pip install -U scikit-image ``` 4. 等待安装完成即可。 ### 回答2: scikit-image是一款Python图像处理库,它能够为我们提供各种各样的图像处理和计算机视觉相关的功能,如图像滤波、变换、分割、特征提取等。scikit-image库底层依赖于NumPy、SciPy和matplotlib等Python科学计算库,因此在安装scikit-image之前,需要确保NumPy、SciPy和matplotlib等库已经安装成功。 下面介绍安装scikit-image的具体步骤: 1.安装Python环境 在安装scikit-image之前,需要先安装Python环境。可以从Python官网(https://www.python.org/)下载对应版本的Python安装包,按照安装向导依次安装即可。 2.安装pip pip是用来安装Python第三方库的包管理工具,可以通过在终端中输入以下命令来安装pip: python get-pip.py 其中get-pip.py是pip的安装文件,可以从官方网站(https://bootstrap.pypa.io/get-pip.py)下载。 3.安装依赖库 由于scikit-image依赖于NumPy、SciPy、matplotlib等库,因此在安装scikit-image之前,需要先安装这些依赖库。可以在终端中输入以下命令来安装: pip install numpy scipy matplotlib 4.安装scikit-image 安装依赖库之后,就可以安装scikit-image了。可以在终端中输入以下命令来安装: pip install scikit-image 安装完成后,可以在Python中导入scikit-image库,如下: import skimage 需要注意的是,由于scikit-image底层是用Cython编写的,因此在安装scikit-image时,需要确保Cython已经安装,否则会出现安装失败的情况。可以在终端中输入以下命令来安装Cython: pip install cython ### 回答3: scikit-image是针对影像处理而设计的Python包。它提供了一整套基于numpy的图像处理和计算机视觉算法,同时该包采用了sklearn、scipy和matplotlib等外部包来实现。这样就使得它在实现特定任务时可以充分利用其他包的强大功能,降低了实现成本。Python标准库中包含的图像处理模块(如pillow)功能较为简单,适合处理基本的图像问题,而scikit-image则具有更为广泛的应用,因为它可以完成更加复杂的图像操作。本篇文章将向你介绍如何在Python中安装scikit-imagescikit-image的安装有两种方式: 方法一: 第一步:安装Python,可以到官网(https://www.python.org/downloads/)下载Python3.6+版本的安装文件。 第二步:安装pip,可以到Python官网下方找到get-pip.py文件,运行该文件即可安装pip。 命令:python get-pip.py 第三步:安装依赖的库 scikit-image依赖于其他的库,需要先安装这些库,命令如下: numpy安装:pip install numpy scipy安装:pip install scipy matplotlib安装:pip install matplotlib imageio安装:pip install imageio 第四步:安装scikit-image库 pip install scikit-image 这样就成功完成了scikit-image库的安装。 方法二: 直接利用Anaconda进行安装: Anaconda是一个比较完整的数据科学和机器学习环境,内置了诸多包。这样的话就不需要再单独安装numpy、scipy、matplotlib、imageio等库了。可以直接打开Anaconda Navigator,选择Environment Tab,然后创建一个新的Python环境。 在这个新的Python环境中安装scikit-image: 打开Anaconda Prompt,输入命令: conda install -c conda-forge scikit-image 等待安装完成即可。 总结: 以上就是在Python中安装scikit-image的两种方法,它们都可以用来完成scikit-image的安装。如果你已经安装了Anaconda,那么采用第二种方法可以更为方便。无论选择哪种方法,需要注意的是依赖库的安装很重要,否则导入scikit-image会出现问题。在使用之前可以先简单的测试一下,如果无法导入,可以使用Anaconda Prompt中的命令进行检查。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值