python-3.x - 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]
谁能指出我正确的方向?
谢谢!
解决方案
似乎您实际上并没有遍历toVisitRecursive
列表。也许您应该添加一个循环,例如:
for pixel in toVisitRecursive:
// region_growing...
或将此行更改if toVisitRecursive != []:
为while循环;
推荐阅读
- ruby - RUBY - 在哈希数组中查找最常见的药物名称
- c# - 如何使用 API Key 调用 TestRail?
- java - 如何根据传入的 UDP 数据包大小动态分配缓冲区大小?
- progressive-web-apps - 使用工作箱而不使用 cdn
- postgresql - PostgreSQL 存储过程可以返回多行吗
- flutter - 有没有办法将小部件对齐到 Flutter 中一行的最右侧?
- sql - Turn Multiple Rows into 1 Column with Multiple Fields in Teradata SQL
- api - SoundCloud 及其缺少客户端 ID 的解决方法
- r - 以整洁的方式通过 tibble 运行 aov 测试
- haskell - converting Num to Fractional in Haskell