SNIC超像素分割python代码
生活随笔
收集整理的這篇文章主要介紹了
SNIC超像素分割python代码
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在網上找了一份SNIC超像素分割的代碼,但是由于是Python2版本的代碼,和我的版本已經不適用,所以進行了修改
出現了兩次報錯:
1. 首先是no module named Queue
在網上查了以后發現Python2和Python3兩個版本之間,有些不兼容的地方,Python3中引入Queue會報出這個問題。 Python3中要這樣引入:import queue2. 修改以后運行代碼又出現了新錯誤:
TypeError: '<' not supported between instances of 'NODE' and 'NODE'; 查到 In python 3 you must define comparison methods for class, for example like below: 所以改了classNode:部分的代碼 class Node:def __init__(self, parent, name, g):self.parent = parentself.name = nameself.g = gdef __eq__(self, other):return (self.name == other.name) and (self.g == other.g)def __ne__(self, other):return not (self == other)def __lt__(self, other):return (self.name < other.name) and (self.g < other.g)def __gt__(self, other):return (self.name > other.name) and (self.g > other.g)def __le__(self, other):return (self < other) or (self == other)def __ge__(self, other):return (self > other) or (self == other) # 修改后的全部代碼如下import numpy as np from PIL import Image from skimage import color import math from queue import PriorityQueueimport cv2def findseeds(im_lab, width, height, k):gridstep_x = int(math.sqrt(height * width / k) + 0.5)gridstep_y = int(math.sqrt(height * width / k) + 0.5) # compute the size of gridstep# compute the location of seeds in gridhalfstep_x = int(gridstep_x / 2)halfstep_y = int(gridstep_y / 2)xsteps = int(width / gridstep_x)ysteps = int(height / gridstep_y)# compute the error of numberof the seedserr1 = abs(xsteps * ysteps - k)err2 = abs(int(width / (gridstep_x - 1)) * int(height / (gridstep_y - 1)) - k)if err1 < err2:gridstep_x = gridstep_x - 1gridstep_y = gridstep_y - 1xsteps = int(width / gridstep_x)ysteps = int(height / gridstep_y)# compute the new numbernumk = xsteps * ystepsck = np.zeros((numk, 5))# i = 0# j = 0k = 0for i in range(ysteps):for j in range(xsteps):temp_x = halfstep_x + j * gridstep_xtemp_y = halfstep_y + i * gridstep_yck[k][0] = temp_xck[k][1] = temp_yck[k][2] = im_lab[temp_y][temp_x][0]ck[k][3] = im_lab[temp_y][temp_x][1]ck[k][4] = im_lab[temp_y][temp_x][2]k = k + 1return numk, ckdef initial_label(height, width):labels = np.zeros((height, width))for i in range(height):for j in range(width):labels[i][j] = -1return labelsclass NODE:def __init__(self, priority, description1, description2, description3):distance = int()xk = int()yk = int()k = int()self.priority = distanceself.description1 = xkself.description2 = ykself.description3 = kdef __eq__(self, other):return self.priority == other.prioritydef __ne__(self, other):return not (self == other)def __lt__(self, other):return self.priority < other.prioritydef __gt__(self, other):return self.priority > other.prioritydef __le__(self, other):return (self < other) or (self == other)def __ge__(self, other):return (self > other) or (self == other)def __cmp__(self, other):return cmp(self.priority, other.priority)def putinQ(ck, Q, numk):for k in range(numk):tempnode = NODE(0.0, 1, 1, 1)tempnode.priority = 0.0tempnode.description1 = ck[k][0]tempnode.description2 = ck[k][1]tempnode.description3 = kQ.put(tempnode)return Qdef runsnic(Q, im_lab, labels, numk, m):Qlength = Q.qsize()ksize = np.zeros((numk, 1))connectivity = 4 # or 8p4_x = [1, -1, 0, 0]p4_y = [0, 0, 1, -1]LABXk = np.zeros((numk, 5))s = math.sqrt((height * width) / numk)# 在這里選擇while的原因在于最終循環的截止條件為隊列長度為0,但是如果將Qlength作為循環# 終止條件,它本身就是變的,我看資料說是最好使用while才能不出錯fnum = 0while Qlength > 0:temp = Q.get()i = int(temp.description2)j = int(temp.description1)k = int(temp.description3)if labels[i][j] == -1:labels[i][j] = kfnum = fnum + 1LABXk[k][0] = LABXk[k][0] + im_lab[i][j][0]LABXk[k][1] = LABXk[k][1] + im_lab[i][j][1]LABXk[k][2] = LABXk[k][2] + im_lab[i][j][2]LABXk[k][3] = LABXk[k][3] + jLABXk[k][4] = LABXk[k][4] + iksize[k] = ksize[k] + 1for t in range(connectivity):ii = i + p4_y[t];jj = j + p4_x[t]if not (ii < 0 or ii >= height or jj < 0 or jj >= width):if labels[ii][jj] == -1:Ldist = LABXk[k][0] / ksize[k] - im_lab[ii][jj][0]Adist = LABXk[k][1] / ksize[k] - im_lab[ii][jj][1]Bdist = LABXk[k][2] / ksize[k] - im_lab[ii][jj][2]Xdist = LABXk[k][3] / ksize[k] - jjYdist = LABXk[k][4] / ksize[k] - iicolordist = Ldist * Ldist + Adist * Adist + Bdist * BdistXYdist = Xdist * Xdist + Ydist * Ydistsnicdist = math.sqrt(colordist / m + XYdist / s)newtemp = NODE(1.0, 5, 5, 5)newtemp.priority = snicdistnewtemp.description1 = jjnewtemp.description2 = iinewtemp.description3 = kQ.put(newtemp)Qlength = Q.qsize()return labels, fnumim_rgb = Image.open("small.jpg") im_lab = color.rgb2lab(im_rgb) # gb2lab是Python自帶的轉換函數,針對灰度圖也是可以進行處理,所以可以用該函數 width, height = im_rgb.size K = 2000 # the initial number of seeds numk, ck = findseeds(im_lab, width, height, K) # 根據ck結果findseeds labels = initial_label(height, width) Q = PriorityQueue() Q = putinQ(ck, Q, numk) # Q為隊列無法查看確定情況,使用函數進行判定m = 20.0 final_labels, fnum = runsnic(Q, im_lab, labels, numk, m) # 畫圖 segments = final_labels h = height w = width newim1 = np.array(im_rgb) newim = np.array(im_rgb) seg = np.zeros((h + 2, w + 2)) for i in range(h):for j in range(w):seg[i + 1][j + 1] = segments[i][j] for i in range(h):for j in range(w):m = i + 1n = j + 1if seg[m][n] != seg[m - 1][n] or seg[m][n] != seg[m + 1][n] or seg[m][n] != seg[m][n - 1] or seg[m][n] != \seg[m][n + 1]:newim1[i][j][0] = 255 # bnewim1[i][j][1] = 255 # gnewim1[i][j][2] = 255 # rnewim3 = newim1[:, :, ::-1] # cv2.imshow('newslic', newim1) # cv2.imwrite('original_Airport.jpg', newim) cv2.imwrite('Small_newslic_k=2000_m=20.0.jpg', newim3) # cv2.waitKey(0)#程序暫停總結
以上是生活随笔為你收集整理的SNIC超像素分割python代码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 个人收款解决方案之三方聚合收款方案
- 下一篇: 闲谈:渗透测试-红队版