查找图像 rgb 像素颜色数量的最快方法
- 2025-04-15 09:20:00
- admin 原创
- 29
问题描述:
我有一个用例,需要计算实时视频每帧连续的RGB像素颜色数量。经过一番搜索,我找到了一段代码,它能完成同样的功能,但性能方面,它需要大约3秒才能输出结果。而在我的例子中,我必须尽快完成这个计算,可能是1秒25帧。有人能帮我重构一下下面的代码吗?
from PIL import Image
import timeit
starttime = timeit.default_timer()
with Image.open("netflix.png") as image:
color_count = {}
width, height = image.size
print(width,height)
rgb_image = image.convert('RGB')
for x in range(width):
for y in range(height):
rgb = rgb_image.getpixel((x, y))
if rgb in color_count:
color_count[rgb] += 1
else:
color_count[rgb] = 1
print('Pixel Count per Unique Color:')
print('-' * 30)
print(len(color_count.items()))
print("The time difference is :", timeit.default_timer() - starttime)
输出:
每个独特颜色的像素数:130869
时差为:3.9660612
解决方案 1:
你需要使用 Numpy 或 OpenCV 来在 Python 中快速处理图像。我制作了一个 9 色版本的帕丁顿熊:
from PIL import Image
import numpy as np
# Open Paddington and make sure he is RGB - not palette
im = Image.open('paddington.png').convert('RGB')
# Make into Numpy array
na = np.array(im)
# Arrange all pixels into a tall column of 3 RGB values and find unique rows (colours)
colours, counts = np.unique(na.reshape(-1,3), axis=0, return_counts=1)
print(colours)
print(counts)
结果
[[ 14 48 84]
[ 19 21 30]
[ 33 108 163]
[ 33 152 190]
[ 72 58 58]
[ 96 154 210]
[180 89 64]
[205 210 200]
[208 151 99]]
[20389 40269 12820 1488 17185 25371 17050 16396 9032]
这意味着有 20,389 个 RGB 像素(14,48,84),依此类推。
在我的 Mac 上,处理一张 400x400 的图像需要 125 毫秒,帧率为 8 fps,因此最好至少有 4 个 CPU 核心,并全部使用它们来获得 25+ fps。
更新
我认为实际上可以比这更快。如果将每个像素与 [1,256,65536] 进行点积,每个像素将得到一个 24 位数,而不是 3 个 8 位数。这样查找唯一值的速度就会快得多。如下所示:
# Open Paddington and make sure he is RGB - not palette
im = Image.open('paddington.png').convert('RGB')
# Make into Numpy array
na = np.array(im)
# Make a single 24-bit number for each pixel
f = np.dot(na.astype(np.uint32),[1,256,65536])
nColours = len(np.unique(f)) # prints 9
这需要 4ms,而不是我的 Mac 上的 125ms :-)
关键词:Python、Numpy、PIL/Pillow、图像处理、计算唯一颜色、计算颜色。
解决方案 2:
此函数返回一个漂亮的 DataFrame,其中包含您需要的所有信息,并且速度极快 -比 colors、counts = np.unique(...) 快 10 倍
import numexpr # Import the mighty mighty 'numexpr' library for efficient numerical expression evaluation - up to 10x faster than numpy
import numpy as np
import pandas as pd
def count_colors(img, sort=True):
"""
Count the unique colors in an image and return a DataFrame with color counts.
Parameters:
img (numpy.ndarray): Input image as a NumPy array with shape (height, width, 3).
sort (bool, optional): Whether to sort the resulting DataFrame by color count. Default is True.
Returns:
pandas.DataFrame: A DataFrame containing color information with columns 'a' ,'r', 'g', 'b', and 'c' (count).
"""
r, g, b = (
img[..., 2],
img[..., 1],
img[..., 0],
) # Extract the red, green, and blue color channels from the image.
absnum = numexpr.evaluate(
# Use 'numexpr' to efficiently calculate a unique numerical representation for each color.
"(r << 16) + (g << 8) + b",
global_dict={},
local_dict={"r": r, "g": g, "b": b},
)
npunique = np.unique(
absnum, return_counts=True
) # Find unique values and their counts in the 'absnum' array.
return pd.merge( # Merge DataFrames to combine color information and color counts.
pd.DataFrame(
{
"r": r.ravel(),
"g": g.ravel(),
"b": b.ravel(),
"a": absnum.ravel(),
}
)
.drop_duplicates() # Remove duplicate rows based on the unique numerical representation 'a'.
.reset_index(drop=True) # Reset the DataFrame index after dropping duplicates.
.set_index("a"), # Set the 'a' column as the index of the DataFrame.
pd.DataFrame({"a": npunique[0], "c": npunique[1]}).set_index("a"),
# Create another DataFrame with 'a' and 'c' columns.
left_index=True, # Merge DataFrames using the index of the left DataFrame ('a' column).
right_index=True, # Merge DataFrames using the index of the right DataFrame ('a' column).
sort=sort, # Sort the resulting DataFrame by color count if 'sort' is True.
).reset_index(
drop=False
) # Reset the index of the merged DataFrame and return it.
# df
# Out[3]:
# a r g b c
# 0 929876 14 48 84 20389
# 1 1250590 19 21 30 40269
# 2 2190499 33 108 163 12820
# 3 2201790 33 152 190 1488
# 4 4733498 72 58 58 17185
# 5 6331090 96 154 210 25371
# 6 11819328 180 89 64 17050
# 7 13488840 205 210 200 16396
# 8 13670243 208 151 99 9032
# %timeit colours, counts = np.unique(pic.reshape(-1,3), axis=0, return_counts=1)
# %timeit df = count_colors(pic)
# 127 ms ± 3.81 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
# 12.8 ms ± 130 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
相关推荐
热门文章
项目管理软件有哪些?
热门标签
曾咪二维码
扫码咨询,免费领取项目管理大礼包!
云禅道AD