├── input └── original_image.png ├── output ├── Region_Merging_--_20_scale.png └── Superpixels_--_3500_super_pixel_size.png ├── README.md └── slic-superpixel.py /input/original_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuyafang1014/research/HEAD/input/original_image.png -------------------------------------------------------------------------------- /output/Region_Merging_--_20_scale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuyafang1014/research/HEAD/output/Region_Merging_--_20_scale.png -------------------------------------------------------------------------------- /output/Superpixels_--_3500_super_pixel_size.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yuyafang1014/research/HEAD/output/Superpixels_--_3500_super_pixel_size.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SLIC-Superpixel-Implementation 2 | > The python implementation to make superpixels by slic. 3 | 4 | ## Requirements: 5 | 6 | > gdal 2.x or 3.x 7 | 8 | > opencv & opencv_contrib >= 3.1 9 | 10 | > skimage 0.14.x or 0.15.x 11 | 12 | > matplotlib >= 1.x 13 | 14 | ## Algorithm description: 15 | 16 | > SLIC超像素分割算法分为四部分: 17 | > 18 | > 第一部分是使用GDAL库读取大文件TIF格式的遥感影像(gdal.Open(sys.argv[1]))。 19 | > 20 | > 第二部分是进行slic影像分割。这一部分是利用skimage库自带的slic函数,可以直接进行调用,非常方便。需要注意的是传入的参数格式和个数。 21 | > 22 | > 第三部分是对分割后的结果进行区域合并。这里采用的是基于区域邻接图(RAG)的分层合并算法。该算法通过构造区域邻接图(RAG)并逐步合并颜色相似的区域来达到合并的效果。合并两个相邻区域会生成一个新区域,其中包含来自合并区域的所有像素,直到没有高度相似的区域就结束合并。 23 | > 24 | >第四部分主要是展示实验slic分割和区域合并结果。通过matplotlib提供的pyplot模块来绘制最终的实验结果。 25 | 26 | ## Run 27 | 28 | ```python 29 | python slic-superpixel.py input_image.tif 3500 5 20 30 | ``` 31 | 32 | ## Results 33 | 34 | * original image 35 | ![image](https://github.com/yuyafang1014/research/blob/master/input/original_image.png) 36 | 37 | * The default value of the compactness is 5 38 | * max_iter is 10 39 | * super_pixel_size is 3500 40 | * sigma is 5 41 | ![image](https://github.com/yuyafang1014/research/blob/master/output/Superpixels_--_3500_super_pixel_size.png) 42 | 43 | * 20 scale 44 | ![image](https://github.com/yuyafang1014/research/blob/master/output/Region_Merging_--_20_scale.png) 45 | -------------------------------------------------------------------------------- /slic-superpixel.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Tuesday July 16 11:30:00 2019 4 | E-mail = yuyafang1014@163.com 5 | @author: Yuyafang 6 | """ 7 | 8 | from skimage.segmentation import slic 9 | from skimage.segmentation import mark_boundaries 10 | import matplotlib.pyplot as plt 11 | from osgeo import gdal 12 | import cv2 13 | import sys 14 | import datetime 15 | from skimage import segmentation 16 | from skimage.future import graph 17 | import numpy as np 18 | 19 | 20 | def _weight_mean_color(graph, src, dst, n): 21 | diff = graph.node[dst]['mean color'] - graph.node[n]['mean color'] 22 | diff = np.linalg.norm(diff) 23 | return {'weight': diff} 24 | 25 | 26 | def merge_mean_color(graph, src, dst): 27 | graph.node[dst]['total color'] += graph.node[src]['total color'] 28 | graph.node[dst]['pixel count'] += graph.node[src]['pixel count'] 29 | graph.node[dst]['mean color'] = (graph.node[dst]['total color'] / 30 | graph.node[dst]['pixel count']) 31 | 32 | 33 | def daw_figure(numSegment, image, segment): 34 | fig = plt.figure("slic-superpixels -- %d segments" % (numSegment)) 35 | ax = fig.add_subplot(1, 1, 1) 36 | ax.imshow(mark_boundaries(image, segment)) 37 | plt.axis("off") 38 | return 0 39 | 40 | 41 | def main(): 42 | 43 | # ------Slic-Superpixel segmentation------ 44 | 45 | if len(sys.argv) < 4: 46 | print("need more args") 47 | # TODO: print usage 48 | exit(-1) 49 | 50 | # Load the image(GDAL) 51 | dataset = gdal.Open(sys.argv[1]) 52 | super_pixel_size = int(sys.argv[2]) 53 | nc_sigma = int(sys.argv[3]) 54 | scale = int(sys.argv[4]) 55 | 56 | im_width = dataset.RasterXSize 57 | im_height = dataset.RasterYSize 58 | im_bands = dataset.RasterCount 59 | 60 | if im_bands == 3: 61 | band1 = dataset.GetRasterBand(1) 62 | band2 = dataset.GetRasterBand(2) 63 | band3 = dataset.GetRasterBand(3) 64 | im_redBand = band1.ReadAsArray(0, 0, im_width, im_height) 65 | im_greenBand = band2.ReadAsArray(0, 0, im_width, im_height) 66 | im_blueBand = band3.ReadAsArray(0, 0, im_width, im_height) 67 | merge_img = cv2.merge([im_redBand, im_greenBand, im_blueBand]) 68 | 69 | numSegments = int(im_width * im_height / super_pixel_size) 70 | 71 | start1 = datetime.datetime.now() 72 | 73 | # Apply SLIC and extract (approximately) the supplied number of segments 74 | segments = slic(merge_img, n_segments=numSegments, sigma=nc_sigma) 75 | print(segments) 76 | print(segments.shape) 77 | 78 | cv2.waitKey(0) 79 | 80 | # Show the output of SLIC 81 | end1 = datetime.datetime.now() 82 | print("The time spent in segmentation (seconds): ", (end1 - start1).seconds) 83 | daw_figure(numSegments, merge_img, segments) 84 | 85 | # Show the plots 86 | plt.show() 87 | 88 | # ------Hierarchical Region Merging Algorithm for Region Adjacent Graph (RAG)------ 89 | start2 = datetime.datetime.now() 90 | 91 | # Compute the Region Adjacency Graph using mean colors 92 | g = graph.rag_mean_color(merge_img, segments) 93 | 94 | end21 = datetime.datetime.now() 95 | print("The time spent in mean colors (seconds): ", (end21 - start2).seconds) 96 | 97 | # Perform hierarchical merging of a RAG 98 | labels = graph.merge_hierarchical(segments, g, thresh=scale, rag_copy=False, 99 | in_place_merge=True, 100 | merge_func=merge_mean_color, 101 | weight_func=_weight_mean_color) 102 | 103 | # Return image with boundaries between labeled regions highlighted 104 | out = segmentation.mark_boundaries(segments, labels) 105 | 106 | # Show the figure 107 | end22 = datetime.datetime.now() 108 | fig = plt.figure("Region Merging -- %d scale" % (scale)) 109 | ax = fig.add_subplot(1, 1, 1) 110 | print("The time spent on region merging (seconds): ", (end22 - start2).seconds) 111 | ax.imshow(out) 112 | plt.axis("off") 113 | plt.show() 114 | 115 | # ------Draw equalized histogram------ 116 | start3 = datetime.datetime.now() 117 | arr = segments.flatten() 118 | 119 | # Show equalized histogram 120 | plt.figure("Equalized histogram") 121 | plt.hist(arr, bins=256, normed=1, edgecolor='None', facecolor='red') 122 | end3 = datetime.datetime.now() 123 | print("The time spent on equalized histogram (seconds): ", (end3 - start3).seconds) 124 | plt.show() 125 | 126 | 127 | ''' 128 | usage: python ./slic-superpixel.py input_image.tif super_pixel_size sigma scale 129 | example: python ./slic-superpixel.py a.tif 3500 5 20 130 | 131 | ''' 132 | if __name__ == '__main__': 133 | main() 134 | --------------------------------------------------------------------------------