首次完成时间:2024 年 10 月 5 日

给摄像头增加夜视能力

一.实验内容

1. 使用opencv提取图像的直方图数据,并打印。

1)程序代码:
import cv2
im = cv2.imread('cat.png')
# 统计直方图数据
hist = cv2.calcHist([im], [0], None, [256], [0, 255])
print("groups", len(hist))
print("resolutions", sum(hist))
print("total resolutions", im.size)
print("hist: ", hist, end=' ')
2)代码分析:

2. 使用opencv对灰度图进行直方图均衡处理,并显示处理前后的图像。

1)程序代码:
import cv2
import numpy as np
im = cv2.imread("cat.png", 0)
newim = cv2.equalizeHist(im)
cv2.imshow("equalhist", np.hstack([im, newim]))
cv2.waitKey(0)
2)代码分析:

3. 使用pyplot绘制红色星形样式的sin(x)函数曲线。

1)程序代码:
import numpy as np
import matplotlib.pyplot as plt
# 1) 准备数据,arange函数以 0.1为单位,生成 0到 6 的数据
X = np.arange(0, 6, 0.1)
Y = np.sin(X)
# 2) 设置属性
fig = plt.figure()
plt.title("sin()")
plt.xlabel("x")
plt.ylabel("y")
# 3) 绘制图形
plt.plot(X, Y, "r*")
# 4)显示图像
plt.show()
# 5)保存图像
fig.savefig("sin.png")
plt.close(fig)
2)代码分析:

4. 在一个绘图区域分别绘制sin()、cos()、tan()子图。

1)程序代码
import numpy as np
import matplotlib.pyplot as plt
# 准备数据,arange函数以0.1为单位,生成0~6的数据
X = np.arange(0, 6, 0.1)
sinY = np.sin(X)
cosY = np.cos(X)
tanY = np.tan(X)
fig = plt.figure()
# 在 2x2,第1个位置绘制 sin()
plt.subplot(2,2,1)
plt.title("sin()")
plt.plot(X, sinY)
# 在 2x2,第2个位置绘制 cos()
plt.subplot(2,2,2)
plt.title("cos()")
plt.plot(X, cosY)
# 在 2x2,第3个位置绘制 tan()
plt.subplot(2,2,3)
plt.title("tan()")
plt.plot(X, tanY)
# 显示图像
plt.show()
fig.savefig("subplt.jpg")
plt.close(fig)
2)代码分析:

5. 读取一张图片,使用Matplotlib绘制对其进行直方图均衡处理前后的直方图,并比较二者的区别。

1)程序代码:
import cv2
import numpy as np
import matplotlib.pyplot as plt
im = cv2.imread("cat.png", 0)
hist_old = cv2.calcHist([im], [0], None, [256], [0, 255])
histim = cv2.equalizeHist(im)
hist_new = cv2.calcHist([histim], [0], None, [256], [0, 255])

fig = plt.figure()
plt.subplot(2, 2, 1)
plt.title("im_old")
plt.imshow(im, cmap='gray')
plt.subplot(2, 2, 2)
plt.title("hist_old")
plt.plot(hist_old)
plt.subplot(2, 2, 3)
plt.title("im_new")
plt.imshow(histim, cmap='gray')
plt.subplot(2, 2, 4)
plt.title("hist_new")
plt.plot(hist_new)
plt.show()
fig.savefig("im_equhist.jpg")
plt.close(fig)
2)代码分析:

6. 读取一张图片,对其分别进行RGB分量均衡、HIS亮度均衡,并使用Matplotlib分别绘制出两种均衡方法处理前后的直方图。

1)程序代码:
# 【实验六】 分别进行RGB分量均衡、HIS亮度均衡
import cv2
import numpy as np
import matplotlib.pyplot as plt

# 直方图均衡化
def histeq(im):
    """
    对灰度图进行直方图均衡化
    :param im:输入图像
    :return: 返回结果图像
    """
    equ = cv2.equalizeHist(im)
    return equ

def rgb_histeq(im):
    """
    RGB分量均衡法,分别对 3个通道进行处理再合并
    :param im:输入图像
    :return: 返回结果图像
    """
    # 获得 r、g、b分量
    B, G, R = cv2.split(im)
    # 绘制 3个原分量直方图
    single(B, "origin_b", "b", 331)
    single(G, "origin_g", "g", 332)
    single(R, "origin_r", "r", 333)

    # 分别对 3个分量进行直方图均衡化处理
    B_hist = histeq(B)
    G_hist = histeq(G)
    R_hist = histeq(R)

    # 绘制处理后 3个分量的结果直方图
    single(B_hist, "origin_b", "b", 334)
    single(G_hist, "origin_b", "g", 335)
    single(R_hist, "origin_b", "r", 336)

    # 合并分量
    img_hist = im.copy()
    img_hist[:, :, 0] = B_hist
    img_hist[:, :, 1] = G_hist
    img_hist[:, :, 2] = R_hist

    # 绘制原始 3通道直方图
    plt.subplot(337)
    plt.title("Original_HTST")
    image_hist(im)

    # 绘制结果 3通道直方图
    plt.subplot(338)
    plt.title("RGB_HIST")
    image_hist(img_hist)
    plt.show()

    # 显示结果图
    cv2.imshow("rgb_hist", img_hist)
    return img_hist

def hsi_hist(im):
    """
    基于 HIS模型的亮度分量均衡法,对 I分量进行直方图均衡操作
    :param im:输入图像
    :return: 结果图像
    """
    # RGB 转为 HSV
    hsv_im = cv2.cvtColor(im, cv2.COLOR_BGR2HSV)
    # HSV 三通道分离
    H, S, V = cv2.split(hsv_im)
    # 绘制 V通道原直方图
    single(V, "origin_i", "r", 221)
    # 对 V分量进行直方图均衡操作
    V = histeq(V)
    # 绘制 V通道结果直方图
    single(V, "cqu_i", "r", 222)
    # 合并分量
    im_hist = im.copy()
    im_hist[:, :, 0] = H
    im_hist[:, :, 1] = S
    im_hist[:, :, 2] = V
    # HSV 转换回 RGB
    hsv_hist = cv2.cvtColor(im_hist, cv2.COLOR_HSV2RGB)
    # 绘制原图像 3通道直方图
    plt.subplot(223)
    plt.title("Original_HIST")
    image_hist(im)
    # 绘制结果图像 3通道直方图
    plt.subplot(224)
    plt.title("HSI_HIST")
    image_hist(hsv_hist)
    plt.show()
    cv2.imshow("hsi_hist", hsv_hist)
    return hsv_im

def single(image, title, color, place):
    """
    绘制单通道图像的直方图
    :param image: 输入图像
    :param title: 图像标题
    :param color: 图像线条颜色
    :param place: 显示坐标
    """
    # 转换为 uint8 格式
    im = image.astype(np.uint8)
    # 统计直方图数据
    hist = cv2.calcHist([im], [0], None, [256], [0, 255])
    # 绘制子图
    plt.subplot(place)
    plt.title(title)
    plt.plot(hist, color)
    # 设置 x坐标显示范围
    plt.xlim([0, 255])

def image_hist(im):
    """
    绘制 3通道图像的直方图
    :param im:
    """
    color = ("red", "green", "blue")  # 这里笔画颜色的值可以为大写或者小写,或只有首字母,或者大小写混写
    for i, color in enumerate(color):
        hist = cv2.calcHist([im], [i], None, [256], [0, 256])  # 计算直方图
        plt.plot(hist, color)
        plt.xlim([0, 255])

# 包含两个部分
# 1.彩色图像的滤波,方法为将 RGB三个通道分别滤破之后再进行合并的方式,滤破方式包括空间滤破和频域滤波
# 2.彩色图的直方图处理,包括直接将 RGB三通道分别做直方图均衡化和将RGB转换为 HISV,然后仅对 V进行直方图均衡化
# 画出均衡化前后 RGB 三通道的直方图,以及显示直方图均衡化前后的图像
if __name__ == '__main__':
    # 图片读入
    im = cv2.imread("cat.png")
    # 直方图处理
    cv2.imshow("cat", im)
    # 直接对 RGB三通道进行直方图均衡化
    rgb_hist = rgb_histeq(im)
    # 转化到 HSV空间之后对 V值进行直方图均衡化
    hsv_hist = hsi_hist(im)

    cv2.waitKey(0)
    cv2.destroyAllWindows()

2)代码分析:

更多推荐