SLIC超像素算法:高效生成紧凑均匀超级像素

需积分: 12 2 下载量 118 浏览量 更新于2024-07-21 1 收藏 3.13MB PDF 举报
"SLIC超像素算法是一种在计算机视觉领域广泛应用的超像素分割方法,由Radhakrishna Achanta等人在2010年提出。SLIC代表“Simple Linear Iterative Clustering”(简单线性迭代聚类),它结合了颜色和空间信息,生成具有低计算复杂度、规则且紧凑的超像素。这种方法在保持高效率的同时,能提供与现有先进方法相当甚至更好的分割质量。" SLIC超像素算法的核心思想是将图像中的像素在五维空间(RGB颜色空间加上两个空间坐标)中进行聚类。这个五维空间包括三个颜色维度(红、绿、蓝)和两个位置维度(x、y)。算法的主要优点在于用户只需指定期望的超像素数量,然后算法会自动进行划分。 算法流程大致如下: 1. 初始化:首先,将图像中的每个像素视为一个点,根据RGB值和空间位置创建五维向量。 2. 聚类:采用K-means聚类方法,将这些点分配到预设数量的聚类中心。SLIC改进了传统的K-means,通过引入距离度量,考虑了颜色和空间邻近性的结合,使得生成的超像素更加连续和紧凑。 3. 更新:计算每个聚类的新中心,通常采用加权平均法,权重可以考虑像素的面积或亮度等。 4. 迭代:重复步骤2和3,直到满足停止条件,如达到最大迭代次数或超像素质量不再显著提升。 SLIC的优势在于其高效性和灵活性。它的计算复杂度相对较低,适用于实时或资源有限的环境。此外,由于超像素边界接近图像的自然边缘,因此在后续的图像分析和处理任务中,如物体检测、语义分割等,SLIC超像素可以提供良好的基础。 与其他方法比较,SLIC在保持相似或更优的边界召回率和欠分割误差的同时,计算成本更低。实验表明,SLIC在对比现有的超像素算法时,在两个任务中展示了优越性,这进一步证明了其在计算机视觉领域的实用性。 SLIC超像素算法是图像分割领域的一个重要工具,它的简单性、高效性和优良的分割质量使其成为许多应用的首选方法。通过合理调整参数,可以适应各种不同的图像和场景需求,为后续的计算机视觉任务提供高质量的预处理结果。

import torch import torch.nn as nn import torch.nn.functional as F import torchvision.transforms as transforms import skimage.segmentation as seg import numpy as np # 超参数 from PIL import Image num_superpixels = 1000 compactness = 10 sigma = 1 # 定义模型 class SuperpixelSegmentation(nn.Module): def init(self): super(SuperpixelSegmentation, self).init() self.convs = nn.Sequential( nn.Conv2d(3, 16, kernel_size=3, stride=1, padding=1), nn.ReLU(inplace=True), nn.Conv2d(16, 32, kernel_size=3, stride=1, padding=1), nn.ReLU(inplace=True), nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1), nn.ReLU(inplace=True), nn.Conv2d(64, num_superpixels, kernel_size=1, stride=1) ) def forward(self, x): x = self.convs(x) return x # 加载图像 imgA = Image.open('1.png').convert('RGB') imgB = Image.open('2.jpg').convert('RGB') # 超像素分割 imgA_np = np.array(imgA) segments = seg.slic(imgA_np, n_segments=num_superpixels, compactness=compactness, sigma=sigma) segments = torch.from_numpy(segments).unsqueeze(0).unsqueeze(0).float() segments = F.interpolate(segments, size=(imgA.height, imgA.width), mode='nearest').long() # 应用超像素块范围到图像B imgB_np = np.array(imgB) for i in range(num_superpixels): mask = (segments == i) imgB_np[mask.expand(3, -1, -1)] = np.mean(imgB_np[mask.expand(3, -1, -1)], axis=1, keepdims=True) # 显示超像素分割图像 imgA_segments = np.zeros_like(imgA_np) for i in range(num_superpixels): mask = (segments == i) imgA_segments[mask.expand(3, -1, -1)] = np.random.randint(0, 255, size=(3,)) imgA_segments = Image.fromarray(imgA_segments.astype(np.uint8)) imgB_segments = Image.fromarray(imgB_np) # 显示图像 transforms.ToPILImage()(imgA).show() transforms.ToPILImage()(imgB).show() imgA_segments.show() imgB_segments.show()上述代码出现错误:RuntimeError: expand(CPUBoolType{[1, 1, 512, 512]}, size=[3, -1, -1]): the number of sizes provided (3) must be greater or equal to the number of dimensions in the tensor (4)

2023-05-30 上传