查找图像每个部分的平均颜色

Find average colour of each section of an image

我正在寻找使用 Python 实现以下目标的最佳方法:

  1. 导入图像。
  2. 添加一个包含 n 个部分的网格(下例中显示了 4 个)。
  3. 为每个部分找到主色。

期望输出

输出一个数组、列表、字典或类似的捕获这些主要颜色值的值。

也许甚至是显示颜色的 Matplotlib 图表(如像素艺术)。

我尝试了什么?

可以使用图像切片器对图像进行切片:

import image_slicer
image_slicer.slice('image_so_grid.png', 4)

然后我可能会使用 this 之类的东西来获得平均颜色,但我确信有更好的方法可以做到这一点。

使用 Python 执行此操作的最佳方法是什么?

这适用于 4 个部分,但您需要了解如何使其适用于 'n' 个部分:

import cv2

img = cv2.imread('image.png')

def fourSectionAvgColor(image):
    rows, cols, ch = image.shape
    colsMid = int(cols/2)
    rowsMid = int(rows/2)

    numSections = 4
    section0 = image[0:rowsMid, 0:colsMid]
    section1 = image[0:rowsMid, colsMid:cols]
    section2 = image[rowsMid: rows, 0:colsMid]
    section3 = image[rowsMid:rows, colsMid:cols]
    sectionsList = [section0, section1, section2, section3]

    sectionAvgColorList = []
    for i in sectionsList:
        pixelSum = 0
        yRows, xCols, chs = i.shape
        pixelCount = yRows*xCols
        totRed = 0
        totBlue = 0
        totGreen = 0
        for x in range(xCols):
            for y in range(yRows):
                bgr = i[y,x]
                b = bgr[0]
                g = bgr[1]
                r = bgr[2]
                totBlue = totBlue+b
                totGreen = totGreen+g
                totRed = totRed+r

        avgBlue = int(totBlue/pixelCount)
        avgGreen = int(totGreen/pixelCount)
        avgRed = int(totRed/pixelCount)
        avgPixel = (avgBlue, avgGreen, avgRed)
        sectionAvgColorList.append(avgPixel)
    return sectionAvgColorList

print(fourSectionAvgColor(img))
cv2.waitKey(0)
cv2.destroyAllWindows()

您可以使用 scikit-image 的 view_as_blocks together with numpy.mean。您指定块大小而不是块数:

import numpy as np
from skimage import data, util
import matplotlib.pyplot as plt

astro = data.astronaut()
blocks = util.view_as_blocks(astro, (8, 8, 3))

print(astro.shape)
print(blocks.shape)

mean_color = np.mean(blocks, axis=(2, 3, 4))

fig, ax = plt.subplots()
ax.imshow(mean_color.astype(np.uint8))

输出:

(512, 512, 3)
(64, 64, 1, 8, 8, 3)

不要忘记转换为 uint8,因为 matplotlib 和 scikit-image 期望浮点图像位于 [0, 1],而不是 [0, 255]。有关详细信息,请参阅 scikit-image documentation on data types