SLIC

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 :

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值