点击上方“小白学视觉”,选择加"星标"或“置顶

重磅干货,第一时间送达

图像增强是对于任何图像处理的一个重要步骤,我们将在日常工作中使用的大多数图像很可能不是在特别理想的环境中拍摄的。过度曝光、曝光不足和彩色阴影等问题在现实生活数据中很常见。因此,了解如何处理此类问题会很有用。

在这篇文章中,我们将讨论如何处理彩色阴影图像。

导入需要的库:

#Import the required Python libraries
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from skimage.io import imshow, imread

天空阴天

正如我们所看到的,上面的图片有一个彩色的阴影,虽然从艺术的角度来看很美,但这样的问题可能会对试图处理数据的机器产生影响。

我们需要做的第一个处理是检查图像的 RGB 光谱。为此,我们必须将图像分解为其 RGB 分量。

rgb_list = ['Reds','Greens','Blues']
fig, ax = plt.subplots(1, 3, figsize=(15,5), sharey = True)
for i in range(3):ax[i].imshow(image_overcast[:,:,i], cmap = rgb_list[i])ax[i].set_title(rgb_list[i], fontsize = 15)

RGB 分割

从纯粹的视觉角度来看,我们可以看到图像具有明显的深红色,当然,这只是我们目测。为了更好地了解图像的实际属性,我们必须以计算机看到的方式来检查它。下面的函数将生成每个颜色通道的相关统计信息。

def channel_statistics(image):df_color = []for i in range(0, 3):max_color =np.max(image[:,:,i])mean_color = np.mean(image[:,:,i])median_color = np.median(image[:,:,i])perc_90 = np.percentile(image[:,:,i], 90, axis=(0,1))perc_95 = np.percentile(image[:,:,i], 95, axis=(0,1))perc_99 = np.percentile(image[:,:,i], 99, axis=(0,1))row = (max_color, mean_color, median_color, perc_90, perc_95, perc_99)df_color.append(row)return pd.DataFrame(df_color, index = ['Red', ' Green', 'Blue'],columns = ['Max', 'Mean', 'Median', 'P_90',' P_95', 'P_99'])
channel_statistics(image_overcast)

频道属性

在生成的表格中,我们看到图像上确实存在红色阴天。现在我们如何平衡它?

虽然这可能行不通,但出于演示原因,让我们通过每个通道的平均值、中值、最大值来调整图像。

def mean_and_median_adjusted(image):fig, ax = plt.subplots(2, 2, figsize=(12,12), sharey = True)f_size = 20ax[0][0].imshow(image_overcast )ax[0][0].set_title('Original', fontsize = f_size)ax[0][1].imshow(img_as_ubyte((image / np.mean(image)).clip(0, 1)))ax[0][1].set_title('Mean Adjusted', fontsize = f_size)ax[1][0].imshow(img_as_ubyte((image/ np.median(image)).clip(0, 1)))ax[1][0].set_title('Median Adjusted', fontsize = f_size)ax[1][1].imshow(img_as_ubyte((image/ np.max(image)).clip(0, 1)))ax[1][1].set_title('Max Adjusted', fontsize = f_size);fig.tight_layout()
mean_and_median_adjusted(image)

通过平均值、中值和最大值进行调整

我们可以看到问题并没有通过这种方法得到解决。虽然可以说图像明显更亮了,但红色阴霾仍然非常明显。解决此问题的一种可能方法是关注红色通道。下面的代码将使用其最大值调整红色通道,而使用其平均值和中值调整所有其他通道。

fig, ax = plt.subplots(1, 3, figsize=(15,7), sharey = True)
f_size = 15
ax[0].imshow(image_overcast)
ax[0].set_title('Original', fontsize = f_size)
ax[1].imshow(img_as_ubyte((image_overcast / [np.max(image_overcast[:,:,0]),np.mean(image_overcast[:,:,1]),np.mean(image_overcast[:,:,2]),np.mean(image_overcast[:,:,3])]).clip(0, 1)))
ax[1].set_title('Red : Max, Others : Mean', fontsize = f_size)
ax[2].imshow(img_as_ubyte((image_overcast / [np.max(image_overcast[:,:,0]),np.median(image_overcast[:,:,1]),np.median(image_overcast[:,:,2]),                                    np.median(image_overcast[:,:,3])]).clip(0, 1)))
ax[2].set_title('Red : Max, Others : Median', fontsize = f_size);

最大红色

看来我们的方法是正确的,图像显然已经去除了红色阴霾,整体更加明亮。然而,我们现在看到了更加明显的绿色和蓝色阴天。这意味着我们可能对红色进行了过多的调整,或者对绿色和蓝色的调整不足。现在我们需要微调我们的参数了。

下面的代码将根据每个通道的特定百分位等级过滤图像。在这篇文章中,我们将其设为 Python 函数,这使我们能够向其中输入任何图像。

def percentile_adjustment(image):fig, ax = plt.subplots(2, 3, figsize=(15,10), sharey = True)f_size = 15red = 99.75  parameter_matrix = [[red] + [99]*3,[red] + [95]*3,[red] + [90]*3,[red] + [85]*3,[red] + [80]*3]ax[0][0].imshow(image)ax[0][0].set_title('Original', fontsize = f_size)ax[0][1].imshow(img_as_ubyte((image /   [np.percentile(image[:,:,i], parameter_matrix[0][i], axis=(0, 1)) \  for i in range(0, 4)]).clip(0,1)))ax[0][1].set_title(f'Red : {red}, Others : {parameter_matrix[0] [1]}', fontsize = f_size)ax[0][2].imshow(img_as_ubyte((image / [np.percentile(image[:,:,i], parameter_matrix[1][i], axis=(0, 1)) \  for i in range(0, 4)]).clip(0,1)))ax[0][2].set_title(f'Red : {red}, Others : {parameter_matrix[1][1]}', fontsize = f_size);ax[1][0].imshow(img_as_ubyte((image / [np.percentile(image[:,:,i], parameter_matrix[2][i], axis=(0, 1)) \for i in range(0, 4)]).clip(0,1)))ax[1][0].set_title(f'Red : {red}, Others : {parameter_matrix[2] [1]}', fontsize = f_size);ax[1][1].imshow(img_as_ubyte((image /[np.percentile(image[:,:,i], parameter_matrix[3][i], axis=(0, 1)) \for i in range(0, 4)]).clip(0,1)))ax[1][1].set_title(f'Red : {red}, Others : {parameter_matrix[3] [1]}', fontsize = f_size);ax[1][2].imshow(img_as_ubyte((image/ [np.percentile(image[:,:,i], parameter_matrix[4][i], axis=(0, 1)) \for i in range(0, 4)]).clip(0,1)))ax[1][2].set_title(f'Red : {red}, Others : {parameter_matrix[4][1]}', fontsize = f_size);percentile_adjustment(image_overcast)

99.75% 处的红色

图像增强的结果是相当明显的。不仅红色阴霾被大大减少,而且其他通道的过度曝光也保持在最低限度。

从视觉上看,最好的结果是当其他通道在 90-95% 之间调整时。在那之后,图像似乎呈现出蓝色调。

有人可能会说,将调整设置为 80 会更好,因为天空本身是蓝色的,因此蓝色阴天是可以接受的。但是,在这篇文章中,我们仍将使用 95。

阴天调整后的天空

然而,图像增强有时会非常棘手。对某些图像非常有效的方法对于其他图像可能并不那么有效,让我们一起来看看下面这个例子。

image_overcast_beach = imread('tinted_sky.png')
imshow(image_overcast_beach);

阴天海滩

第二张图片清楚地展示了与第一张图片类似的问题。让我们尝试应用相同的过程,看看结果是否一样好。由于我们已经编写了一个函数,我们应该能够调用它并将其提供给我们的第二张图像。

percentile_adjustment(image_overcast_beach)

我们看到阴天大大减少了。但是,我们可以看到,我们的方法在图像上半部分和下半部分的有效性之间存在显着差异。图像的天空部分显示超过 95% 的过度曝光。但是,水只有在低于 95%才没有曝光过度。我们如何解决这个问题?

请记住,计算机实际上是通过数字矩阵读取图像的。因此,我们可以很容易地将其拆分,并将不同的参数应用于每个区域。在这种情况下,让我们将图像分割为天空和水。

f_size = 15
parameter_matrix = [[99.9] + [97.75]*3,[99.75] + [92]*3]
fig, ax = plt.subplots(2, 2, figsize=(15,6), sharey = True)
ax[0][0].imshow(image_overcast_beach[0:320])
ax[0][0].set_title('Sky Original', fontsize = f_size)
ax[1][0].imshow(image_overcast_beach[320:])
ax[1][0].set_title('Water Original', fontsize = f_size)
ax[0][1].imshow(img_as_ubyte(((image_overcast_beach[0:320]/ [np.percentile(image_overcast_beach[:,:,i], parameter_matrix[0][i], axis=(0, 1)) for i in range(4)]).clip(0,1))))
ax[0][1].set_title('Sky Adjusted', fontsize = f_size)
ax[1][1].imshow(img_as_ubyte(((image_overcast_beach[320:]/ [np.percentile(image_overcast_beach[:,:,i], parameter_matrix[1][i], axis=(0, 1)) for i in range(4)]).clip(0,1))))
ax[1][1].set_title('Water Adjusted', fontsize = f_size);
fig.tight_layout()

拆分和调整

最后,我们可以使用NumPy的连接函数将这两部分结合起来。

imshow(np.concatenate((beach_correction_top, beach_correction_bottom), axis=0));

连接调整后的图像

正如我们所见,图像增强可能非常棘手。对一个图像有效的方法可能对另一个图像无效。但是只要我们记住图像只不过是 3 维矩阵,我们就应该能够找到一种方法来充分处理它以满足我们的需求。

下载1:OpenCV-Contrib扩展模块中文版教程

在「小白学视觉」公众号后台回复:扩展模块中文教程即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。

下载2:Python视觉实战项目52讲

在「小白学视觉」公众号后台回复:Python视觉实战项目即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。

下载3:OpenCV实战项目20讲

在「小白学视觉」公众号后台回复:OpenCV实战项目20讲即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。

交流群

欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~

Python 图像处理简介——色彩阴影调整相关推荐

  1. Python图像处理丨详解图像去雾处理方法

    摘要:本文主要讲解ACE去雾算法.暗通道先验去雾算法以及雾化生成算法. 本文分享自华为云社区<[Python图像处理] 三十.图像预处理之图像去雾详解(ACE算法和暗通道先验去雾算法)丨[拜托了 ...

  2. python图像处理---python的图像处理模块Image

    https://blog.csdn.net/jiaoyangwm/article/details/79293272 [python图像处理]python的图像处理模块Image 版本信息:2.7.11 ...

  3. 万字长文告诉新手如何学习Python图像处理(上篇完结 四十四) | 「Python」有奖征文

    该系列文章是讲解Python OpenCV图像处理知识,前期主要讲解图像入门.OpenCV基础用法,中期讲解图像处理的各种算法,包括图像锐化算子.图像增强技术.图像分割等,后期结合深度学习研究图像识别 ...

  4. 【python图像处理】python的图像处理模块Image【原创】

    版本信息:2.7.11 环境:windows 7 64位系统 编辑器:PyCharm 运行工具: PyCharm 文件地址:D:\phpStudy\WWW\python\Image 一.引入图像模块 ...

  5. 《OpenCv视觉之眼》Python图像处理二十一:Opencv图像处理之图像线性变换和非线性变换的方法及原理

    本专栏主要介绍如果通过OpenCv-Python进行图像处理,通过原理理解OpenCv-Python的函数处理原型,在具体情况中,针对不同的图像进行不同等级的.不同方法的处理,以达到对图像进行去噪.锐 ...

  6. 《从问题到程序:用Python学编程和计算》——1.2 Python语言简介

    本节书摘来自华章计算机<从问题到程序:用Python学编程和计算>一书中的第1章,第1.2节,作者 裘宗燕,更多章节内容可以访问云栖社区"华章计算机"公众号查看. 1. ...

  7. Python图像处理【2】探索Python图像处理库

    探索Python图像处理库 0. 前言 1. 利用 scikit-image 绘制图像 2. 使用 SciPy 模块裁剪/调整图像大小 3. 使用 OpenCV 绘制轮廓 3.1 轮廓简介 3.2 绘 ...

  8. python图像处理《数字图像处理与python实现》读书笔记

    文章目录 很重要! 第一章 基础知识 1.1 图像采样和量化 1.2 图像的表示和可视化 1.3 简单图像处理 参考 很重要! scikit-image的开发文档:https://scikit-ima ...

  9. 《OpenCv视觉之眼》Python图像处理十六:Opencv图像处理实战一之图像中的硬币检测

    本专栏主要介绍如果通过OpenCv-Python进行图像处理,通过原理理解OpenCv-Python的函数处理原型,在具体情况中,针对不同的图像进行不同等级的.不同方法的处理,以达到对图像进行去噪.锐 ...

最新文章

  1. DFS+剪枝 hdu 5113 Black And White
  2. canny算子的运用
  3. SERV-U FTP SERVER和SERV-U MFT SERVER的区别
  4. /etc/passwd 文件详解
  5. php excel批量导入,PHP将excel文件中的数据批量导入到数据库中
  6. boost::spirit模块实现罗马数字解析器的测试程序
  7. 【机器学习】 - keras学习 - 图片生成器ImageDataGenerator
  8. Linux 下Kill多进程的方法
  9. aftool刷工具提示15天_【15天】【指数600+】关键词百度首页【实战分析】【面授学员】...
  10. ZH奶酪:Ubuntu 14.04配置LAMP(Linux、Apache、MySQL、PHP)
  11. 用python画玫瑰花-使用Python画一朵玫瑰花
  12. canal 监控数据库表 快速使用
  13. theano学习--theano.function
  14. 项目Kick Off 我们应该做什么?
  15. php 干扰曲线,曲线干扰控制
  16. JSP 手机销售管理系统 myeclipse开发web网页 mysql数据库
  17. 《狂飙》壁纸大嫂如此惊艳,做成日历壁纸天天看
  18. JTextArea用法
  19. vue-cli 创建项目不成功 原因为项目文件夹无node_modules文件 进行npm install不成功解决办法
  20. 安卓7.0 申请相机及读写权限

热门文章

  1. 因果关系是通向强AI的阶梯or作用被夸大?
  2. 一行Python代码能实现这么多丧心病狂的功能?(代码可复制)
  3. 教你用OpenCV实现机器学习最简单的k-NN算法
  4. A* 算法之父、人工智能先驱Nils Nilsson逝世 | 缅怀
  5. “GANs之父”Ian Goodfellow被爆已从Google离职
  6. 李飞飞计算机视觉经典课程上线,今年都有哪些新内容?
  7. 线程池的一个BUG,被我发现了
  8. 可能是最好的跨域解决方案了
  9. Dubbo 和 HSF 在阿里的实践:携手走向下一代云原生微服务
  10. 惊呆了,Spring中竟然有12种定义bean的方法