首页 > 解决方案 > 计算图像中不同颜色的面积比例

问题描述

我正在尝试计算图像中颜色的比例并将其作为比率返回。我有很多“日志”图像,它们是颜色的垂直序列,我想知道一种颜色的总面积与另一种颜色的差异,以及一种颜色相对于整个图像的比率。

例如,在下图中,如果我计算蓝色占据的总面积并将其与整个区域(蓝色和棕色相结合,我得到比率 = 69.14。(我通过对面积求和得到该值)所有蓝色矩形的总和除以所有蓝色和棕色矩形的总面积)

*注意,颜色并不总是下面的颜色,如果可能的话,我希望能够使用两种以上的颜色(也许只是给出我关注的颜色的 RGB 代码并想要该颜色与整体的比例)。

注意我有很多图像我必须运行这个,所以如果可能的话,循环遍历文件夹中的所有图像会很有帮助。

我从几个例子拼凑出下面的代码,但我对一些事情感到困惑。一,我不一定想将图像转换为二进制,除非我必须这样做,二,看起来我正在计算白色像素的数量而不是黑色。不知道我哪里出错了。

import cv2
import numpy as np 
from matplotlib import pyplot as plt

# load image
image = cv2.imread('/Users/Me/Desktop/logtest.png',0)

# plot the binary image
imgplot = plt.imshow(image, "gray")
plt.show()

#Calculate percent of pixels that are black
ret,thresh = cv2.threshold(image,0,230, cv2.THRESH_BINARY)
height, width = image.shape

print ("Height and Width : ",height, width)
size = image.size

print ("Total number of pixels in the image is =", size)

ChosenPix = cv2.countNonZero(image)
print("Total number of black pixels =", count)

Ratio = (ChosenPix/size)*100
print("Ratio of black to total is =", Ratio)

在此处输入图像描述

标签: pythonimagergb

解决方案


我制作了一些这样的示例图像:

在此处输入图像描述 在此处输入图像描述 在此处输入图像描述

然后我使用一个 glob 来选择所有命名log*png并处理每个文件的文件。这包括计算图像中的独特颜色并迭代这些颜色以计算与每种独特颜色匹配的像素数:

#!/usr/bin/env python3

from PIL import Image
import numpy as np
import glob

def processLog(filename):
    print(f"Processing log: {filename}")
    # Open this image and make a Numpy version for easy processing
    im   = Image.open(filename).convert('RGBA').convert('RGB')
    imnp = np.array(im)
    h, w = imnp.shape[:2]

    # Get list of unique colours...
    # Arrange all pixels into a tall column of 3 RGB values and find unique rows (colours)
    colours, counts = np.unique(imnp.reshape(-1,3), axis=0, return_counts=1)

    # Iterate through unique colours
    for index, colour in enumerate(colours):
        count = counts[index]
        proportion = (100 * count) / (h * w)
        print(f"   Colour: {colour}, count: {count}, proportion: {proportion:.2f}%")

# Iterate over all images called "log*png" in current directory
for filename in glob.glob('log*png'):
    processLog(filename)

输出

Processing log: log2.png
   Colour: [  0 255 255], count: 800, proportion: 5.00%
   Colour: [255   0 255], count: 6400, proportion: 40.00%
   Colour: [255 255   0], count: 8800, proportion: 55.00%
Processing log: log1.png
   Colour: [  0 255   0], count: 6400, proportion: 36.36%
   Colour: [255   0   0], count: 11200, proportion: 63.64%
Processing log: log9.png
   Colour: [ 83 195 187], count: 16160, proportion: 67.33%
   Colour: [ 87 190 179], count: 80, proportion: 0.33%
   Colour: [ 88 184 171], count: 80, proportion: 0.33%
   Colour: [ 89 180 165], count: 80, proportion: 0.33%
   Colour: [ 94 175 158], count: 80, proportion: 0.33%
   Colour: [ 96 164 143], count: 80, proportion: 0.33%
   Colour: [107 146 116], count: 80, proportion: 0.33%
   Colour: [120 114  71], count: 80, proportion: 0.33%
   Colour: [124  99  50], count: 80, proportion: 0.33%
   Colour: [126  88  35], count: 7120, proportion: 29.67%
   Colour: [126  90  37], count: 80, proportion: 0.33%

当然,如果您不想编写任何 Python,您可以循环遍历文件bash并使用ImageMagick为您提取总像素数和每种颜色的像素数。ImageMagick安装在大多数 Linux 发行版上,适用于 macOS 和 Windows:

for f in log*png; do magick "$f" -format "%f: %[fx:w*h]\n"  -write info: -format %c histogram:info: ; done

输出

log1.png: 17600
      6400: (  0,255,  0) #00FF00 lime
     11200: (255,  0,  0) #FF0000 red
log2.png: 16000
       800: (  0,255,255) #00FFFF cyan
      6400: (255,  0,255) #FF00FF magenta
      8800: (255,255,  0) #FFFF00 yellow
log9.png: 24000
     16160: ( 83,195,187,255) #53C3BBFF srgba(83,195,187,1)
        80: ( 87,190,179,255) #57BEB3FF srgba(87,190,179,1)
        80: ( 88,184,171,251) #58B8ABFB srgba(88,184,171,0.984314)
        80: ( 89,180,165,255) #59B4A5FF srgba(89,180,165,1)
        80: ( 94,175,158,246) #5EAF9EF6 srgba(94,175,158,0.964706)
        80: ( 96,164,143,255) #60A48FFF srgba(96,164,143,1)
        80: (107,146,116,246) #6B9274F6 srgba(107,146,116,0.964706)
        80: (120,114, 71,246) #787247F6 srgba(120,114,71,0.964706)
        80: (124, 99, 50,255) #7C6332FF srgba(124,99,50,1)
      7120: (126, 88, 35,255) #7E5823FF srgba(126,88,35,1)
        80: (126, 90, 37,250) #7E5A25FA srgba(126,90,37,0.980392)

推荐阅读