[opencv][python] 学习手册2:练习代码2

[opencv][python] 学习手册2:练习代码2

26_灰度图的直方图.py
27_灰度直方图api.py
28_灰度图的直方图均衡化.py
29_灰度图直方图均衡化-api.py
30_彩色图像的直方图.py
31_彩色图像直方图均衡化.py




26_灰度图的直方图.py

概念

在统计学中,直方图(英语:Histogram)是一种对数据分布情况的图形表示,是一种二维统计图表,它的两个坐标分别是统计样本(横坐标)和该样本对应的某个属性的度量(纵坐标),以长条图(bar)的形式具体表现。因为直方图的长度及宽度很适合用来表现数量上的变化,所以较容易解读差异小的数值。(wiki)

在灰度图直方图中,统计样本(横坐标)是灰度值的分布范围(对 np.uint8 类型,0-255),样本统计值(纵坐标)是每一个灰度值在图像中出现的总次数。

代码

"""
需求:
统计灰度图中每一个灰度值出现的次数
并绘制灰度值次数直方图

1.读取图像,获取信息
2.定义一个0-255的容器,x轴:灰度值,y轴:出现次数
3.统计
4.绘制直方图
"""

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

# 1.读取图像,获取信息
filename = r"../img/lena.jpg"
src = cv.imread(filename, cv.IMREAD_COLOR)
src_gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
height = src.shape[0]
width = src.shape[1]

# 2.定义一个0-255的容器,x轴:灰度值,y轴:出现次数
statistic_array = np.zeros(256, np.int)

# 3.统计
for row in range(height):
    for col in range(width):
        color = src_gray[row, col]
        statistic_array[color] += 1

# 4.绘制直方图
x = np.linspace(0, 255, 256)
y = statistic_array
plt.bar(x, y, width=0.8, color="red")

cv.imshow("src", src)

plt.show()
cv.waitKey(0)

运行结果
在这里插入图片描述


27_灰度直方图api.py

代码

"""
需求:
统计灰度图中每一个灰度值出现的次数
并绘制灰度值次数直方图

1.读取图像,获取信息
2.使用 cv 的 api calcHist 绘制直方图
3.使用 plt 的 hist 绘制直方图
"""

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

# 1.读取图像,获取信息
filename = r"../img/lena.jpg"
src = cv.imread(filename, cv.IMREAD_COLOR)
src_gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)

# 2.使用 cv 的 api calcHist 绘制直方图
# # 1. 计算直方图
hist = cv.calcHist([src_gray], [0], None, [256], [0, 256])
# # 2. 绘制直方图
plt.figure()
plt.plot(hist, color="red")

# 3.使用 plt 的 hist 绘制直方图
# print(src_gray.shape)  # (400, 400)
# print(src_gray.ravel().shape)  # (160000,), A 1-D array, containing the elements of the input, is returned. np.ravel
plt.figure()
plt.hist(src_gray.ravel(), bins=256, rwidth=0.8)

plt.show()

运行结果
在这里插入图片描述
补充

使用matplotlib绘制直方图有两种方式

方式一:
    # 使用api将直方图数据计算好 图片 通道  掩膜  数量  值的范围
    hist = cv.calcHist([grayImg],[0],None,[256],[0.0,255.0])
    # 调用plot函数显示
    plt.plot(hist,color="green")
    plt.show()
方式二:
    # 1.使用Img.ravel()将多行的矩阵转成单行的矩阵
    # 2. 然后调用matplot的hist函数自动计算直方图,bins表示像素区间数量
    plt.hist(grayImg.ravel(),color="red",bins=256)
    plt.show()

28_灰度图的直方图均衡化.py

概念

  • 直方图均衡化是将原图象的直方图通过变换函数修正为均匀的直方图,然后按均衡直方图修正原图象。图象均衡化处理后,图象的直方图是平直的,即各灰度级具有相同的出现频数,那么由于灰度级具有均匀的概率分布,图象看起来就更清晰了。
  • 经过直方图均衡化处理之后,我们整个图像的颜色变化就是一种平滑变化的状态

代码

"""
需求:
对灰度图像进行手动直方图均衡化
不借助 api,全手工

算法:
1. 计算图像的直方图(颜色统计报告,x:颜色值,y:颜色出现次数)
2. 计算概率直方图(x:颜色值,y:次数概率 = 次数 / 像素总数),通过直方图
3. 计算累积概率直方图,通过概率直方图
4. 对图像进行均衡化,old_color -> sum_ration ->_new color

步骤:
1. 读取图像,获取信息,转化成灰度图
2. 直方图均衡化
3. 显示图像,等待按键

"""

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

# 1. 读取图像,获取信息,转化成灰度图
filename = r"../img/lena.jpg"
src = cv.imread(filename, cv.IMREAD_COLOR)
gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
height = src.shape[0]
width = src.shape[1]

# 2. 直方图均衡化
# # 1. 计算图像的直方图(颜色统计报告,x:颜色值,y:颜色出现次数)
# color_count = np.zeros(256, np.int)
hist = np.zeros(256, np.int)

for row in range(height):
    for col in range(width):
        color = gray[row, col]
        hist[color] += 1

fig1 = plt.figure()
fig1.canvas.set_window_title('histogram')
x = np.linspace(0, 255, 256)
y = hist
plt.bar(x, y, color="red")

# # 2. 计算概率直方图(x:颜色值,y:次数概率 = 次数 / 像素总数),通过直方图
total_pix = height * width
hist_ratio = hist / total_pix

fig2 = plt.figure()
fig2.canvas.set_window_title('histogram_ratio')
x = np.linspace(0, 255, 256)
y = hist_ratio
plt.bar(x, y, color="orange")

# # 3. 计算累积概率直方图,通过概率直方图
hist_ratio_accum = np.zeros(256, np.float)

for i in range(256):
    if i == 0:
        hist_ratio_accum[i] = hist_ratio[i]
    else:
        hist_ratio_accum[i] += (hist_ratio_accum[i - 1] + hist_ratio[i])

fig3 = plt.figure()
fig3.canvas.set_window_title('histogram_ratio_accum')
x = np.linspace(0, 255, 256)
y = hist_ratio_accum
plt.bar(x, y, color="blue")

# # 4. 对图像进行均衡化,old_color -> sum_ration ->_new color
dst = np.zeros((height, width), np.uint8)

for row in range(height):
    for col in range(width):
        old_color = gray[row, col]
        old_color_ratio_accum = hist_ratio_accum[old_color]
        new_color = np.uint(old_color_ratio_accum * 255)
        dst[row, col] = new_color

# # 5. 计算 dst 的直方图
hist_dst = np.zeros(256, np.int)

for row in range(height):
    for col in range(width):
        color = dst[row, col]
        hist_dst[color] += 1

fig4 = plt.figure()
fig4.canvas.set_window_title('histogram_dst')
x = np.linspace(0, 255, 256)
y = hist_dst
plt.bar(x, y, color="green")

# 3. 显示图像,等待按键
cv.imshow("src", src)
cv.imshow("gray", gray)
cv.imshow("dst", dst)
plt.show()

key = cv.waitKey(1)
print("key = ", key)

运行结果
在这里插入图片描述
在这里插入图片描述
优化代码

"""
需求:
对灰度图像进行手动直方图均衡化
不借助 api,全手工

算法:
1. 计算图像的直方图(颜色统计报告,x:颜色值,y:颜色出现次数)
2. 计算概率直方图(x:颜色值,y:次数概率 = 次数 / 像素总数),通过直方图
3. 计算累积概率直方图,通过概率直方图
4. 对图像进行均衡化,old_color -> sum_ration ->_new color

步骤:
1. 读取图像,获取信息,转化成灰度图
2. 直方图均衡化
3. 显示图像,等待按键

"""

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

"""------------------------- 函数代码区 -------------------------"""


def histogram_equalization(gray, name):
    global row, col, color, x, y, dst
    # # 1. 计算图像的直方图(颜色统计报告,x:颜色值,y:颜色出现次数)
    hist = calc_histogram(gray, name)
    # # 2. 计算概率直方图(x:颜色值,y:次数概率 = 次数 / 像素总数),通过直方图
    hist_ratio = calc_histogram_ratio(hist, name)
    # # 3. 计算累积概率直方图,通过概率直方图
    hist_ratio_accum = calc_histogram_ratio_accu(hist_ratio, name)
    # # 4. 对图像进行均衡化,old_color -> sum_ration ->_new color
    # dst = np.zeros((height, width), np.uint8)
    do_equalization(dst, gray, hist_ratio_accum)


def do_equalization(dst, gray, hist_ratio_accum):
    global row, col
    for row in range(height):
        for col in range(width):
            old_color = gray[row, col]
            old_color_ratio_accum = hist_ratio_accum[old_color]
            new_color = np.uint(old_color_ratio_accum * 255)
            dst[row, col] = new_color


def calc_histogram_ratio_accu(hist_ratio, name):
    global x, y
    hist_ratio_accum = np.zeros(256, np.float)
    for i in range(256):
        if i == 0:
            hist_ratio_accum[i] = hist_ratio[i]
        else:
            hist_ratio_accum[i] += (hist_ratio_accum[i - 1] + hist_ratio[i])
    fig3 = plt.figure()
    fig3.canvas.set_window_title('histogram_ratio_accum_{0}'.format(name))
    x = np.linspace(0, 255, 256)
    y = hist_ratio_accum
    plt.bar(x, y, color="blue")
    return hist_ratio_accum


def calc_histogram_ratio(hist, name):
    global x, y
    total_pix = height * width
    hist_ratio = hist / total_pix
    fig2 = plt.figure()
    fig2.canvas.set_window_title('histogram_ratio_{0}'.format(name))
    x = np.linspace(0, 255, 256)
    y = hist_ratio
    plt.bar(x, y, color="orange")
    return hist_ratio


def calc_histogram(gray, name):
    global row, col, color, x, y
    # color_count = np.zeros(256, np.int)
    hist = np.zeros(256, np.int)
    for row in range(height):
        for col in range(width):
            color = gray[row, col]
            hist[color] += 1
    fig1 = plt.figure()
    fig1.canvas.set_window_title('histogram_{0}'.format(name))
    x = np.linspace(0, 255, 256)
    y = hist
    plt.bar(x, y, color="red")
    return hist


"""------------------------- 测试代码区 -------------------------"""

# 1. 读取图像,获取信息,转化成灰度图
filename = r"../img/lena.jpg"
src = cv.imread(filename, cv.IMREAD_COLOR)
gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
height = src.shape[0]
width = src.shape[1]

# 2. src-gray 直方图均衡化
dst = np.zeros((height, width), np.uint8)
histogram_equalization(gray, "src")

# # 5. 计算 dst 的直方图
hist_dst = calc_histogram(dst, "dst")

# # 6. 计算 dst 的累积直方图
hist_dst_ratio = calc_histogram_ratio(hist_dst, "dst")
hist_dst_ratio_accu = calc_histogram_ratio_accu(hist_dst_ratio, "dst")

# 3. 显示图像,等待按键
cv.imshow("src", src)
cv.imshow("gray", gray)
cv.imshow("dst", dst)
plt.show()

key = cv.waitKey(1)
print("key = ", key)

运行结果

在这里插入图片描述


29_灰度图直方图均衡化-api.py

代码

"""
需求:
1. 读取灰度图
2. 绘制灰度图直方图
3. 直方图均衡化,equalizeHist api
4. 绘制直方图
5. 显示图像,等待按键
"""

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


# 1. 读取灰度图
filename = r"../img/lena.jpg"
gray = cv.imread(filename, cv.IMREAD_GRAYSCALE)

# 2. 绘制灰度图直方图
fig1 = plt.figure()
fig1.canvas.set_window_title("hist_gray")
plt.hist(gray.ravel(), bins=256)

# 3. 直方图均衡化,equalizeHist api
dst = cv.equalizeHist(gray)

# 4. 绘制直方图
fig2 = plt.figure()
fig2.canvas.set_window_title("hist_dst")
plt.hist(dst.ravel(), bins=256)

# 5. 显示图像,等待按键
cv.imshow("gray", gray)
cv.imshow("dst", dst)
plt.show()

key = cv.waitKey(0)
print("key = ", key)

运行结果
在这里插入图片描述
在这里插入图片描述


30_彩色图像的直方图.py

代码

"""
需求:
1. 读取彩色图像
2. 拆分图像 split
3. 分别统计 BGR 通道直方图,使用 api
"""

import cv2 as cv
import matplotlib.pyplot as plt

# 1. 读取彩色图像
filename = r"../img/lena.jpg"
src = cv.imread(filename, cv.IMREAD_COLOR)

# 2. 拆分图像 split
channels = cv.split(src)
colors = ["blue", "green", "red"]

# 3. 分别统计 BGR 通道直方图,使用 api
for i in range(3):
    fig = plt.figure()
    fig.canvas.set_window_title("hist_{0}".format(colors[i]))
    plt.hist(channels[i].ravel(), bins=256, color=colors[i], rwidth=0.8)

plt.show()

运行结果
在这里插入图片描述


31_彩色图像直方图均衡化.py

代码

"""
需求:
1. 读取彩色图像
2. 拆分图像 split
3. 对每个通道进行均衡化 equalizeHist api
4. 再将均衡化的单通道进行融合 merge api
"""

import cv2 as cv
import matplotlib.pyplot as plt

# 1. 读取彩色图像
filename = r"../img/lena.jpg"
src = cv.imread(filename, cv.IMREAD_COLOR)

# 2. 拆分图像 split
channels = cv.split(src)

# # 3. 对每个通道进行均衡化 equalizeHist api
cb_eq = cv.equalizeHist(channels[0])
cg_eq = cv.equalizeHist(channels[1])
cr_eq = cv.equalizeHist(channels[2])

# 4. 再将均衡化的单通道进行融合 merge api
c3_eq = cv.merge([cb_eq, cg_eq, cr_eq])

# 5. 显示图像,等待按键
cv.imshow("src", src)
cv.imshow("c3_eq", c3_eq)

# fig = plt.figure()
# fig.canvas.set_window_title("c3_equalize")
# plt.hist(c3_eq.ravel(), bins=256, histtype="barstacked")

plt.figure()
plt.hist(cb_eq.ravel(), bins=256, color="blue", histtype="stepfilled")

plt.figure()
plt.hist(cg_eq.ravel(), bins=256, color="green", histtype="stepfilled")

plt.figure()
plt.hist(cr_eq.ravel(), bins=256, color="red", histtype="stepfilled")


plt.show()

key = cv.waitKey(0)
print("key = ", key)

运行结果
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这个问题可能是因为安装的opencv-python版本不兼容你使用的Python版本。你可以尝试以下解决方案: 1. 确认你是否安装了正确版本的opencv-python,可以通过pip list命令查看已安装的包列表,并检查opencv-python的版本是否正确。 2. 如果你使用的是Python3.x版本,可以尝试使用以下命令安装opencv-python: ``` pip3 install opencv-python ``` 3. 如果你使用的是Python2.x版本,可以尝试使用以下命令安装opencv-python: ``` pip install opencv-python==3.4.2.17 ``` 注意,这里指定的版本号可能需要根据你的Python版本和操作系统进行调整。 如果以上解决方案无法解决问题,你可以尝试卸载并重新安装opencv-python,或者考虑使用其他图像处理库。 ### 回答2: 安装了opencv-python模块后出现"ModuleNotFoundError: No module named 'cv2'"的错误是因为找不到cv2模块。 出现这个错误的原因可能有以下几种: 1. 安装的opencv-python版本不兼容:请确保安装的opencv-python模块与您的Python版本兼容。如果您的Python版本是3.x,建议安装opencv-python 4.x版本;如果您的Python版本是2.x,建议安装opencv-python 3.x版本。 2. 安装路径问题:在某些情况下,安装的opencv-python模块可能没有正确地被Python解释器找到。您可以尝试重新安装模块并确保将模块安装到正确的Python解释器路径下。 3. Python环境变量问题:如果您的Python环境变量没有配置正确,可能会导致Python解释器无法找到安装的模块。您可以尝试在安装路径中查找cv2模块文件,并将其路径添加到Python环境变量中。 解决这个问题的方法: 1. 确认您的Python版本,并选择与之对应的opencv-python版本进行安装。 2. 检查并重新安装opencv-python模块。可以通过pip命令安装:打开命令提示符或终端窗口,运行以下命令:pip install opencv-python。 3. 检查Python解释器的路径配置。可以通过在命令提示符或终端窗口中运行以下命令来找到安装的模块路径:python -c "import cv2; print(cv2.__file__)" 如果以上方法都没有解决问题,您可以尝试去官方网站或相关技术论坛搜索相关错误信息,也可以尝试卸载并重新安装一个新的Python版本以及opencv-python模块来解决该问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值