首页 > 解决方案 > python中的区域增长实现,无需播种

问题描述

我正在尝试在 python 中实现区域增长分割算法,但我不允许使用种子点。到目前为止,我的想法是这样的:

从第一个像素开始,验证其邻居的边界检查(在宽度和高度内),然后验证邻居,使它们在阈值内(我通过使用当前像素和邻居之间的欧几里德距离获得了这一点)。为了确保不再访问同一个像素,我创建了一个与图像(宽度、高度)具有相同尺寸的矩阵,并在开始时将所有元素设为 0。我将从currentArea数字 1 开始,并随着时间的推移而增加。最后,在获得所有区域的平均颜色后,我将使用一个函数,根据我获得的元组记下新的图像。(averagePixelColor, areaNumber)

这是我的代码:

from PIL import Image
from scipy.spatial import distance
import statistics
import numpy as np
import sys
sys.setrecursionlimit(10**9)
# SCRIPT: color palette reduction applier script
# SCRIPT: this is the second method. region growing segmentation

# list of red values of pixels
rList = []
# list of green values of pixels
gList = []
# list of blue values of pixels
bList = []
# this matrix will be initially 0, then every region growth
# will be updated to its number
overlayMatrix = []
# starting area number
currentArea = 1

def isValidPixel(x, y, width, height):
    if x < 0 or x >= width:
        return False
    if y < 0 or y >= height:
        return False

    return True

def get_average_color():

    global rList
    global gList
    global bList

    # set values to none
    r = None
    g = None
    b = None

    # get average value for each chanel
    if rList != []:
        r = sum(rList)/len(rList)
        g = sum(gList)/len(gList)
        b = sum(bList)/len(bList)

        # make values integers to be used as pixel
        r = int(r)
        g = int(g)
        b = int(b)

    # return values
    return (r, g, b)

def add_pixel_to_lists(pixel):
    global rList
    global gList
    global bList

    rList.append(pixel[0])
    gList.append(pixel[1])
    bList.append(pixel[2])

def region_growing(x, y, pixel, img, currentArea):
    global overlayMatrix
    global rList
    global gList
    global bList
    # get width, heihgt
    width, height = img.size
    # set this pixel to be visited on current area
    overlayMatrix[x][y] = currentArea
    # set a list for all possible neighbours
    neighbouringPixels = [(x-1, y), (x-1, y-1), (x-1, y+1), (x, y-1), (x, y+1), (x+1, y), (x+1, y-1), (x+1, y+1)]
    # filter to get only valid neighbours
    validPixels = [x for x in neighbouringPixels if isValidPixel(x[0], x[1], width, height) == True]

    # filter pixels to be not visited
    notVisitedPixels = [x for x in validPixels if overlayMatrix[x[0]][x[1]] == 0]

    # set a threshold value
    threshold = 5

    # filter to get only pixels in threshold
    thresholdPixels = []
    thresholdPixels = [x for x in notVisitedPixels if distance.euclidean(img.getpixel(x), pixel) < threshold]

    # set the list for pixels to make recursive calls
    toVisitRecursive = []

    # for every pixel that is a valid neighbour, add it to the toVisit list in recursive call
    # and add its rgb values to the lists so an average can be computed
    for pixel in thresholdPixels:
        toVisitRecursive.append(pixel)
        add_pixel_to_lists(img.getpixel(pixel))

    # compute average
    averagePixel = get_average_color()

    # if I still have neighoburs that haven't been visited
    # and are within the threshold, get first from list
    # remove it so we don't do the same again, then apply
    # the algorithm for it
    if toVisitRecursive != []:
        pixel = toVisitRecursive[0]
        toVisitRecursive.remove(pixel)
        region_growing(pixel[0], pixel[1], averagePixel, img, currentArea)

    # finally, return
    return (averagePixel, currentArea+1)


def write_image():
    pass
    # this will write to the image based on the list of tuples
    # average color to the area with number X

def palette_reduction_mt2(input_image):
    # open original image
    img = Image.open(input_image)
    tuple_list = []
    # get width, height
    width, height = img.size

    # make overlay matrix of 0, initial
    global overlayMatrix
    overlayMatrix = np.zeros((width, height), dtype=np.int32)
    # create new image
    newimg = Image.new("RGB", (width, height), "white")
    currentArea = 1
    # iterate through image pixels
    for y in range(0, height-1):
        for x in range(0, width-1):
            global rList
            global gList
            global bList

            # get pixel from edge image
            p = img.getpixel((x, y))
            # apply region growing

            average, currentArea = region_growing(x, y, p, img, currentArea)
            tuple_list.append((average, currentArea-1))

            # reset color lists to compute new average
            rList = []
            gList = []
            bList = []
    print(tuple_list)
    # Save image
    newimg.save("images/reduced_mt1.jpg")
    # return the name of the image
    return "images/reduced_mt1.jpg"

出于某种原因,当我打印元组列表时,我只得到一个值:[(0,0,0), 1]

谁能指出我正确的方向?

谢谢!

标签: python-3.ximage-processingimage-segmentation

解决方案


似乎您实际上并没有遍历toVisitRecursive列表。也许您应该添加一个循环,例如:

 for pixel in toVisitRecursive:
   // region_growing...

或将此行更改if toVisitRecursive != []:为while循环;


推荐阅读