opencv imshow放大后看不到像素值_对OpenCV中图片亮度和对比度的一些理解

e74422dd5e030a3f20ad5234a91c7335.png

简单的改变图片的亮度和对比度可以看作一个线性的过程:

相当于就是原图像每个像素点对应色彩或灰度的映射。直观上看,
决定了对比度,
越大,各像素之间的差别越大,对比度越大。
决定了亮度,
越大,各像素整体都变大,亮度提升了。

但其实这种表述并不准确,因为在对图像进行线性处理时存在溢出的问题,当

值太大时,
由于超过数据类型的上限被OpenCV置为特定值(比如CV_8U会被置为255)。对于灰度图,这些值都被置为相同值,相当于这部分像素点对比度调节完全失效了;对于三通道的彩色图,有一部分通道溢出,则会导致对比度比预期小的现象。

另一个层面上,

的改变也影响了亮度,因为上式中
的变化会统一的放大或缩小所有像素点的灰度值。当想要提高对比度时,如果不变化
的值,视觉上的”亮度“还是会提升。不妨把上式改写成如下式子:

大于1时,式子2表示对所有比T小的像素点的灰度值变得更小,对所有比T大的像素点的灰度值变得更大,这样当T值等于图像的平均灰度值(当然,是否就是平均灰度值也有待商榷)时就不会带来
的改变影响亮度的问题了。式子1实际上就是式子2中T等于0的特例,所有像素点的灰度值都大于等于0,所以整幅图像的亮度被
单调影响了。

完整的调整代码如下:

import cv2
import numpy as np
​
img = cv2.imread('connelly.jpg')
​
# 此处需注意,下面有说明
res = np.uint8(np.clip((2 * (np.int16(img) - 60) + 50), 0, 255))
tmp = np.hstack((img, res))  # 两张图片横向合并显示
​
cv2.imshow('image', tmp)
cv2.waitKey(0)

输出效果如下:

6db2f376ecb8d91248e5d2c607463818.png

在用python改变图片的亮度和对比度时,有两个问题需要注意,第一个问题是数据类型,式子中其实有一个乘法,这是极有可能出现溢出的,如果代码是这样res = np.uint8(np.clip((2 * img - 60) + 50), 0, 255)),就会出现这样的结果:

ab21b576df4ac639a12ab3543a3a637e.png

解决的办法有两个,一是改变img的类型:使用np.int16(img)代替img;二是用浮点数2.0代替2,这样2.0 * img的数据类型会自动变成float64

print((2.0 * img).dtype) # float64

第二个问题是对于溢出NumPy和OpenCV的处理方式不同:

x = np.uint8([250])
y = np.uint8([10])
print(cv2.add(x, y))  # 250 + 10 = 260 => 255 --255封顶
print(x + y)  # 250 + 10 = 260 % 256 = 4 --会溢出

如果我们使用NumPy处理就需要使用np.clip()函数将数据限定在0~255。

OpenCV-python-4 | Homeward​lil-q.github.io
c1daffd4aeaad4c02364cc9cb7417988.png

参考

  1. https://www.numpy.org.cn/article/other/py_basic_ops.html#%E7%9B%AE%E6%A0%87
  2. https://blog.csdn.net/abc20002929/article/details/40474807
  3. https://docs.opencv.org/2.4/doc/tutorials/core/basic_linear_transform/basic_linear_transform.html#basic-linear-transform
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值