SNIC超像素分割python代码

在网上找了一份SNIC超像素分割的代码,但是由于是Python2版本的代码,和我的版本已经不适用,所以进行了修改

出现了两次报错:

1. 首先是no module named Queue

在网上查了以后发现Python2和Python3两个版本之间,有些不兼容的地方,Python3中引入Queue会报出这个问题。
Python3中要这样引入:import queue

2. 修改以后运行代码又出现了新错误:

 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 = parent
        self.name = name
        self.g = g

    def __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 PriorityQueue

import cv2


def 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 grid
    halfstep_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 seeds
    err1 = abs(xsteps * ysteps - k)
    err2 = abs(int(width / (gridstep_x - 1)) * int(height / (gridstep_y - 1)) - k)
    if err1 < err2:
        gridstep_x = gridstep_x - 1
        gridstep_y = gridstep_y - 1
        xsteps = int(width / gridstep_x)
        ysteps = int(height / gridstep_y)
    # compute the new number
    numk = xsteps * ysteps
    ck = np.zeros((numk, 5))
    # i = 0
    # j = 0
    k = 0
    for i in range(ysteps):
        for j in range(xsteps):
            temp_x = halfstep_x + j * gridstep_x
            temp_y = halfstep_y + i * gridstep_y
            ck[k][0] = temp_x
            ck[k][1] = temp_y
            ck[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 + 1
    return numk, ck


def initial_label(height, width):
    labels = np.zeros((height, width))
    for i in range(height):
        for j in range(width):
            labels[i][j] = -1
    return labels


class NODE:
    def __init__(self, priority, description1, description2, description3):
        distance = int()
        xk = int()
        yk = int()
        k = int()
        self.priority = distance
        self.description1 = xk
        self.description2 = yk
        self.description3 = k

    def __eq__(self, other):
        return self.priority == other.priority

    def __ne__(self, other):
        return not (self == other)

    def __lt__(self, other):
        return self.priority < other.priority

    def __gt__(self, other):
        return self.priority > other.priority

    def __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.0
        tempnode.description1 = ck[k][0]
        tempnode.description2 = ck[k][1]
        tempnode.description3 = k
        Q.put(tempnode)
    return Q


def runsnic(Q, im_lab, labels, numk, m):
    Qlength = Q.qsize()
    ksize = np.zeros((numk, 1))
    connectivity = 4  # or 8
    p4_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 = 0
    while 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] = k
            fnum = fnum + 1
            LABXk[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] + j
            LABXk[k][4] = LABXk[k][4] + i
            ksize[k] = ksize[k] + 1
            for 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] - jj
                        Ydist = LABXk[k][4] / ksize[k] - ii
                        colordist = Ldist * Ldist + Adist * Adist + Bdist * Bdist
                        XYdist = Xdist * Xdist + Ydist * Ydist
                        snicdist = math.sqrt(colordist / m + XYdist / s)
                        newtemp = NODE(1.0, 5, 5, 5)
                        newtemp.priority = snicdist
                        newtemp.description1 = jj
                        newtemp.description2 = ii
                        newtemp.description3 = k
                        Q.put(newtemp)
        Qlength = Q.qsize()
    return labels, fnum


im_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 + 1
        n = j + 1
        if 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  # b
            newim1[i][j][1] = 255  # g
            newim1[i][j][2] = 255  # r
        newim3 = 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)#程序暂停

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值