22

我一直在尝试在 Opencv 中获取图像亮度,到目前为止,我使用了 calcHist 并考虑了直方图值的平均值。但是,我觉得这并不准确,因为它实际上并不能确定图像的亮度。我在图像的灰度版本上执行了 calcHist,并试图区分从明亮图像获得的平均值与中等图像的平均值。到目前为止,我还没有成功。您能否帮助我提供一种可以通过 OpenCv 实现的方法或算法来估计图像的亮度?提前致谢。

4

4 回答 4

21

我想,HSV 颜色模型对您的问题很有用,其中通道 V 是值:

"值是颜色的明暗度,随颜色饱和度而变化。范围从0到100%。当值为'0'时,颜色空间将是全黑的。随着值的增加,颜色空间的亮度和显示各种颜色。”

所以使用 OpenCV 方法cvCvtColor (const CvArr* src, CvArr* dst, int code),将图像从一种颜色空间转换为另一种颜色空间。在您的情况下,代码 = CV_BGR2HSV.Than 计算第三通道 V 的直方图。

于 2013-01-10T08:09:25.767 回答
10

我正要问同样的问题,但后来发现,类似的问题没有给出令人满意的答案。我在 SO 上找到的所有答案都涉及人类对单像素 RGB 与 HSV 的观察。

根据我的观察,图像的主观亮度也很大程度上取决于图案。在白天,黑暗天空中的星星可能看起来比多云的天空更亮,而第一张图像的平均像素值会小得多。

我使用的图像是由显微镜产生的灰度细胞图像。形式差异很大。有时它们是非常黑的背景上的小亮点,有时是不太暗的背景上不太亮的较大区域。

我的做法是:

  • 使用去除热像素的阈值查找直方图最大值 (HMax)。
  • 计算 HMax * 2/3 和 HMax 之间的所有像素的平均值

比率 2/3 也可以增加到 3/4(这减少了被认为是明亮的像素范围)。

该方法效果很好,因为具有相同滴定度的不同细胞图案会产生相似的亮度。

PS:我真正想问的是,在OpenCV或SimpleCV中是否有类似的计算功能。非常感谢您的任何评论!

于 2014-02-25T16:23:07.460 回答
5

我更喜欢Valentin 的回答,但是对于确定平均每像素亮度的“另一种”方法,您可以使用numpy几何平均值而不是算术平均值。对我来说它有更好的结果。

from numpy.linalg import norm

def brightness(img):
    if len(img.shape) == 3:
        # Colored RGB or BGR (*Do Not* use HSV images with this function)
        # create brightness with euclidean norm
        return np.average(norm(img, axis=2)) / np.sqrt(3)
    else:
        # Grayscale
        return np.average(img)
于 2020-07-07T16:48:03.843 回答
3

一些 OpenCV C++ 源代码,用于简单检查以区分明暗图像。这是受到@ann-orlova 多年前提供的上述答案的启发:

const int darkness_threshold = 128; // you need to determine what threshold to use

cv::Mat mat = get_image_from_device();

cv::Mat hsv;
cv::cvtColor(mat, hsv, CV_BGR2HSV);
const auto result = cv::mean(hsv);

// cv::mean() will return 3 numbers, one for each channel:
//      0=hue
//      1=saturation
//      2=value (brightness)

if (result[2] < darkness_threshold)
{
    process_dark_image(mat);
}
else
{
    process_light_image(mat);
}
于 2019-09-19T00:47:49.030 回答