[英]What are some methods to analyze image brightness using Python?
使用问题中提到的技术,我想出了几个不同的版本。
每个方法都返回一个 close 值,但与其他方法不完全相同。 此外,除最后一种方法外,所有方法的运行速度大致相同,后者根据图像大小慢得多。
将图像转换为灰度,返回平均像素亮度。
def brightness( im_file ): im = Image.open(im_file).convert('L') stat = ImageStat.Stat(im) return stat.mean[0]
将图像转换为灰度,返回 RMS 像素亮度。
def brightness( im_file ): im = Image.open(im_file).convert('L') stat = ImageStat.Stat(im) return stat.rms[0]
平均像素,然后转换为“感知亮度”。
def brightness( im_file ): im = Image.open(im_file) stat = ImageStat.Stat(im) r,g,b = stat.mean return math.sqrt(0.241*(r**2) + 0.691*(g**2) + 0.068*(b**2))
像素的 RMS,然后转换为“感知亮度”。
def brightness( im_file ): im = Image.open(im_file) stat = ImageStat.Stat(im) r,g,b = stat.rms return math.sqrt(0.241*(r**2) + 0.691*(g**2) + 0.068*(b**2))
计算像素的“感知亮度”,然后返回平均值。
def brightness( im_file ): im = Image.open(im_file) stat = ImageStat.Stat(im) gs = (math.sqrt(0.241*(r**2) + 0.691*(g**2) + 0.068*(b**2)) for r,g,b in im.getdata()) return sum(gs)/stat.count[0]
更新测试结果我对 200 张图像进行了模拟。 我发现方法#2、#4 给出了几乎相同的结果。 此外,方法#3、#5 也几乎相同。 方法#1 紧随#3、#5(有几个例外)。
鉴于您只是在寻找整个图像的平均值,而不是每个像素的亮度值,平均 PIL 的直方图并将亮度函数应用于输出似乎是该库的最佳方法。
如果使用ImageMagick (使用PythonMagick绑定),我建议使用带有“verbose”选项集的识别命令。 这将为您提供每个通道的平均值,使您无需对直方图求和和求平均值——您可以直接将每个通道相乘。
我认为您最好的结果是使用您最喜欢的公式将 RGB 转换为灰度,然后获取该结果的直方图。 我不确定直方图的均值或中值是否更合适,但在大多数图像上它们可能相似。
我不确定如何使用任意公式在 PIL 中转换为灰度,但我猜这是可能的。
下面的代码将为您提供 0-10 图像的亮度级别
1-使用opencv将图像转换为HSV格式后计算图像的平均亮度。
2- 找到该值在亮度范围列表中的位置。
import numpy as np
import cv2
import sys
from collections import namedtuple
#brange brightness range
#bval brightness value
BLevel = namedtuple("BLevel", ['brange', 'bval'])
#all possible levels
_blevels = [
BLevel(brange=range(0, 24), bval=0),
BLevel(brange=range(23, 47), bval=1),
BLevel(brange=range(46, 70), bval=2),
BLevel(brange=range(69, 93), bval=3),
BLevel(brange=range(92, 116), bval=4),
BLevel(brange=range(115, 140), bval=5),
BLevel(brange=range(139, 163), bval=6),
BLevel(brange=range(162, 186), bval=7),
BLevel(brange=range(185, 209), bval=8),
BLevel(brange=range(208, 232), bval=9),
BLevel(brange=range(231, 256), bval=10),
]
def detect_level(h_val):
h_val = int(h_val)
for blevel in _blevels:
if h_val in blevel.brange:
return blevel.bval
raise ValueError("Brightness Level Out of Range")
def get_img_avg_brightness():
if len(sys.argv) < 2:
print("USAGE: python3.7 brightness.py <image_path>")
sys.exit(1)
img = cv2.imread(sys.argv[1])
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
_, _, v = cv2.split(hsv)
return int(np.average(v.flatten()))
if __name__ == '__main__':
print("the image brightness level is:
{0}".format(detect_level(get_img_avg_brightness())))
这可以通过将 BGR 图像从 cv2 转换为灰度,然后找到强度 - x 和 y 是像素坐标来完成。 在这个https://docs.opencv.org/3.4/d5/d98/tutorial_mat_operations.html文档中已经很好地解释了它。
Scalar intensity = img.at<uchar>(y, x);
def calculate_brightness(image):
greyscale_image = image.convert('L')
histogram = greyscale_image.histogram()
pixels = sum(histogram)
brightness = scale = len(histogram)
for index in range(0, scale):
ratio = histogram[index] / pixels
brightness += ratio * (-scale + index)
return 1 if brightness == 255 else brightness / scale
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.