估计图像 Opencv 的亮度
Posted
技术标签:
【中文标题】估计图像 Opencv 的亮度【英文标题】:Estimate Brightness of an image Opencv 【发布时间】:2012-12-23 23:41:55 【问题描述】:我一直在尝试在 Opencv 中获取图像亮度,到目前为止,我使用了 calcHist 并考虑了直方图值的平均值。但是,我觉得这并不准确,因为它实际上并不能确定图像的亮度。我在图像的灰度版本上执行了 calcHist,并试图区分从明亮图像获得的平均值与中等图像的平均值。到目前为止,我还没有成功。您能否帮助我提供一种可以通过 OpenCv 实现的方法或算法来估计图像的亮度?提前致谢。
【问题讨论】:
亮度到底是什么意思?您可以发布您正在使用的明亮和中等图像的示例吗?理想情况下在他们的直方图旁边? ***.com/questions/4876315/… 这可能会有所帮助 感谢您的帮助和回复。我必须尝试使用建议的 HSV 或链接给出的 YUV。我现在要试试。抱歉回复晚了。 @Brandon :我所说的明亮图像是指暴露在更多白光下的图像,与那些不那么明亮但对比度更好的图像相比。我会尽快按您的要求上传示例。 @LakshmiNarayanan 如果可能,请检查并让我知道。 【参考方案1】:我想,HSV color model 对您的问题很有用,其中通道 V 是值:
"值是颜色的明暗度,随颜色饱和度而变化,范围从0到100%。当值为'0'时,颜色空间将是全黑的。随着值的增加,颜色空间调高亮度并显示各种颜色。”
所以使用 OpenCV 方法 cvCvtColor(const CvArr* src, CvArr* dst, int code),将图像从一种颜色空间转换为另一种颜色空间。在您的情况下,代码 = CV_BGR2HSV。然后计算第三通道 V 的直方图。
【讨论】:
请注意,HSV 将相同的值分配给例如白色和蓝色像素,虽然白色像素明显比蓝色像素亮。 @Ann Orlova ***.com/questions/4876315/…您对此有何看法? 感谢您的帮助和回复。我必须尝试使用建议的 HSV 或链接给出的 YUV。我现在要试试。抱歉回复晚了。 CIE-LAB 色彩空间也可以工作github.com/imneonizer/How-to-find-if-an-image-is-bright-or-dark【参考方案2】:我正要问同样的问题,但后来发现,类似的问题没有给出令人满意的答案。我在 SO 上找到的所有答案都涉及人类对单像素 RGB 与 HSV 的观察。
根据我的观察,图像的主观亮度也很大程度上取决于图案。在白天,黑暗天空中的星星可能看起来比多云的天空更亮,而第一张图像的平均像素值会小得多。
我使用的图像是由显微镜产生的灰度细胞图像。形式差异很大。有时它们是非常黑的背景上的小亮点,有时是不太暗的背景上不太亮的较大区域。
我的做法是:
使用阈值查找直方图最大值 (HMax) 以去除热点。 计算 HMax * 2/3 和 HMax 之间所有像素的平均值2/3 的比率也可以增加到 3/4(这会减少被认为是明亮的像素范围)。
这种方法效果很好,因为具有相同滴定度的不同细胞图案会产生相似的亮度。
P.S.:我真正想问的是,在 OpenCV 或 SimpleCV 中是否有类似的计算功能。非常感谢任何 cmets!
【讨论】:
我们使用的是基本相同的东西,但取而代之的是中位数。【参考方案3】:我更喜欢Valentin's answer,但对于确定每像素平均亮度的“另一种”方法,您可以使用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)
【讨论】:
【参考方案4】:一些 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);
【讨论】:
以上是关于估计图像 Opencv 的亮度的主要内容,如果未能解决你的问题,请参考以下文章