OpenCV—python 颜色直方图与直方图均衡化[通俗易懂]

OpenCV—python 颜色直方图与直方图均衡化[通俗易懂]一、读取图片并展示:颜色直方图OpenCV-Python中调用的直方图计算函数为cv2.calcHist。"""hist=cv2.calcHist([image],#传入图像(列表)[0],#使用的通道(使用通道:可选[0],[1],[2])…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

一、颜色直方图

1.1 使用opencv展示直方图
函数
cv2.calcHist(image,channels,mask,histSize,ranges) -> list

image: array为待计算直方图的图像
channels:list 通道,RGB图像可以指定[0,1,2],灰度图像只有[0],
mask 掩码,可以指定图像的范围,如果是全图,默认为none
hitsize 为直方图的灰度级数,例如[0,255]一共256级
range 为像素值范围,为[0,255]

下面三个函数功能在RGB图像处理下差不多,请自行查阅资料
np.histogram()
np.bincount()
cv2.calcHist()

import cv2    
import numpy as np


def calcAndDrawHist(image, color):  
    hist= cv2.calcHist([image], [0], None, [256], [0.0,255.0])  
    minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(hist)  
    histImg = np.zeros([256,256,3], np.uint8)  
    hpt = int(0.9* 256);  
      
    for h in range(256):  
        intensity = int(hist[h]*hpt/maxVal)  
        cv2.line(histImg,(h,256), (h,256-intensity), color)  
    return histImg


if __name__ == '__main__':  
    original_img = cv2.imread("666.png")
    b, g, r = cv2.split(img)  
  
    histImgB = calcAndDrawHist(b, [255, 0, 0])  
    histImgG = calcAndDrawHist(g, [0, 255, 0])  
    histImgR = calcAndDrawHist(r, [0, 0, 255])  

    cv2.imshow("histImgB", histImgB)  
    cv2.imshow("histImgG", histImgG)  
    cv2.imshow("histImgR", histImgR)  
    cv2.imshow("Img", img)  
    cv2.waitKey(0)  
    cv2.destroyAllWindows() 

在这里插入图片描述

1.2 使用matplotlib绘制

matplotlib.pyplot.plot(hist,color)进行绘制

plt.hist(img.ravel(),hitsizes,ranges,color=)

img.ravel()将原图像的array数组转成一维的数组


hitsizes为直方图的灰度级数


ranges为灰度范围[0,255]


color使用color=’’来指定颜色
展示方法:
hist = cv2.calcHist([res],[0],None,[256],[0,255])
plt.plot(hist,'r')
plt.show()
=======================================================
plt.hist(res.ravel(), 256, [0, 256],color='r')
plt.show()

二、直方图均衡化

为什么要进行直方图均衡化呢?我们日常拍照时,背对太阳时或晚上出现图像欠曝,面对太阳拍照会出现过曝,图像均衡可以通过图像直方图均衡来调整图像,也可以通过 γ \gamma γ 校正,来校正图片。

图像的直方图是对图像对比度效果上的一种处理,旨在使得图像整体效果均匀,黑与白之间的各个像素级之间的点更均匀一点。亮度可以更好地在直方图上分布。这样就可以用于增强局部的对比度而不影响整体的对比度,直方图均衡化通过有效地扩展常用的亮度来实现这种功能。(直接效果展示)
在这里插入图片描述
cv2.equalizeHist(img) 均衡化的原图像【输入img:单通道图像】则返回值即为均衡化后的图像。

2.1 全局直方图均衡化与自适应均衡化
import cv2
import numpy as np
 
img = cv2.imread('0002.jpg',0)
 
img1 = cv2.equalizeHist(img)                               # 全局直方图均衡化
clahe = cv2.createCLAHE(clipLimit=2.0,tileGridSize=(8,8))  # 自适应直方图均衡化
cll = clahe.apply(img)
 
res = np.hstack((img,img1,cll))
cv2.imwrite("res.jpg",res)

显然全局直方图均衡化效果不好,造成部分过曝,部分细节消失。
如下图:依次是原图;全局直方图均衡化;自适应直方图均衡化
在这里插入图片描述

2.2 使用查找表来拉伸直方图

在图像处理中,直方图均衡化一般用来均衡图像的强度,或增加图像的对比度。
观察上图中原始图像的直方图,很容易发现大部分强度值范围都没有用到。
因此先检测图像非0的最低(imin)强度值和最高(imax)强度值。
将最低值imin设为0,最高值imax设为255。中间的按255.0*(i-imin)/(imax-imin)+0.5)的形式设置。

import cv2
import numpy as np
 
image = cv2.imread("ABC.png", 0)
lut = np.zeros(256, dtype = image.dtype )                  #创建空的查找表
 
hist,bins = np.histogram(image.flatten(),256,[0,256]) 
cdf = hist.cumsum()                                        #计算累积直方图
cdf_m = np.ma.masked_equal(cdf,0)                          #除去直方图中的0值
cdf_m = (cdf_m - cdf_m.min())*255/(cdf_m.max()-cdf_m.min())#等同于前面介绍的lut[i] = int(255.0 *p[i])公式
cdf = np.ma.filled(cdf_m,0).astype('uint8')                #将掩模处理掉的元素补为0
 
#计算
result2 = cdf[image]
result = cv2.LUT(image, cdf)
 
cv2.imshow("OpenCVLUT", result)
cv2.imshow("NumPyLUT", result2)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

import cv2
import numpy as np
 
image = cv2.imread("ABC.png", 0)
lut = np.zeros(256, dtype = image.dtype )  # 创建空的查找表
hist= cv2.calcHist([image],[0],None,[256],[0.0,255.0])
minBinNo, maxBinNo = 0, 255

for binNo, binValue in enumerate(hist):         #计算从左起第一个不为0的直方图柱的位置
    if binValue != 0:
        minBinNo = binNo
        break

for binNo, binValue in enumerate(reversed(hist)):#计算从右起第一个不为0的直方图柱的位置
    if binValue != 0:
        maxBinNo = 255-binNo
        break
print(minBinNo, maxBinNo)
 
for i,v in enumerate(lut):                      #生成查找表,方法来自参考文献1第四章第2节
    print(i)
    if i < minBinNo:
        lut[i] = 0
    elif i > maxBinNo:
        lut[i] = 255
    else:
        lut[i] = int(255.0*(i-minBinNo)/(maxBinNo-minBinNo)+0.5)

#计算
result = cv2.LUT(image, lut)
cv2.imshow("hist", hist)
cv2.imshow("Result", result)
cv2.waitKey(0)
cv2.destroyAllWindows()
2.3 直方图均衡化—RGB2YCrCb

方法:将RGB彩色图像先转换到YPbPr空间,然后只对亮度通道进行全局直方图均衡化和自适应直方图均衡化,最后再将亮度通道和PbPr通道合并形成彩色图像,然后再转换回RGB空间中。
代码详细:https://docs.opencv2.org/4.1.0/d5/daf/tutorial_py_histogram_equalization.html

import numpy as np
import cv2


# RGB图像全局直方图均衡化
def hisEqulColor1(img):
    ycrcb = cv2.cvtColor(img, cv2.COLOR_BGR2YCR_CB)
    channels = cv2.split(ycrcb)
    cv2.equalizeHist(channels[0], channels[0])   # 对第1个通道即亮度通道进行全局直方图均衡化并保存
    ycrcb = cv2.merge(channels)
    img = cv2.cvtColor(ycrcb, cv2.COLOR_YCR_CB2BGR)
    return img


# RGB图像进行自适应直方图均衡化,代码同上的地方不再添加注释
def hisEqulColor2(img):
    ycrcb = cv2.cvtColor(img, cv2.COLOR_BGR2YCR_CB)
    channels = cv2.split(ycrcb)
    clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
    clahe.apply(channels[0], channels[0])

    ycrcb = cv2.merge(channels)
    img = cv2.cvtColor(ycrcb, cv2.COLOR_YCR_CB2BGR)
    return img

if __name__ == '__main__':
    img = cv2.imread(r'C:\Users\xxx\Desktop
import numpy as np
import cv2
# RGB图像全局直方图均衡化
def hisEqulColor1(img):
ycrcb = cv2.cvtColor(img, cv2.COLOR_BGR2YCR_CB)
channels = cv2.split(ycrcb)
cv2.equalizeHist(channels[0], channels[0])   # 对第1个通道即亮度通道进行全局直方图均衡化并保存
ycrcb = cv2.merge(channels)
img = cv2.cvtColor(ycrcb, cv2.COLOR_YCR_CB2BGR)
return img
# RGB图像进行自适应直方图均衡化,代码同上的地方不再添加注释
def hisEqulColor2(img):
ycrcb = cv2.cvtColor(img, cv2.COLOR_BGR2YCR_CB)
channels = cv2.split(ycrcb)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
clahe.apply(channels[0], channels[0])
ycrcb = cv2.merge(channels)
img = cv2.cvtColor(ycrcb, cv2.COLOR_YCR_CB2BGR)
return img
if __name__ == '__main__':
img = cv2.imread(r'C:\Users\xxx\Desktop\004.png')
img1 = img.copy()
img2 = img.copy()
res1 = hisEqulColor1(img1)
res2 = hisEqulColor2(img2)
res = np.hstack((img, res1, res2))
cv2.imwrite(r'C:\Users\xxx\Desktop\res1.jpg', res)
4.png'
) img1 = img.copy() img2 = img.copy() res1 = hisEqulColor1(img1) res2 = hisEqulColor2(img2) res = np.hstack((img, res1, res2)) cv2.imwrite(r'C:\Users\xxx\Desktop\res1.jpg', res)

如下图:依次是原图;全局直方图均衡化;自适应直方图均衡化
在这里插入图片描述

2.4 直方图均衡化—RGB2YUV
import numpy as np
import cv2


# 全局直方图均衡化
def hisEqulColor1(img):
    image_yuv = cv2.cvtColor(img, cv2.COLOR_BGR2YUV)
    image_yuv[:, :, 0] = cv2.equalizeHist(image_yuv[:, :, 0])
    img = cv2.cvtColor(image_yuv, cv2.COLOR_YUV2BGR)
    return img


# 自适应直方图均衡化
def hisEqulColor2(img):
    image_yuv = cv2.cvtColor(img, cv2.COLOR_BGR2YUV)
    clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
    clahe.apply(image_yuv[:, :, 0])
    img = cv2.cvtColor(image_yuv, cv2.COLOR_YUV2BGR)
    return img

if __name__ == '__main__':
    img = cv2.imread(r'C:\Users\xxx\Desktop
import numpy as np
import cv2
# 全局直方图均衡化
def hisEqulColor1(img):
image_yuv = cv2.cvtColor(img, cv2.COLOR_BGR2YUV)
image_yuv[:, :, 0] = cv2.equalizeHist(image_yuv[:, :, 0])
img = cv2.cvtColor(image_yuv, cv2.COLOR_YUV2BGR)
return img
# 自适应直方图均衡化
def hisEqulColor2(img):
image_yuv = cv2.cvtColor(img, cv2.COLOR_BGR2YUV)
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
clahe.apply(image_yuv[:, :, 0])
img = cv2.cvtColor(image_yuv, cv2.COLOR_YUV2BGR)
return img
if __name__ == '__main__':
img = cv2.imread(r'C:\Users\xxx\Desktop\004.png')
img1 = img.copy()
img2 = img.copy()
res1 = hisEqulColor1(img1)
res2 = hisEqulColor2(img2)
res = np.hstack((img, res1, res2))
cv2.imwrite(r'C:\Users\xxx\Desktop\res4.jpg', res)
4.png'
) img1 = img.copy() img2 = img.copy() res1 = hisEqulColor1(img1) res2 = hisEqulColor2(img2) res = np.hstack((img, res1, res2)) cv2.imwrite(r'C:\Users\xxx\Desktop\res4.jpg', res)

如下图:依次是原图;全局直方图均衡化;自适应直方图均衡化
在这里插入图片描述
仔细观察 RGB2YUV与RGB2YCrCb 自适应直方图均衡化结果:个人觉得RGB2YUV的暗部细节更多一些。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/179721.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • c语言tinyxml使用方法,TinyXml使用方法[通俗易懂]

    c语言tinyxml使用方法,TinyXml使用方法[通俗易懂]本文用一个详细的例子说明了TiXml的使用方法。如写、查找、插入、替换、加载、遍历等常见操作。首先简单介绍一下TinyXml,要看详细的在网上搜搜了^_^:1、TinyXml源代码只有4个cpp文件和2个头文件。2、首先要理解TinyXml中的各个基本类型之间的关系,看看这个继承图大家就会很明白了!可以看到TinyXml中的注释comment,声明declaration,元素element,文本等…

  • 资料整理汇编_做资料汇编模板

    资料整理汇编_做资料汇编模板  Windows.环境下32位汇编语言程序设计(第2版)http://www.happycampus.cn/docs/957100583237@hc10/275980/ 汇编语言编程艺术 Intel汇编语言程序设计(第四版) Intel汇编语言程序设计(第五版)范例http://download.csdn.net/source/1523425

  • SSM的简介

    SSM的简介SSM的简介

  • JAVA生成uuid_java接口default方法

    JAVA生成uuid_java接口default方法java生成UUID的方法总结前言:我们开发的时候,数据库表总会有一个主键,以前我们可能会使用自增的数字作为主键。这样做去确实查询的时候比较快,但是在做系统集成或者数据迁移的的时候就麻烦了。这是id就有可能重复了。那么有什么比较好的方法解决这一问题呢?于是jdk1.5出了UUID这个类来生成唯一的字符串标识。知识点一:什么是UUID?UUID含义是通用唯一识别码(UniversallyUniqu

  • 激活成功教程quartus ii13.0_quartus ii 13.0安装

    激活成功教程quartus ii13.0_quartus ii 13.0安装文章目录一、QuartusII的下载二、QuartusII的安装三、QuartusII的激活成功教程1.下载激活成功教程器文件2.激活成功教程器的使用一、QuartusII的下载百度网盘下载链接:https://pan.baidu.com/s/1a9d-bq9RZmWrRV542X4IEA提取码:ifte说明:本链接来自于正点原子官方资料下载二、QuartusII的安装解压后双击运行exe文件:点击next:勾选“Iaccepttheagreement”,然后点击Next:

    2022年10月10日
  • mybatis中LIKE模糊查询的几种写法以及注意点

    mybatis中LIKE模糊查询的几种写法以及注意点mybatis中对于使用like来进行模糊查询的几种方式:(1)使用${…}注意:由于$是参数直接注入的,导致这种写法,大括号里面不能注明jdbcType,不然会报错org.mybatis.spring.MyBatisSystemException:nestedexceptionisorg.apache.ibatis.reflection.ReflectionExc…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号