如何提取照片的对比度 - opencv
How extract contrast level of a photo - opencv
我需要 return 图像的(平均)对比度值。
这可能吗,如果可以,请说明如何做?
不仅仅是代码,(显然欢迎代码),我应该用什么颜色 space 工作? HSV 是合适的还是最好的?能否计算单个像素的对比度值?
对比度通常被理解为强度对比度,可以在亮度分量(Y)上计算。它是直方图分布的度量,例如标准偏差。
可以从任何强度 (I) 计算对比度,例如 LAB 中的 L、HSI 中的 I 或 HSV 中的 V 或 YCbCr 中的 Y(甚至是去饱和图像的灰度版本)使用最大和最小值全局或每个像素周围某些区域的平均值。经常使用 LAB 色彩空间,但我不知道是否有任何普遍共识 "best".
一个公式是:
对比度=(Imax - Imin)/(Imax + Imin)
见here
1) Convert the image to say LAB and get the L channel
2) Compute the max for an NxN neighborhood around each pixel
3) Compute the min for an NxN neighborhood around each pixel
4) Compute the contrast from the equation above at each pixel.
5) Compute the average for all pixels in the result of step 4)
其中 N 是一些小整数,例如 5 或 7。
使用 ImageMagick(unix 语法),这将是:
magick zelda1.jpg -colorspace LAB -channel 0 -separate +channel \
\( -clone 0 -statistic maximum 5x5 \) \
\( -clone 0 -statistic minimum 5x5 \) \
\( -clone 1 -clone 2 +swap -define compose:clamp=off -compose minus -composite \) \
\( -clone 1 -clone 2 +swap -define compose:clamp=off -compose plus -composite \) \
-delete 0-2 \
+swap -define compose:clamp=off -compose divide -composite \
-scale 1x1! -format "%[fx:100*u]\%" info:
17.4745%
1 个像素的对比度实际上是上述给定像素周围 3x3 邻域的公式。邻域可以包含所有 8 个周围像素或仅包含给定像素周围的顶部、底部、左侧、右侧像素。
单个像素本身不能有对比度。对比度是一个相对(差异)的概念,所以至少在两个像素之间。
请注意,NxN 结构元素的腐蚀和膨胀等同于最小值和最大值。
这是 OpenCV 中的代码:
#!/bin/python3.7
import cv2
import numpy as np
# read image
img = cv2.imread("zelda1.jpg")
# convert to LAB color space
lab = cv2.cvtColor(img,cv2.COLOR_BGR2LAB)
# separate channels
L,A,B=cv2.split(lab)
# compute minimum and maximum in 5x5 region using erode and dilate
kernel = np.ones((5,5),np.uint8)
min = cv2.erode(L,kernel,iterations = 1)
max = cv2.dilate(L,kernel,iterations = 1)
# convert min and max to floats
min = min.astype(np.float64)
max = max.astype(np.float64)
# compute local contrast
contrast = (max-min)/(max+min)
# get average across whole image
average_contrast = 100*np.mean(contrast)
print(str(average_contrast)+"%")
17.481959221048086%
我需要 return 图像的(平均)对比度值。 这可能吗,如果可以,请说明如何做? 不仅仅是代码,(显然欢迎代码),我应该用什么颜色 space 工作? HSV 是合适的还是最好的?能否计算单个像素的对比度值?
对比度通常被理解为强度对比度,可以在亮度分量(Y)上计算。它是直方图分布的度量,例如标准偏差。
可以从任何强度 (I) 计算对比度,例如 LAB 中的 L、HSI 中的 I 或 HSV 中的 V 或 YCbCr 中的 Y(甚至是去饱和图像的灰度版本)使用最大和最小值全局或每个像素周围某些区域的平均值。经常使用 LAB 色彩空间,但我不知道是否有任何普遍共识 "best".
一个公式是:
对比度=(Imax - Imin)/(Imax + Imin)
见here
1) Convert the image to say LAB and get the L channel
2) Compute the max for an NxN neighborhood around each pixel
3) Compute the min for an NxN neighborhood around each pixel
4) Compute the contrast from the equation above at each pixel.
5) Compute the average for all pixels in the result of step 4)
其中 N 是一些小整数,例如 5 或 7。
使用 ImageMagick(unix 语法),这将是:
magick zelda1.jpg -colorspace LAB -channel 0 -separate +channel \
\( -clone 0 -statistic maximum 5x5 \) \
\( -clone 0 -statistic minimum 5x5 \) \
\( -clone 1 -clone 2 +swap -define compose:clamp=off -compose minus -composite \) \
\( -clone 1 -clone 2 +swap -define compose:clamp=off -compose plus -composite \) \
-delete 0-2 \
+swap -define compose:clamp=off -compose divide -composite \
-scale 1x1! -format "%[fx:100*u]\%" info:
17.4745%
1 个像素的对比度实际上是上述给定像素周围 3x3 邻域的公式。邻域可以包含所有 8 个周围像素或仅包含给定像素周围的顶部、底部、左侧、右侧像素。
单个像素本身不能有对比度。对比度是一个相对(差异)的概念,所以至少在两个像素之间。
请注意,NxN 结构元素的腐蚀和膨胀等同于最小值和最大值。
这是 OpenCV 中的代码:
#!/bin/python3.7
import cv2
import numpy as np
# read image
img = cv2.imread("zelda1.jpg")
# convert to LAB color space
lab = cv2.cvtColor(img,cv2.COLOR_BGR2LAB)
# separate channels
L,A,B=cv2.split(lab)
# compute minimum and maximum in 5x5 region using erode and dilate
kernel = np.ones((5,5),np.uint8)
min = cv2.erode(L,kernel,iterations = 1)
max = cv2.dilate(L,kernel,iterations = 1)
# convert min and max to floats
min = min.astype(np.float64)
max = max.astype(np.float64)
# compute local contrast
contrast = (max-min)/(max+min)
# get average across whole image
average_contrast = 100*np.mean(contrast)
print(str(average_contrast)+"%")
17.481959221048086%