英文:
np.histogram2d exception too many values to unpack (expected 2)
问题
该函数用于从一组图像和参数图像(rgb图像的数组)中计算ab颜色空间中颜色值的分布。
在执行时,会抛出异常(ValueError('too many values to unpack (expected 2)')),这是在执行histogramdd
函数时发生的。它获得的形状是3,但期望的是2。
如何修改以消除异常或进行替代实现?
import numpy as np
from skimage.color import rgb2lab
from scipy.ndimage import gaussian_filter
def compute_color_distribution(images, ab_bins=32, sigma=5, lam=0.5):
ab_values = np.linspace(-1, 1, ab_bins)
ab_space = np.stack(np.meshgrid(ab_values, ab_values), axis=-1).reshape(-1, 2)
pixel_ab = []
for img in images:
lab_img = rgb2lab(img / 255.0)
pixel_ab.append(lab_img[:, :, 1:] / 128)
pixel_ab = np.vstack(pixel_ab)
hist, _, _ = np.histogram2d(pixel_ab[:, 0], pixel_ab[:, 1], bins=(ab_values[:-1], ab_values[:-1]), density=True)
smoothed_hist = gaussian_filter(hist, sigma)
p = smoothed_hist / np.sum(smoothed_hist)
p_tilde = (1 - lam) * p + lam / (ab_bins * ab_bins)
weights = (1 / p_tilde).flatten()
weights /= np.sum(p * weights)
return ab_space, weights
英文:
The function is to calculate the distribution of color values in the ab color space from a set of images and the parameter images is array of rgb images.
When executing
np.histogram2d(pixel_ab[:, 0], pixel_ab[:, 1], bins=(ab_values[:-1], ab_values[:-1]), density=True)
> exception (<class 'ValueError'>, ValueError('too many values to unpack (expected 2)'))
is thrown in executing histogramdd function. It the shape it is getting is 3 but it is expecting 2.
How this can be altered to remove exception or alternate implementation?
import numpy as np
from skimage.color import rgb2lab
from scipy.ndimage import gaussian_filter
def compute_color_distribution(images, ab_bins=32, sigma=5, lam=0.5):
ab_values = np.linspace(-1, 1, ab_bins)
ab_space = np.stack(np.meshgrid(ab_values, ab_values), axis=-1).reshape(-1, 2)
pixel_ab = []
for img in images:
lab_img = rgb2lab(img / 255.0)
pixel_ab.append(lab_img[:, :, 1:] / 128)
pixel_ab = np.vstack(pixel_ab)
hist, x_edges, y_edges = np.histogram2d(pixel_ab[:, 0], pixel_ab[:, 1], bins=(ab_values[:-1], ab_values[:-1]), density=True)
smoothed_hist = gaussian_filter(hist, sigma)
p = smoothed_hist / np.sum(smoothed_hist)
p_tilde = (1 - lam) * p + lam / (ab_bins * ab_bins)
weights = (1 / p_tilde).flatten()
weights /= np.sum(p * weights)
return ab_space, weights
答案1
得分: 2
以下是您要翻译的内容:
以下的回答将会处理这个异常,并且可能无法修复整个代码...
根据 numpy.histogram2d 的文档。
> numpy.histogram2d(x, y, bins=10, range=None, density=None, weights=None)
> 计算两个数据样本的双维直方图。
> 参数
> - x: array_like, 形状 (N,)
> 包含要制作直方图的点的 x 坐标的数组。
> - y array_like, 形状 (N,)
> 包含要制作直方图的点的 y 坐标的数组。
根据文档,x
参数的形状是 (N,)
,而 y
参数的形状也是 (N,)
。
这意味着 x
和 y
参数都是包含 N
个元素的一维数组。
根据您的代码(使用调试器),我们可以看到:
pixel_ab[:, 0].shape
= (N, 2)
,而 pixel_ab[:, 1].shape
= (N, 2)
。
当执行 np.histogram2d(pixel_ab[:, 0], pixel_ab[:, 1]...
时,x
和 y
参数是二维数组,而不是一维数组(正如np.histogram2d
期望的那样)。
结果是异常 ValueError('too many values to unpack (expected 2)
。
修复代码超出了本回答的范围。
以下的代码示例是一个不会引发异常的示例(并且有些幸运的话会更接近您期望的功能):
import numpy as np
from skimage.color import rgb2lab
from scipy.ndimage import gaussian_filter
def compute_color_distribution(images, ab_bins=32, sigma=5, lam=0.5):
ab_values = np.linspace(-1, 1, ab_bins)
ab_space = np.stack(np.meshgrid(ab_values, ab_values), axis=-1).reshape(-1, 2)
pixel_a = []
pixel_b = []
for img in images:
lab_img = rgb2lab(img / 255.0)
a_img = lab_img[:, :, 1] / 128
b_img = lab_img[:, :, 2] / 128
a_img_as_row = np.ravel(a_img)
b_img_as_row = np.ravel(b_img)
pixel_a.append(a_img_as_row)
pixel_b.append(b_img_as_row)
pixel_a = np.hstack(pixel_a)
pixel_b = np.hstack(pixel_b)
hist, x_edges, y_edges = np.histogram2d(pixel_a, pixel_b, bins=ab_bins, density=True) # hist.shape = (32, 32)
smoothed_hist = gaussian_filter(hist, sigma)
p = smoothed_hist / np.sum(smoothed_hist)
p_tilde = (1 - lam) * p + lam / (ab_bins * ab_bins)
weights = 1 / p_tilde
weights /= np.sum(p * weights)
return ab_space, weights
images = [np.random.randint(0, 255, (100, 100, 3), np.uint8), np.random.randint(0, 255, (100, 100, 3), np.uint8), np.random.randint(0, 255, (100, 100, 3), np.uint8)]
ab_space, weights = compute_color_distribution(images)
英文:
The following answer is going to address the exception, and may not fix the entire code...
Following the documentation of numpy.histogram2d.
> numpy.histogram2d(x, y, bins=10, range=None, density=None, weights=None)
>Compute the bi-dimensional histogram of two data samples.
>Parameters
> - x: array_like, shape (N,)
> An array containing the x coordinates of the points to be histogrammed.
> - y array_like, shape (N,)
>An array containing the y coordinates of the points to be histogrammed.
According to the documentation the shape of x
argument is (N,)
, and the shape if y
argument is also (N,)
.
That means that x
and y
arguments are 1 dimensional arrays with N
elements.
Following your code (using the debugger), we can see that:
pixel_ab[:, 0].shape
= (N, 2)
and pixel_ab[:, 1].shape
= (N, 2)
.
When executing np.histogram2d(pixel_ab[:, 0], pixel_ab[:, 1]...
the x
and y
arguments are two dimensional arrays instead of 1 dimensional (as expected by np.histogram2d
).
The result is the exception ValueError('too many values to unpack (expected 2)
.
Fixing the code is outside the scope of the answer.
The following code sample is an example that doesn't rise an exception (and with some luck gets closer to your desired functionality):
import numpy as np
from skimage.color import rgb2lab
from scipy.ndimage import gaussian_filter
def compute_color_distribution(images, ab_bins=32, sigma=5, lam=0.5):
ab_values = np.linspace(-1, 1, ab_bins)
ab_space = np.stack(np.meshgrid(ab_values, ab_values), axis=-1).reshape(-1, 2)
#pixel_ab = []
#for img in images:
# lab_img = rgb2lab(img / 255.0)
# pixel_ab.append(lab_img[:, :, 1:] / 128)
#pixel_ab = np.vstack(pixel_ab)
pixel_a = []
pixel_b = []
for img in images:
lab_img = rgb2lab(img / 255.0)
a_img = lab_img[:, :, 1] / 128
b_img = lab_img[:, :, 2] / 128
a_img_as_row = np.ravel(a_img)
b_img_as_row = np.ravel(b_img)
pixel_a.append(a_img_as_row)
pixel_b.append(b_img_as_row)
pixel_a = np.hstack(pixel_a)
pixel_b = np.hstack(pixel_b)
#hist, x_edges, y_edges = np.histogram2d(pixel_ab[:, 0], pixel_ab[:, 1], bins=(ab_values[:-1], ab_values[:-1]), density=True)
hist, x_edges, y_edges = np.histogram2d(pixel_a, pixel_b, bins=ab_bins, density=True) # hist.shape = (32, 32)
smoothed_hist = gaussian_filter(hist, sigma)
p = smoothed_hist / np.sum(smoothed_hist)
p_tilde = (1 - lam) * p + lam / (ab_bins * ab_bins)
#weights = (1 / p_tilde).flatten()
weights = 1 / p_tilde # If we flatten() then we can multiply p*weights in the next statement.
weights /= np.sum(p * weights)
return ab_space, weights
images = [np.random.randint(0, 255, (100, 100, 3), np.uint8), np.random.randint(0, 255, (100, 100, 3), np.uint8), np.random.randint(0, 255, (100, 100, 3), np.uint8)]
ab_space, weights = compute_color_distribution(images)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论