Bootstrap

直方图实例详解(颜色直方图、灰度直方图)

直方图实例详解(颜色直方图、灰度直方图)

本篇目录:

🦄 一、前言

🦄 二、直方图的概念

🦄 三、颜色直方图

(1)、颜色直方图定义

(2)、颜色直方图使用方法

(3)、绘制颜色直方图

①、绘制普通颜色直方图

②、绘制灰度图像直方图

③、绘制彩色图像直方图

④、不同亮度图片直方图对比图

⑤、彩色图像直方图(绘制在同一张图)

🦄 四、灰度直方图

(1)、灰度直方图定义

(2)、灰度直方图函数

(3)、灰度直方图实例

①、绘制普通灰度直方图

②、绘制多通道图像直方图

🦄 五、使用掩模绘制直方图

①、绘制方形掩模图像及直方图

②、绘制圆形掩模图像及直方图

🦄 六、总结


🦄 一、前言

2ab463de26a541818271efa176656ae6.png

  最近经常被人质疑年龄的问题,没错,我年龄是很大了,但我很自豪。我因故在家专心做家务很多很多年,一直和父母一起居住,连电脑都没时间碰,可以说和社会脱节了。重新拾起计算机各种知识也是从去年才开始。从前端技术,到后台编程,从。。。到。。。从UI设计到现在最新的ai绘图,我都能。。。,记录我学习过程的CSDN博客(https://blog.csdn.net/weixin_69553582?type=lately)不到一年时间,访问量马上就要到50万了(纯自然状态,我不善也不喜营销自己)

  去年某个时候,我曾看到一条别人的动态(他当时被一个年龄较小的网友怼,说他年纪大)

  我当时是这样回复的:

  我希望你和我那么大的时候,能够做得比我更出色!

  年轻是代表了无限可能,但其中也有很多变数。纵观各个年龄层次的人,能做到卓越的有几人?能做到优秀的又有几人?

  只要你今天比昨天的自己进步,什么时候开始启航并不是问题。

  花自开不是为了被人欣赏,

  人自律自强不是为了被人称赞!

逆境清醒

2023.4.16

f3751a45350f4910835ba888fb79118a.gif

🦄 二、直方图的概念

  在图像处理中, 经常用到直方图, 如颜色直方图、 灰度直方图等。

  直方图是进行图像处理过程中的一种非常重要的工具。它是从图像内部灰度级的角度对图像进行表述。

  直方图统计的是图像内各个灰度级出现的次数。

  图像的构成是有像素点构成的,每个像素点的值代表着该点的颜色(灰度图或者彩色图)。

  直方图就是对图像的中的这些像素点的值进行统计,得到一个统一的整体的灰度概念。

  直方图的好处就在于可以清晰了解图像的整体灰度分布,便于后期依据直方图处理图像。

  图像的直方图就是像素值出现的总的频数,其公式如下:

   通常将其除以总的像素数,通过概率的形式进行表述:

🦄 三、颜色直方图

(1)、颜色直方图定义

颜色直方图:

  • 1、颜色直方图,是一种能快速描述图像整体像素值分布的统计信息图表。

   图表能显示出某一像素值范围的像素点的个数,X轴为像素值,Y为个数。

  • 2、颜色直方图只能描述颜色的分布,不能描述数据几何上的信息。

   即只知道这个像素值范围的点的个数有多少个,但无法知道这个点在哪个位置上多。

(2)、颜色直方图使用方法

绘制颜色直方图方法:

  用numpy的histogram()函数得到直方图的信息,再用matplotlib绘制出图像。

函数:img.ravel():

作用:把多维数组转化成一维数组,使用方法见下文举例。

绘制直方图函数:matplotlib.pyplot.hist(X, BINS)

  • X:数据源,必须是一维的。通常二维图像,需要使用ravel()函数将图像处理为一维数据源。
  • BINS:表示灰度级的分组情况。

  

hist函数使用方式举例:

plt.hist(img.ravel(),256,[0,256],facecolor ='black')

  • hist:hist函数只支持一维的数组(数组下标为横坐标,值为纵坐标)
  • 256:256 表示横坐标的最大值为256,有256条柱
  • [0,256]:[0,256]表示数据显示范围,横坐标超过256的数据也归到256处
  • facecolor:facecolor 表示柱状图的颜色

函数ravel()的作用是将二维数组降维成一维数组,举例如下:

  假设存在一图像img,其灰度值分别为:

[[235 198 148]
  [238 203 153]
  [241 207 161]
  ...
  [250 227 205]
  [255 232 210]
  [255 238 216]]

我们使用ravel()函数对img图像降维处理:

matrix = img.ravel()

  可得到matrix为:

 [235 198 148 238 203 153 241 207 161... 250 227 205 255 232 210 255 238 216]

(3)、绘制颜色直方图

①、绘制普通颜色直方图

完整代码:

import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread(r'girl2aa.jpg') #读入图像
hist, bins = np.histogram(img.ravel(), bins=50) 
#通过histogram就可以得到每段像素值范围bins的像素点个数hist
plt.hist(img.ravel(), bins=50);
cv2.imshow('img', img)
cv2.waitKey(0)
plt.show()

运行效果:

②、绘制灰度图像直方图

完整代码:

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

img_gray = cv2.imread(r'girl2aaa.jpg', cv2.IMREAD_GRAYSCALE) #读入灰度图像
hist, bins = np.histogram(img_gray.ravel(), bins=50) 
plt.hist(img_gray.ravel(), bins=50);
cv2.waitKey(0)
plt.show()

运行效果:

③、绘制彩色图像直方图

  彩色图像有三个通道,分别绘制。

  可以看到每个通道上像素的分布情况,分析出原图中哪种颜色比较多。

完整代码:

import cv2
import matplotlib.pyplot as plt
# 彩色图像直方图
img_bgr_data = cv2.imread(r'girl2aaa.jpg')
plt.figure(figsize=(15, 5)) #设置画布的大小
# B通道 直方图
ax1 = plt.subplot(131)
ax1.hist(img_bgr_data[:, :, 0].ravel(), bins=50, color='b')
# G通道 直方图
ax2 = plt.subplot(132)
ax2.hist(img_bgr_data[:, :, 1].ravel(), bins=50, color='g')
# R通道 直方图
ax3 = plt.subplot(133)
ax3.hist(img_bgr_data[:, :, 2].ravel(), bins=50, color='r')
cv2.waitKey(0)
plt.show()

运行效果:

④、不同亮度图片直方图对比图

(a)、普通图像

 完整代码:

import cv2
import matplotlib.pyplot as plt
img = cv2.imread(r'girl2aaa.jpg')
cv2.imshow('img', img)
plt.hist(img.ravel(), 256)
plt.show()
cv2.waitKey(0)

运行效果:

图像图像正常

(b)、偏暗图像

完整代码:

import cv2
import matplotlib.pyplot as plt
img = cv2.imread(r'girl2bbb.jpg')
cv2.imshow('img', img)
plt.hist(img.ravel(), 256)
plt.show()
cv2.waitKey(0)

运行效果:

偏暗图像图像偏暗

(c)、偏亮图像

完整代码:

import cv2
import matplotlib.pyplot as plt
img = cv2.imread(r'girl2ccc.jpg')
cv2.imshow('img', img)
plt.hist(img.ravel(), 256)
plt.show()
cv2.waitKey(0)

运行效果:

偏亮图像图像偏亮

(d)、亮度过于集中图像

完整代码:

import cv2
import matplotlib.pyplot as plt
img = cv2.imread(r'girl2ddd.jpg')
cv2.imshow('img', img)
plt.hist(img.ravel(), 256)
plt.show()
cv2.waitKey(0)

运行效果:

图像图像亮度过于集中

⑤、彩色图像直方图(绘制在同一张图)

代码:

import cv2
import matplotlib.pyplot as plt
import numpy as np
img = cv2.imread("cat1.jpg")
n_bins = 256  
hist_range = [0, 256] 
hists = []
channels = {0: "blue", 1:"green", 2: "red"}
for ch in channels:
    hist = cv2.calcHist(
        [img], channels=[ch], mask=None, histSize=[n_bins], ranges=hist_range
    )
    hist = hist.squeeze(axis=-1)
    hists.append(hist)

def plot_hist(bins, hist, color):
    centers = (bins[:-1] + bins[1:]) / 2
    widths = np.diff(bins)
    ax.bar(centers, hist, width=widths, color=color)

bins = np.linspace(*hist_range, n_bins + 1)
fig, ax = plt.subplots()
ax.set_xticks([0, 256])
ax.set_xlim([0, 256])
ax.set_xlabel("Pixel Value")

for hist, color in zip(hists, channels.values()):
    plot_hist(bins, hist, color=color)
plt.show()

运行效果:

图像直方图

🦄 四、灰度直方图

(1)、灰度直方图定义

  图像的灰度直方图:

  描述了图像中灰度分布情况, 能够很直观的展示出图像中各个灰度级所占的多少。很好地体现出图像的亮度和对比度信息:灰度图分布居中说明亮度正常,偏左说明亮度较暗,偏右表明亮度较高;狭窄陡峭表明对比度降低,宽泛平缓表明对比度较高。

  图像的灰度直方图是灰度级的函数, 描述的是图像中具有该灰度级的像素的个数: 其中,

  横坐标是灰度级(横坐标代表像素值的取值区间),

  纵坐标是该灰度级出现的率(纵坐标代表每一像素值在图像中的像素总数或者所占的百分比)。

  根据直方图的形态可以判断图像的质量,通过调控直方图的形态可以改善图像的质量。

(2)、灰度直方图函数

  OpenCV 提供了函数 cv2.calcHist 可以计算直方图,Numpy 中的函数 np.bincount 也可以实现同样的功能。

cv2.calcHist()函数的作用:

  通过直方图可以很好的对整幅图像的灰度分布有一个整体的了解,直方图的x轴是灰度值(0~255),y轴是图片中具有同一个灰度值的点的数目。而calcHist()函数则可以帮助我们统计一幅图像的直方图。

cv2.calcHist(images,channels,mask,histSize,ranges)
  该函数有5个参数:

  • images: 输入图像,原图像图像格式为 uint8 或 float32。当传入函数时应 用中括号 [] 括来例如[img]
  • channels: 传入图像的通道,同样用中括号括来它会告函数我们统幅图像的直方图。如果入图像是灰度图,只有一个通道,它的值就是 [0];如果是彩色图像,有3个通道,传入的参数可以是 [0][1][2] 它们分别对应着 BGR 各个通道。这个值也得用[]传入。
  • mask: 掩模图像。如果统计整幅图像的直方图,就把它为 None。但是如果你想统计图像某一分的直方图,就得制作一个掩模图像并使用它。
  • histSize:BIN 的数目。灰度级的个数,也应用中括号括来,比如[250]
  • ranges: 像素值的范围,像素值范围常为 [0 256],有的图像如果不是0-256,则需要调整后才可以。


绘制直方图需要的一些知识:

  灰度级,正常情况下就是0-255共256个灰度级,从最黑一直到最亮(白),那么每一个灰度级对应一个数来储存该灰度对应的点数目。也就是说直方图其实就是一个1*m(灰度级)的一个数组而已。但是有的时候我们不希望一个一个灰度的递增,比如现在我想15个灰度一起作为一个灰度级来花直方图,这个时候我们可能只需要1*(m/15)这样一个数组就够了。那么这里的15就是直方图的间隔宽度了。

  如果您不需要单独查找所有像素值的像素数,而是在像素值间隔内查找像素数,该怎么办?例如,您需要找到介于 0 到 15 之间的像素数,然后是 16 到 31、...、240 到 255。您只需要 16 个值来表示直方图。因此,只需将整个直方图拆分为 16 个子部分,每个子部分的值就是其中所有像素计数的总和。这每个子部分都称为"BIN"。在第一种情况下,条柱数为256(每个像素一个),而在第二种情况下,它只有16。BINS 在 OpenCV 文档中由术语histSize表示

  1、 直方图反映了图像中的灰度分布规律。

  它描述每个灰度级具有的像素个数, 但不包含这些像素在图像中的位置信息。

  图像直方图不关心像素所处的空间位置, 因此不受图像旋转和平移变化的影响, 可以作为图像的特征。

  2、 任何一幅特定的图像都有唯一的直方图与之对应, 但不同的图像可以有相同的直方图。

  3、如果一幅图像有两个不相连的区域组成, 并且每个区域的直方图已知, 则整幅图像的直方图是该两个区域的直方图之和。

(3)、灰度直方图实例

①、绘制普通灰度直方图

完整代码:

import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('girl2a.jpg', 0)  # 0表示灰度图
hist = cv2.calcHist([img], [0], None, [256], [0, 256])
plt.hist(img.ravel(),256);
cv2.waitKey(0)
plt.show()

 运行效果:

灰度直方图

 ②、绘制多通道图像直方图

完整代码:

import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread('cat1.jpg') 
color = ('b','g','r')
for i,col in enumerate(color): 
    histr = cv2.calcHist([img],[i],None,[256],[0,256]) 
    plt.plot(histr,color = col) 
    plt.xlim([0,256]) 
cv2.imshow('img', img)
cv2.waitKey(0)
plt.show()

 运行效果:

灰度直方图

🦄 五、使用掩模绘制直方图

  cv2.calcHist()函数,其中参数mask用于标识是否使用掩模图像,当使用掩模图像获取直方图时,仅获取mask指定区域的直方图。

  构造掩模图像时,通常先构造一个像素值都是0的二维数组,再将数组中指定区域的像素值设定为255,就得到了掩模图像。

例如:mask = np.zeros([600, 600], np.uint8)
      mask[200:400, 200:400] = 255

  该代码首先生成了一个600×600大小的黑色快,接着令行200-400、列200-400的区域为白色,由此得到掩模图像。

①、绘制方形掩模图像及直方图

完整代码:

import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread(r'girl2a.jpg', cv2.IMREAD_GRAYSCALE)
mask = np.zeros(img.shape, np.uint8)
mask[90:300, 50:280] = 250
histimg = cv2.calcHist([img], [0], None, [256], [0, 255])
histmaskimg = cv2.calcHist([img], [0], mask, [256], [0, 255])
image = cv2.add(img, np.zeros(np.shape(img), dtype=np.uint8), mask=mask)
cv2.imshow("img", img)
cv2.imshow("image", image)
plt.subplot(1, 2, 1)
plt.subplot(1, 2, 2)
plt.plot(histimg)
plt.plot(histmaskimg)
cv2.waitKey(0)
plt.show()

 运行效果:

imgimage

 ②、绘制圆形掩模图像及直方图

完整代码:

import cv2
import numpy as np
import matplotlib.pyplot as plt
img1 = cv2.imread("girl2a.jpg") 
Mask1 = np.zeros((img1.shape[0], img1.shape[1]), dtype=np.uint8)  
Mask2 = Mask1.copy()
cv2.circle(Mask1, (150, 200), 110, (255, 255, 255), -1)  # -1 实心
imgAddMask1 = cv2.add(img1, np.zeros(np.shape(img1), dtype=np.uint8), mask=Mask1)  # 取圆
cv2.imshow("imgAddMask1", imgAddMask1) 
hist = cv2.calcHist([imgAddMask1], [0], None, [256], [0, 256])
plt.hist(imgAddMask1.ravel(),256);
cv2.waitKey(0) 
plt.show()

 运行效果:

imgimage

🦄 六、总结

  本文介绍了计算机视觉里直方图的原理和应用。

  下篇文章我们学习一下如何通过直方图调整图片效果。

  直方图均衡化是一种经典的图像处理算法,用以改善图像的亮度和对比度。

  对图像进行直方图均衡化的目的是,使其原本分布集中的像素值,均衡的分布到所有可取值的范围,这样,图像就既有明亮也有灰暗,对比度和亮度就得到了改善。

  通过直方图均衡化调整后的图像对比效果图如下:

          推荐阅读:

计算机视觉__基本图像操作(显示、读取、保存)直方图(颜色直方图、灰度直方图)直方图均衡化(调节图像亮度、对比度)

 语音识别实战(python代码)(一)

 人工智能基础篇

 计算机视觉基础__图像特征

93d65dbd09604c4a8ed2c01df0eebc38.png

 matplotlib 自带绘图样式效果展示速查(28种,全)

074cd3c255224c5aa21ff18fdc25053c.png

Three.js实例详解___旋转的精灵女孩(附完整代码和资源)(一)

fe88b78e78694570bf2d850ce83b1f69.png

cb4b0d4015404390a7b673a2984d676a.png

立体多层玫瑰绘图源码__玫瑰花python 绘图源码集锦

 Python 3D可视化(一)

 让你的作品更出色——词云Word Cloud的制作方法(基于python,WordCloud,stylecloud)

e84d6708316941d49a79ddd4f7fe5b27.png

938bc5a8bb454a41bfe0d4185da845dc.jpeg

0a4256d5e96d4624bdca36433237080b.png

 python Format()函数的用法___实例详解(一)(全,例多)___各种格式化替换,format对齐打印

 用代码写出浪漫__合集(python、matplotlib、Matlab、java绘制爱心、玫瑰花、前端特效玫瑰、爱心)

python爱心源代码集锦(18款)

dc8796ddccbf4aec98ac5d3e09001348.jpeg

0f09e73712d149ff90f0048a096596c6.png

40e8b4631e2b486bab2a4ebb5bc9f410.png

 Python中Print()函数的用法___实例详解(全,例多)

 Python函数方法实例详解全集(更新中...)

 《 Python List 列表全实例详解系列(一)》__系列总目录、列表概念

09e08f86f127431cbfdfe395aa2f8bc9.png

用代码过中秋,python海龟月饼你要不要尝一口?

 python练习题目录

03ed644f9b1d411ba41c59e0a5bdcc61.png

daecd7067e7c45abb875fc7a1a469f23.png

17b403c4307c4141b8544d02f95ea06c.png

草莓熊python turtle绘图(风车版)附源代码

 ​草莓熊python turtle绘图代码(玫瑰花版)附源代码

 ​草莓熊python绘图(春节版,圣诞倒数雪花版)附源代码

4d9032c9cdf54f5f9193e45e4532898c.png

c5feeb25880d49c085b808bf4e041c86.png

 巴斯光年python turtle绘图__附源代码

皮卡丘python turtle海龟绘图(电力球版)附源代码

vue3 项目搭建教程(基于create-vue,vite,Vite + Vue)

fea225cb9ec14b60b2d1b797dd8278a2.png

bba02a1c4617422c9fbccbf5325850d9.png

37d6aa3e03e241fa8db72ccdfb8f716b.png

2023年春节祝福第二弹——送你一只守护兔,让它温暖每一个你【html5 css3】画会动的小兔子,炫酷充电,字体特

 别具一格,原创唯美浪漫情人节表白专辑,(复制就可用)(html5,css3,svg)表白爱心代码(4套)

SVG实例详解系列(一)(svg概述、位图和矢量图区别(图解)、SVG应用实例)

5d409c8f397a45c986ca2af7b7e725c9.png

6176c4061c72430eb100750af6fc4d0e.png

1f53fb9c6e8b4482813326affe6a82ff.png

【程序人生】卡塔尔世界杯元素python海龟绘图(附源代码),世界杯主题前端特效5个(附源码)HTML+CSS+svg绘制精美彩色闪灯圣诞树,HTML+CSS+Js实时新年时间倒数倒计时(附源代码)

 2023春节祝福系列第一弹(上)(放飞祈福孔明灯,祝福大家身体健康)(附完整源代码及资源免费下载)

80007dbf51944725bf9cf4cfc75c5a13.png

1ab685d264ed4ae5b510dc7fbd0d1e55.jpeg

1750390dd9da4b39938a23ab447c6fb6.jpeg

 Node.js (v19.1.0npm 8.19.3) vue.js安装配置教程(超详细)

 色彩颜色对照表(一)(16进制、RGB、CMYK、HSV、中英文名)

2023年4月多家权威机构____编程语言排行榜__薪酬状况

aa17177aec9b4e5eb19b5d9675302de8.png

38266b5036414624875447abd5311e4d.png

6824ba7870344be68efb5c5f4e1dbbcf.png

 手机屏幕坏了____怎么把里面的资料导出(18种方法)

【CSDN云IDE】个人使用体验和建议(含超详细操作教程)(python、webGL方向)

 查看jdk安装路径,在windows上实现多个java jdk的共存解决办法,安装java19后终端乱码的解决

fffa2098008b4dc68c00a172f67c538d.png

5218ac5338014f389c21bdf1bfa1c599.png

c6374d75c29942f2aa577ce9c5c2e12b.png

 tomcat11、tomcat10 安装配置(Windows环境)(详细图文)

 Tomcat端口配置(详细)

 Tomcat 启动闪退问题解决集(八大类详细)

;