文章目录
Ⅰ、项目任务要求
II、实现过程
III、完整代码
Ⅰ、项目任务要求
任务描述:
图像分割是图像处理和计算机视觉中重要的一环,在实际生活中得到了广泛的应用。例如,在医学上,用于测量医学图像中组织体积、三维重建、手术模拟等;在遥感图像中,分割合成孔径雷达图像中的目标、提取遥感云图中不同云系与背景等、定位卫星图像中的道路和森林等。图像分割也可作为预处理将最初的图像转化为若干个更加抽象、更便于计算机处理的形式,既保留了图像中的重要特征信息,又有效减少了图像中的无用数据、提高了后续图像处理的准确率和效率。例如,在通信方面,可事先提取目标的轮廓结构、区域内容等,保证不失有用信息的同时,有针对性地压缩图像,以提高网络传输效率;在交通领域可用来对车辆进行轮廓提取、识别或跟踪,行人检测等。总的来说,凡是与目标的检测、提取和识别等相关的内容,都需要利用到图像分割技术。因此,无论是从图像分割的技术和算法,还是从对图像处理、计算机视觉的影响以及实际应用等各个方面来深入研究和探讨图像分割,都具有十分重要的意义。 聚类技术是图像分割技术中重要组成部分,其中特征空间聚类法,如Kmeans算法及其相应变体是划分聚类方法中的典范。利用特征空间聚类法进行图像分割是将图像空间中的像素用对应的特征空间点表示,根据它们在特征空间的聚集对特征空间进行分割,然后将它们映射回原图像空间,得到分割结果。 本次实验利用图像的灰度、颜色、纹理、形状等特征,把图像分成若干个互不重叠的区域,并使这些特征在同一区域内呈现相似性,在不同的区域之间存在明显的差异性。然后就可以将分割的图像中具有独特性质的区域提取出来用于不同的研究。 实验内容:分别用Kmeans、Kmeans++和二分K均值三种聚类方法对图片进行图像分割,并写出实验结果分析。
主要任务要求:
简述三种算法思想和实现原理。 小组每人准备一张自己喜欢的图片(图片种类多样化) 写出实验结果分析:
实验运行环境描述。如开发平台、编程语言、调参情况等。 不同初始簇数下三种方法对图片的分割效果对比、分析。
对比表样式如下所示,可将分割效果图分别粘贴到对应位置; 采用轮廓系数(或其它评价指标)评估三种方法的聚类效果(见参考资料网址); 结合对比表(表样如下)结果和评估结果对实验结果进行分析说明。
II、实现过程
数据集描述
实现描述
具体实现过程
III、完整代码
代码①
import numpy as np
import PIL. Image as image
from sklearn. cluster import KMeans
from sklearn. metrics import silhouette_score
import matplotlib. pyplot as plt
def loadData ( filePath) :
f = open ( filePath, 'rb' )
data = [ ]
img = image. open ( f)
m, n = img. size
for i in range ( m) :
for j in range ( n) :
x, y, z = img. getpixel( ( i, j) )
data. append( [ x / 256.0 , y / 256.0 , z / 256.0 ] )
f. close( )
return np. asarray( data) , m, n
imgData1, row, col = loadData( "1.jpg" )
imgData2, row, col = loadData( "1.jpg" )
imgData3, row, col = loadData( "1.jpg" )
imgData4, row, col = loadData( "1.jpg" )
print ( "# Todo: KMeans聚类 ------------------------------------------------------------" )
def KMeansModel ( n_clusters, img) :
imgData = img
label = KMeans( n_clusters= n_clusters, init= 'random' ) . fit_predict( imgData)
label = label. reshape( [ row, col] )
pic_new = image. new( "L" , ( row, col) )
for i in range ( row) :
for j in range ( col) :
pic_new. putpixel( ( i, j) , int ( 256 / ( label[ i] [ j] + 1 ) ) )
pic_new. save( "KMeans{}.jpg" . format ( n_clusters) , "JPEG" )
silhouette_avg = silhouette_score( imgData, label. flatten( ) )
print ( f"聚类n_clusters= { n_clusters} 效果的轮廓系数为: { silhouette_avg} " )
plt. imshow( pic_new, cmap= 'gray' )
plt. axis( 'off' )
plt. show( )
KMeansModel( 2 , imgData1)
KMeansModel( 3 , imgData1)
KMeansModel( 4 , imgData1)
print ( "# Todo: KMeans++聚类 ------------------------------------------------------------" )
def KMeansPlusPlusModel ( n_clusters, img) :
imgData = img
kmeans = KMeans( n_clusters= n_clusters, init= 'k-means++' )
label = kmeans. fit_predict( imgData)
label = label. reshape( [ row, col] )
pic_new = image. new( "L" , ( row, col) )
for i in range ( row) :
for j in range ( col) :
pic_new. putpixel( ( i, j) , int ( 256 / ( label[ i] [ j] + 1 ) ) )
pic_new. save( "KMeansPlusPlus{}.jpg" . format ( n_clusters) , "JPEG" )
silhouette_avg = silhouette_score( imgData, label. flatten( ) )
print ( f"KMeans++聚类n_clusters= { n_clusters} 效果的轮廓系数为: { silhouette_avg} " )
plt. imshow( pic_new, cmap= 'gray' )
plt. axis( 'off' )
plt. show( )
KMeansPlusPlusModel( 2 , imgData2)
KMeansPlusPlusModel( 3 , imgData2)
KMeansPlusPlusModel( 4 , imgData2)
print ( "# Todo: 二分K均值 ------------------------------------------------------------" )
def bisectingKMeans ( imgData, k) :
clusters = [ imgData]
while len ( clusters) < k:
cluster_idx = - 1
max_sse = - 1
for i in range ( len ( clusters) ) :
sse = np. sum ( ( clusters[ i] - np. mean( clusters[ i] , axis= 0 ) ) ** 2 )
if sse > max_sse:
max_sse = sse
cluster_idx = i
kmeans = KMeans( n_clusters= 2 , init= 'k-means++' )
cluster_data = clusters. pop( cluster_idx)
kmeans. fit( cluster_data)
labels = kmeans. labels_
cluster1 = cluster_data[ labels == 0 ]
cluster2 = cluster_data[ labels == 1 ]
clusters. append( cluster1)
clusters. append( cluster2)
labels = np. zeros( len ( imgData) )
for i in range ( len ( clusters) ) :
labels[ np. isin( imgData, clusters[ i] ) . all ( axis= 1 ) ] = i
clustered_img = labels. reshape( [ row, col] )
pic_new = image. new( "L" , ( row, col) )
for i in range ( row) :
for j in range ( col) :
pic_new. putpixel( ( i, j) , int ( 256 / ( clustered_img[ i] [ j] + 1 ) ) )
pic_new. save( "BisectingKMeans{}.jpg" . format ( k) , "JPEG" )
silhouette_avg = silhouette_score( imgData, labels. flatten( ) )
print ( f"Bisecting K-Means with { k} clusters - Silhouette Score: { silhouette_avg} " )
plt. imshow( pic_new, cmap= 'gray' )
plt. axis( 'off' )
plt. show( )
bisectingKMeans( imgData3, 2 )
bisectingKMeans( imgData3, 3 )
bisectingKMeans( imgData3, 4 )
代码②