继续回答这个问题:How could you rewrite a list of lists so that "islands" of values are unique from one another?

简介:如何解析图像,例如:

example input

通过这种方式,您可以识别不同像素的几个簇,并重写文件,使每个簇具有唯一的 colored颜色 ,例如:

example output

以下是我如何在几个来源的帮助下实现它,包括stackoverflow user@Rabinzel:(主要代码块下面的详细推理)

    from scipy import ndimage
    import numpy as np
    from PIL import Image
    
    #set the file path to wherever your provinces.png is located
    im = Image.open(r"C:\\Users\\scoop\\Desktop\\prov_test.png")
    
    print('-------------------------------------------')
    #DEBUGGING: simply prints the format, size, and mode of your file
    print(im.format, im.size, im.mode)
    #saves the width and depth of the file
    im_xsize = im.size[0]
    im_ysize = im.size[1]
    #DEBUGGING: prints it
    print(im_xsize, im_ysize)
    #DEBUGGNG: prints data bands, should be R, G, B
    print(im.getbands())
    
    #DEBUGGING: prints RGB value of pixel of choice
    print(im.getpixel((0,0)))
    print('-------------------------------------------')
    
    #creates array for pixel RGBs
    rgb_array = [[None] * im_ysize for length in range(0,im_xsize)]
    
    #fills pixel RGB array
    for x in range(0,im_xsize):
        for y in range(0,im_ysize):
            rgb_array[x][y] = im.getpixel((x,y))
       
    #find unique clusters of identical RGB codes
    def find_clusters(array):
        clustered = np.empty_like(array)
        unique_vals = np.unique(array)
        cluster_count = 0
        for val in unique_vals:
            labelling, label_count = ndimage.label(array == val)
            for k in range(1, label_count + 1):
                clustered[labelling == k] = cluster_count
                cluster_count += 1
        return clustered, cluster_count
    
    clusters, cluster_count = find_clusters(rgb_array)
    print("Found {} clusters:".format(cluster_count))
    #print(clusters)
    
    #defining a list of unique colors
    province_color_list = [[0] * 3 for length in range(0,cluster_count)] 
    
    #DEBUGGING
    print('province count...', cluster_count)
    #variables
    r = 255
    g = 0
    b = 0
    count = 0
    
    #generating colors
for length in range(0,cluster_count):
    province_color_list[length][0] = r
    province_color_list[length][1] = g
    province_color_list[length][2] = b
    g += 25
    b += 25
    count += 1
    if count >= 11:
        r -= 1
        g = 0
        b = 0
        count = 0

#DEBUGGING
print('# of colors... ', len(province_color_list))
print(province_color_list)
print('-------------------------------------------')

#writing colors to pixels
for x in range(0,im_xsize):
    for y in range(0,im_ysize):
        #places province color based on which province current pixel is assigned to
        im.putpixel((x,y),   (province_color_list[0][0],   province_color_list[0][1],   province_color_list[0][2]))
         
#im.save(r"C:\\Users\\scoop\\Desktop\\prov_test.png", im.format)

我使用PIL加载图像:

im = Image.open(r"C:\\Users\\scoop\\Desktop\\prov_test.png")

我创建一个数组来更容易(?)访问图像数组,该数组以元组形式将每个像素的 colored颜色 存储为RGB colored颜色 代码.然后该方法识别相关的像素簇.

rgb_array = [[None] * im_ysize for length in range(0,im_xsize)]

#fills pixel RGB array
for x in range(0,im_xsize):
    for y in range(0,im_ysize):
        rgb_array[x][y] = im.getpixel((x,y))
   
#find unique clusters of identical RGB codes
def find_clusters(array):
    clustered = np.empty_like(array)
    unique_vals = np.unique(array)
    cluster_count = 0
    for val in unique_vals:
        labelling, label_count = ndimage.label(array == val)
        for k in range(1, label_count + 1):
            clustered[labelling == k] = cluster_count
            cluster_count += 1
    return clustered, cluster_count

clusters, cluster_count = find_clusters(rgb_array)

然后我创建了一个独特的RGB代码列表,即存在的#个像素簇的长度.

province_color_list = [[0] * 3 for length in range(0,cluster_count)] 

#DEBUGGING
print('province count...', cluster_count)
#variables
r = 255
g = 0
b = 0
count = 0

#generating colors
for length in range(0,cluster_count):
    province_color_list[length][0] = r
    province_color_list[length][1] = g
    province_color_list[length][2] = b
    g += 25
    b += 25
    count += 1
    if count >= 11:
        r -= 1
        g = 0
        b = 0
        count = 0

最后,我用新的RGB代码重写每个像素,该代码与之前的唯一簇关联(并保存图像).

#writing colors to pixels
for x in range(0,im_xsize):
    for y in range(0,im_ysize):
        #places province color based on which province current pixel is assigned to
        im.putpixel((x,y),   (province_color_list[clusters[x][y]][0],   province_color_list[clusters[x][y]][1],   province_color_list[clusters[x][y]][2]))
         
#im.save(r"C:\\Users\\scoop\\Desktop\\prov_test.png", im.format)

不幸的是,这个脚本有多个问题,我觉得它已经退化成了一点废话.主要的问题似乎是访问.PNG图像类,并将其更改为整数以正确识别它们,以及区分不同的簇,而不仅仅是不同的 colored颜色 .到目前为止,我甚至无法让脚本将图像写成平淡的 colored颜色 .

作为参考,我希望能够放大它来处理这样的图像:

enter image description here

给每个小簇一个独特的 colored颜色 .感谢所有帮助.

推荐答案

好吧,让我们看看这对你是否有效.如果我正确理解了你想要实现的目标,下面是我的(初学者)解决方案.

基本上,我在3D数组中拍摄图像,找到图片中所有独特的 colored颜色 ,并用整数替换它们(函数:arr_to_int).然后使用函数find_clusters查找所有簇.创建一个包含新 colored颜色 的字典, colored颜色 的数量与簇的数量相同(这样每个簇的每个int都会再次替换为一种 colored颜色 ).

这是我一开始使用的图像:

enter image description here

这是我作为输出得到的新图片:

enter image description here

如果你改变了将它们应用到你想要使用的特定 colored颜色 的过程,我认为我非常接近你想要实现的目标(希望如此:)

import numpy as np
import cv2
from scipy import ndimage

# array of GBR colors to single int
def arr_to_int(arr, col_mask):
    out = np.ndarray(shape=arr.shape[:2], dtype=int)
    out[:,:] = -1
    for rgb, idx in col_mask.items():
        out[(arr==rgb).all(2)] = idx
    return out

# find unique clusters of identical RGB codes
def find_clusters(array):
    clustered = np.empty_like(array)
    unique_vals = np.unique(array)
    cluster_count = 0
    for val in unique_vals:
        labelling, label_count = ndimage.label(array == val)
        for k in range(1, label_count + 1):
            clustered[labelling == k] = cluster_count
            cluster_count += 1
    return clustered, cluster_count
# Load image
im = cv2.imread("prov_test.png")
#im = cv2.resize(im, (2, 3)) #resize for debugging
#print('original image: \n', im, '\n')

#find all unique colors in image (cv2 presents in BGR format!!!)
unique_col_BGR = list(set(tuple(v) for m2d in im for v in m2d))
print('unique values: ', unique_col_BGR, '\n')

#create dict with GBR_colors as keys and unique integers as value
mask_GBR_int = {color:idx for idx,color in enumerate(unique_col_BGR)}
print('mask dict: ', mask_GBR_int, '\n')

#change all color values in im to a single int (mask)
im_with_ints = arr_to_int(im, mask_GBR_int)
#print('pic with mask values: \n', im_with_ints, '\n')

# due to replacing array of 3 values to a single int, new array has one dimension less
print('orig pic resized shape', im.shape)
print('Mask int pic shape', im_with_ints.shape, '\n')

clusters, cluster_count = find_clusters(im_with_ints)
print(f'Found {cluster_count} clusters', '\n')
#print(clusters)

#create dict with length equal to number of clusters and choose color of list_of_colors (random from the internet)
list_of_colors = [[192,192,192],[128,128,128],[128,0,0],[128,128,0],[0,128,0],[128,0,128],[0,128,128],[0,0,128],[255,0,0],[0,255,0],[0,0,255],[255,255,0],[0,255,255],[255,0,255]]
new_color_dict = {idx:val for idx,val in enumerate(list_of_colors[:cluster_count])}
print('new_color_dict: ', new_color_dict,'\n')

#change arr with int to colors again
res = np.array([*new_color_dict.values()])[clusters]
#print('image array with new colors: \n', res)

cv2.imwrite("prov_test_output.png", res)


Output:

unique values:  [(0, 255, 0), (255, 0, 0), (0, 0, 255), (0, 255, 255)] 

mask dict:  {(0, 255, 0): 0, (255, 0, 0): 1, (0, 0, 255): 2, (0, 255, 255): 3} 

orig pic resized shape (100, 100, 3)
Mask int pic shape (100, 100) 

Found 9 clusters 

new_color_dict:  {0: [192, 192, 192], 1: [128, 128, 128], 2: [128, 0, 0], 3: [128, 128, 0], 4: [0, 128, 0], 5: [128, 0, 128], 6: [0, 128, 128], 7: [0, 0, 128], 8: [255, 0, 0]} 


Python相关问答推荐

如何确保Flask应用程序管理面板中的项目具有单击删除功能?

如何从. text中进行pip安装跳过无法访问的库

try 使用tensorFlow.keras.models时optree Import错误

定义同侪组并计算同侪组分析

如何计算部分聚合数据的统计数据

如何修复使用turtle和tkinter制作的绘画应用程序的撤销功能

ambda将时间戳与组内另一列的所有时间戳进行比较

在Pandas 日历中插入一行

沿着数组中的轴计算真实条目

_repr_html_实现自定义__getattr_时未显示

pandas滚动和窗口中有效观察的最大数量

按顺序合并2个词典列表

如何将Docker内部运行的mariadb与主机上Docker外部运行的Python脚本连接起来

为什么以这种方式调用pd.ExcelWriter会创建无效的文件格式或扩展名?

numpy卷积与有效

Django REST Framework:无法正确地将值注释到多对多模型,不断得到错误字段名称字段对模型无效'<><>

driver. find_element无法通过class_name找到元素'""

如何并行化/加速并行numba代码?

需要帮助重新调整python fill_between与数据点

lityter不让我输入左边的方括号,'