超像素分割学习笔记

article/2025/10/1 8:17:36

学习目标

掌握超像素分割的原理、超像素分割方法的推导过程以及实现方法

1.1 超像素

超像素是指将具有相似纹理、颜色、亮度等特征的相邻像素聚合成某一个像素块,结合超像素的思想,这样可以使少量的像素块代替原本大量的像素。
目前超像素广泛应用于图像分割、目标识别等领域。

1.2 SLIC

SLIC(Simple Linear IterativeClustering,简单线性迭代聚类)是超像素分割中使用比较多的方法,主要特点(优点)如下:
1.基于LAB颜色空间
2.运行速度快,生成的超像素紧凑
3.思想比较简单

1.3 SLIC实现的具体步骤

1.初始化种子点

在图像内均匀分布种子点(与Kmeans不同)
若图像像素为N*N,预想分为K个像素块,则:

  • 每个像素块的初始大小为 N ∗ N / K N*N/K NN/K

  • 相邻种子点间的步长S为 N ∗ N / K \sqrt {N*N/K} NN/K (假设初始每个像素块的大小是均匀的)

2.重新选择种子点

结合图像中的梯度信息,在n*n邻域内重新选择种子点(一般n取3)。重新选择种子点是为了防止均匀初始化后的种子点处于边缘或是噪声,将种子点移动到梯度比较小的位置。

3.以各像素块种子点为中心更新标签

以超像素的种子点为中心,在其上下左右2S的范围内搜索(和Kmeans 不同,这里的搜索不是全局范围的)

在这里插入图片描述
4.计算距离

计算各像素点与种子点的距离,距离包括颜色距离空间位置的距离。

颜色距离 d c d_c dc的计算方法如下:

l j − l i ) 2 + ( a i − a j ) 2 + ( b i − b j ) 2 \sqrt {l_j-l_i)^2+(a_i-a_j)^2+(b_i-b_j)^2} ljli)2+(aiaj)2+(bibj)2

空间距离 d s d_s ds的计算方法如下:

( x j − x i ) 2 + ( y i − y j ) 2 \sqrt {(x_j-x_i)^2+(y_i-y_j)^2} (xjxi)2+(yiyj)2

总距离 D D D的计算方法如下:

( d c m ) 2 + ( d s S ) 2 \sqrt {(\frac{d_c}{m})^2+(\frac{d_s}{S})^2} (mdc)2+(Sds)2

其中 m m m为常数,取值范围在[1,40],常以10代替

因为搜索范围在种子点的[-2S,2S]内,有些像素点会被重复搜索到,所以应该同时记录距离,最终取最小值对应的种子点作为其聚类中心

将上述3-4过程不断迭代,一直到满足最大迭代次数或者中心种子点不再发生变化为止。

5.增强连通性

经过迭代之后有可能会出现过分割、多连通、单个超像素被分割成多个不连续的超像素等,需要增强连通性

主要思路是:新建一张标记表,表内元素均为-1,按照“Z”型走向(从左到右,从上到下顺序)将不连续的超像素、尺寸过小超像素重新分配给邻近的超像素,遍历过的像素点分配给相应的标签,直到所有点遍历完毕为止

2 实战

import cv2
import numpy as np
from skimage import img_as_float
import matplotlib.pyplot as plt

1.初始化种子点

def init_cluster(pic,n_segments):cluster_w,cluster_h=int(cluster_S/2),int(cluster_S/2)  #计算出每个的长和宽center={}i=0while cluster_h<pic.shape[0]:  #shape[0]是高度while cluster_w<pic.shape[1]:center[i]=[cluster_w,cluster_h,pic[cluster_w,cluster_h,0],pic[cluster_w,cluster_h,1],pic[cluster_w,cluster_h,2]]cluster_w=cluster_w+cluster_Si=i+1cluster_w=int(cluster_S/2)cluster_h=cluster_h+cluster_Sreturn center

2.计算梯度

def caculate_grad(w,h):if h+1>=pic.shape[0] or w+1>=pic.shape[1]:w=w-2h=h-2grad=np.sum(pic[w+1,h+1,:]-pic[w,h,:])return grad

3.在3*3邻域内根据计算得到的梯度,更新种子点

def update_center(center):#更新中心点for i in range(0,len(center)):w,h=center[i][0],center[i][1] now_grad=caculate_grad(w,h)  #计算当前的梯度for dw in range(-1,2): #在3*3邻域内for dh in range(-1,2):new_grad=caculate_grad(w+dw,h+dh)  #计算新梯度if new_grad<now_grad:now_grad=new_gradcenter[i]=[w+dw,h+dh,pic[w+dw,h+dh,0],pic[w+dw,h+dh,1],pic[w+dw,h+dh,2]]return center

4.可视化种子点

def draw_center(center)for i in range(0,len(center)): cv2.circle(ori_pic,(center[i][0],center[i][1]),1, (255, 0, 0),4) #将初始化中心标出来fig=plt.figure()ax=fig.add_subplot(1,1,1)ax.imshow(ori_pic)plt.show()
n_segments=50
ori_pic=cv2.imread('Lenna.png')
ori_pic=cv2.cvtColor(ori_pic,cv2.COLOR_BGR2RGB)
pic=cv2.cvtColor(ori_pic,cv2.COLOR_BGR2LAB)
cluster_shape=pic.shape[0]*pic.shape[1]/n_segments    #每个超像素块中包含的像素数
cluster_S=int(np.sqrt(cluster_shape))  #超像素块的长/宽/初始种子点之间的距离(假设形状规则)
center=init_cluster(pic,n_segments) #初始化中心
center=update_center(center)  #更新中心,避免中心在梯度高(噪声点等)
draw_center(center) #可视化初始中心点

得到初始的种子点(已经进行了梯度更新,可以看出中心点分布不是绝对均匀)
在这里插入图片描述

5.初始化距离矩阵(用来存储每个像素点与其中心点间的距离)

def init_distance():distance=[]for i in range(pic.shape[0]):distance_item=[np.inf for j in range(pic.shape[1])]distance.append(distance_item)return distance

7.初始化像素矩阵(用来记录每个像素块中包含的具体像素位置)

def init_pixel():pixel={}for i in range(0,len(center)):pixel[i]=[]return pixel

8.计算某像素与其种子点之间的距离(这里M取10)

def caculate_distance(w_,h_,center_):#根据颜色空间和像素位置进行更新color_dic=np.sqrt(np.sum(np.square(pic[w_,h_,:]-np.array(center_[2:]))))geo_dic=np.sqrt(np.sum(np.square(np.array([w_,h_])-np.array(center_[:2]))))dis=np.sqrt(np.square(color_dic/10)+np.square(geo_dic/cluster_S))return dis

9.计算各个像素点所属的标签(即所属种子点)

def get_cluster(center,distance,label,pixel):for i in range(0,len(center)):for dw in range(center[i][0]-2*cluster_S,center[i][0]+2*cluster_S):  #在2S范围内if dw<0 or dw>=pic.shape[0]:  continue for dh in range(center[i][1]-2*cluster_S,center[i][1]+2*cluster_S):if dh<0 or dh>=pic.shape[1]:  continuedis=caculate_distance(dw,dh,center[i])#计算距离if dis<distance[dw][dh]:distance[dw][dh]=dislabel[(dw,dh)]=center[i]  #记录当前的中心点for j in list(pixel.values()):if(dw,dh) in j:#若该像素点之前已经隶属于某个中心,需要先将其去掉,再添加至新的中心j.remove((dw,dh))pixel[i].append((dw,dh))return label,distance,pixel

10.更新各超像素的中心(所属种子点)

def update_cluster(center,pixel):#更新中心for i,item in enumerate(pixel.values()): #{1:[(),()]w,h=0,0for j in item:  w+=j[0]h+=j[1]center_w=int(w/len(item))center_h=int(h/len(item))center[i]=[center_w,center_h,pic[center_w,center_h,0],pic[center_w,center_h,1],pic[center_w,center_h,2]]return center

11.可视化超像素分割结果

def save_cluster(center,pixel):image_arr = np.copy(ori_pic)for i,item in enumerate(pixel.values()): #{1:[(),()]for j in item:image_arr[j[0],j[1],0]=image_arr[center[i][0],center[i][1],0]image_arr[j[0],j[1],1]=image_arr[center[i][0],center[i][1],1]image_arr[j[0],j[1],2]=image_arr[center[i][0],center[i][1],2]fig=plt.figure()ax=fig.add_subplot(1,1,1)ax.imshow(image_arr)plt.show() 
label={}       
distance=init_distance()  
pixel=init_pixel()#初始化簇内的像素点 形如:{0: [], 1: [], 2: [], 3: [], 4: [], 5: []}for epoch in range(10):#循环迭代十次old_label=labelprint('epoch:',epoch)label,distance,pixel=get_cluster(center,distance,old_label,pixel)center=update_cluster(center,pixel)save_cluster(center,pixel)

最终可以得到超像素分割的结果为:
在这里插入图片描述
在这里插入图片描述
调包:

from skimage.segmentation import slic,mark_boundaries
from skimage import img_as_float
pic=cv2.imread('Lenna.png')
segments = slic(img_as_float(pic), n_segments=50,sigma=2)
marked_img=mark_boundaries(img_as_float(cv2.cvtColor(pic, cv2.COLOR_BGR2RGB)), segments)
fig=plt.figure()
# fig.show(marked_img)
ax=fig.add_subplot(1,1,1)
ax.imshow(marked_img)
plt.axis('off')
plt.show()

在这里插入图片描述

参考文献

[1] Achanta,Radhakrishna, et al. “SLIC superpixels compared to state-of-the-artsuperpixel methods.” Pattern Analysis and Machine Intelligence, IEEETransactions on 34.11 (2012): 2274-2282.


http://chatgpt.dhexx.cn/article/xRMGkWFe.shtml

相关文章

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和…

OPPO AI Lab 核心岗位开放招聘:至美之路,等你加入!

国产手机越来越受青睐&#xff0c;在中国&#xff0c;更多年轻人选择 OPPO 拍照手机。 十年来&#xff0c;OPPO 一直专注手机拍照的技术创新&#xff0c;开创了“手机自拍美颜”时代。 如今&#xff0c;全球超过 2 亿年轻人正在使用 OPPO 拍照手机。 关于OPPO 使命&#xff1a…

8月顺利拿到OPPO公司Android架构师offer,一面+部长面

上周喜提oppo面试offer&#xff0c;本人在深圳&#xff0c;有4年多的Android项目经验&#xff0c;普通本科学历。面试是相互选择的过程&#xff0c;而OPPO给我的印象确实如其核心价值观所说&#xff1a;本分。 一面、部长面和HR面都蛮顺利&#xff08;一千个人可能要了一百左右…

十年老码农吐血经验:跳槽千万不能选高年终低base的公司,超过15薪就要慎重!...

低base高年终VS高base低年终&#xff0c;哪个更好&#xff1f; 一个工作十年的老码农总结了自己的经验&#xff1a;跳槽千万不能选年终月数多的公司&#xff0c;超过15薪就要好好掂量掂量。能选外企就选外企&#xff0c;奖金基本就是一个月&#xff0c;不会坑你。 一网友惊呼&a…