计算机视觉OpenCv学习系列:第七部分、图像操作-3

第一节、图像统计信息

1.像素值统计


对单通道来说,一个像素点除了R,G,B三个维度之外,还有两个维度表示位置信息x,y,所以一个单通道的图片,每个像素点是五个维度

对像素值进行统计与像素所处的位置无关只是单纯统计数值的大小。

(图像像素在OpenCV中相当于数组)

例如:

  • 以单通道为例

    • 均值

在这里插入图片描述

  • 均值 + 方差

  • 根据计算出来的均值和方差,可以对图像所携带的信息做出一些判断。
    比如方差,方差就是数据的分散程度(偏离均值)。图像中有个人和有辆车,那么他们的灰度值是不同的(颜色不同),你把全图像的灰度值取平均,偏离平均值越大,方差越大。方差越大,说明信息越多,能量越大。

  • 方差为0,说明该图片的像素点没有变化,是张纯色图片,说明图片不携带任何有效信息。
    在这里插入图片描述

  • 极值(最大、最小)
    在这里插入图片描述

OpenCV中多通道计算均值方差,是在每个通道上分别计算的。

2.函数支持说明


1. cv.mean(src[, mask]	) ->retval
2. cv.meanStdDev(src[, mean[, stddev[, mask]]]) ->mean, stddev
3. cv.minMaxLoc(src[, mask]) ->minVal, maxVal, minLoc, maxLoc
# src表示输入图像,mask表示计算区域,不写mask表示计算全图
# mean, stddev, minVal, maxVal分别表示均值,标准方差,最小与最大
4. Dst = (Src-mean) * contrast + mean  # 简单应用 -- 对比度

3.代码练习与测试


# 简单应用 -- 对比度
Dst = (Src-mean) * contrast + mean
# contrast < 1.0 降低对比度
# contrast > 1.0 提升对比度
# 例如,均值是70,100-70=30,当contrast=0.5时,差值变为30*0.5=15。
# 图像像素统计 -- 改变对比度 + 均值
def stats_demo_2():
    image = cv.imread(r"F:\python\opencv-4.x\samples\data\butterfly.jpg")
    cv.namedWindow("butterfly", cv.WINDOW_AUTOSIZE)
    cv.imshow("butterfly", image)
    # 计算全图均值
    bgr_m = cv.mean(image)
    # 对原图像设置低对比度
    sub_m = np.float32(image)[:, :] - (bgr_m[0], bgr_m[1], bgr_m[2])
    result = sub_m * 0.5  # 提升差值
    result = result[:, :] + (bgr_m[0], bgr_m[1], bgr_m[2])  # 提升差值之后还要把均值加上去
    cv.imshow("low-contrast-butterfly", cv.convertScaleAbs(result))  # convertScaleAbs转换为绝对值,然后转成CV_8UC
    # 对原图像设置高对比度
    result2 = sub_m * 2.0  # 提升差值
    result2 = result2[:, :] + (bgr_m[0], bgr_m[1], bgr_m[2])  # 提升差值之后还要把均值加上去
    cv.imshow("high-contrast-butterfly", cv.convertScaleAbs(result2))  # convertScaleAbs转换为绝对值,然后转成CV_8UC
    # 输出不同对比度下的图片均值
    m1 = cv.mean(image)
    m2 = cv.mean(cv.convertScaleAbs(result))
    m3 = cv.mean(cv.convertScaleAbs(result2))
    print("image:", m1)
    print("result_low:", m2)
    print("result_high:", m3)
    cv.waitKey(0)
    cv.destroyAllWindows()

结果示例:

在这里插入图片描述

上面三张图片的像素均值:可以看出均值可以反应出图片的明暗程度

在这里插入图片描述

# 图像像素统计 -- 均值、方差、极值(最大、最小)
def stats_demo_1():
    # 计算均值和方差
    roi = np.array([[5, 3, 4], [9, 6, 7], [8, 2, 3]], dtype=np.uint8)  # 定义一个3*3的数组
    mask = np.array([[0, 3, 0], [0, 6, 0], [0, 2, 0]], dtype=np.uint8)  # 定义一个mask区域
    m1 = cv.meanStdDev(roi)  # 计算全图均值,方差
    m2 = cv.meanStdDev(roi, mask=mask)  # 计算mask区域的均值,方差
    minx, maxx, minx_loc, max_loc = cv.minMaxLoc(roi)  # 计算最小值,最大值,最小值坐标,最大值坐标
    print("roi:\n", roi, "\n", "mask:\n", mask)
    print("m1:", m1, "\n", "m2: ", m2)
    print("min: ", minx, " max: ", maxx, " min_loc: ", minx_loc, " max_loc: ", max_loc)
    # 计算均值
    m3 = cv.mean(roi)  # 计算全图均值
    # 计算结果是四个值,对应四个通道,opencv使用mat(数组矩阵)来表示图片数据,其中四个通道分别表示R,G,B,透明度
    m4 = cv.meanStdDev(roi, mask=mask)  # 计算mask区域的均值和方差
    print("roi:\n", roi, "\n", "mask:\n", mask)
    print("m3: ", m3, "\n", "m4: ", m4)

结果示例:

在这里插入图片描述

第二节、图像直方图

1.图像直方图定义


图像直方图就是图像像素值的分布

例如,有图像数据8x8,像素值范围0~14共15个灰度等级,统计得到各个等级(x)出现次数(y)及直方图如右侧所示,每个紫色的长条叫BIN

在这里插入图片描述

每一个图像都可以绘制出自己的图像直方图

三个通道三个不同的直方图分布,将上图中的每个顶点连成线

在这里插入图片描述

注意:两个图像直方图相同,但是图像可能不同,因为直方图只关注了像素信息,没有关注空间位置信息。

2.直方图函数


1. calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]]) -> hist
# images表示图像
# channels表示通道
# mask 默认None
# histSzie表示bin的个数,横坐标的等级个数
# ranges表示通道的取值范围
# 例如 hist = cv.calcHist([image], [i], None, [32], [0, 255])
# image输入图像
# i表示通道索引
# mask=None
# 表示分为32个bin
# 表示取值范围0~256,即每个bin是256/32 = 每个范围的步长为8,即8个灰度等级
# hsv中h通道的取值范围为0-180,sv取值范围为0-255

3.代码练习与测试


# 图像直方图
def image_hist():
    image = cv.imread(r"F:\python\opencv-4.x\samples\data\ml.png")
    cv.imshow("input", image)
    color = ('blue', 'green', 'red')
    # enumerate遍历数组类型同时返回下标和对应数组值
    for i, color in enumerate(color):
        # 一共分32类,每一类256/32步长,按照B,G,R的通道顺序一次使用blue,green,red颜色绘制
        hist = cv.calcHist([image], [i], None, [32], [0, 255])
        print(hist.dtype)
        plt.plot(hist, color=color)
        plt.xlim([0, 32])
    plt.show()
    cv.waitKey(0)
    cv.destroyAllWindows()

结果示例:

在这里插入图片描述

第三节、图像直方图均衡化

1.直方图均衡化


均衡化作用

  • 提升对比度(通过拉大低值和高值之间的差距)
  • 灰度图像支持

在这里插入图片描述

  • k类别名
  • rk每类对应的等级分数
  • nk每类的像素点数
  • nk/n占总像素的比例
  • Sk表示累计(0.44 = 0.19+0.25)
  • ps(sk)表示每一个s累计之后所属类的概率

三个通道三个不同的直方图分布

在这里插入图片描述

2.直方图均衡化函数


cv.equalizeHist(src[, dst]) --> dst
# src必须是八位(0,255)单通道图像(即必须是个灰度图像)
# dst返回结果图像,类型与src保持一致

3.代码练习与测试


# 图像直方图均衡化
def image_eq_demo():
    # 直接读入灰度图片
    # image = cv.imread(r"F:\python\opencv-4.x\samples\data\lena.jpg", cv.IMREAD_GRAYSCALE)
    # 读入RGB彩色图片,切分通道,取单通道
    image = cv.imread(r"F:\python\opencv-4.x\samples\data\lena.jpg")
    image = cv.split(image)
    cv.imshow("input", image[0])
    # 提取原图的B通道作图像直方图
    hist = cv.calcHist([image[0]], [0], None, [32], [0, 255])
    print(hist.dtype)
    plt.plot(hist, color="gray")
    # 灰度等级设定为256/32 = 8
    plt.xlim([0, 32])
    plt.show()

    eqimg = cv.equalizeHist(image[0])
    cv.imshow("eq", eqimg)
    # 确保均衡化的输入是一个八位(0,255)单通道图像
    hist = cv.calcHist([eqimg], [0], None, [32], [0, 255])
    print(hist.dtype)
    plt.plot(hist, color="gray")
    plt.xlim([0, 32])
    plt.show()
    cv.waitKey(0)
    cv.destroyAllWindows()

结果示例:

发现均衡化之后对比度明显提升,并且直方图高值与低值差距拉大。

在这里插入图片描述

学习参考

本系列所有OpenCv相关的代码示例和内容均来自博主学习的网站:opencv_course

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Liuyc-Code boy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值