opencv 最快的方法来找到图像的rgb像素颜色计数

mbzjlibv  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(137)

我有一个用例,我必须找到连续的rgb像素颜色计数的每帧视频后,搜索我发现了一段代码,它做同样的事情,但性能明智的,它需要左右~ 3秒给我给予输出,但在我的情况下,我必须尽可能快地做这个计算可能是25帧在1秒。有人可以帮助我弄清楚如何通过重构以下代码

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

r7xajy2e

r7xajy2e1#

你需要使用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]

这意味着RGB(14,48,84)有20,389个像素,依此类推。
这需要125毫秒在我的Mac上为400 × 400的图像,这将给你给予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

这在我的Mac上需要4毫秒而不是125毫秒:-)

关键词:Python,Numpy,PIL/Pillow,图像处理,count unique colors,count colors。

zzlelutf

zzlelutf2#

此函数返回一个漂亮的DataFrame,其中包含您需要的所有信息,并且速度快如 lightning -**比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)

相关问题