基于python的对比度增强(线性变换、直方图正规化、直方图均衡化、CLAHE)

这篇具有很好参考价值的文章主要介绍了基于python的对比度增强(线性变换、直方图正规化、直方图均衡化、CLAHE)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

线性变换

假设输入图像为I,宽为W,高为H,输出图像为O,图像的线性变换可以用以下公式定义:
O ( r , c ) = a × I ( r , c ) + b , 0 ≤ r < H , 0 ≤ c < W O(r, c) = a × I(r, c) + b, 0 ≤ r < H, 0 ≤ c < W O(r,c)=a×I(r,c)+b,0r<H,0c<W
当a=1,b=0时,O为I的一个副本;如果a>1,则输出图像O的对比度比I有所增大;如果0<a<1,则O的对比度比I有所减小。而b值的改变,影响的是输出图像的亮度,当b>0时,亮度增加;当b<0时,亮度减小

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt

# 统计灰度直方图并绘制
def calGrayHist(I):
    h, w = I.shape
    grayHist = np.zeros(256, np.uint64)
    for i in range(h):
        for j in range(w):
            grayHist[I[i][j]] += 1
    
    plt.plot(grayHist)
    plt.xlabel("gray label")
    plt.ylabel("number of pixels")

img_gray = cv.imread("./001_07.bmp", 0)
out = 2.0 * img_gray + 5
# 进行数据截断,大于255的像素值截断为255
out[out > 255] = 255
out = out.astype(np.uint8)

plt.figure(figsize=(20,5))
plt.subplot(141)
plt.imshow(img_gray, cmap = "gray")
plt.subplot(142)
calGrayHist(img_gray)
plt.subplot(143)
plt.imshow(out, cmap = "gray")
plt.subplot(144)
calGrayHist(out)
# plt.savefig("./showimg.jpg")
plt.show()

基于python的对比度增强(线性变换、直方图正规化、直方图均衡化、CLAHE)
线性变换的参数需要根据不同的应用及图像自身的信息进行合理的选择,可能需要进行多次测试,所以选择合适的参数是相当麻烦的。直方图正规化就是基于当前图像情况自动选取a和b的值的方法

直方图正规化

基于python的对比度增强(线性变换、直方图正规化、直方图均衡化、CLAHE)

# 直方图正规化
# 计算原图中出现的最小灰度级和最大灰度级
Imin, Imax = cv.minMaxLoc(img_gray)[:2]
'''
# 也可以使用numpy计算
Imax = np.max(img_gray)
Imin = np.min(img_gray)
'''
Omin, Omax = 0, 255
a = float(Omax - Omin) / (Imax - Imin)
b = Omin - a * Imin
out = a * img_gray + b
out = out.astype(np.uint8)

基于python的对比度增强(线性变换、直方图正规化、直方图均衡化、CLAHE)
代码中计算原图中出现的最小灰度级和最大灰度级可以使用OpenCV提供的函数

minVal, maxVal, minLoc, maxLoc = cv.minMaxLoc(src[, mask])

返回值分别为:最小值,最大值,最小值的位置索引,最大值的位置索引。

正规化函数normalize: dst=cv.normalize(src, dst[, alpha[, beta[, norm_type[, dtype[, mask]]]]])

使用函数normalize对图像进行对比度增强时,经常令参数norm_type=NORM_MINMAX,此函数内部实现和上边讲的计算方法是相同的,参数alpha相当于Omax,参数beta相当于Omin。注意,使用normalize可以处理多通道矩阵,分别对每一个通道进行正规化操作。使用该函数的代码如下,实现结果和上边是相同的

out = np.zeros(img_gray.shape, np.uint8)
cv.normalize(img_gray, out, 255, 0, cv.NORM_MINMAX, cv.CV_8U) # 调库
cv.imshow("img", img)
cv.imshow("out", out)
cv.waitKey(0)
cv.destroyAllWindows()

直方图均衡化(Histogram Equalization)

直方图均衡化是指: 利用图像直方图对对比度进行调整的方法
直方图均衡化通常用来增加许多图像的局部对比度,尤其是当图像的有用数据的对比度相当接近的时候
为讨论方便起见,以 r 和 s 分别表示归一化了的原图像灰度和经直方图均衡化后的图像灰度。当 r = s = 0 时,表示黑色;当 r = s = 1 时,表示白色;当 r, s ∈ (0, 1) 时,表示像素灰度在黑白之间变化
在 [0,1] 区间内的任何一个 r ,经变换函数 T ( r ) T(r) T(r) 都可以产生一个对应的 s
s = T ( r ) s = T(r) s=T(r)
式中, T ( r ) T(r) T(r) 应当满足以下两个条件:

  1. 在 0 ≤ r ≤ 1 内, T ( r ) T(r) T(r) 为单调递增函数;(此条件保证了均衡化后图像的灰度级从黑到白的次序不变)
  2. 在 0 ≤ r ≤ 1 内有 0 ≤ T ( r ) ≤ 1 0 ≤ T(r) ≤ 1 0T(r)1。(此条件保证了均衡化后图像的像素灰度值在允许的范围内)

如果已知随机变量 r 的概率密度是 p r ( r ) p_{r}(r) pr(r),而随机变量 s 是 r 的函数,则 s 的概率密度 p s ( s ) p_{s}(s) ps(s) 可以由 p r ( r ) p_{r}(r) pr(r) 求出
基于python的对比度增强(线性变换、直方图正规化、直方图均衡化、CLAHE)
则有: p s ( s ) d s = p r ( r ) d r p_{s}(s)ds = p_{r}(r)dr ps(s)ds=pr(r)dr
又有:从人眼视觉特性来考虑,一幅图像的灰度直方图如果是均匀分布的,那么该图像看上去效果比较好 (参考冈萨雷斯数字图像处理3.3节)。因此要做直方图均衡化,这里的 p s ( s ) p_{s}(s) ps(s) 应当是均匀分布的概率密度函数
基于python的对比度增强(线性变换、直方图正规化、直方图均衡化、CLAHE)
由概率论知识可知,对于区间 [a,b] 上的均匀分布,其概率密度函数等于 1 b − a \frac{1}{b-a} ba1。 如果原图像没有进行归一化,即 r ∈ [ 0 , L − 1 ] r \in [0, L-1] r[0,L1], 那么 p s ( s ) = 1 ( L − 1 ) − 0 = 1 L − 1 p_{s}(s) = \frac{1}{(L-1)-0} = \frac{1}{L-1} ps(s)=(L1)01=L11,归一化之后 r ∈ [ 0 , 1 ] r \in [0, 1] r[0,1],所以这里的 p s ( s ) = 1 1 − 0 = 1 p_{s}(s) = \frac{1}{1-0} = 1 ps(s)=101=1

p s ( s ) = 1 p_{s}(s) = 1 ps(s)=1代入上式有: d s = p r ( r ) d r ds = p_{r}(r)dr ds=pr(r)dr
两边积分得: s = T ( r ) = ∫ 0 r p r ( r ) d r s = T(r) = \int_{0}^{r}p_{r}(r)dr s=T(r)=0rpr(r)dr
由于数字图像灰度级是离散的,所以推广到离散情况,即用频率代替概率,有:
s k = T ( r k ) = ∑ i = 0 k p r ( r i ) = ∑ i = 0 k n i N s_{k} = T(r_{k}) = \sum_{i=0}^{k}p_{r}(r_{i}) = \sum_{i=0}^{k}\frac{n_{i}}{N} sk=T(rk)=i=0kpr(ri)=i=0kNni
式中, 0 ⩽ r k ⩽ 1 , k = 0 , 1 , 2 , . . . , L − 1 0 \leqslant r_{k} \leqslant 1, k = 0, 1, 2, ..., L-1 0rk1,k=0,1,2,...,L1 (注: 这里的 r k = k L − 1 r_{k} = \frac{k}{L-1} rk=L1k,表示归一化后的灰度级;k表示归一化前的灰度级),而且需要注意的是,这里的 s k s_{k} sk 也是归一化后的灰度级,其值在 0 到 1 之间;有时需要将其乘以L-1再取整,使其灰度级范围在 0 到 L-1 之间,与原图像一致

# 全局直方图均衡化
def equalHist(img, z_max = 255): # z_max = L-1 = 255
    # 灰度图像矩阵的高、宽
    H, W = img.shape
    # S is the total of pixels
    S = H * W

    out = np.zeros(img.shape)
    sum_h = 0
    for i in range(256):
        ind = np.where(img == i)
        sum_h += len(img[ind])
        z_prime = z_max / S * sum_h
        out[ind] = z_prime

    out = out.astype(np.uint8)
    return out

基于python的对比度增强(线性变换、直方图正规化、直方图均衡化、CLAHE)
从结果图的直方图分布来看,并不是理想的一条水平线,原因是我们是在连续分布上推导得到的转换函数,但作用于离散分布,且不允许出现非整数形式的新结果
不过,整体看来该转换函数使得新的分布具有展开直方图分布的效果,增强了整体的对比度

限制对比度的自适应直方图均衡化(CLAHE)

关于CLAHE原理讲解的大多数文章讲的都很泛,就像蜻蜓点水般随便扯一下就直接调库实现了,所以真要弄懂的话还是要看源码
http://www.realtimerendering.com/resources/GraphicsGems/gemsiv/clahe.c

上述HE算法得到的结果存在一些问题: 1) 部分区域由于对比度增强过大,成为噪点;2) 一些区域调整后变得更暗/更亮,丢失细节信息

针对问题1),有人提出了CLHE (即 Contrast Limited HE对比度限制的HE算法)
对统计得到的直方图进行裁剪,使其幅值低于某个上限,将裁剪掉的部分均匀分布在整个灰度区间,以确保直方图总面积不变
基于python的对比度增强(线性变换、直方图正规化、直方图均衡化、CLAHE)
可以看到,这时直方图又会整体上升了一个高度,会超过我们设置的上限
其实在具体实现的时候有很多解决方法,可以多重复几次裁剪过程,使得上升的部分变得微不足道,或是用另一种常用的方法:

  • 设裁剪值为ClipThreshold,求直方图中高于该阈值的部分的总和totalExcess,此时如果把totalExcess均分给所有灰度级,那么最终的直方图整体会上升一个高度,这个高度是averageIncrease = totalExcess / N,以upper = ClipThreshold - averageIncrease为界限对直方图进行如下处理:
    1.若幅值高于ClipThreshold,直接设置为ClipThreshold
    2.若幅值处于upperClipThreshold之间,从totalExcess中取出ClipThreshold - 幅值,将幅值填补成ClipThreshold
    3.若幅值低于upper,直接加上averageIncrease即可
    基于python的对比度增强(线性变换、直方图正规化、直方图均衡化、CLAHE)
  • 实现完上面的操作后,还有一些剩余的totalExcess没有被分出去,这个剩余是来自于1.和2.,这时需要再把这些均匀分给那些目前幅值依旧低于ClipThreshold的灰度值
'''
  This function performs clipping of the histogram and redistribution of bins.
  The histogram is clipped and the number of excess pixels is counted. Afterwards
  the excess pixels are equally redistributed across the whole histogram (providing the bin count is smaller than the cliplimit).
'''
def ClipHistogram(pHistogram, ClipThreshold):
    totalExcess = 0
    # 累计超出阈值的部分
    for i in range(256):
        if pHistogram[i] > ClipThreshold:
            totalExcess += (pHistogram[i] - ClipThreshold)
    
    averageIncrease = totalExcess // 256
    upper = ClipThreshold - averageIncrease
    
    # 修剪直方图并重新分配数值
    for i in range(256):
        if pHistogram[i] >= ClipThreshold: # 幅值高于ClipThreshold
            pHistogram[i] = ClipThreshold
        else:
            if pHistogram[i] > upper: # 幅值介于upper和ClipThreshold之间
                totalExcess -= (ClipThreshold - pHistogram[i])
                pHistogram[i] = ClipThreshold
            else: # 幅值小于upper
                totalExcess -= averageIncrease
                pHistogram[i] += averageIncrease
    
    pStartBin = 0
    while totalExcess > 0:
        # 上述过程后totalExcess仍会有剩余未分配,设置步长将剩余的进行均分
        step_size = int(256 / totalExcess)
        if step_size < 1: # step_size至少为1
            step_size = 1
        
        for i in range(pStartBin, 256, step_size):
            if totalExcess == 0:
                break
            if pHistogram[i] < ClipThreshold:
                pHistogram[i] += 1
                totalExcess -= 1 # 减少totalExcess

        pStartBin += 1 # 在其他位置重新开始分配
    
    return pHistogram

针对问题2),有人提出AHE (Adaptive HE自适应直方图均衡化算法),基本思想是: 对原图中每个像素,计算其周围一个邻域内的直方图,并使用HE映射得到新的像素值。为了能够处理图像边缘的像素,一般先对原始图像做镜像扩边处理
不过这样做计算量偏大,为了减少计算量,一般先把原始图像分块,分别对每个子区域进行HE变换。但是这样又产生了新的问题,子区域相接处像素值分布不连续,产生很强的分割线
基于python的对比度增强(线性变换、直方图正规化、直方图均衡化、CLAHE)
为了解决这个问题,提出了优化方案双线性插值的AHE,然后在这个基础上,再使用CLHE的限制对比度的思想,就变成了我们熟知的CLAHE算法

CLAHE算法的步骤:

  1. 图像分块,以块为单位,统计子块的直方图
  2. 使用限制对比度方法进行修剪直方图,最后再直方图均衡化
  3. 像素点灰度值重构,使用的是双线性插值

【双线性插值】
对图像分块,然后对每一块求直方图均衡化,但不是把直方图均衡化的结果全部赋给这个子块,因为这样会造成块跟块之间像素值不连续
那像素点的灰度级该如何更新? 根据像素点所在位置分成三类
在粉色区域内的点的灰度就等于直方图均衡化的结果,即直接由映射函数计算得到
在绿色区域内的点的灰度由相邻两个子图映射函数插值得到
在其他区域内的所有点的灰度由相邻四个子图映射函数双线性插值得到
基于python的对比度增强(线性变换、直方图正规化、直方图均衡化、CLAHE)
如下图所示便是双线性插值的情况,O点的灰度值为 r o r_o ro,对其周围最近的四个子块的灰度映射函数进行双线性插值的结果为:
s o = ( 1 − x ) ( 1 − y ) T A ( r o ) + x ( 1 − y ) T B ( r o ) + ( 1 − x ) y T C ( r o ) + x y T D ( r o ) s_o = (1 - x)(1 - y)T_A(r_o) + x(1 - y)T_B(r_o) + (1 - x)yT_C(r_o) + xyT_D(r_o) so=(1x)(1y)TA(ro)+x(1y)TB(ro)+(1x)yTC(ro)+xyTD(ro)
基于python的对比度增强(线性变换、直方图正规化、直方图均衡化、CLAHE)
【线性插值代码实现中的细节】
举个例子:
把一张图片分成4×3个子图,每个格子为4×4大小,图中的P、Q两点位于边界处,所以需要使用线性插值得到这两个点的灰度级,线性插值第一步找到该点周围相邻的两个子图,那P点和Q点的相邻子图分别是什么?假设P点坐标为(11, 2)、Q点坐标为(9, 2)
基于python的对比度增强(线性变换、直方图正规化、直方图均衡化、CLAHE)
可以看到,虽然P点和Q点在同一个子图中,但相邻子图是不同的,Q点的灰度级是由 T A ( r ) T_A(r) TA(r) T B ( r ) T_B(r) TB(r)这两个映射函数得到,也就是说Q点相邻的两个子图是第3个和第6个子图(从0开始编号),而P点的灰度级是由 T B ( r ) T_B(r) TB(r) T C ( r ) T_C(r) TC(r)这两个映射函数得到,是第6个子图和第9个子图
代码中如何判定?

Q = (9, 2)
P = (11, 2)
tileGridSize = (4, 3) # 将图片分成4×3份
height_block, width_block = 4, 4 # 每个子图的大小

Q_numi = int((Q[0] - height_block / 2) / height_block)
Q_num1 = Q_numi * tileGridSize[1]
Q_num2 = Q_num1 + tileGridSize[1]

P_numi = int((P[0] - height_block / 2) / height_block)
P_num1 = P_numi * tileGridSize[1]
P_num2 = P_num1 + tileGridSize[1]

print(Q_num1, Q_num2)
print(P_num1, P_num2)

运行结果为:

3 6
6 9

Q点的灰度级公式就为:
s Q = ( 1 − y Q ) T A ( r Q ) + y Q T B ( r Q ) s_Q = (1 - y_Q)T_A(r_Q) + y_QT_B(r_Q) sQ=(1yQ)TA(rQ)+yQTB(rQ)
P点的灰度级公式就为:
s P = ( 1 − y P ) T B ( r P ) + y P T C ( r P ) s_P = (1 - y_P)T_B(r_P) + y_PT_C(r_P) sP=(1yP)TB(rP)+yPTC(rP)
问题来了: yQ和yP怎么获得?
基于python的对比度增强(线性变换、直方图正规化、直方图均衡化、CLAHE)
从上图来看,无非就是该点到相邻的第一个子图中心的距离,所以我们需要知道第一个子图中心位置,Q点相邻的第一个子图中心坐标为(6, 2),P点相邻的第一个子图中心坐标为(10, 2)

print(Q_numi * height_block + height_block / 2)
print(P_numi * height_block + height_block / 2)

yQ = (Q[0] - (Q_numi * height_block + height_block / 2)) / height_block
yP = (P[0] - (P_numi * height_block + height_block / 2)) / height_block  # 除以height_block是为了归一化
print(yQ)
print(yP)

代码运行结果:

6.0
10.0
0.75
0.25

当然,应该也可以使用另一种方式求yQ和yP,但我不知道这个对不对,因为我刚开始是想着用求余的方式求yQ和yP,就推出了这个,和上面那种方法求出来的结果是一样的

yQ = (Q[0] - height_block / 2) % height_block / height_block
yP = (P[0] - height_block / 2) % height_block / height_block
print(yQ)
print(yP)

CLAHE代码:

def my_CLAHE(img, clipLimit, tileGridSize):
    height, width = img.shape
    height_block = height // tileGridSize[0]
    width_block = width // tileGridSize[1]
    total = width_block * height_block

    average = width_block * height_block / 256
    ClipThreshold = int(clipLimit * average)

    multi_cdf = []
    for i in range(tileGridSize[0]):
        for j in range(tileGridSize[1]):
            grid = img[i*height_block : (i+1)*height_block, j*width_block : (j+1)*width_block]
            hist = calGrayHist(grid) # 统计每个子块的直方图
            hist = ClipHistogram(hist, ClipThreshold) # 限制对比度对直方图进行修剪
            
            # 获取累计分布直方图cdf
            cdf = np.zeros(256)
            for k in range(256):
                if k == 0:
                    cdf[k] = hist[k] / total
                else:
                    cdf[k] = cdf[k-1] + (hist[k] / total)
            
            
            multi_cdf.append(cdf.tolist())

    print(np.array(multi_cdf).shape)
    
    out = np.zeros(img.shape)
    # 计算CLAHE后的像素值: 根据像素点的位置,选择不同的计算方法
    for i in range(height):
        for j in range(width):
            # four coners,即红色区域,灰度级直接由映射函数计算得到
            if i <= height_block / 2 and j <= width_block / 2: # 左上角
                num = 0
                out[i][j] = int(multi_cdf[num][img[i][j]] * 255)
            elif i <= height_block / 2 and j >= ((tileGridSize[1] - 1) * width_block + width_block / 2): # 右上角
                num = tileGridSize[1] -1
                out[i][j] = int(multi_cdf[num][img[i][j]] * 255)
            elif i >= ((tileGridSize[0] - 1) * height_block + height_block / 2) and j <= width_block: # 左下角
                num = tileGridSize[1] * (tileGridSize[0] - 1)
                out[i][j] = int(multi_cdf[num][img[i][j]] * 255)
            elif i >= ((tileGridSize[0] - 1) * height_block + height_block / 2) and j >= ((tileGridSize[1] - 1) * width_block + width_block / 2): # 右下角
                num = tileGridSize[0] * tileGridSize[1] - 1
                out[i][j] = int(multi_cdf[num][img[i][j]] * 255)

            # four edges except coners,即绿色区域,灰度级由线性插值得到
            elif j <= width_block / 2: # 左边界
                num_i = int((i - height_block / 2) / height_block)
                num1 = num_i * tileGridSize[1]
                num2 = num1 + tileGridSize[1]
                y = (i - (num_i * height_block + height_block / 2)) / height_block # 归一化
                out[i][j] = int(((1 - y) * multi_cdf[num1][img[i][j]] + y * multi_cdf[num2][img[i][j]]) * 255)

            elif i <= height_block / 2: # 上边界
                num_j = int((j - width_block / 2) / width_block)
                num1 = num_j
                num2 = num1 + 1
                x = (j - (num_j * width_block + width_block / 2)) / width_block # 归一化
                out[i][j] = int(((1 - x) * multi_cdf[num1][img[i][j]] + x * multi_cdf[num2][img[i][j]]) * 255)

            elif j >= ((tileGridSize[1] - 1) * width_block + width_block / 2): # 右边界
                num_i = int((i - height_block / 2) / height_block)
                num1 = num_i * tileGridSize[1] + tileGridSize[1] - 1
                num2 = num1 + tileGridSize[1]
                y = (i - (num_i * height_block + height_block / 2)) / height_block # 归一化
                out[i][j] = int(((1 - y) * multi_cdf[num1][img[i][j]] + y * multi_cdf[num2][img[i][j]]) * 255)

            elif i >= ((tileGridSize[0] - 1) * height_block + height_block / 2): # 下边界
                num_j = int((j - width_block / 2) / width_block)
                num1 = num_j + (tileGridSize[0] - 1) * tileGridSize[1]
                num2 = num1 + 1
                x = (j - (num_j * width_block + width_block / 2)) / width_block # 归一化
                out[i][j] = int(((1 - x) * multi_cdf[num1][img[i][j]] + x * multi_cdf[num2][img[i][j]]) * 255)

            # inner area,即紫色区域,灰度级由双线性插值得到
            else:
                num_i = int((i - height_block / 2) / height_block)
                num_j = int((j - width_block / 2) / width_block)
                num1 = num_i * tileGridSize[1] + num_j
                num2 = num1 + 1
                num3 = num1 + tileGridSize[1]
                num4 = num2 + tileGridSize[1]
                x = (j - (num_j * width_block + width_block / 2)) / width_block # 归一化
                y = (i - (num_i * height_block + height_block / 2)) / height_block # 归一化
                out[i][j] = int(((1 - x) * (1 - y) * multi_cdf[num1][img[i][j]] + 
                                 x * (1- y) * multi_cdf[num2][img[i][j]] + 
                                 (1 - x) * y * multi_cdf[num3][img[i][j]] + 
                                 x * y * multi_cdf[num4][img[i][j]]) * 255)

    out = out.astype(np.uint8)
    return out

代码运行结果:
基于python的对比度增强(线性变换、直方图正规化、直方图均衡化、CLAHE)
调库实现

# 创建CLAHE对象
clahe = cv.createCLAHE(clipLimit=4.0, tileGridSize=(8, 8))
# 限制对比度的自适应阈值直方图均衡化
img_gray_clahe = clahe.apply(img_gray)

我代码中没有考虑过如果图像尺寸无法整除分块大小的情况,贴上别人的博客吧,以后有时间再去想
OpenCV自适应直方图均衡CLAHE图像和分块大小不能整除的处理


代码下载:
https://download.csdn.net/download/weixin_45771864/86329433

参考资源:文章来源地址https://www.toymoban.com/news/detail-459650.html

  • 【图像处理算法】直方图均衡化
  • 限制对比度自适应直方图均衡(CLAHE算法)
  • 直方图均衡化(HE, AHE, CLAHE)
  • 限制对比度自适应直方图均衡化(自我理解)
  • OpenCV–Python 图像增强(线性变换,直方图正规化,伽马变换,全局直方图均衡化,限制对比度的自适应直方图均衡化)

到了这里,关于基于python的对比度增强(线性变换、直方图正规化、直方图均衡化、CLAHE)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • opencv-图像对比度增强

    对比度增强,即将图片的灰度范围拉宽,如图片灰度分布范围在[50,150]之间,将其范围拉升到[0,256]之间。这里介绍下 线性变换,直方图正规化,伽马变换,全局直方图均衡化,限制对比度自适应直方图均衡化等算法。 线性变换 通过函数y=ax+b对灰度值进行处理,例如对于过暗

    2024年01月16日
    浏览(52)
  • OpenCv:直方图均衡化(HE),自适应直方图均衡化(AHE),限制对比度自适应直方图均衡化(CLAHE)

    总结了使用Python OpenCv处理图像直方图均衡化(HE),自适应直方图均衡化(AHE),限制对比度自适应直方图均衡化(CLAHE)的方法。 HE直方图增强,大家都不陌生,是一种比较古老的对比度增强算法。 通过equalizeHist()可以实现图像的直方图均衡,它是一种全局直方图均衡,考量的对象

    2024年02月03日
    浏览(41)
  • 数字图像处理:亮度对比度-几何变换-噪声处理

    亮度与对比度转换 图像变换可分为以下两种: 点算子:基于像素变换,在这一类图像变换中,仅仅根据输入像素值计算相应的输出像素值 邻域算子:基于图像区域进行变换 两种常用的点算子是用常数对点的像素值进行乘法或加法运算,可以表示为: g ( i , j ) = α ∗ f ( i ,

    2024年02月10日
    浏览(55)
  • 【opencv】示例-demhist.cpp 调整图像的亮度和对比度,并在GUI窗口中实时显示调整后的图像以及其直方图。...

    这段代码是使用C++和OpenCV库编写的图像处理程序,其主要功能是 调整图像的亮度和对比度,并在GUI窗口中实时显示调整后的图像以及其直方图。 用户可以通过界面上的滑动条来动态地调整亮度和对比度参数从而观察到图像即时的变化效果。程序首先读取并显示一个灰度图像

    2024年04月10日
    浏览(47)
  • 【色彩一致性损失:场景亮度解纠缠网络:纹理-对比度增强网络:IVIF】

    (DIVFusion:无暗区红外与可见光图像融合) 红外与可见光图像融合是一种重要的图像增强技术,其目的是在极端环境下生成目标显著、纹理丰富的高质量融合图像。然而,现有的图像融合方法都是针对正常光照条件下的红外和可见光图像而设计的。在夜景场景中,由于可见光

    2024年02月08日
    浏览(43)
  • 【对比度增强】Learning Tone Curves for Local Image Enhancement(LTMNet)

    LTMNet这篇文章借鉴了CLAHE算法,所有步骤与CLAHE一致,不同之处在于LTMNet中局部映射曲线是通过CNN预测得到,而CLAHE中是通过直方图均衡化而得。关于CLAHE,【数字图像处理】直方图均衡化这篇博客有简单介绍。 论文:Learning Tone Curves for Local Image Enhancement 代码:https://github.co

    2023年04月23日
    浏览(46)
  • Python OpenCV调整图像亮度对比度及RGB色彩

    python通过opencv库调整图像的步骤: 1. 读取图像 直接通过cv2库读取图像,可以读取jpg, png等格式 2. 调整图像亮度及对比度 OpenCV提供 convertScaleAbs 函数来调整对比度和亮度,可以直接调用该函数 如果只调整RGB颜色通道,则可以忽略此步骤 3. 分离出图片的B,R,G颜色通道 使用

    2024年02月03日
    浏览(45)
  • python numpy opencv调整图片亮度对比度饱和度

    (想要完整代码直接划到最后) 原理比较简单,本质上是对图像各个通道的每个像素点做线性变换,对超出范围[0,255]的做截断处理,所以使用numpy处理比较方便 一下函数为了

    2024年02月12日
    浏览(42)
  • OpenCV进阶 —— 调整图像亮度对比度

    图像变换就是找到一个函数,把原始图像矩阵经过函数处理后,转换为目标图像矩阵。 可以分为两种方式,即像素级别的变换和区域级别的变换 Point operators (pixel transforms) Neighborhood (area-based) operators 像素级别的变换就相当于即变换后的每个像素值都与变换前的同位置的像素值

    2024年02月14日
    浏览(45)
  • OpenCV改变图像的对比度和亮度

    在本教程中,您将学习如何: 访问像素值 用零初始化矩阵 了解 cv::saturate_cast 的作用以及它为什么有用 获取有关像素转换的一些很酷的信息 在实际示例中提高图像的亮度 注意 下面的解释属于Richard Szeliski的《计算机视觉:算法和应用》一书 图像处理 一般图像处理算子是

    2024年02月21日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包