OpenCV直方图正规化(归一化)

比如说,数据集中在000处(左侧)的图像全体会偏暗,数据集中在255255255处(右侧)的图像会偏亮。

如果直方图有所偏向,那么其动态范围( dynamic range )就会较低。

为了使人能更清楚地看见图片,让直方图归一化、平坦化是十分必要的。

这种归一化直方图的操作被称作灰度变换(Grayscale Transformation)。像素点取值范围从[c,d][c,d][c,d]转换到[a,b][a,b][a,b]的过程由下式定义。这回我们将imori_dark.jpg的灰度扩展到[0,255][0, 255][0,255]范围:

Opencv 直方图归一化

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

def hist_normalization(img, a=0, b=255):
    c = img.min()
    d = img.max()

    out = img.copy()
    # normalization
    out = (b - a) / (d - c) * (out - c) + a
    out[out < a] = a
    out[out > b] = b

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


# Read image
img  = cv2.imread("imori_dark.jpg").astype(np.float)
H, W, C = img.shape

# histogram normalization
out = hist_normalization(img)

# Display histogram
plt.hist(out.ravel(), bins=255, rwidth=0.8, range=(0, 255))
plt.savefig("out_his.png")
plt.show()

cv2.imshow("result", out)
cv2.waitKey(0)
cv2.imwrite("out.jpg", out)

输入:

Opencv 直方图归一化

输出:

Opencv 直方图归一化

直方图:

API

cv2.normalize(src, dst, alpha, beta, norm_type, dtype, mask)

详细:

src-输入数组
dst-输出数组,支持原地运算
alpha-range normalization模式的最小值
beta-range normalization模式的最大值,不用于norm normalization(范数归一化)模式。
normType-归一化的类型,可以有以下的取值:
1. NORM_MINMAX:数组的数值被平移或缩放到一个指定的范围,线性归一化,一般较常用
2. NORM_INF: 此类型的定义没有查到,根据OpenCV 1的对应项,可能是归一化数组的C-范数(绝对值的最大值)
3.NORM_L1 : 归一化数组的L1-范数(绝对值的和)
4.NORM_L2: 归一化数组的(欧几里德)L2-范数
dtype-dtype为负数时,输出数组的type与输入数组的type相同;否则,输出数组与输入数组只是通道数相同,而tpye=CV_MAT_DEPTH(dtype).
mask-操作掩膜,用于指示函数是否仅仅对指定的元素进行操作。

适用于:灰度级主要在0 ~ 150之间,造成图像对比度较低,可用直方图归一化将图像灰度级拉伸到0~255,使其更清晰。

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

if __name__ == '__main__':
    src = cv2.imread("child.jpg", cv2.IMREAD_ANYCOLOR)
    dst = np.zeros_like(src)

    cv2.normalize(src, dst, 0, 255, cv2.NORM_MINMAX, cv2.CV_8U)


    #计算灰度直方图
    grayHist = cv2.calcHist([src], [0], None, [256], [0, 256])
    grayHist1 = cv2.calcHist([dst], [0], None, [256], [0, 256])

    #画出直方图
    x_range = range(256)
    plt.plot(x_range, grayHist, 'r', linewidth=1.5, c='black')
    plt.plot(x_range, grayHist1, 'r', linewidth=1.5, c='b')
    #设置坐标轴的范围
    y_maxValue = np.max(grayHist)
    plt.axis([0, 255, 0, y_maxValue]) #画图范围
    plt.xlabel("gray Level")
    plt.ylabel("number of pixels")
    plt.show()

    cv2.imshow("src", src)
    cv2.imshow("dst", dst)
    cv2.waitKey(0)
    cv2.destroyWindow()

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值