Assiment
超像素处理图片,显示每个区域的相邻区域,并有图片的直观结果做验证。
代码:
from __future__ import division
import collections as coll
import numpy as np
from scipy import ndimage as ndi
from skimage.util import img_as_float, regular_grid
from skimage.segmentation._slic import _slic_cython, _enforce_label_connectivity_cython
from skimage.color import rgb2lab
from PIL import Image
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
def slic(image, n_segments=100, compactness=10., max_iter=10, sigma=0,
spacing=None, multichannel=True, convert2lab=None,
enforce_connectivity=None, min_size_factor=0.5, max_size_factor=3,
slic_zero=False):
"""Segments image using k-means clustering in Color-(x,y,z) space.
Parameters
----------
image : 2D, 3D or 4D ndarray
Input image, which can be 2D or 3D, and grayscale or multichannel
(see `multichannel` parameter).
n_segments : int, optional
The (approximate) number of labels in the segmented output image.
compactness : float, optional
Balances color proximity and space proximity. Higher values give
more weight to space proximity, making superpixel shapes more
square/cubic. In SLICO mode, this is the initial compactness.
This parameter depends strongly on image contrast and on the
shapes of objects in the image. We recommend exploring possible
values on a log scale, e.g., 0.01, 0.1, 1, 10, 100, before
refining around a chosen value.
max_iter : int, optional
Maximum number of iterations of k-means.
sigma : float or (3,) array-like of floats, optional
Width of Gaussian smoothing kernel for pre-processing for each
dimension of the image. The same sigma is applied to each dimension in
case of a scalar value. Zero means no smoothing.
Note, that `sigma` is automatically scaled if it is scalar and a
manual voxel spacing is provided (see Notes section).
spacing : (3,) array-like of floats, optional
The voxel spacing along each image dimension. By default, `slic`
assumes uniform spacing (same voxel resolution along z, y and x).
This parameter controls the weights of the distances along z, y,
and x during k-means clustering.
multichannel : bool, optional
Whether the last axis of the image is to be interpreted as multiple
channels or another spatial dimension.
convert2lab : bool, optional
Whether the input should be converted to Lab colorspace prior to
segmentation. The input image *must* be RGB. Highly recommended.
This option defaults to ``True`` when ``multichannel=True`` *and*
``image.shape[-1] == 3``.
enforce_connectivity: bool, optional
Whether the generated segments are connected or not
min_size_factor: float, optional
Proportion of the minimum segment size to be removed with respect
to the supposed segment size ```depth*width*height/n_segments```
max_size_factor: float, optional
Proportion of the maximum connected segment size. A value of 3 works
in most of the cases.
slic_zero: bool, optional
Run SLIC-zero, the zero-parameter mode of SLIC. [2]_
Returns
-------
labels : 2D or 3D array
Integer mask indicating segment labels.
Raises
------
ValueError
If ``convert2lab`` is set to ``True`` but the last array
dimension is not of length 3.
Notes
-----
* If `sigma > 0`, the image is smoothed using a Gaussian kernel prior to
segmentation.
* If `sigma` is scalar and `spacing` is provided, the kernel width is
divided along each dimension by the spacing. For example, if ``sigma=1``
and ``spacing=[5, 1, 1]``, the effective `sigma` is ``[0.2, 1, 1]``. This
ensures sensible smoothing for anisotropic images.
* The image is rescaled to be in [0, 1] prior to processing.
* Images of shape (M, N, 3) are interpreted as 2D RGB images by default. To
interpret them as 3D with the last dimension having length 3, use
`multichannel=False`.
References
----------
.. [1] Radhakrishna Achanta, Appu Shaji, Kevin Smith, Aurelien Lucchi,
Pascal Fua, and Sabine Süsstrunk, SLIC Superpixels Compared to
State-of-the-art Superpixel Methods, TPAMI, May 2012.
.. [2] http://ivrg.epfl.ch/research/superpixels#SLICO
Examples
--------
# >>> from skimage.segmentation import slic
# >>> from skimage.data import astronaut
# >>> img = astronaut()
# >>> segments = slic(img, n_segments=100, compactness=10)
# Increasing the compactness parameter yields more square regions:
# >>> segments = slic(img, n_segments=100, compactness=20)
"""
image = img_as_float(image)
is_2d = False
if image.ndim == 2:
# 2D grayscale image
image = image[np.newaxis, ..., np.newaxis]
is_2d = True
elif image.ndim == 3 and multichannel:
# Make 2D multichannel image 3D with depth = 1
image = image[np.newaxis, ...]
is_2d = True
elif image.ndim == 3 and not multichannel:
# Add channel as single last dimension
image = image[..., np.newaxis]
if spacing is None:
spacing = np.ones(3)
elif isinstance(spacing, (list, tuple)):
spacing = np.array(spacing, dtype=np.double)
if not isinstance(sigma, coll.Iterable):
sigma = np.array([sigma, sigma, sigma], dtype=np.double)
sigma /= spacing.astype(np.double)
elif isinstance(sigma, (list, tuple)):
sigma = np.array(sigma, dtype=np.double)
if (sigma > 0).any():
# add zero smoothing for multichannel dimension
sigma = list(sigma) + [0]
image = ndi.gaussian_filter(image, sigma)
if multichannel and (convert2lab or convert2lab is None):
if image.shape[-1] != 3 and convert2lab:
raise ValueError("Lab colorspace conversion requires a RGB image.")
elif image.shape[-1] == 3:
image = rgb2lab(image)
depth, height, width = image.shape[:3]
# initialize cluster centroids for desired number of segments
grid_z, grid_y, grid_x = np.mgrid[:depth, :height, :width]
slices = regular_grid(image.shape[:3], n_segments)
step_z, step_y, step_x = [int(s.step if s.step is not None else 1)
for s in slices]
segments_z = grid_z[slices]
segments_y = grid_y[slices]
segments_x = grid_x[slices]
segments_color = np.zeros(segments_z.shape + (image.shape[3],))
segments = np.concatenate([segments_z[..., np.newaxis],
segments_y[..., np.newaxis],
segments_x[..., np.newaxis],
segments_color],
axis=-1).reshape(-1, 3 + image.shape[3])
segments = np.ascontiguousarray(segments)
# we do the scaling of ratio in the same way as in the SLIC paper
# so the values have the same meaning
step = float(max((step_z, step_y, step_x)))
ratio = 1.0 / compactness
image = np.ascontiguousarray(image * ratio)
labels = _slic_cython(image, segments, step, max_iter, spacing, slic_zero)
if enforce_connectivity:
segment_size = depth * height * width / n_segments
print(segment_size)
min_size = int(min_size_factor * segment_size)
max_size = int(max_size_factor * segment_size)
labels = _enforce_label_connectivity_cython(labels,
min_size,
max_size)
if is_2d:
labels = labels[0]
return labels
def predict(img, labels):
array = []
# array = [([] for j in range(10)) for i in range(100)]
# num为用于验证的标签,当num>0时显示图像
num = 65
# height 列数
height = img.size[0]
# length 行数
length = img.size[1]
last_tag = labels[length-1][height-1]
# i为每个像素的标签
for i in range(last_tag+1):
# j为二维数组的总行数
for j in range(length):
# k为数组的列数
for k in range(height):
if labels[j][k] == i and k-1 >= 0 and labels[j][k-1] !=i and labels[j][k-1] not in array:
array.append(labels[j][k-1])
elif labels[j][k] == i and k+1 <= height-1 and labels[j][k+1] != i and labels[j][k+1] not in array:
array.append(labels[j][k+1])
elif labels[j][k] == i and j+1 <= length-1 and labels[j+1][k] != i and labels[j+1][k] not in array:
array.append(labels[j+1][k])
elif labels[j][k] == i and j-1 >= 0 and labels[j-1][k] != i and labels[j-1][k] not in array:
array.append(labels[j-1][k])
if array != []:
# print(i, 'next to', array)
if i == num:
list1 = np.where(labels == num)
length1 = len(list1[0])
for j in range(length1):
img.putpixel((list1[0][j], list1[1][j]), (0, 0, 0))
for k in array:
list2 = np.where(labels == k)
length2 = len(list2[0])
for l in range(length2):
img.putpixel((list2[0][l], list2[1][l]), (255, 255, 255))
array = []
else:
array = []
if num>0:
plt.imshow(img)
plt.axis('off')
plt.show()
else:
pass
if __name__ == '__main__':
img = Image.open('red_tower2.png')
segments = slic(img, n_segments=100, compactness=100, sigma=0)
plt.imshow(segments)
plt.axis('off')
plt.show()
# predict(img, segments)
标签处理结果
问题记录
1、
解决方案:
知识点
1、SLIC
利用聚类算法将有相同标签的像素点聚合在一起,形成像素块。SLIC算法处理图片出来的结果是一个存着每个像素点的label的二维数组。
2、python Image 图像处理
From PIL import Image
1、修改单个像素点的颜色
Img.putpixel((x,y),(255,0,0))
2、得到单个像素点的RGB值
Img.getpixel((x,y))
3、 显示一张图片:
im.show()
4. 保存图片:
im.save(“save.gif”,”GIF”) #保存图像为gif格式
5. 创建新图片:
Image.new(mode,size)
Image.new(mode,size,color)
例子:newImg = Image.new(“RGBA”,(640,480),(0,255,0))
newImg.save(“newImg.png”,”PNG”)
6.两张图片相加:
Image.blend(img1,img2,alpha) # 这里alpha表示img1和img2的比例参数
7. 点操作:
im.point(function) #,这个function接受一个参数,且对图片中的每一个点执行这个函数
比如:out=im.point(lambdai:i*1.5)#对每个点进行50%的加强
8. 查看图像信息:
im.format, im.size, im.mode
9. 图片裁剪:
box=(100,100,500,500)
/设置要裁剪的区域/
region=im.crop(box) #此时,region是一个新的图像对象。
10. 图像黏贴(合并)
im.paste(region,box)#粘贴box大小的region到原先的图片对象中。
11. 通道分离:
r,g,b=im.split()#分割成三个通道,此时r,g,b分别为三个图像对象。
12. 通道合并:
im=Image.merge(“RGB”,(b,g,r))#将b,r两个通道进行翻转。
13. 改变图像的大小:
out=img.resize((128,128))#resize成128*128像素大小
14. 旋转图像:
out=img.rotate(45) #逆时针旋转45度
有更方便的:
region = region.transpose(Image.ROTATE_180)
15. 图像转换:
out = im.transpose(Image.FLIP_LEFT_RIGHT)
左右对换
out = im.transpose(Image.FLIP_TOP_BOTTOM)
上下对换
16. 图像类型转换:
im=im.convert(“RGBA”)
17.打开图片
Img = Image.open(‘lenna.png’)
18、图片的尺寸
宽度(列数)img.size[0]
长度(行数)img.size[1]
3、numpy.where()的用法
return两个列表,第一个列表存的是x坐标,第二个列表存的是y坐标。
list1 = np.where(labels == num)
for j in range(length1):
img.putpixel((list1[0][j], list1[1][j]), (0, 0, 0))
x值 list1[0][j]
y值 list1[1][j]
4、列表生成式
List = [([] for j in range(4)) for i in range(5)]
生成一个5行4列的空列表
5、not的使用
判断变量a是否在array里面:
if a not in array :