查找图像各部分的平均颜色

时间:2019-04-28 21:32:56

标签: python opencv machine-learning scikit-image

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

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

sky

所需的输出

输出捕获这些主要颜色值的数组,列表,字典或类似内容。

甚至可能是Matplotlib图形显示颜色(如像素图)。

我尝试了什么?

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

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

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

使用Python做到这一点的最佳方法是什么?

2 个答案:

答案 0 :(得分:1)

这适用于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()

答案 1 :(得分:0)

您可以将scikit-image的view_as_blocksnumpy.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)

blocked and averaged

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