图像处理: 超像素(superpixels)分割 SLIC算法

article/2025/9/30 13:10:11

原理

超像素概念是2003年Xiaofeng Ren提出和发展起来的图像分割技术,是指具有相似纹理、颜色、亮度等特征的相邻像素构成的有一定视觉意义的不规则像素块。它利用像素之间特征的相似性将像素分组,用少量的超像素代替大量的像素来表达图片特征,很大程度上降低了图像后处理的复杂度,所以通常作为分割算法的预处理步骤。

常见的超像素分割方法包括: Graph-basedNCutTurbopixelQuick-shiftGraph-cut aGraph-cut b 以及 SLIC

其中,SLIC(simple linear iterativeclustering),即 简单线性迭代聚类
它是2010年提出的一种思想简单、实现方便的算法,将彩色图像转化为CIELAB颜色空间和XY坐标下的5维特征向量,然后对5维特征向量构造距离度量标准,对图像像素进行局部聚类的过程。

SLIC主要优点如下:

  1. 生成的超像素如同细胞一般紧凑整齐,邻域特征比较容易表达。这样基于像素的方法可以比较容易的改造为基于超像素的方法。
  2. 不仅可以分割彩色图,也可以兼容分割灰度图。
  3. 需要设置的参数非常少,默认情况下只需要设置一个预分割的超像素的数量。
  4. 相比其他的超像素分割方法,SLIC在运行速度、生成超像素的紧凑度、轮廓保持方面都比较理想。

效果图

经过观察发现,在迭代至第10轮后,分割效果基本不再发生变化。

原图

这里写图片描述


K=64 时

第1轮迭代,效果图:
这里写图片描述

第20轮迭代,效果图:
这里写图片描述

K=128 时

第1轮迭代,效果图:
这里写图片描述

第20轮迭代,效果图:
这里写图片描述

K=256 时

第1轮迭代,效果图:
这里写图片描述

第20轮迭代,效果图:
这里写图片描述

K=1024 时

第1轮迭代,效果图:
这里写图片描述

第20轮迭代,效果图:
这里写图片描述

实现代码

代码是我上网找来的,稍微改动了一丢丢。

原代码出处:SLIC算法分割超像素原理及Python实现

import math
from skimage import io, color
import numpy as np
from tqdm import trangeclass Cluster(object):cluster_index = 1def __init__(self, h, w, l=0, a=0, b=0):self.update(h, w, l, a, b)self.pixels = []self.no = self.cluster_indexself.cluster_index += 1def update(self, h, w, l, a, b):self.h = hself.w = wself.l = lself.a = aself.b = bdef __str__(self):return "{},{}:{} {} {} ".format(self.h, self.w, self.l, self.a, self.b)def __repr__(self):return self.__str__()class SLICProcessor(object):@staticmethoddef open_image(path):"""Return:3D array, row col [LAB]"""rgb = io.imread(path)lab_arr = color.rgb2lab(rgb)return lab_arr@staticmethoddef save_lab_image(path, lab_arr):"""Convert the array to RBG, then save the image"""rgb_arr = color.lab2rgb(lab_arr)io.imsave(path, rgb_arr)def make_cluster(self, h, w):return Cluster(h, w,self.data[h][w][0],self.data[h][w][1],self.data[h][w][2])def __init__(self, filename, K, M):self.K = Kself.M = Mself.data = self.open_image(filename)self.image_height = self.data.shape[0]self.image_width = self.data.shape[1]self.N = self.image_height * self.image_widthself.S = int(math.sqrt(self.N / self.K))self.clusters = []self.label = {}self.dis = np.full((self.image_height, self.image_width), np.inf)def init_clusters(self):h = self.S / 2w = self.S / 2while h < self.image_height:while w < self.image_width:self.clusters.append(self.make_cluster(h, w))w += self.Sw = self.S / 2h += self.Sdef get_gradient(self, h, w):if w + 1 >= self.image_width:w = self.image_width - 2if h + 1 >= self.image_height:h = self.image_height - 2gradient = self.data[w + 1][h + 1][0] - self.data[w][h][0] + \self.data[w + 1][h + 1][1] - self.data[w][h][1] + \self.data[w + 1][h + 1][2] - self.data[w][h][2]return gradientdef move_clusters(self):for cluster in self.clusters:cluster_gradient = self.get_gradient(cluster.h, cluster.w)for dh in range(-1, 2):for dw in range(-1, 2):_h = cluster.h + dh_w = cluster.w + dwnew_gradient = self.get_gradient(_h, _w)if new_gradient < cluster_gradient:cluster.update(_h, _w, self.data[_h][_w][0], self.data[_h][_w][1], self.data[_h][_w][2])cluster_gradient = new_gradientdef assignment(self):for cluster in self.clusters:for h in range(cluster.h - 2 * self.S, cluster.h + 2 * self.S):if h < 0 or h >= self.image_height: continuefor w in range(cluster.w - 2 * self.S, cluster.w + 2 * self.S):if w < 0 or w >= self.image_width: continueL, A, B = self.data[h][w]Dc = math.sqrt(math.pow(L - cluster.l, 2) +math.pow(A - cluster.a, 2) +math.pow(B - cluster.b, 2))Ds = math.sqrt(math.pow(h - cluster.h, 2) +math.pow(w - cluster.w, 2))D = math.sqrt(math.pow(Dc / self.M, 2) + math.pow(Ds / self.S, 2))if D < self.dis[h][w]:if (h, w) not in self.label:self.label[(h, w)] = clustercluster.pixels.append((h, w))else:self.label[(h, w)].pixels.remove((h, w))self.label[(h, w)] = clustercluster.pixels.append((h, w))self.dis[h][w] = Ddef update_cluster(self):for cluster in self.clusters:sum_h = sum_w = number = 0for p in cluster.pixels:sum_h += p[0]sum_w += p[1]number += 1_h = sum_h / number_w = sum_w / numbercluster.update(_h, _w, self.data[_h][_w][0], self.data[_h][_w][1], self.data[_h][_w][2])def save_current_image(self, name):image_arr = np.copy(self.data)for cluster in self.clusters:for p in cluster.pixels:image_arr[p[0]][p[1]][0] = cluster.limage_arr[p[0]][p[1]][1] = cluster.aimage_arr[p[0]][p[1]][2] = cluster.bimage_arr[cluster.h][cluster.w][0] = 0image_arr[cluster.h][cluster.w][1] = 0image_arr[cluster.h][cluster.w][2] = 0self.save_lab_image(name, image_arr)def iterate_10times(self):self.init_clusters()self.move_clusters()for i in trange(20):self.assignment()self.update_cluster()name = 'Elegent_Girl_M{m}_K{k}_loop{loop}.jpg'.format(loop=i, m=self.M, k=self.K)self.save_current_image(name)if __name__ == '__main__':for k in [64, 128, 256, 1024]:p = SLICProcessor('800.jpg', k, 30)p.iterate_10times()


打印结果:

  0%|          | 0/20 [00:00<?, ?it/s]/home/user/anaconda2/lib/python2.7/site-packages/skimage/util/dtype.py:111: UserWarning: Possible precision loss when converting from float64 to uint8"%s to %s" % (dtypeobj_in, dtypeobj))
100%|##########| 20/20 [32:36<00:00, 97.83s/it] 
100%|##########| 20/20 [24:37<00:00, 73.88s/it]
100%|##########| 20/20 [21:30<00:00, 64.55s/it]
100%|##########| 20/20 [18:49<00:00, 56.46s/it]Process finished with exit code 0



http://chatgpt.dhexx.cn/article/6JT38A5y.shtml

相关文章

超像素SLIC算法源码阅读

超像素SLIC算法源码阅读 超像素SLIC算法源码阅读SLIC简介源码阅读实验结果其他超像素算法对比 超像素SLIC算法源码阅读 SLIC简介 SLIC的全称Simple Linear Iterative Clustering&#xff0c;即简单线性迭代聚类&#xff0c;论文和代码链接如下&#xff1a; 论文传送门&#x…

python 超像素分割

SILC算法超像素分割&#xff08;源码实现&#xff09; 主体代码来自github.com/laixintao/slic-python-implementation 原代码中只有分割之后的小方块 即1.png 没有明显边界 没有继续进行图像分割 源码修改&#xff1a; 1.向Cluster类添加了label属性&#xff0c;以便于标记…

超像素分割学习笔记

学习目标 掌握超像素分割的原理、超像素分割方法的推导过程以及实现方法 1.1 超像素 超像素是指将具有相似纹理、颜色、亮度等特征的相邻像素聚合成某一个像素块&#xff0c;结合超像素的思想&#xff0c;这样可以使少量的像素块代替原本大量的像素。 目前超像素广泛应用于图…

SLIC超像素算法

原文出自&#xff1a;https://blog.csdn.net/Fighting_Dreamer/article/details/77170859 SLIC与目前最优超像素算法的比较 Radhakrishna Achanta, Appu Shaji, Kevin Smith, Aurelien Lucchi, Pascal Fua, and Sabine Susstrunk 摘要 近年来&#xff0c;计算机视觉应用越来…

超像素池化全监督语义分割

Efficient semantic image segmentation with superpixel pooling 摘要 在这项工作中&#xff0c;我们评估了超像素池化层在深层网络结构中用于语义分割的应用。超像素池化是一种灵活有效的方法&#xff0c;可以替代其他包含空z间先验信息的池策略。我们提出了一个简单而高效…

SLIC超像素分割算法

SLIC超像素分割算法 《SLIC Superpixels》 摘要 超像素在计算机视觉应用中越来越受欢迎。然而&#xff0c;很少有算法能够输出所需数量的规则、紧凑的超级像素&#xff0c;并且计算开销低。我们介绍了一种新的算法&#xff0c;将像素聚类在组合的五维颜色和图像平面空间中&a…

matlab 超像素合并,超像素区域合并

应广大学术同行的请求,将以往研究的一些代码进行整理,特发布一个学术版本的小软件工具:SuperpixelMerge, 基本功能:实现超像素的区域合并 参数说明:共7个参数,分别为图像路径、超像素分割标记图像路径、输出结果路径、合并准则、合并后区域个数、形状参数、紧凑度参数。详…

超像素—学习笔记

文章目录 概念超像素判别条件超像素初始化的方法超像素算法SLIC算法 参考资料 概念 超像素由一系列位置相邻且颜色、亮度、纹理等特征相似的像素点组成的小区域。这些小区域大多保留了进一步进行图像分割的有效信息&#xff0c;且一般不会破坏图像中物体的边界信息。 超像素是…

超像素采样网络(英伟达)

Superpixel Sampling Networks 摘要 超像素为图像数据提供了一种高效的低/中层次的表示&#xff0c;大大减少了后续视觉任务的图像基元数量。现有的超像素算法是不可微的&#xff0c;这使得它们很难集成到其他端到端可训练的深度神经网络中。我们开发了一种新的超像素采样可微…

超像素、语义分割、实例分割、全景分割

图像分割&#xff08;Image segmentation&#xff09;就是根据某些规则把图像中的像素分成不同的部分&#xff08;打上不同的标签&#xff09;。 1. 超像素&#xff08;superpixels&#xff09; 超像素并不是在普通的像素基础上继续像微观细分&#xff0c;恰恰相反的是&#…

超像素

《超像素》   超像素是一种以聚类思想为初衷的方法&#xff0c;目的是为了对较大像素的图像进行区域划分&#xff0c;来帮助理解&#xff0c;本文介绍了一个开源项目在火灾检测场景使用超像素&#xff0c;比较巧妙&#xff0c;虽然效果不是很理想&#xff0c;但是提供了一个…

超像素学习笔记(1)——概念及判别条件

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、超像素的概念二、超像素判别条件&#xff1a;一般参考三个指标1.Undersegmentation Error&#xff08;UE&#xff09;——欠分割误差2.Boundary Recall&…

超像素(superpixel)——SLIC和深度学习法

定义 可以理解成在图像上做的聚类问题。超像素的做法是将感知上相似的像素组在一起&#xff0c;称为一个超像素&#xff0c;以此来提供图像数据的紧凑表示。然后在后续的处理&#xff0c;处理单位就变成了超像素&#xff0c;而不是我们常用的像素。 一般超像素的结果可以为下…

学习笔记4:ubuntu常用命令

cd //打开路径cd.. //回到上一级目录cd &#xff5e; //回到主目录ls //列表touch demo.c //创建一个“demo.c”文件mkdir project //创建一个“project”文件夹vi . //进入当前目录删除文件 pwd //显示当前路径ifconfig //查看本机IP地址mv 文件名 /PATH //移动文件到某一目…

Ubuntu常用命令(持续更新)

Ubuntu常用命令&#xff08;持续更新&#xff09; 检查更新并升级切换至root账号修改root账号密码下载文件命令wget&#xff0c;举例&#xff1a;安装.deb文件&#xff08;在文件所在目录打开终端&#xff09;查看本机ip地址&#xff08;注意和windows系统的区别ipconfig&#…

Ubuntu常用命令 (超详细版)

1.切换到 root 用户 &#xff0c;输入 “sudo -i ”, 退出 “exit” pwd 显示当前目录&#xff0c; pwd print working directory ls 列出目录下当前文件 cp 复制文件/目录 cp (源文件或目录) (目标文件或目录) cp -r 复制文件夹 包括子目录和文件 r…

Ubuntu 常用命令大全——长期不定时更新

1. 系统相关 uname -a 显示当前系统相关信息sudo 临时获取超级用户权限su root 切换 root 用户sudo shutdown 关机sudo reboot 重启sudo nautilus 进入有 root 权限的文件管理器ps -A 查看当前有哪些进程kill 5 位进程号 结束进程 sudo fdisk -l 查看磁盘信息sudo mount /dev/…

爆料一家互联网中厂的年终奖,真香。

前不久刷到宇宙条32岁员工14万的月薪截图&#xff0c;突然想起来已经快四月底了&#xff0c;正是各大互联网公司年终奖开奖的时候&#xff0c;但相比以往&#xff0c;今年互联网圈好像安静了很多。各种“凡尔赛”的年终奖金额刷屏的情况不复存在。 各家大厂都暗戳戳地分完了奖…

OPPO K9试水“捆绑销售”,消费者“赚了”还是“亏了”?

【原创】 号称“充电5分钟&#xff0c;开黑两小时”的OPPO新品K9于5月6日正式发布&#xff0c;这句“似曾相识”的OPPO“过气”广告语&#xff0c;又重新出现在了江湖&#xff0c;说是词穷也好&#xff0c;为了突出手机卖点也罢&#xff0c;反正新品是上了。 出了新品&#x…

2021年多媒体技术圈年终事件大回顾

今年的年终总结&#xff0c;虽迟但到&#xff0c;回看往年的总结&#xff1a; 2018年多媒体技术圈年终事件大回顾 2019年多媒体技术圈年终事件大回顾 2020&#xff08;我鸽了&#xff09; 以下内容均为个人见解&#xff0c;大佬轻拍~ 一月 一月属于WebRTC&#xff0c;W3C和…