Когда я изменяю вложенный словарь, другие словари, вложенные в него, изменяются - PullRequest
0 голосов
/ 26 марта 2020

Я пытаюсь извлечь значения RGB, HSV и LAB из каждого пикселя в списке изображений и суммировать результаты для каждого изображения. Сейчас я сосредоточен на суммировании значений R, G и B. Я использую вложенный словарь для хранения данных по имени изображения и цветовому пространству.

from skimage import io, color

# Define images to analyze
images = ['pic1.jpg', 'pic2.jpg']

# Create a dictionary of RGB image
read_images = {img:{} for img in images}
for i in images:
    read_images[i]['rgb'] = io.imread('./{}'.format(i))

# Define color spaces and create a dictionary to store data
color_spaces = ['rgb']
colors = {cs:{cs[0]:0, cs[1]:0, cs[2]:0} for cs in color_spaces}
img_data = {img:colors for img in images}

for img in images: # Select image
    for cs in color_spaces: # Select colorspce
        # Start Reading Image
        for line in read_images[img][cs]:
            for pixel in line:
                # Store pixel values
                val0, val1, val2 = pixel
                img_data[img][cs][cs[0]] += val0
                img_data[img][cs][cs[1]] += val1
                img_data[img][cs][cs[2]] += val2

Я хочу, чтобы результат этого был:

img_data = {
            'pic1':{
                    'rgb':{
                          r: sum of r-values for pic1
                          g: sum of g-values for pic1
                          b: sum of b-valuse for pic1}}
            'pic2':{
                    'rgb':{
                          r: sum of r-values for pic2
                          g: sum of g-values for pic2
                          b: sum of b-valuse for pic2
                         }
                     }}

Проблема в том, что каждый раз, когда он просматривает список изображений, он добавляет значения RGB этого изображения в rgb диктует для обоих изображений, так что сумма значений R, G и B равна pic1 + pic2 для обоих изображений.

Ответы [ 3 ]

0 голосов
/ 26 марта 2020

Вы потерялись в своих собственных диктетных пониманиях ... и просто переназначаете разные имена одному и тому же объекту, как указано @ dspencer

# Define color spaces and create a dictionary to store data
color_spaces = ['rgb']
img_data = {}
for img in images:
    for cs in color_spaces:
        for element in cs:
            if img not in img_data:
                img_data[img] = {}
            if cs not in img_data[img]:
                img_data[img][cs] = {}
            img_data[img][cs][element] = 0

for img in images:  # Select image
    for cs in color_spaces:  # Select colorspce
        # Start Reading Image
        for line in read_images[img][cs]:
            for pixel in line:
                # Store pixel values
                val0, val1, val2 = pixel
                img_data[img][cs][cs[0]] += val0
                img_data[img][cs][cs[1]] += val1
                img_data[img][cs][cs[2]] += val2
print(img_data)
0 голосов
/ 26 марта 2020
import numpy as np
from PIL import Image

arr = np.transpose(np.array(Image.open(images[0], 'hsv')), (2,0,1))
np.sum(arr[0]), np.sum(arr[1]), np.sum(arr[2])

Простой способ получения суммы значений r, g и b.

Также вы конвертируете свое изображение rgb в hsv следующим образом:

from skimage.color import rgb2hsv
rgb_img = Image.open(images[0])
hsv_img = rgb2hsv(rgb_img)
0 голосов
/ 26 марта 2020

Оба ваших изображения совместно используют одну копию словаря colors ({"rgb": {"r": 0, "g": 0, "b": 0}}), вам нужно сделать копию для каждого изображения, используя copy.deepcopy. Мы используем deepcopy здесь, так как вам нужно сделать копию вложенного словаря.

В частности, строка

img_data = {img:colors for img in images}

должна быть изменена на:

import copy

img_data = {img: copy.deepcopy(colors) for img in images}

Без этого, когда вы позже придете к изменению словарей colors внутри img_data, вы будете изменять одну копию словаря в памяти, независимо от того, к какому изображению вы обращаетесь.

...