转自:https://www.cnblogs.com/hangy/p/12569157.html

白平衡:即白色的平衡,最早用于摄像领域技术,可以用来解决色彩还原和调处理的一系列问题。

网上参考别人python版白平衡的运算,索性自己优化了下代码。用numpy矩阵运算取代原有的通道运算,提高运行速度。

tip:用python图像处理尽可能用numpy运算(分通道写法会使处理速度变慢,特别是较大图片),而在C++中的图像处理需要分通道处理。

下面是优化过整理过的代码:

import cv2
import numpy as npdef white_balance(img, mode=1):"""白平衡处理(默认为1均值、2完美反射、3灰度世界、4基于图像分析的偏色检测及颜色校正、5动态阈值)"""# 读取图像b, g, r = cv2.split(img)# 均值变为三通道h, w, c = img.shapeif mode == 1:# 默认均值  ---- 简单的求均值白平衡法b_avg, g_avg, r_avg = cv2.mean(b)[0], cv2.mean(g)[0], cv2.mean(r)[0]# 求各个通道所占增益k = (b_avg + g_avg + r_avg) / 3kb, kg, kr = k / b_avg, k / g_avg, k / r_avgb = cv2.addWeighted(src1=b, alpha=kb, src2=0, beta=0, gamma=0)g = cv2.addWeighted(src1=g, alpha=kg, src2=0, beta=0, gamma=0)r = cv2.addWeighted(src1=r, alpha=kr, src2=0, beta=0, gamma=0)output_img = cv2.merge([b, g, r])elif mode == 2:# 完美反射白平衡 ---- 依赖ratio值选取而且对亮度最大区域不是白色的图像效果不佳。output_img = img.copy()sum_ = np.double() + b + g + rhists, bins = np.histogram(sum_.flatten(), 766, [0, 766])Y = 765num, key = 0, 0ratio = 0.01while Y >= 0:num += hists[Y]if num > h * w * ratio / 100:key = YbreakY = Y - 1sumkey = np.where(sum_ >= key)sum_b, sum_g, sum_r = np.sum(b[sumkey]), np.sum(g[sumkey]), np.sum(r[sumkey])times = len(sumkey[0])avg_b, avg_g, avg_r = sum_b / times, sum_g / times, sum_r / timesmaxvalue = float(np.max(output_img))output_img[:, :, 0] = output_img[:, :, 0] * maxvalue / int(avg_b)output_img[:, :, 1] = output_img[:, :, 1] * maxvalue / int(avg_g)output_img[:, :, 2] = output_img[:, :, 2] * maxvalue / int(avg_r)elif mode == 3:# 灰度世界假设b_avg, g_avg, r_avg = cv2.mean(b)[0], cv2.mean(g)[0], cv2.mean(r)[0]# 需要调整的RGB分量的增益k = (b_avg + g_avg + r_avg) / 3kb, kg, kr = k / b_avg, k / g_avg, k / r_avgba, ga, ra = b * kb, g * kg, r * kroutput_img = cv2.merge([ba, ga, ra])elif mode == 4:# 基于图像分析的偏色检测及颜色校正I_b_2, I_r_2 = np.double(b) ** 2, np.double(r) ** 2sum_I_b_2, sum_I_r_2 = np.sum(I_b_2), np.sum(I_r_2)sum_I_b, sum_I_g, sum_I_r = np.sum(b), np.sum(g), np.sum(r)max_I_b, max_I_g, max_I_r = np.max(b), np.max(g), np.max(r)max_I_b_2, max_I_r_2 = np.max(I_b_2), np.max(I_r_2)[u_b, v_b] = np.matmul(np.linalg.inv([[sum_I_b_2, sum_I_b], [max_I_b_2, max_I_b]]), [sum_I_g, max_I_g])[u_r, v_r] = np.matmul(np.linalg.inv([[sum_I_r_2, sum_I_r], [max_I_r_2, max_I_r]]), [sum_I_g, max_I_g])b0 = np.uint8(u_b * (np.double(b) ** 2) + v_b * b)r0 = np.uint8(u_r * (np.double(r) ** 2) + v_r * r)output_img = cv2.merge([b0, g, r0])elif mode == 5:# 动态阈值算法 ---- 白点检测和白点调整# 只是白点检测不是与完美反射算法相同的认为最亮的点为白点,而是通过另外的规则确定def con_num(x):if x > 0:return 1if x < 0:return -1if x == 0:return 0yuv_img = cv2.cvtColor(img, cv2.COLOR_BGR2YCrCb)# YUV空间(y, u, v) = cv2.split(yuv_img)max_y = np.max(y.flatten())sum_u, sum_v = np.sum(u), np.sum(v)avl_u, avl_v = sum_u / (h * w), sum_v / (h * w)du, dv = np.sum(np.abs(u - avl_u)), np.sum(np.abs(v - avl_v))avl_du, avl_dv = du / (h * w), dv / (h * w)radio = 0.5  # 如果该值过大过小,色温向两极端发展valuekey = np.where((np.abs(u - (avl_u + avl_du * con_num(avl_u))) < radio * avl_du)| (np.abs(v - (avl_v + avl_dv * con_num(avl_v))) < radio * avl_dv))num_y, yhistogram = np.zeros((h, w)), np.zeros(256)num_y[valuekey] = np.uint8(y[valuekey])yhistogram = np.bincount(np.uint8(num_y[valuekey].flatten()), minlength=256)ysum = len(valuekey[0])Y = 255num, key = 0, 0while Y >= 0:num += yhistogram[Y]if num > 0.1 * ysum:  # 取前10%的亮点为计算值,如果该值过大易过曝光,该值过小调整幅度小key = YbreakY = Y - 1sumkey = np.where(num_y > key)sum_b, sum_g, sum_r = np.sum(b[sumkey]), np.sum(g[sumkey]), np.sum(r[sumkey])num_rgb = len(sumkey[0])b0 = np.double(b) * int(max_y) / (sum_b / num_rgb)g0 = np.double(g) * int(max_y) / (sum_g / num_rgb)r0 = np.double(r) * int(max_y) / (sum_r / num_rgb)output_img = cv2.merge([b0, g0, r0])else:raise TypeError('mode should be in [1,2,3,4,5]. Got {}'.format(mode))output_img = np.uint8(np.clip(output_img, 0, 255))return output_img

python实现图像白平衡相关推荐

  1. Python 对图像进行base64编码及解码读取为numpy、opencv、matplot需要的格式

    Python 对图像进行base64编码及解码读取为numpy.opencv.matplot需要的格式 1. 效果图 2. 源码 参考 这篇博客将介绍Python如何对图像进行base64编解码及读取 ...

  2. 使用OpenCV和Python计算图像的“彩色度”

    使用OpenCV和Python计算图像"彩色度" 1. 效果图 2. 炫彩度量方法是什么? 3. 源代码 参考 你是否尝试过计算每个图像的炫彩值,并根据炫彩值对自己的图像数据集进行 ...

  3. Matlab实现图像白平衡(灰度世界法、全反射算法)

    参考:https://www.cnblogs.com/molakejin/p/5766132.html 白平衡 白平衡的英文为White Balance,其基本概念是"不管在任何光源下,都能 ...

  4. 【python】图像映射:单应性变换与图像扭曲

    [python]图像映射:单应性变换与图像扭曲 单应性变换(Homography) 图像扭曲(仿射变换) 图中图 分段仿射扭曲 单应性变换(Homography) 单应性变换(Homography)即 ...

  5. Python计算机视觉——图像到图像的映射

    Python计算机视觉--图像到图像的映射 文章目录 Python计算机视觉--图像到图像的映射 写在前面 1 单应性变换 1.1 直接线性变换算法 1.2 仿射变换 2 图像扭曲 2.1 图像中的图 ...

  6. 使用 Python 的图像隐写术

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 今天,世界正在见证前所未有的数据爆炸,我们每天产生的数据量确实令人 ...

  7. Python垂直翻转图像(Vertically Flip Image)

    Python垂直翻转图像(Vertically Flip Image) 目录 Python垂直翻转图像(Vertically Flip Image) #原始图像 #垂直图像翻转

  8. Python为图像添加文本内容(Writing Text on Image)

    Python为图像添加文本内容(Writing Text on Image) #原始图像 #图像添加文本 # from PIL import Image, ImageDraw, ImageFontim ...

  9. Python为图像添加水印(add watermark to an image)

    Python为图像添加水印(add watermark to an image) 目录 Python为图像添加水印(add watermark to an image) #原始图像

最新文章

  1. MPEG2-TS音视频同步原理
  2. (转)FFMPEG解码H264拼帧简解
  3. ubuntu10.04 解决打开windows记事本.txt文件乱码的方法
  4. 操作系统(三十一)死锁的检测和解除
  5. 无向图求桥 UVA 796
  6. Linux chown命令:给资源绑定用户权限
  7. node 没有界面的浏览器_node.js爬虫入门(二)爬取动态页面(puppeteer)
  8. 第三十一讲:UML类图(上)
  9. git 开源 java_开源中国GIT中Java分类下TOP10项目的活动情况分析
  10. 如何教女朋友学 Python?
  11. 安卓自定义列表dialog
  12. SpringMVC学习(三)RestFul风格
  13. 长虹电视+刷回android,【原创教程】长虹智能电视Q3T手动升级and刷机救砖教程
  14. typora设置标题自动编号
  15. 【飘儿菜】-Matplotlib-绘制饼图
  16. 航旅纵横被质疑泄露用户数据;杭州网警破获67万台电脑数据遭黑客偷窃案;简历倒卖黑产:低至3毛一条,700元买采集器可无限量导数据...
  17. SQLServer 连接不上 找不到网络路径
  18. 公司常用协同管理软件介绍
  19. 《你是我生命中最美的相遇》
  20. 使用cfssl签发证书

热门文章

  1. 如何运用计算机教学教学的收获,计算机教学中行动感悟法的应用
  2. 小白安装cadence virtuoso
  3. ASCII二进制一键转换
  4. 使用EL表达式输出数据
  5. FFmpeg源码分析:音频滤镜介绍(上)
  6. VS2010和VS2013同时安装visual assist X助手
  7. 计算机系统管理规程考试题,计算机基础考试卷试题及标准答案.docx
  8. python处理字体(动态字体库)
  9. 四十四、​Fluent 收敛标准-质量和能量守恒
  10. linux tomcat cpu占用高,排查tomcat服务器CPU使用率过高