Python cv2 (二) 图像的灰度化 二值化 直方图 mask|均衡

1 灰度化 和二值化

按照颜色对图像进行分类

- 二值图像:0和1 ,0 表示黑色,1 表示白色。
- 灰度图像:[0,255] 表示灰度,如:0 表示纯黑,255 表示纯白。
- 彩色图像:BGR 三个色彩通道的组合表示。
1.1灰度化

灰度化图像:
①可以读取时候灰度化 cv2.imread(“dog.jpg”,0) # 0灰度
② 用命令转变 cv2.cvtColor(狗图,cv2.COLOR_BGR2GRAY)

狗图=cv2.imread("dog.jpg")
狗图_gray=cv2.imread("dog.jpg",0) # 0灰度
狗图_gray2=cv2.cvtColor(狗图,cv2.COLOR_BGR2GRAY)

在这里插入图片描述

1.2 二值化

二值图像,可以突出图像轮廓,把目标从背景中分割出来。

cv2.threshold(src, 阈值, 最大值, type)
		参数:
		阈值  0-255  需要调整合适值
		最大值 一般 255
		type:
			cv2.THRESH_BINARY:大于阈值时置 255,否则置 0
			cv2.THRESH_BINARY_INV:大于阈值时置 0,否则置 255
			cv2.THRESH_TRUNC:大于阈值时置为阈值 thresh,否则不变(保持原色)
阈值,狗图_二值化=cv2.threshold(狗图,120,255,cv2.THRESH_BINARY)
阈值,狗图_二值化_INV=cv2.threshold(狗图,120,255,cv2.THRESH_BINARY_INV)  
	# 小于阈值设为0, 否则255
阈值,狗图_二值化_TRUNC=cv2.threshold(狗图,120,255,cv2.THRESH_TRUNC)  
	# 大于阈值设为 阈值,否则不变色

2 灰度化转换

【目的】图像增强:动态范围扩大 图像对比度增强,图像更清晰,特征更明显,从而改善图像的显示效果。

【方法】按一定规则(灰度映射函数)修改图像每一个像素的灰度值,从而改变图像灰度的动态范围。
【分类】根据灰度映射函数的性质,灰度变换可以分:

种类说明
反相 变换反相每个像素值 ,增强 暗部区域的 白色和灰色细节
线性 变换线性拉伸每个像素,凸显图像的细节,提高图像的对比度。
分段 线性变换
非线性 变换- 最为常用。

2.1 反相

【思路】 读出每个像素值, 取补(255-n), 写进去
1,灰度化图片
2,新建黑色画布,等尺寸原图
3,用for循环,用原图每个像素的补数,填充画布的对应坐标
【目的】 增强 暗部区域的 白色和灰色细节

# 1, 读入图片
图片 = cv2.imread("lena.jpg")
# 2,灰度图片
图片_灰度=cv2.cvtColor(图片,cv2.COLOR_BGR2GRAY)

# 3 新建黑色等原图尺寸的图片
图片反相=np.zeros_like(图片)
w,h=图片.shape[:2]

# 4 填充用灰度图的每一个像素的补数,填充反相的对应坐标位置
for i in range(w):
    for j in range(h):
        图片反相[i][j]=255-图片_灰度[i][j]   # 用灰度图的每一个像素的补数,填充反相的对应坐标位置

在这里插入图片描述

2.2 线性 变换

线性拉伸每个像素,凸显图像的细节,提高图像的对比度
公式 Dt=αD+β , (D为原图灰度值,Dt为变换后的灰度值)

当 α = 1 , β = 0 ,原图不变
当 α = 1 , β > 0 ,灰度值上移,图像发白(彩色图像颜色发亮)
当 α = 1 , β < 0   , 灰度值下移,图像颜色发黑(彩色图像颜色发暗)

当 α > 1  ,图像的对比度增强
当 0<α<1 ,图像的对比度减小
当 α < 0 , β = 255,图像暗区域变亮,亮区域变暗,图像求补
当 α = − 1 ,β=255 时,图像的灰度值反转
  • 小步骤
    1, 读入图片并灰度化
    2, 创建新画布

     h, w = 图片.shape[:2]  # 图片的高度和宽度
    

    3, 画布1 = np.empty((w, h), np.uint8) # 创建空白数组

     画布1 = np.zeros_like(图片)  # 创建空白数组
     画布2 = np.zeros_like(图片)  # 创建空白数组
     画布3 = np.zeros_like(图片)  # 创建空白数组
     画布4 = np.zeros_like(图片)  # 创建空白数组
     画布5 = np.zeros_like(图片)  # 创建空白数组
     画布6 = np.zeros_like(图片)  # 创建空白数组
    

    4,线性化 像素 Dt[i,j] = a*D[i,j] + b

     for i in range(h) :
         for j in range(w) :
             画布1[i][j] = min(255, max((图片_灰度[i][j] + 50), 0))  # a=1,b>0: 颜色发白
             画布2[i][j] = min(255, max((图片_灰度[i][j] - 50), 0))  # a=1,b<0: 颜色发黑
             画布3[i][j] = min(255, max(1.5 * 图片_灰度[i][j], 0))  # a>1,b=0: 对比度增强
             画布4[i][j] = min(255, max(0.5 * 图片_灰度[i][j], 0))  # 0<a<1,b=0: 对比度减小
             画布5[i][j] = -0.5 * 图片_灰度[i][j] + 255  # a<0,b=255: 暗区域变亮,亮区域变暗
             画布6[i][j] = min(255, max(-1 * 图片_灰度[i][j] + 255, 0))  # a=-1,b=255: 灰度值反转
    

代码奉上

# coding:utf8
import numpy as np
import cv2
from matplotlib import pyplot as plt

# 1,读入并灰度
图片 = cv2.imread("lena.jpg")
图片_灰度 = cv2.cvtColor(图片, cv2.COLOR_BGR2GRAY)  # 颜色转换:BGR(OpenCV) -> Gray

# 2,创建新画布
h, w = 图片.shape[:2]  # 图片的高度和宽度
# 画布1 = np.empty((w, h), np.uint8)  # 创建空白数组
画布1 = np.zeros_like(图片)  # 创建空白数组
画布2 = np.zeros_like(图片)  # 创建空白数组
画布3 = np.zeros_like(图片)  # 创建空白数组
画布4 = np.zeros_like(图片)  # 创建空白数组
画布5 = np.zeros_like(图片)  # 创建空白数组
画布6 = np.zeros_like(图片)  # 创建空白数组

# 线性化 像素  Dt[i,j] = a*D[i,j] + b
for i in range(h) :
    for j in range(w) :
        画布1[i][j] = min(255, max((图片_灰度[i][j] + 50), 0))  # a=1,b>0: 颜色发白
        画布2[i][j] = min(255, max((图片_灰度[i][j] - 50), 0))  # a=1,b<0: 颜色发黑
        画布3[i][j] = min(255, max(1.5 * 图片_灰度[i][j], 0))  # a>1,b=0: 对比度增强
        画布4[i][j] = min(255, max(0.5 * 图片_灰度[i][j], 0))  # 0<a<1,b=0: 对比度减小
        画布5[i][j] = -0.5 * 图片_灰度[i][j] + 255  # a<0,b=255: 暗区域变亮,亮区域变暗
        画布6[i][j] = min(255, max(-1 * 图片_灰度[i][j] + 255, 0))  # a=-1,b=255: 灰度值反转


def bgr2rgb(cv2_img) :
    # 灰度图片直接返回
    if len(cv2_img.shape) == 2 :
        return cv2_img
    # 3通道的BGR图片
    elif len(cv2_img.shape) == 3 and cv2_img.shape[2] == 3 :  # 三位数,三通道
        b, g, r = cv2.split(cv2_img)
        return cv2.merge((r, g, b))
    # 4通道的BGR图片
    elif len(cv2_img.shape) == 3 and cv2_img.shape[2] == 4 :  # 三位数,三通道+明度
        b, g, r, a = cv2.split(cv2_img)
        return cv2.merge((r, g, b, a))
    # 未知格式
    else :
        return cv2_img


plt.rcParams["font.sans-serif"] = ["SimHei"]  # 显示汉字
plt.figure(figsize=(10, 20))

plt.subplot(421), plt.imshow(bgr2rgb(图片)), plt.title("原图")
plt.subplot(422), plt.imshow(bgr2rgb(图片_灰度), "gray"), plt.title("灰度")

plt.subplot(423), plt.imshow(bgr2rgb(画布1), "gray"), plt.title("a=1,b>0: 颜色发白")
plt.subplot(424), plt.imshow(bgr2rgb(画布2), "gray"), plt.title("a=1,b<0: 颜色发黑")

plt.subplot(425), plt.imshow(bgr2rgb(画布3), "gray"), plt.title("a>1,b=0: 对比度增强")
plt.subplot(426), plt.imshow(bgr2rgb(画布4), "gray"), plt.title("0<a<1,b=0: 对比度减小")

plt.subplot(4, 2, 7), plt.imshow(bgr2rgb(画布5), "gray"), plt.title("a<0,b=255: 暗区域变亮,亮区域变暗")
plt.subplot(4, 2, 8), plt.imshow(bgr2rgb(画布6), "gray"), plt.title("a=-1,b=255: 灰度值反转")

plt.show()

在这里插入图片描述

2.3 分段性 线性变换

分段: 例如ps里面的 锐化里面的蒙版保护
感兴趣的 对比度拉伸,扩展图像中的灰度级范围,从而覆盖设备的理想灰度范围。
[ 实现方案]
①将原始灰度范围拉伸到较宽的灰度范围;
②原始灰度范围拉伸到全域灰度范围(0,255)
③原始灰度范围拉伸到较宽的灰度范围,同时对下限或上限进行截断处理。

== 看不懂 ,跳过==

2.3.1 灰度级分层
  • 灰度级分层可以突出图像中特定的灰度级区间,可以对灰度级进行分层处理。

  • 灰度级分层有两种常用方案:一种方案是二值处理,将感兴趣的灰度级区间设为较大的灰度值,其它区间设为较小的灰度值;另一种方案是窗口处理,将感兴趣的灰度级区间设为较大的灰度值,其它区间不变。

# coding:utf8
import numpy as np
import cv2
from matplotlib import pyplot as plt

# # 1.53 分段线性灰度变换 (灰度级分层)  # Gray layered
imgGray = cv2.imread("lena.jpg", flags=0)  # flags=0 读取为灰度图像
width, height = imgGray.shape[:2]  # 图片的高度和宽度

# Gray layered strategy 1: binary image
a, b = 155, 245  # 突出 [a, b] 区间的灰度
imgLayer1 = imgGray.copy()
imgLayer1[(imgLayer1[:, :] < a) | (imgLayer1[:, :] > b)] = 0  # 区间外:黑色
imgLayer1[(imgLayer1[:, :] >= a) & (imgLayer1[:, :] <= b)] = 255  # 区间内,即灰度级窗口:白色

# Gray layered strategy 2: grayscale image
imgLayer2 = imgGray.copy()
imgLayer2[(imgLayer2[:, :] >= a) & (imgLayer2[:, :] <= b)] = 255  # 灰度级窗口:白色,其它区域不变

plt.figure(figsize=(10, 6))
plt.subplot(131), plt.imshow(imgGray, cmap='gray'), plt.title('Original'), plt.axis('off')
plt.subplot(132), plt.imshow(imgLayer1, cmap='gray'), plt.title('Binary layered'), plt.axis('off')
plt.subplot(133), plt.imshow(imgLayer2, cmap='gray'), plt.title('Grayscale layered'), plt.axis('off')
plt.show()

在这里插入图片描述

2.3.2 比特平面

== 看不懂 ,记录==

  • 像素值也可以表示为二进制形式,对 8bits 二进制数的每一位进行切片,可以得到 8 个比特平面,称为比特平面分层(Bit-plane slicing)。
  • 通常,高阶比特平面包含了大量有视觉意义的数据,而低阶比特平面包含了更精细的灰度细节。因此,比特平面分层可以用于图像压缩和图像重建
# coding:utf8
import numpy as np
import cv2
from matplotlib import pyplot as plt

# # 1.54 分段线性灰度变换 (比特平面分层)  Bit-plane slicing
图像 = cv2.imread("lena.jpg", flags=0)  # flags=0 读取为灰度图像
height, width = 图像.shape[:2]  # 图片的高度和宽度
# imgRec = np.zeros((height, width), dtype=np.uint8)  # 创建零数组

plt.figure(figsize=(10, 8))
for l in range(9, 0, -1) :
    plt.subplot(3, 3, (9 - l) + 1, xticks=[], yticks=[])
    if l == 9 :
        plt.imshow(图像, 'gray'), plt.title('原图')
    else :
        图像_Bit = np.empty((height, width), dtype=np.uint8)  # 创建空数组
        for w in range(width) :
            for h in range(height) :
                x = np.binary_repr(图像[w, h], width=8)  # 以字符串形式返回输入数字的二进制表示形式
                x = x[: :-1]
                a = x[l - 1]
                图像_Bit[w, h] = int(a)  # 第 i 位二进制的值
        plt.imshow(图像_Bit, 'gray')
        plt.title(f"{bin((l - 1))}")
plt.show()

在这里插入图片描述
版权声明:本文为CSDN博主「Python小白进阶」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/youcans/article/details/121191241

2.3.3 对数变换

== 看不懂 ,记录==

  • 线性灰度变换将原始图像灰度值的动态范围按线性关系扩展到指定范围或整个动态范围。

对数变换可以由以下公式描述:

D t = c ∗ l o g ( 1 + D ) Dt = c * log(1+D)
Dt=c∗log(1+D)

对数曲线在像素值较低的区域斜率大,在像素值较高的区域斜率小。对数变换将输入中范围较窄的低灰度值映射为范围较宽的灰度级,输入中的高灰度值则被映射为范围较窄的灰度级。对数变换后,较暗区域的对比度提升,可以增强图像的暗部细节。

对数变换实现了扩展低灰度值而压缩高灰度值的效果,广泛应用于频谱图像的显示中。对数变换的典型应用是傅立叶频谱的动态范围很宽,直接显示时受显示设备动态范围的限制而丢失大量的暗部细节;使用对数变换将图像的动态范围进行非线性压缩后,就可以清晰地显示。
————————————————
版权声明:本文为CSDN博主「Python小白进阶」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/youcans/article/details/121508842

    # 1.55 图像的非线性灰度变换:对数变换
    img = cv2.imread("lena.jpg", flags=0)  # flags=0 读取为灰度图像

    normImg = lambda x: 255. * (x-x.min()) / (x.max()-x.min()+1e-6)  # 归一化
    fft = np.fft.fft2(img)  # 傅里叶变换
    fft_shift = np.fft.fftshift(fft)  # 中心化
    amp = np.abs(fft_shift)  # 傅里叶变换的频谱
    amp = np.uint8(normImg(amp))  # 映射到 [0, 255]
    ampLog = np.abs(np.log(1 + np.abs(fft_shift)))  # 对数变换
    ampLog = np.uint8(normImg(ampLog))  # 映射到 [0, 255]

    plt.figure(figsize=(9, 5))
    plt.subplot(131), plt.imshow(img, cmap='gray', vmin=0, vmax=255), plt.title('Original'), plt.axis('off')
    plt.subplot(132), plt.imshow(amp, cmap='gray', vmin=0, vmax=255), plt.title("FFT spectrum"), plt.axis('off')
    plt.subplot(133), plt.imshow(ampLog, cmap='gray', vmin=0, vmax=255), plt.title("FFT spectrum - log trans"), plt.axis('off')
    plt.tight_layout()
    plt.show()
2.3.4 伽马变换

== 看不懂 ,记录==
线性灰度变换将原始图像灰度值的动态范围按线性关系扩展到指定范围或整个动态范围。

幂律变换也称伽马变换,可以提升暗部细节,对发白(曝光过度)或过暗(曝光不足)的图片进行矫正。

幂律变换可以由以下公式描述:

在这里插入图片描述

伽马变换本质上是对图像矩阵中的每个值进行幂运算。$ 0< \gamma <1$ 时,拉伸图像中灰度级较低的区域,压缩灰度级较高的部分,增加图像的对比度;γ > 1 \gamma >1γ>1 时,拉伸图像中灰度级较高的区域,压缩灰度级较低的部分,降低图像的对比度。
伽马变换通过非线性变换对人类视觉特性进行补偿,最大化地利用有效的灰度级带宽。很多拍摄、显示、打印设备的亮度曲线都符合幂律曲线,因此伽马变换广泛应用于各种设备显示效果的调校,称为伽马校正。
————————————————
版权声明:本文为CSDN博主「Python小白进阶」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/youcans/article/details/121508973

    # 1.56 图像的非线性灰度变换: 幂律变换 (伽马变换)
    img = cv2.imread("../images/imgB2.jpg", flags=0)  # flags=0 读取为灰度图像

    gammaList = [0.125, 0.25, 0.5, 1.0, 2.0, 4.0]  # gamma 值
    normImg = lambda x: 255. * (x-x.min()) / (x.max()-x.min()+1e-6)  # 归一化为 [0,255]

    plt.figure(figsize=(9,6))
    for k in range(len(gammaList)):
        imgGamma = np.power(img, gammaList[k])
        imgGamma = np.uint8(normImg(imgGamma))

        plt.subplot(2, 3, k+1), plt.axis('off')
        plt.imshow(imgGamma,  cmap='gray', vmin=0, vmax=255)
        plt.title(f"$\gamma={gammaList[k]}$")
    plt.show()

在这里插入图片描述

3 直方图

图像直方图是反映图像像素分布的统计表

  • 灰度直方图反映了图像中的灰度分布规律,直观地表现了图像中各灰度级的占比,很好地体现出图像的亮度和对比度信息:灰度图分布居中说明亮度正常,偏左说明亮度较暗,偏右表明亮度较高;狭窄陡峭表明对比度降低,宽泛平缓表明对比度较高。

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

3.1 柱状图
plt.hist(图像.ravel(), 10),plt.title("直方图")
[参数]: 10  柱子数

在这里插入图片描述

	第一步 读入
	第二步 画图  plt.hist(图像.lavel())
	第三步 展示 plt.show
  • 基本型
图像=cv2.imread("cat.jpg",0)  # 0 表示灰度图
plt.hist(图像.ravel(), 10)  # plt.hist(img.ravel()) 直方图
plt.show()		
  • 晋级型
图像=cv2.imread("cat.jpg",0)  # 0 表示灰度图
plt.hist(图像.ravel(), 10)  # plt.hist(img.ravel()) 直方图
plt.title("直方图名字,10柱子")
plt.xlabel("x轴名字")
plt.ylabel("y轴名字")
plt.show()

在这里插入图片描述

3.2 折线图
cv2.calcHist(images,channels,mask,histSize,ranges)
例: cv2.calcHist([图像],[0],None,[10],[0,255])

参数说明:
[0] 第几个通道,
mask 表示掩码,通常生成一部分白色,一部分黑色的掩码图 边框?
[256] 柱子数量
[0, 256] 对应的数字范围
注: 中括号必须的
在这里插入图片描述

	第一步:读图   
	第二步:找点   cv2.calhist([img], [0], None, [256], [0, 256]) 获得每个像素点的频数值
	第三步: 画画    plt.plot  画出直方图
	第四步 展示 plt.show
图像=cv2.imread("cat.jpg",0)  # 0 表示灰度图
折线图=cv2.calcHist([图像],[0],None,[10],[0,255])
plt.plot(折线图)  # 画画
plt.show()
[其他参数] plt.plot(折线图,color="red"),plt.title("折线图")
3.3 彩色通道 折线图

在这里插入图片描述

第一步  读图
第二步  列出三个通道
第三步  用 for in enumerate  历遍循环
第四步 用cv2.calcHist 找点
第五步 用cv2.plot 画图

注意 : plt 列表显示的时候 标题汉字的解决
plt.rcParams[“font.sans-serif”]=[“SimHei”] # 显示汉字

## 读图
图像=cv2.imread("cat.jpg")
## 分色
color=("b","g","r")
## 找点
for 序号,颜色 in enumerate(color):
    三色折线图=cv2.calcHist([图像],[序号],None,[20],[0,255])
    ## 画画
    plt.plot(三色折线图,color=颜色)
plt.show()
3.4 列表综合显示
  imshow 显示图像
  plot  显示折线 
  hist 配合ravel  显示 柱状图
plt.subplot(221),plt.imshow(图像,"gray"),plt.title("原图")  # imshow 显示图像
plt.subplot(222),plt.hist(图像.ravel(),20) ,plt.title("柱状图") #  hist 配合ravel  显示 柱状图
plt.subplot(223),plt.plot(折线图),plt.title("折线图")  # plot  显示折线
plt.subplot(224),plt.plot(三色折线图),plt.title("三线图")

plt.show()

在这里插入图片描述
三色折线图不能循环, 故做函数 引用

# 三色折线图
## 读图
图像=cv2.imread("cat.jpg")
## 分色
color=("b","g","r")
## 找点
def 三色折线图(img):
    for 序号,颜色 in enumerate(color):
        三色折线图=cv2.calcHist([img],[序号],None,[20],[0,255])
        ## 画画
        plt.plot(三色折线图,color=颜色)
    plt.show()

#汇总显示下
plt.subplot(221),plt.imshow(图像,"gray"),plt.title("原图")  # imshow 显示图像
plt.subplot(222),plt.hist(图像.ravel(),20) ,plt.title("柱状图") #  hist 配合ravel  显示 柱状图
plt.subplot(223),plt.plot(折线图),plt.title("折线图")  # plot  显示折线
plt.subplot(224),plt.plot(三色折线图(图像))

plt.show()
3.5 用掩码 mask 删选出部分图像后,做直方图

在这里插入图片描述

	第一步 读图
	# 第二步 生成和原图一样大小的黑色画布  np.zeros 
	第三步 生成掩码 坐标区域内白色,其他为黑色    画布[100:300, 100:400] = 255
	第四步 缝合  cv2.bitwise 
	第五步 找点   分别找点,  cv2.calcHist 
	第六步 画图  
# 第一步 读图
图片 = cv2.imread('cat.jpg',0) #0表示灰度图
# 第二步 生成和原图一样大小的黑色画布
画布 = np.zeros(图片.shape[:2], np.uint8)
# 第三步 生成掩码 坐标区域内白色,其他为黑色
画布[100:300, 100:400] = 255
# 第四步 合成
合成=cv2.bitwise_and(图片,图片,mask=画布)
# 第五步 找点 生成直方图数据    中括号 一定要带
直方图_原图=cv2.calcHist([图片],[0],None,[256],[0,255])
直方图_合成=cv2.calcHist([图片],[0],画布,[256],[0,255])

# 第六步  画画
plt.subplot(221),plt.imshow(图片,"gray")  #  展示图片
plt.subplot(222),plt.imshow(画布,"gray")#  展示图片
plt.subplot(223),plt.imshow(合成,"gray")#  展示图片
plt.subplot(224)
plt.plot(直方图_合成)  #  显示折线
plt.plot(直方图_原图)
plt.grid(color='r', linestyle='--', linewidth=1,alpha=0.3)
plt.show()

4 直方图均衡化

4.1 均衡化

cv2.equalizeHist(img) # 表示进行直方图均衡化

	第一步  读图
	第二步 均衡  cv2.equalizeHist(img)
	第三步  找点 plt.hist 
	第四步 展示  plt.imshow
##  第一步 读图
图片2=cv2.imread("a01.jpg",0)  # 0 表示灰度
## 第二步 均衡化
均衡_图片2=cv2.equalizeHist(图片2)  # 均衡化图片
## 第三步 找点 直方图数据
直方图_图片2=plt.hist(图片2.ravel(),256)  #  直方图数据_原图
直方图_均衡_图片2=plt.hist(均衡_图片2.ravel(),256)   # 直方图数据_均衡化后

代码

# coding:utf8
import numpy as np
import cv2
from matplotlib import pyplot as plt
## 1,读图,并灰度
图片2=cv2.imread("lena.jpg",0)  # 0 表示灰度
## 2,均衡化
均衡_图片2=cv2.equalizeHist(图片2)  # 均衡化图片

plt.rcParams["font.sans-serif"] = ["SimHei"]  # 显示汉字
plt.subplots(constrained_layout=True)  # 子图自适应行距 constrained 受约束的
plt.subplot(221),plt.imshow(图片2),plt.title("原图")
plt.subplot(222),plt.imshow(均衡_图片2),plt.title("均衡_图片2")
## 3,  找点 直方图数据
直方图_图片2=plt.subplot(223),plt.hist(图片2.ravel(),256),plt.title("直方图_图片2")  #  直方图数据_原图
直方图_均衡_图片2=plt.subplot(224),plt.hist(均衡_图片2.ravel(),256),plt.title("直方图_均衡_图片2")   # 直方图数据_均衡化后
plt.show()

在这里插入图片描述

4.2 自适应均衡化

cv2.createCLAHE(clipLimit=2.0,tileGridSize=(8,8))

	第一步  读图
	第二步 自适应化均衡 createCLAHE
	第三步  自适应均衡数据,加载到图片  apply
# 第一步 读图
图片2=cv2.imread("a01.jpg",0)
# 第二步:自适应均衡化
自适应均衡=cv2.createCLAHE(clipLimit=2.0,tileGridSize=(8,8))
# 第三步:自适应均衡化数据 加载到图片
自适应均衡_图片2=自适应均衡.apply(图片2)

4.3 绘图展示

plt.subplots(constrained_layout=True)# 子图自适应行距
plt.subplot(321),plt.imshow(图片2,"gray"),plt.title("原图")
plt.subplot(322),plt.hist(图片2.ravel(),256),plt.title("直方图,原图")

plt.subplot(323),plt.imshow(均衡_图片2,"gray"),plt.title("均衡_图片2")
plt.subplot(324),plt.hist(均衡_图片2.ravel(),256),plt.title("直方图 均衡化")

plt.subplot(325),plt.imshow(自适应均衡_图片2,"gray"),plt.title("自适应均衡化 图片")
plt.subplot(326),plt.hist(自适应均衡_图片2.ravel(),256),plt.title("直方图 自适应均衡")

plt.show()

在这里插入图片描述

4.4 大图展示

展示=np.hstack((图片2,均衡_图片2,自适应均衡_图片2))
cv2.imshow("zhan",展示)
cv2.waitKey(0)

在这里插入图片描述## 7plt 一张图参数:

import matplotlib.pyplot as plt
plt.figure(figsize=(20,8),dpi=90) # 设置画布大小及像素
plt.xticks() # 设置x坐标刻度
plt.yticks() # 设置y坐标刻度
plt.xlabel() # 设置x坐标名
plt.ylabel() # 设置y坐标名
plt.title() # 设置主题
plt.plot() # 画图
plt.legend(loc=’’) # 显示图例"""

  • 13
    点赞
  • 74
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
图像直方图可以使用Python中的OpenCV库中的calcHist函数进行计算。具体实现步骤如下: 1. 导入OpenCV库 ```python import cv2 ``` 2. 读取图像并转换为灰度图像 ```python img = cv2.imread('image.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ``` 3. 计算直方图 ```python hist = cv2.calcHist([gray], [0], None, [256], [0, 256]) ``` 其中,[gray]表示输入的图像,[0]表示通道数,None表示没有使用mask,[256]表示直方图的bin数,[0, 256]表示像素值的范围。 4. 显示直方图 ```python import matplotlib.pyplot as plt plt.plot(hist) plt.show() ``` 5. 选择最佳阈值并二值化图像 根据直方图图像的灰度分布,可以选择一个合适的阈值将图像进行二值化。在这里,我们可以使用OpenCV库中的threshold函数实现。 ```python ret, thresh = cv2.threshold(gray, threshold_value, 255, cv2.THRESH_BINARY) ``` 其中,gray表示输入的灰度图像,threshold_value表示阈值,255表示最大值,cv2.THRESH_BINARY表示二值化类型。 完整代码如下: ```python import cv2 import matplotlib.pyplot as plt # 读取图像并转为灰度图像 img = cv2.imread('image.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 计算直方图 hist = cv2.calcHist([gray], [0], None, [256], [0, 256]) # 显示直方图 plt.plot(hist) plt.show() # 选择最佳阈值并二值化图像 threshold_value = 127 ret, thresh = cv2.threshold(gray, threshold_value, 255, cv2.THRESH_BINARY) # 显示二值化后的图像 cv2.imshow('Binary Image', thresh) cv2.waitKey(0) cv2.destroyAllWindows() ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值