0
点赞
收藏
分享

微信扫一扫

基于灰度世界、完美反射、动态阈值等图像自动白平衡算法


文章目录

  • ​​一、灰度世界算法​​
  • ​​二、完美反射算法​​
  • ​​三、动态阈值算法​​

一、灰度世界算法

C++ 算法: ​​灰度世界​​ 灰度世界算法(Gray World)是以灰度世界假设为基础的,该假设认为对于一幅有着大量色彩变化的图像, R、 G、 B 三个分量的平均值趋于同一个灰度K。一般有两种方法来确定该灰度。

算法步骤

  1. 直接给定为固定值, 取其各通道最大值的一半,即取为127或128;
    令 K = (Raver+Gaver+Baver)/3,其中Raver,Gaver,Baver分别表示红、 绿、 蓝三个通道的平均值。
  2. 分别计算各通道的增益:
    Kr=K/Raver;
    Kg=K/Gaver;
    Kb=K/Baver;
  3. 根据Von Kries 对角模型,对于图像中的每个像素R、G、B,计算其结果值:
    Rnew = R * Kr;
    Gnew = G * Kg;
    Bnew = B * Kb;
    对于上式,计算中可能会存在溢出(>255,不会出现小于0的)现象,处理方式有两种。
    a、 直接将像素设置为255,这可能会造成图像整体偏白。
    b、 计算所有Rnew、Gnew、Bnew的最大值,然后利用该最大值将将计算后数据重新线性映射到[0,255]内。实践证明这种方式将会使图像整体偏暗,建议采用第一种方案。

import numpy as np
import cv2


def grayworld(img):
height,width = img.shape[:2]
dst = np.zeros((height,width,3),dtype=np.float64)
BGR = np.sum(img,axis=(1,2))
BGR = np.divide(BGR,height*width)
GrayValue = np.mean(BGR)
kb = GrayValue / BGR[0]
kg = GrayValue / BGR[1]
kr = GrayValue / BGR[2]

dst[:,:,0] = np.multiply(kb,img[:,:,0])
dst[:,:,1] = np.multiply(kg,img[:,:,1])
dst[:,:,2] = np.multiply(kr,img[:,:,2])
dst = np.where(dst>255.0,255, dst).astype(np.uint8)
return dst



if __name__ == '__main__':
img = cv2.imread("001.png")
dst = grayworld(img)
cv2.imshow("raw_img",img)
cv2.imshow("dst_img",dst)
cv2.waitKey(0)
cv2.destroyAllWindows()

一般来说,灰度世界算法的效果还是比较好的呢,并且该算法的执行速度非常之快,目前也存在了不少对该算法进行改进的效果。

处理效果图:(原图 – 效果图)

基于灰度世界、完美反射、动态阈值等图像自动白平衡算法_c++


显然衣服白平衡有所改善,但是脸部出现高光的情形。

二、完美反射算法

C++ 实现:​​自动白平衡之完美反射算法原理​​

  1. 计算每个像素之和并保存。
  2. 按照 R+G+B 的值的大小计算出其前10%或其他Ratio的白色参考点的阈值T。
  3. 遍历图像中的每个点,计算其中R+G+B值大于T的所有点的R、G、B 分量的累积和的平均值。
  4. 将每个像素量化到 [0,255] 。

原理:完美全反射理论perfect Reflector假设图像上最亮点就是白点,并以此白点为参考对图像进行自动白平衡,最亮点定义为R+G+B的最大值,具体编码步骤如下:

python 实现

import numpy as np
import cv2


def perfect_reflection(img):
height,width = img.shape[:2]
thresh = height * width * 0.1
sum_array = np.sum(img.copy(),axis=2)
MaxVal = np.max(sum_array)
HistRGB = np.bincount(sum_array.reshape(1,-1)[0])
HistRGB_Sum = np.add.accumulate(HistRGB[::-1])
Threshold = np.argwhere(HistRGB_Sum>thresh)[0][0]

Thresh_array = np.where(sum_array>Threshold,1,0)
cnt = np.count_nonzero(Thresh_array)

Thresh_array = Thresh_array[:, :, np.newaxis].repeat(3, axis=2)
sumBGR = np.sum(np.multiply(img,Thresh_array),axis=(0,1))
AvgB = sumBGR[0]/cnt
AvgG = sumBGR[1]/cnt
AvgR = sumBGR[2]/cnt

dst = np.zeros_like(img,dtype=np.float64)
dst[:,:,0] = np.divide(np.multiply(img[:,:,0],MaxVal),AvgB)
dst[:,:,1] = np.divide(np.multiply(img[:,:,1],MaxVal),AvgG)
dst[:,:,2] = np.divide(np.multiply(img[:,:,2],MaxVal),AvgR)

dst = np.where(dst>255,255,0).astype(np.uint8)
return dst



if __name__ == '__main__':
img = cv2.imread("001.png")
dst = perfect_reflection(img)
cv2.imwrite("perfect_reflection.png",dst)

效果不对,待改进。

三、动态阈值算法

参考论文:A Novel Automatic White Balance Method For Digital Still Cameras

C++ 算法:​​动态阈值法​​ 同经典的一些算法相同,算法分为两个步骤:白点检测和白点调整。

白点检测:

  1. 为了增强算法的鲁棒性,原文将图像分成12部分,其中宽高比为4:3,关于这一点,我认为不合理,对图像不是通用的,后文再说。
  2. 计算每个区域的Cb\Cr分量的平均值Mb/Mr。
  3. 按下式计算每个区域的Cb\Cr分量的绝对差的累积值Db/Dr:
  4. 基于灰度世界、完美反射、动态阈值等图像自动白平衡算法_计算机视觉_02

    基于灰度世界、完美反射、动态阈值等图像自动白平衡算法_灰度_03

  5. 上式中N为每个区域的像素数。
  6. 如果Db/Dr的值偏小,则我们忽略这一块,因为这表明这一块的颜色分布比较均匀,而这样的局部对于白平衡不好。这个偏小的准则我们稍微再谈。
  7. 统计对于除了符合第四条的的其他区域的Mb/Mr/Db/Dr的平均值作为整幅图像的Mb/Mr/Db/Dr值。
    关于这一条,原文的话是:The final Mb、Mr、Db、Dr are obtained by taking the average of those regions that pass this additional step。
    我在实际中做的时候就是分别对每块进行的,似乎效果也还不错。
  8. 按下述规则初步确定哪些点是属于白色参考点:
  9. 基于灰度世界、完美反射、动态阈值等图像自动白平衡算法_灰度_04

    基于灰度世界、完美反射、动态阈值等图像自动白平衡算法_计算机视觉_05

  10. 对于初步判断已经属于白色参考点的像素,按大小取其亮度值为前10%的位最终确定的白色参考点。

白点调整:

  1. 计算白色参考点亮度值的平均值Raver,Gaver,Baver,(各通道分开计算)。
  2. 按照以下各式计算每个通道的增益:
  3. 基于灰度世界、完美反射、动态阈值等图像自动白平衡算法_c++_06

    基于灰度世界、完美反射、动态阈值等图像自动白平衡算法_c++_07

    基于灰度世界、完美反射、动态阈值等图像自动白平衡算法_c++_08

  4. 式中,Ymax就是YCbCr颜色空间中Y分量的在整幅图像中的最大值。
  5. 按照以下各式计算最终每个通道的颜色值:
  6. 基于灰度世界、完美反射、动态阈值等图像自动白平衡算法_c++_09

    基于灰度世界、完美反射、动态阈值等图像自动白平衡算法_ide_10

    基于灰度世界、完美反射、动态阈值等图像自动白平衡算法_灰度_11

  7. 其中R/G/B为在原始的颜色空间中的值,注意这里要进行溢出检测的。
    简单的谈下白点检测的分块操作吧,原文把图像分成4*3的12快,这样做事针对于我们很多数码照片是这个比例的,如果通用,我觉得应该用每个块的大小来控制,比如每块为 100*100个像素。
    python代码:

待续


举报

相关推荐

0 条评论