首先,我对Python及其库相对较新。我尝试使用Pillow循环遍历图像的所有像素,将图像划分为原始尺寸的一小部分,方法是从原始图像的所有颜色中提取最接近的RGB颜色作为划分矩阵。使用以下函数,对于具有大量颜色的平均图像,这需要超过 * 三个小时 *:
def divide_image_by_rgb(image_file, division=4):
input_img = Image.open(image_file)
width, height = input_img.size
pixels_count = width * height
if division < 2:
raise Exception("Invalid division!")
white = (255, 255, 255)
width_out = width // division
height_out = height // division
output_img = Image.new('RGB', (width_out, height_out), white)
all_colors = list(get_colors_count(input_img).keys())
for x in range(width_out):
for y in range(height_out):
pixels = []
[r, g, b] = [0, 0, 0]
for d1 in range(division):
for d2 in range(division):
pos_x = x * division + d1
pos_y = y * division + d2
if pos_x > width or pos_y > height:
continue
pixel = input_img.getpixel((pos_x, pos_y))
pixels.append(pixel)
r += pixel[0] ** 2
g += pixel[1] ** 2
b += pixel[2] ** 2
div = division ** 2
mean_color = (
round(sqrt(r // div)),
round(sqrt(g // div)),
round(sqrt(b // div))
)
mean_color = closest(all_colors, mean_color)
output_img.putpixel((x, y), mean_color)
# log_reduce_progress(changed, pixels_count, height, width, idx, x, y)
output_file = f"resized.[{division}].{os.path.basename(image_file)}"
output_img.save(output_file)
return output_file
def closest(colors, color):
colors = np.array(colors)
color = np.array(color)
distances = np.sqrt(np.sum((colors - color) ** 2, axis=1))
index_of_smallest = np.where(distances == np.amin(distances))
smallest_distance = tuple(colors[index_of_smallest][0])
return smallest_distance
字符串
目标:我想用numpy替换显式循环
输入图片:输入图像类似于以下内容:
PNG,大小:(6.32MP)尺寸:2228x2836,深度:24位,颜色计数:632576
结果:
PNG,大小:(0.39MP)尺寸:557x709,深度:24位,颜色计数:110896
为什么:我想减少图像尺寸和颜色,用最少的颜色进行平滑,图像的色调,均匀性和组成不应该丢失。我使用 libimagequant,* quantization ADAPTIVE*,从给定的 RGB palette csv中减少颜色,等等。以前,但这种方法给我最接近的颜色组合所需的结果,我使用结果图像作为RGB调色板,以减少原始图像的颜色相对于主颜色。
**尝试:**我尝试用numpy函数来做这件事,但失败了,每次更改,我的错误和困惑都会增加:
def resize_image_manual_ex(image_file, division=4):
input_img = Image.open(image_file)
width, height = input_img.size
pixels_count = width * height
white = (255, 255, 255)
width_out = width // division
height_out = height // division
output_img = Image.new('RGB', (width_out, height_out), white)
# Convert the input image to a NumPy array
input_array = np.array(input_img)
# Use NumPy's reshaping to create sub-images
sub_images = input_array.reshape(height_out, division, width_out, division, 3)
# Calculate the mean color of each sub-image
mean_colors = np.mean(sub_images, axis=(1, 3))
# Find the closest color for each mean color
all_colors = list(get_colors_count(input_img).keys())
closest_colors = [closest(all_colors, color) for color in mean_colors]
for x in range(width_out):
for y in range(height_out):
output_img.putpixel((x, y), closest_colors[y, x])
output_file = f"resized.[{division}].{os.path.basename(image_file)}"
output_img.save(output_file)
return output_file
型
上次错误:
sub_images = input_array.reshape(height_out,division,width_out,division,3)
ValueError:无法将大小为56925的数组整形为shape(57,2,82,2,3)
有没有办法用numpy(或其他)代替 for 循环来减少运行时间?非常感谢您的光临。
1条答案
按热度按时间shstlldc1#
我想这应该能满足你的要求。我不想清除
PIL
命令,所以检查一下。字符串
我做过的大事:
view_as_blocks
中的view
来保存内存。保留了对RGB值求平均值所需的均方根功能,还通过closest
搜索携带平方。closest
更改为KDTree
功能。对于大量的颜色,这要快得多