超像素分割 SLIC算法 使用示例
參考博客
介紹超像素分割 & SLIC算法?
SLIC超像素分割詳解(一):簡介_計算機視覺life的博客-CSDN博客_slic超像素分割
機器學(xué)習(xí):simple linear iterative clustering (SLIC) 算法_Matrix_11的博客-CSDN博客_簡單線性迭代聚類算法
?圖像處理: 超像素(superpixels)分割 SLIC算法_haoji007的博客-CSDN博客_超像素分割
Image Segmentation論文學(xué)習(xí)翻譯-SLIC Superpixels Compared to State-of-the-Art Superpixel Methods_暮雨橙海的博客-CSDN博客_slic論文翻譯
如何使用SLIC算法?
圖像分割:Python的SLIC超像素分割_程序媛一枚~的博客-CSDN博客_python slic
Python實現(xiàn)超像素分割_技術(shù)挖掘者的博客-CSDN博客_python 超像素分割
python 自帶slic代碼分析_北落師門XY的博客-CSDN博客_python slic
具體示例
SLIC超像素分割并保存分割得到的超像素塊,python代碼_LarkMi的博客-CSDN博客_python超像素分割代碼
超像素分割, 并獲取每一個分區(qū) - 默盒 - 博客園 (cnblogs.com)
論文&代碼
SLIC Superpixels Compared to State-of-the-Art Superpixel Methods | IEEE Journals & Magazine | IEEE Xplore
SLIC Superpixels ? IVRL ‐ EPFL
superpixels ? IVRL ‐ EPFL
http://github.com/laixintao/slic-python-implementation
https://github.com/LarkMi/SLIC
徐其鈺/MyProject - Gitee.com?(超像素分割、邊緣檢測)
示例 SLIC分割圖
標(biāo)題???示例來自SLIC Superpixels ? IVRL ‐ EPFL “怎么不蒜呢”(無惡意.jpg超像素分割
簡介
超像素概念是2003年Xiaofeng Ren提出和發(fā)展起來的圖像分割技術(shù),是指具有相似紋理、顏色、亮度等特征的相鄰像素構(gòu)成的有一定視覺意義的不規(guī)則像素塊。它利用像素之間特征的相似性將像素分組,用少量的超像素代替大量的像素來表達(dá)圖片特征,很大程度上降低了圖像后處理的復(fù)雜度,所以通常作為分割算法的預(yù)處理步驟。在像素網(wǎng)格上按照一定的方式進(jìn)行像素局部分組,可得到超像素。
它已經(jīng)廣泛用于圖像分割、姿勢估計、目標(biāo)跟蹤、目標(biāo)識別等計算機視覺應(yīng)用。幾種常見的超像素分割方法及其效果對比如下:
Graph-based? NCut? ? ?Turbopixel? ? Quick-shift? ?Graph-cut a? ?Graph-cut b? ? ?SLIC 使用SLIC的分割示例?其中,SLIC(simple linear iterativeclustering),即簡單的線性迭代聚類。它是2010年提出的一種思想簡單、實現(xiàn)方便的算法,將彩色圖像轉(zhuǎn)化為CIELAB顏色空間和XY坐標(biāo)下的5維特征向量,然后對5維特征向量構(gòu)造距離度量標(biāo)準(zhǔn),對圖像像素進(jìn)行局部聚類的過程。SLIC算法能生成緊湊、近似均勻的超像素,在運算速度,物體輪廓保持、超像素形狀方面具有較高的綜合評價。
SLIC主要優(yōu)點
計算效率高、含有更多感知(有意義的)信息、過度分割可減少像素?fù)p失、超像素上表示圖形更加高效。?
- 生成的超像素如同細(xì)胞一般緊湊整齊,鄰域特征比較容易表達(dá)。這樣基于像素的方法可以比較容易的改造為基于超像素的方法。
- 不僅可以分割彩色圖,也可以兼容分割灰度圖。
- 需要設(shè)置的參數(shù)非常少,默認(rèn)情況下只需要設(shè)置一個預(yù)分割的超像素的數(shù)量。
- 相比其他的超像素分割方法,SLIC在運行速度、生成超像素的緊湊度、輪廓保持方面都比較理想。
Lab顏色空間
在介紹SLIC之前,插播一下Lab顏色空間的介紹。Lab色彩模型是由亮度(L)和有關(guān)色彩的a, b三個要素組成。L表示亮度(Luminosity),L的值域由0(黑色)到100(白色)。a表示從洋紅色至綠色的范圍(a為負(fù)值指示綠色而正值指示品紅),b表示從黃色至藍(lán)色的范圍(b為負(fù)值指示藍(lán)色而正值指示黃色)。
Lab顏色空間的優(yōu)點:
- 不像RGB和CMYK色彩空間,Lab 顏色被設(shè)計來接近人類生理視覺。它致力于感知均勻性,它的 L 分量密切匹配人類亮度感知。因此可以被用來通過修改 a 和 b 分量的輸出色階來做精確的顏色平衡,或使用 L 分量來調(diào)整亮度對比。這些變換在 RGB 或 CMYK 中是困難或不可能的。
- 因為 Lab 描述的是顏色的顯示方式,而不是設(shè)備(如顯示器、打印機或數(shù)碼相機)生成顏色所需的特定色料的數(shù)量,所以 Lab 被視為與設(shè)備無關(guān)的顏色模型。
- 色域?qū)掗煛K粌H包含了RGB,CMYK的所有色域,還能表現(xiàn)它們不能表現(xiàn)的色彩。人的肉眼能感知的色彩,都能通過Lab模型表現(xiàn)出來。
另外,Lab色彩模型的絕妙之處還在于它彌補了RGB色彩模型色彩分布不均的不足,因為RGB模型在藍(lán)色到綠色之間的過渡色彩過多,而在綠色到紅色之間又缺少黃色和其他色彩。如果我們想在數(shù)字圖形的處理中保留盡量寬闊的色域和豐富的色彩,最好選擇Lab。
SLIC具體步驟
- 初始化種子點(聚類中心):按照設(shè)定的超像素個數(shù),在圖像內(nèi)均勻的分配種子點。假設(shè)圖片總共有 N 個像素點,預(yù)分割為 K 個相同尺寸的超像素,那么每個超像素的大小為N/ K ,則相鄰種子點的距離(步長)近似為S=sqrt(N/K)。
- 在種子點的n*n鄰域內(nèi)重新選擇種子點(一般取n=3)。具體方法為:計算該鄰域內(nèi)所有像素點的梯度值,將種子點移到該鄰域內(nèi)梯度最小的地方。這樣做的目的是為了避免種子點落在梯度較大的輪廓邊界上,以免影響后續(xù)聚類效果。
- 在每個種子點周圍的鄰域內(nèi)為每個像素點分配類標(biāo)簽(即屬于哪個聚類中心)。和標(biāo)準(zhǔn)的k-means在整張圖中搜索不同,SLIC的搜索范圍限制為2S*2S,可以加速算法收斂,如下圖。在此注意一點:期望的超像素尺寸為S*S,但是搜索的范圍是2S*2S。
- ?距離度量。包括顏色距離和空間距離。對于每個搜索到的像素點,分別計算它和該種子點的距離。距離計算方法如下:
其中,dc代表顏色距離,ds代表空間距離,Ns是類內(nèi)最大空間距離,定義為Ns=S=sqrt(N/K),適用于每個聚類。最大的顏色距離Nc既隨圖片不同而不同,也隨聚類不同而不同,所以取一個固定常數(shù)m(取值范圍[1,40],一般取10)代替。最終的距離度量D'。
由于每個像素點都會被多個種子點搜索到,所以每個像素點都會有一個與周圍種子點的距離,取最小值對應(yīng)的種子點作為該像素點的聚類中心。
- 迭代優(yōu)化。理論上上述步驟不斷迭代直到誤差收斂(可以理解為每個像素點聚類中心不再發(fā)生變化為止),實踐發(fā)現(xiàn)10次迭代對絕大部分圖片都可以得到較理想效果,所以一般迭代次數(shù)取10。
- 增強連通性。經(jīng)過上述迭代優(yōu)化可能出現(xiàn)以下瑕疵:出現(xiàn)多連通情況、超像素尺寸過小,單個超像素被切割成多個不連續(xù)超像素等,這些情況可以通過增強連通性解決。主要思路是:新建一張標(biāo)記表,表內(nèi)元素均為-1,按照“Z”型走向(從左到右,從上到下順序)將不連續(xù)的超像素、尺寸過小超像素重新分配給鄰近的超像素,遍歷過的像素點分配給相應(yīng)的標(biāo)簽,直到所有點遍歷完畢為止。
偽代碼
SLIC代碼使用
直接調(diào)庫
from skimage.segmentation import slic,mark_boundaries segments = slic(image, n_segments=60, compactness=10)# 參數(shù)說明: # n_segments: 分割塊的個數(shù)。可能最后分割出的塊數(shù)與實際設(shè)置并不一樣,可能是slic算法做了后續(xù)處理,將小的超像素合并到大的超像素中。 # compactness:分割塊的邊界是否壓縮,壓縮會使分割快的邊沿更光滑。具體SLIC代碼附在文章最后。
超像素分割
例1?
項目介紹?
SLIC超像素分割并保存分割得到的超像素塊,python代碼_LarkMi的博客-CSDN博客_python超像素分割代碼
完整代碼
GitHub - LarkMi/SLIC: SLIC分割并存儲分割后的超像素塊
# https://github.com/LarkMi/SLIC/blob/main/SLIC.pyimport skimage from skimage.segmentation import slic,mark_boundaries from skimage import io import matplotlib.pyplot as plt from PIL import Image, ImageEnhance import numpy as np import cv2 # # np.set_printoptions(threshold=np.inf) path = 'C:\\Users\\Administrator\\Desktop\\SLIC\\' img_name = 'test.png' img = io.imread(path + img_name,as_gray=True) #as_gray是灰度讀取,得到的是歸一化值 segments = slic(img, n_segments=10, compactness=0.2,start_label = 1)#進(jìn)行SLIC分割 out=mark_boundaries(img,segments) out = out*255 #io的灰度讀取是歸一化值,若讀取彩色圖片去掉該行 img3 = Image.fromarray(np.uint8(out)) img3.show() seg_img_name = 'seg.png' img3.save(path +'\\' +seg_img_name)#顯示并保存加上分割線后的圖片maxn = max(segments.reshape(int(segments.shape[0]*segments.shape[1]),)) for i in range(1,maxn+1):a = np.array(segments == i)b = img * aw,h = [],[]for x in range(b.shape[0]):for y in range(b.shape[1]):if b[x][y] != 0:w.append(x)h.append(y)c = b[min(w):max(w),min(h):max(h)]c = c*255d = c.reshape(c.shape[0],c.shape[1],1)e = np.concatenate((d,d),axis=2)e = np.concatenate((e,d),axis=2)img2 = Image.fromarray(np.uint8(e))img2.save(path +'\\'+str(i)+'.png')print('已保存第' + str(i) + '張圖片')wid,hig = [],[] img = io.imread(path+'\\'+seg_img_name)for i in range(1,maxn+1):w,h = [],[]for x in range(segments.shape[0]):for y in range(segments.shape[1]):if segments[x][y] == i:w.append(x)h.append(y)font=cv2.FONT_HERSHEY_SIMPLEX#使用默認(rèn)字體#print((min(w),min(h)))img=cv2.putText(img,str(i),(h[int(len(h)/(2))],w[int(len(w)/2)]),font,1,(255,255,255),2)#添加文字,1.2表示字體大小,(0,40)是初始的位置,(255,255,255)表示顏色,2表示粗細(xì) img = Image.fromarray(np.uint8(img)) img.show() img.save(path +'\\'+seg_img_name+'_label.png')效果展示:
原圖,超像素分割圖,下圖分割后的標(biāo)識區(qū)域 各個分割區(qū)域例2
超像素分割, 并獲取每一個分區(qū) - 默盒 - 博客園 (cnblogs.com)
from skimage.segmentation import slic from skimage.segmentation import mark_boundaries from skimage.util import img_as_float import matplotlib.pyplot as plt import numpy as np import cv2# args args = {"image": './hand_0.png'}# load the image and apply SLIC and extract (approximately) # the supplied number of segments image = cv2.imread(args["image"]) segments = slic(img_as_float(image), n_segments=100, sigma=5)# show the output of SLIC fig = plt.figure('Superpixels') ax = fig.add_subplot(1, 1, 1) ax.imshow(mark_boundaries(img_as_float(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)), segments)) plt.axis("off") plt.show() print("segments:\n", segments) print("np.unique(segments):", np.unique(segments)) # loop over the unique segment values for (i, segVal) in enumerate(np.unique(segments)):# construct a mask for the segmentprint("[x] inspecting segment {}, for {}".format(i, segVal))mask = np.zeros(image.shape[:2], dtype="uint8")mask[segments == segVal] = 255# show the masked regioncv2.imshow("Mask", mask)cv2.imshow("Applied", np.multiply(image, cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR) > 0))cv2.waitKey(0)例3
項目介紹 & 效果展示
?python 超像素分割_Afleve的博客-CSDN博客_python超像素
?代碼?
opencv/超像素分割 · 徐其鈺/MyProject - 碼云 - 開源中國 (gitee.com)
例4
Python實現(xiàn)超像素分割_技術(shù)挖掘者的博客-CSDN博客_python 超像素分割
# import the necessary packages from skimage.segmentation import slic from skimage.segmentation import mark_boundaries from skimage.util import img_as_float from skimage import io import matplotlib.pyplot as plt# load the image and convert it to a floating point data type image = img_as_float(io.imread("image.jpg"))# loop over the number of segments for numSegments in (100, 200, 300):# apply SLIC and extract (approximately) the supplied number# of segmentssegments = slic(image, n_segments = numSegments, sigma = 5)# show the output of SLICfig = plt.figure("Superpixels -- %d segments" % (numSegments))ax = fig.add_subplot(1, 1, 1)ax.imshow(mark_boundaries(image, segments))plt.axis("off")# show the plots plt.show()效果展示:通過超像素分割我們可以將整個圖像劃分為含有固定個超像素組的感知塊,具體如圖中的黃色塊所示。
邊緣檢測
%% Clean up clear all close all clc%Generate image img = imread('test.jpg'); img = double(rgb2gray(img));%Invert circle brightness img = abs(img-1);%Blur original image with Gaussian kernel with a blur width (standard %deviaion) of 0.9 pixels BlurGaussian = 0.9; G = fspecial('Gaussian',5,BlurGaussian); img = imfilter(img,G,'replicate');%Blurring occurs from quantization and from Gaussian BlurQuantization = 1/sqrt(12); BlurWidth = sqrt( BlurQuantization^2 + BlurGaussian^2);%% Create mask %Only consider edges on columns 35-50 M = true(size(img));%% Perform edge localization %Get pixel-level edges with Sobel operator [E] = edge(img,'sobel');%Refine to subpixel accuracy edges = SubpixelEdge(img,E,BlurWidth,M);%% Plot results %Show image figure(1); imshow(uint8(img)),hold on, axis on; plot(edges.u,edges.v,'co')figure(2); imshow(uint8(M)),hold on, axis on; plot(edges.u,edges.v,'co')% p1 = [edges.u(1), edges.v(1), 0]; % p2 = [edges.u(100), edges.v(100), 0]; % p3 = [edges.u(500), edges.v(500), 0]; % p = CircleCenter(p1, p2, p3); % % disp('當(dāng)前圓的半徑為%d', p);x=edges.u; y=edges.v; [R,x0,y0]=circ(x,y,edges.NumPts-1); disp(['第一個圓的半徑是: ' num2str(R),' mm' ]); disp(['第一個圓的圓心坐標(biāo):( ' num2str(x0) ,',',num2str(y0),')']); plot(x0, y0, 'gx');效果展示:超像素可以準(zhǔn)確的檢測出齒輪的邊緣信息,包括它的內(nèi)環(huán)和外環(huán)信息。
SLIC超像素分割算法的應(yīng)用
應(yīng)用廣泛
詳見?superpixels ? IVRL ‐ EPFL?,里面列舉很多使用超像素算法的論文工作。包括有視頻檢測、無人機數(shù)據(jù)對齊、語義分割、目標(biāo)跟蹤、3d重建、數(shù)據(jù)增強、水印恢復(fù),等等。
IEEE TIP 2014年 的《Robust superpixeltracking》,基于超像素的方法解決外觀發(fā)生劇烈變化的物體追蹤問題。
ICCV 2009年 的《Class segmentation andobject localization with superpixel neighborhoods》,從像素級別的分割遷移到超像素級別的分割。
CVPR 2013年的《Improving an objectdetector and extracting regions using superpixels》,把樣本中超像素級的特征通過k-means聚類為超像素級詞袋,再結(jié)合SVM對難分類樣本進(jìn)一步分類。
IET? 2014年的 《Video object segmentation with shape cue based on spatiotemporal superpixel neighbourhood》,用于視頻前景分割。
JEI 2015年的《Improving video foreground segmentation with an object-like pool》,在無監(jiān)督條件下對序列圖像中運動目標(biāo)進(jìn)行精細(xì)的分割。
ECCV 2022年 的?《SPSN: Superpixel Prototype Sampling Network for RGB-D Salient Object Detection》,用超像素分割做顯著性檢測。
如何設(shè)置待分割超像素的數(shù)目?
使用超像素對圖像進(jìn)行分割時,設(shè)置的超像素數(shù)目K比較重要:如果K比較小,每個超像素尺寸會比較大,這樣超像素對邊界的保持就會變差,如果K比較大,每個超像素的尺寸會比較小,那么會出現(xiàn)類似“過擬合”現(xiàn)象,超像素的形狀會變得非常不規(guī)則,鄰域關(guān)系很難保持,而且數(shù)目也比較多。
不同尺寸的超像素分割結(jié)果對比。(a)原圖,超像素尺寸:(b)100X100,(c)30X30,(d)8X8
具體分割數(shù)目K和具體應(yīng)用有關(guān),比如如果對上圖做主要人物(左邊的小魔女)分割的話,100X100大小的超像素就夠了,但是如果對兩個騎自行的人物也進(jìn)行分割的話,需要使用30X30的尺寸,但是此時較小人物的分割精度不高,如果有更高要求,則需要使用8X8甚至更小的尺寸。尺寸也需要根據(jù)不同場合選擇。
?
SLIC代碼細(xì)節(jié)
封裝工具、C++、Matlab代碼:SLIC Superpixels ? IVRL ‐ EPFL
1、設(shè)定期望分割的超像素數(shù)目,打開圖片。將彩色RGB圖片轉(zhuǎn)換為LAB空間及x、y像素坐標(biāo)共5維空間。
2、DetectLabEdges。求圖片中所有點的梯度=dx+dy.其中
dx=(l(x-1)-l(x+1))*(l(x-1)-l(x+1))+(a(x-1)-a(x+1))*(a(x-1)-a(x+1))+(b(x-1)-b(x+1))*(b(x-1)-b(x+1));
dy=(l(y-1)-l(y+1))*(l(y-1)-l(y+1))+(a(y-1)-a(y+1))*(a(y-1)-a(y+1))+(b(y-1)-b(y+1))*(b(y-1)-b(y+1));
3、GetLABXYSeeds_ForGivenK。給定了要分割的超像素總數(shù)K,根據(jù)LABXY信息獲得種子點。
1) ? 超像素的種子點間步長Step=sqrt(N/K)。初始化種子點。按照步長均勻播撒種子點,初始化后種子點是均勻分布的(圖1中的紅色點)。
2) ? PerturbSeeds。擾亂種子點。在每個種子點的3*3鄰域內(nèi),計算該種子點的8個鄰域內(nèi)像素點的Lab顏色梯度(同上述步驟2),分別與初始種子點梯度進(jìn)行比較,取梯度值最小(最“平坦”)的點,并記錄其LABXY信息作為新的種子點(圖1中綠色點為擾亂后的新種子點)。
?
4、超像素的步長Step=sqrt(N/K)+2。加了一個小偏置2是為了避免Step太小,造成超像素太密集的情況。
5、PerformSuperpixelSegmentation_VariableSandM。對于每個超像素,最大的顏色距離M取值范圍[1,40],一般取10。最大空間距離取步長為Step。
- 1) ? 搜索范圍2step* 2step,即設(shè)置offset=step。 在步長較短時(step<10)可以擴展offset=step*1.5作為搜索范圍。
- 2) ?初始化distlab、distxy、distvec為無窮大。maxlab初始化為10*10,maxxy初始化為step*step。distlab代表某點與種子點的lab顏色空間距離,計算如下:distlab(i)=(l-kseedsl(n))*(l-kseedsl(n))+(a-kseedsa(n))*(a-kseedsa(n))+(b-kseedsb(n))*(b-kseedsb(n));distxy代表某點與種子點的空間坐標(biāo)距離,計算如下:distxy(i)=(x-kseedsx(n))*(x-kseedsx(n))+(y-kseedsy(n))*(y-kseedsy(n));dist代表某點與種子點的綜合距離(歸一化的顏色距離+空間距離),計算如下:dist=distlab/( maxlab)+ distxy/(maxxy);在此提醒一下:如果將C++程序轉(zhuǎn)為matlab代碼時特別要注意數(shù)據(jù)類型。uint16類型變量減去double類型變量的結(jié)果是uint16類型,所以如果后者值大于前者,結(jié)果就為0。此處容易出錯,需要強制類型轉(zhuǎn)換。
- 3) ? 計算搜索區(qū)域內(nèi)每個點離種子點的距離dist,并將搜索區(qū)域內(nèi)每個點離種子點的距離保存在distvec中。因為某點可能位于多個種子點的搜索區(qū)域,所以最后保存的是離相鄰種子點最近的距離,并將該像素標(biāo)號為最近種子點相同的標(biāo)號。同一個超像素內(nèi)所有像素的標(biāo)號相同
- 4) ? 計算每個新超像素內(nèi)所有像素的labxy均值和坐標(biāo)重心。將坐標(biāo)重心作為該超像素的新種子點位置。
- 5) ? 上述步驟2)到4)重復(fù)迭代10次。
6、EnforceLabelConnectivity。該函數(shù)主要有幾個作用:保證同一個超像素都是單連通區(qū)域;去掉尺寸過小的超像素;避免單個超像素被切割的情況。
- 1) ? 先計算超像素理想面積大小:SUPSZ = sz/K = N/K;
- 2) ? 有兩種標(biāo)號向量:上一步驟中得到的舊標(biāo)號向量labels(即步驟5中得到的klabels),但其存在多連通,過小超像素等問題,需要優(yōu)化。新標(biāo)號向量nlabels,初始化值全為-1。
- 3) ? 首先選擇每個超像素的起始點(左上角的第一個點),起始點判斷條件:a) 按照從左到右,從上到下的“Z”型順序查找。b)該點在新標(biāo)號向量nlabels中未被標(biāo)記過(值為-1)。將其坐標(biāo)保存在xvec[0],yvec[0]中。
- 4) ? 記錄前一個相鄰超像素的標(biāo)號值adjlabel。判斷條件:a)在步驟3中起始點的四鄰域。b)在新標(biāo)號向量nlabels中被標(biāo)記過(標(biāo)號大于0)。記錄adjlabel的目的是:如果當(dāng)前超像素尺寸過小,將當(dāng)前超像素標(biāo)號全部用adjlabel代替。即合并到前一個相鄰超像素,參考下面步驟6)。
- 5) ? 擴展當(dāng)前超像素。首先選擇起始點作為當(dāng)前操作的中心點,然后對其四鄰域進(jìn)行判斷是否屬于該超像素成員。判斷條件:a) 該點在新標(biāo)號向量nlabels中未被標(biāo)記過(值為-1);b)該點n和當(dāng)前操作中心點c在舊標(biāo)號向量中標(biāo)號一致,即labels(n)= labels(c),可以理解為原先就是屬于同一個超像素的成員。如果判斷是超像素的新成員,那么把該新成員作為新的操作中心點,循環(huán)直到找不到新成員為止。
- 6) ? 如果新超像素大小小于理想超像素大小的一半(可以根據(jù)需要自己定義),將該超像素標(biāo)號用前一個相鄰超像素的標(biāo)號值adjlabel代替,并且不遞增標(biāo)號值。
- 7) ? 迭代上述步驟3)到6)直到整張圖片遍歷結(jié)束。
7、繪制分割結(jié)果,退出窗口。
?
SLIC Superpixels Compared to State-of-the-art Superpixel Methods,TPAMI 2012
超像素算法將像素組合成感知有意義的原子區(qū)域( atomic regions),其可以用于替換像素網(wǎng)格的剛性結(jié)構(gòu)。它們捕獲圖像冗余,提供計算圖像特征的方便原語( primitive ),并且大大降低了后續(xù)圖像處理任務(wù)的復(fù)雜性。用下面三點來判斷算法的優(yōu)劣性:
- 超像素應(yīng)當(dāng)良好地粘附到圖像邊界。
- 當(dāng)作為預(yù)處理步驟用于降低的計算復(fù)雜度時,超像素應(yīng)當(dāng)快速計算,存儲 器效率高且易于使用。
- 當(dāng)用于分割目的時,超像素應(yīng)當(dāng)增加速度并提高結(jié)果的質(zhì)量。
論文列舉其他超像素方法,再提出SLIC算法進(jìn)行對比。
用于生成超像素的算法可以大致分類為基于圖或梯度上升的方法。?
SLIC與現(xiàn)有超像素算法的對比。基于圖形的方法
基于圖形的超像素生成方法將每個像素視為圖中的節(jié)點。兩個節(jié)點之間的邊權(quán)重與相鄰像素之間的相似性成比例。超像素通過最小化圖中定義的成本函數(shù)來創(chuàng)建。
NC05,歸一化切割算法遞歸地使用輪廓和紋理線索分割圖像中的所有像素的圖形,從而全局性地最小化在分割邊界處的邊緣定義的成本函數(shù)。它產(chǎn)生非常規(guī)則,視覺上令人愉快的超像素。然而,NC05的邊界粘附相對較差,并且它是方法中最慢的(特別是對于大圖像),盡管試圖加速的算法存在。NC05具有的復(fù)雜度,其中N是像素的數(shù)量。
GS04,提出了一種替代的基于圖形的方法,已被應(yīng)用于生成超像素。它將像素作為圖的節(jié)點,使得每個超像素是組成像素的最小生成樹。GS04在實踐中很好地粘附到圖像邊界,但是產(chǎn)生具有非常不規(guī)則的尺寸和形狀的超像素。它的復(fù)雜度是,在實踐中速度很快。然而,它不提供對超像素的量或其緊湊性的明確控制。
SL08,提出了一種通過確定將圖像分割成更小的垂直或水平區(qū)域的最佳路徑或接縫來生成符合網(wǎng)格的超像素的方法。使用類似于SeamCarving的圖切割方法找到最佳路徑。復(fù)雜的是,但這并不考慮預(yù)先計算的邊界圖,這強烈影響輸出的質(zhì)量和速度。
GCa10和GCb10。使用紋理合成工作的全局優(yōu)化方法。通過將重疊的圖像塊拼接在一起來獲得超像素,使得每個像素僅屬于重疊區(qū)域中的一個。這個方法有兩個變種,一個用于生成緊湊超像素(GCa10),一個用于恒定強度超像素(GCb10)。
基于梯度上升的方法
從粗略的像素初始聚類開始,梯度上升法迭代地修改聚類,直到滿足一些收斂標(biāo)準(zhǔn)以形成超像素。
MS02,平均偏移,用于定位密度函數(shù)的局部最大值的迭代模式尋找過程被應(yīng)用于圖像的顏色或強度特征空間中的第一模式。會聚到相同模式的像素定義超像素。MS02是一種較舊的方法,產(chǎn)生不均勻尺寸的不規(guī)則形狀的超像素。它是復(fù)雜度,使其相對較慢,并且不提供對超像素的量,尺寸或緊密度的直接控制。
QS08,也使用模式查找分割方案。它使用medoid移位過程初始化分割。然后將特征空間中的搜索點移動到最近的鄰居,從而增加Parzen密度估計。雖然它具有相對良好的邊界粘附,但是QS08的運行速度相當(dāng)緩慢,具有復(fù)雜度(d是一個小常數(shù))。而且QS08不允許對超像素的大小或數(shù)量的顯式控制。
WS91,從局部最小值開始執(zhí)行梯度上升以產(chǎn)生分水嶺,和分離集水盆地的線條。所得到的超像素在尺寸和形狀上通常是高度不規(guī)則的,并且不表現(xiàn)出良好的邊界粘附。具有的復(fù)雜度),但不提供對超像素量或其緊湊性的控制。
TP09,使用基于水平集的幾何流動逐漸擴大一組種子位置。幾何流依賴于局部圖像梯度,目的是在圖像平面上規(guī)則地分布超像素。與WS91不同,TP09超像素被約束為具有均勻的尺寸,緊湊性和邊界粘附。TP09依賴于不同復(fù)雜度的算法,但在實踐中,如作者所聲稱的,具有大約的復(fù)雜度,是所檢查的最慢的算法之一,并且表現(xiàn)出相對較差的邊界粘附。
SLIC
比現(xiàn)有方法更快,更高的記憶效率,展示了目前最優(yōu)的邊界依從性,并提高了分割算法的性能。簡單線性迭代聚類(SLIC)采用K均值算法生成超像素,相較與其他算法具有兩個重要的區(qū)別:
1)通過將搜索空間限制為與超像素大小成比例的區(qū)域,顯著地減少了優(yōu)化中的距離計算的數(shù)量。這降低了像素數(shù)N的線性復(fù)雜度,并且與超像素k的數(shù)量無關(guān)。
2)加權(quán)距離度量組合顏色和空間接近度,同時提供對超像素的尺寸和緊湊性的控制。
SLiC使用簡單,其唯一的參數(shù)是所需的超像素數(shù),是產(chǎn)生超體素的為數(shù)不多的方法之一。最后,在現(xiàn)有的方法中,SLIC的獨特之處在于它能夠通過m來控制超像素緊密性和邊界粘著性之間的權(quán)衡。
?
python中的slic函數(shù)
def slic(image, n_segments=100, compactness=10., max_iter=10, sigma=0,spacing=None, multichannel=True, convert2lab=None,enforce_connectivity=True, 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 ndarrayInput image, which can be 2D or 3D, and grayscale or multichannel(see `multichannel` parameter).n_segments : int, optionalThe (approximate) number of labels in the segmented output image.compactness : float, optional控制顏色和空間之間的平衡,約高越方塊,和圖關(guān)系密切,最好先確定指數(shù)級別,再微調(diào)Balances color proximity and space proximity. Higher values givemore weight to space proximity, making superpixel shapes moresquare/cubic. In SLICO mode, this is the initial compactness.This parameter depends strongly on image contrast and on theshapes of objects in the image. We recommend exploring possiblevalues on a log scale, e.g., 0.01, 0.1, 1, 10, 100, beforerefining around a chosen value.max_iter : int, optional最大k均值迭代次數(shù)Maximum number of iterations of k-means.sigma : float or (3,) array-like of floats, optional圖像每個維度進(jìn)行預(yù)處理時的高斯平滑核寬。若給定為標(biāo)量值,則同一個值運用到各個維度。0意味著不平滑。如果“sigma”是標(biāo)量的,并且提供了手動體素間距,則自動縮放它(參見注釋部分)。Width of Gaussian smoothing kernel for pre-processing for eachdimension of the image. The same sigma is applied to each dimension incase of a scalar value. Zero means no smoothing.Note, that `sigma` is automatically scaled if it is scalar and amanual voxel spacing is provided (see Notes section).spacing : (3,) array-like of floats, optional代表沿著圖像每個維度的體素空間。默認(rèn)情況下,slic假定均勻的空間(沿x,y,z軸相同的體素分辨率),這個參數(shù)控制在k均值聚類中各軸距離的權(quán)重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二進(jìn)制參數(shù),代表圖像的最后一個軸代表多通道還是另一個空間維度Whether the last axis of the image is to be interpreted as multiplechannels or another spatial dimension.convert2lab : bool, optional二進(jìn)制參數(shù),判斷輸入需要在分割之前轉(zhuǎn)到LAB顏色空間。輸入必須是RGB。當(dāng)多通道參數(shù)為True,輸入圖片的通道數(shù)為3時,該參數(shù)默認(rèn)為TrueWhether the input should be converted to Lab colorspace prior tosegmentation. 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二進(jìn)制參數(shù),控制生成的分割塊連接或不連接Whether the generated segments are connected or notmin_size_factor: float, optional與分割目標(biāo)數(shù)有關(guān)的要刪去的最小分割塊比率,(大概是小于長*寬*高/目標(biāo)數(shù)量 的分割結(jié)果會被融合掉)Proportion of the minimum segment size to be removed with respectto 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 worksin most of the cases.slic_zero: bool, optional不知所謂的零參數(shù)Run SLIC-zero, the zero-parameter mode of SLIC. [2]_Returns-------labels : 2D or 3D arrayInteger mask indicating segment labels.Raises------ValueErrorIf ``convert2lab`` is set to ``True`` but the last arraydimension is not of length 3.Notes-----* If `sigma > 0`, the image is smoothed using a Gaussian kernel prior tosegmentation.* If `sigma` is scalar and `spacing` is provided, the kernel width isdivided along each dimension by the spacing. For example, if ``sigma=1``and ``spacing=[5, 1, 1]``, the effective `sigma` is ``[0.2, 1, 1]``. Thisensures sensible smoothing for anisotropic images.如果有平滑參數(shù)sigma和體素空間參數(shù)spacing,那么空間體素參數(shù)會對平滑參數(shù)有平分的影響,比如 1/[5,1,1]=[0.2,1,1]* The image is rescaled to be in [0, 1] prior to processing.圖像在預(yù)處理之前會被處理為[0,1]之間的標(biāo)量* Images of shape (M, N, 3) are interpreted as 2D RGB images by default. Tointerpret them as 3D with the last dimension having length 3, use`multichannel=False`.(M,N,3)的圖像默認(rèn)為2維(RGB的圖像),要想被理解為3維圖需要設(shè)置多通道參數(shù)=FalseReferences----------.. [1] Radhakrishna Achanta, Appu Shaji, Kevin Smith, Aurelien Lucchi,Pascal Fua, and Sabine Süsstrunk, SLIC Superpixels Compared toState-of-the-art Superpixel Methods, TPAMI, May 2012... [2] http://ivrg.epfl.ch/research/superpixels#SLICOExamples-------->>> 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#2D灰度圖if image.ndim == 2:# 2D grayscale imageimage = image[np.newaxis, ..., np.newaxis]is_2d = True#比如2D RGB的圖elif image.ndim == 3 and multichannel:# Make 2D multichannel image 3D with depth = 1image = image[np.newaxis, ...]is_2d = True#比如3D圖elif image.ndim == 3 and not multichannel:# Add channel as single last dimensionimage = image[..., np.newaxis]#控制聚類時各軸權(quán)重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)#有可能發(fā)生的體素除elif isinstance(sigma, (list, tuple)):sigma = np.array(sigma, dtype=np.double)#高斯濾波處if (sigma > 0).any():# add zero smoothing for multichannel dimensionsigma = list(sigma) + [0]image = ndi.gaussian_filter(image, sigma)#多通道RGB圖且需要轉(zhuǎn)lab,用rab2lab即可實現(xiàn)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#為實現(xiàn)目標(biāo)分割塊數(shù),初始化聚類中心。#grid_* 相當(dāng)于index#slices是根據(jù)目標(biāo)數(shù)量分的塊,有取整需要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 meaningstep = 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_segmentsmin_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總結(jié)
以上是生活随笔為你收集整理的超像素分割 SLIC算法 使用示例的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MATLAB学习之均值滤波
- 下一篇: 淘宝B2C上线 马云初试将阿里巴巴三合一