Реализация растущего региона в Python, без заполнения - PullRequest
0 голосов
/ 23 декабря 2018

Я пытаюсь реализовать алгоритм сегментации растущего региона в 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]

Может кто-нибудь, пожалуйста, укажите мне в правильном направлении?

Спасибо!

1 Ответ

0 голосов
/ 04 января 2019

Похоже, вы на самом деле не просматриваете список toVisitRecursive.Возможно, вам следует добавить цикл вроде:

 for pixel in toVisitRecursive:
   // region_growing...

или изменить эту строку if toVisitRecursive != []: на время цикла;

...