Python-opencv学习第二十四课:图像直方图


文章目录

  • Python-opencv学习第二十四课:图像直方图
  • 一、学习部分
  • 二、代码部分
  • 1.引入库
  • 2.读入数据
  • 3.完整代码
  • 三、运行结果
  • 总结



一、学习部分

记录笔者学习Python-opencv学习第二十四课:图像直方图,代码资料来源于网络贾老师视频。

二、代码部分

1.引入库

代码如下:

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

2.读入数据

代码如下:

def image_hist():
    image=cv.imread("C:/Users/akaak/Pictures/OpenCV/1.png")
    cv.imshow("input",image)
    color=('blue','green','red')#三通道
    for i,color in enumerate(color):#每个通道循环一次
        hist=cv.calcHist([image],[i],None,[256],[0,256])#计算直方图统计的API函数
        print(hist)#打印
        plt.plot(hist,color=color)
        plt.xlim([0,256])#可改参数【32】
    plt.show()
    cv.waitKey(0)
    cv.destroyAllWindows()

3.完整代码

代码如下:

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


def read_demo_():
    image = cv.imread("C:/Users/akaak/Pictures/OpenCV/1.png")  # BGR 0-255
    cv.imshow("input", image)
    cv.waitKey(0)
    cv.destroyAllWindows()


def color_space_demo_():
    image = cv.imread("C:/Users/akaak/Pictures/OpenCV/1.png")  # BGR 0-255
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)  # 将bgr转换为gray
    hsv = cv.cvtColor(image, cv.COLOR_BGR2HSV)  # 将bgr转换为hsv
    thsv = cv.cvtColor(image, cv.COLOR_HSV2BGR)  # 将HSV转换为BGR
    # cv.namedwindow("input",cv.WINDOW.AUTOSIZE)
    cv.imshow("gray", gray)  # 显示一个窗口名为gray的gray图像
    cv.imshow("hsv", hsv)  # 显示一个窗口名为hsv的hsv图像
    cv.imshow("thsv", thsv)  # 显示一个窗口名为thsv的thsv图像
    cv.waitKey(0)  # 相当于按键操作,当键盘触发时候,显示图片窗口关闭,否则不关闭
    cv.destroyAllWindows()


def mat_demo_():
    image = cv.imread("C:/Users/akaak/Pictures/OpenCV/1.png")  # BGR 0-255
    h, w, c = image.shape  # 打印图像的维度 H高度 W宽度 C通道数,色彩图片有三通道,灰色图片零通道
    roi = image[100:200, 100:200, :]  # 感兴趣局部区域像素分布 H高度100-200像素,W宽度100-200像素。灰度图像就没有最后一个冒号
    blank = np.zeros((h, w, c), dtype=np.uint8)  # 产生一个空白窗口,需要说明H,W,C以及字节数,这是区别于np.zeros_like()函数。
    # blank[60:200, 60:280, :] = image[60:200, 60:280, :]  # blank和image要一致才能匹配
    # blank = np.copy(image)#使用copy函数直接进行复制,将blank上述注释掉
    blank = image  # 实现原图到blank的复制
    cv.imshow("image", image)  # 显示原图窗口
    cv.imshow("blank", blank)  # 显示blank空白窗口
    cv.waitKey(0)  # 相当于按键操作,当键盘触发时候,显示图片窗口关闭,否则不关闭
    cv.destroyAllWindows()


def pixel_demo():
    image = cv.imread("C:/Users/akaak/Pictures/OpenCV/1.png")  # BGR 0-255
    cv.imshow("input", image)
    h, w, c = image.shape  # 打印图像维度
    for row in range(h):  # 行
        for col in range(w):  # 列
            b, g, r = image[row, col]  # 图像写像素
            image[row, col] = (0, g, r)  # 取反操作,可对其进行更改
    cv.imshow("result", image)  # 显示取反后的图片
    cv.imwrite("C:/Users/akaak/Pictures/OpenCV/csdn/4/savedexample.png", image)  # 保存数据图
    cv.waitKey(0)  # 设置关闭窗口
    cv.destroyAllWindows()


def math_demo():
    image = cv.imread("C:/Users/akaak/Pictures/OpenCV/1.png")  # BGR 0-255
    cv.imshow("input", image)
    h, w, c = image.shape  # 打印图像维度
    blank = np.zeros_like(image)  # 创建一个和image同尺寸的blank空白窗口
    blank[:, :] = (2, 2, 2)  # 让blank空白窗口上面的像素都是50x50
    cv.imshow("blank", blank)  # 显示一个blank空白窗口,窗口上面的像素都是50x50
    # result=cv.add(image,blank)#进行加减时候,两幅图像大小必须一致,数据类型可以不用一致(增加亮度变亮)
    # result = cv.subtract(image, blank)  # 进行加减时候,两幅图像大小必须一致,数据类型可以不用一致(减少亮度变黑)
    result = cv.divide(image, blank)  # 改变对比度,对比度降低
    # result = cv.multiply(image, blank)#改变对比度,对比度提高
    cv.imshow("result", result)  # 显示取反后的图片
    # cv.imwrite("C:/Users/akaak/Pictures/OpenCV/csdn/4/savedexample.png", image)#保存数据图
    cv.waitKey(0)  # 设置关闭窗口
    cv.destroyAllWindows()


def nothing(x):
    print(x)


def adjust_light_demo():
    image = cv.imread("C:/Users/akaak/Pictures/OpenCV/1.png")  # BGR 0-255
    cv.namedWindow("input", cv.WINDOW_AUTOSIZE)  # 创建一个自动大小的窗口
    cv.createTrackbar("lightness", "input", 0, 100, nothing)  # 创建一个名为lightness的trackbar,窗口与创建窗口一致。0-100,无回调
    cv.imshow("input", image)
    blank = np.zeros_like(image)  # 创建一个和image同尺寸的blank空白窗口
    while True:
        pos = cv.getTrackbarPos("lightness", "input")  # 拖动第几个TrackBar,TrackBar在哪个窗口。
        blank[:, :] = (pos, pos, pos)  # 让blank空白窗口上面的像素都是50x50
        # cv.imshow("blank", blank)#显示一个blank空白窗口,窗口上面的像素都是50x50
        result = cv.add(image, blank)
        cv.imshow("result", result)  # 显示取反后的图片
        # cv.imwrite("C:/Users/akaak/Pictures/OpenCV/csdn/4/savedexample.png", image)#保存数据图
        c = cv.waitKey(1)  # 设置关闭窗口
        if c == 27:  # Esc
            break
    cv.destroyAllWindows()


def adjust_contrast_demo():
    image = cv.imread("C:/Users/akaak/Pictures/OpenCV/1.png")  # BGR 0-255
    cv.namedWindow("input", cv.WINDOW_AUTOSIZE)  # 创建一个自动大小的窗口
    cv.createTrackbar("lightness", "input", 0, 100, nothing)  # 创建一个名为lightness的trackbar,窗口与创建窗口一致。0-100,无回调
    cv.createTrackbar("contrast", "input", 100, 200, nothing)  # 创建一个名为contrast的trackbar,窗口与创建窗口一致。100-200,无回调
    cv.imshow("input", image)
    blank = np.zeros_like(image)  # 创建一个和image同尺寸的blank空白窗口
    while True:
        # pos=cv.getTrackbarPos("lightness","input")#拖动第几个TrackBar,TrackBar在哪个窗口。
        light = cv.getTrackbarPos("lightness", "input")  # 拖动第几个TrackBar,TrackBar在哪个窗口。亮度
        contrast = cv.getTrackbarPos("contrast", "input") / 100  # 拖动第几个TrackBar,TrackBar在哪个窗口。对比度
        print("light:", light, "contrast:", contrast)  # 打印输出实时light和contrast
        # blank[:,:]=(light,light,light)#让blank空白窗口上面的像素都是50x50
        # cv.imshow("blank", blank)#显示一个blank空白窗口,窗口上面的像素都是50x50
        result = cv.addWeighted(image, contrast, blank, 0.5, light)  # 对比度和亮度调整函数
        cv.imshow("result", result)  # 显示取反后的图片
        # cv.imwrite("C:/Users/akaak/Pictures/OpenCV/csdn/4/savedexample.png", image)#保存数据图
        c = cv.waitKey(1)  # 设置关闭窗口
        if c == 27:  # Esc
            break
    cv.destroyAllWindows()


def keys_demo():
    image = cv.imread("C:/Users/akaak/Pictures/OpenCV/1.png")  # BGR 0-255
    cv.namedWindow("input", cv.WINDOW_AUTOSIZE)  # 创建一个自动大小的窗口
    cv.imshow("input", image)
    while True:
        c = cv.waitKey(1)  # 设置关闭窗口
        gray = image
        if c == 49:  # 1控制gray窗口
            gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
            cv.imshow("result", gray)  # 显示灰度图片
        if c == 50:  # 2控制hsv窗口
            hsv = cv.cvtColor(image, cv.COLOR_BGR2HSV)
            cv.imshow("result", hsv)  # 显示灰度图片
        if c == 51:  # 3控制图像几何操作
            invert = cv.bitwise_not(image)
            cv.imshow("result", invert)  # 显示图片几何操作
        if c == 27:  # Esc关闭所有窗口
            break
    cv.destroyAllWindows()


def color_table_demo():
    colormap = [
        cv.COLORMAP_AUTUMN,
        cv.COLORMAP_BONE,
        cv.COLORMAP_JET,
        cv.COLORMAP_WINTER,
        cv.COLORMAP_RAINBOW,
        cv.COLORMAP_OCEAN,
        cv.COLORMAP_SUMMER,
        cv.COLORMAP_SPRING,
        cv.COLORMAP_COOL,
        cv.COLORMAP_PINK,
        cv.COLORMAP_HOT,
        cv.COLORMAP_PARULA,
        cv.COLORMAP_MAGMA,
        cv.COLORMAP_INFERNO,
        cv.COLORMAP_PLASMA,
        cv.COLORMAP_VIRIDIS,
        cv.COLORMAP_CIVIDIS,
        cv.COLORMAP_TWILIGHT,
        cv.COLORMAP_TWILIGHT_SHIFTED
    ]  # 自带颜色表操作代码19个

    image = cv.imread("C:/Users/akaak/Pictures/OpenCV/1.png")  # BGR 0-255
    cv.namedWindow("input", cv.WINDOW_AUTOSIZE)  # 创建一个自动大小的窗口
    cv.imshow("input", image)
    index = 0
    while True:
        dst = cv.applyColorMap(image, colormap[index] % 19)  # 循环19颜色
        index += 1
        cv.imshow("color style", dst)
        c = cv.waitKey(1000)  # 设置关闭窗口
        if c == 27:  # Esc关闭所有窗口
            break
    cv.destroyAllWindows()


def bitwise_demo():
    b1 = np.zeros((400, 400, 3), dtype=np.uint8)  # 创建一个彩色图片
    b1[:, :] = (255, 0, 255)  # 赋值
    b2 = np.zeros((400, 400, 3), dtype=np.uint8)  # 创建一个彩色图片
    b2[:, :] = (0, 255, 0)  # 赋值
    cv.imshow("b1", b1)
    cv.imshow("b2", b2)

    dst1 = cv.bitwise_and(b1, b2)  # 与
    dst2 = cv.bitwise_or(b1, b2)  # 或

    cv.imshow("bitwise_and", dst1)
    cv.imshow("bitwise_or", dst2)
    cv.waitKey(0)  # 设置关闭窗口
    cv.destroyAllWindows()


def channel_split_demo():
    b1 = cv.imread("C:/Users/akaak/Pictures/OpenCV/1.png")  # BGR 0-255
    print(b1.shape)  # 打印维度
    cv.imshow("input", b1)
    cv.imshow("b1", b1[:, :, 2])
    mv = cv.split(b1)  # 图像分离
    print(len(mv))
    mv[0][:, :] = 255  #
    result = cv.merge(mv)  # 图像合并

    dst = np.zeros(b1.shape, dtype=np.uint8)
    cv.mixChannels([b1], [dst], fromTo=[2, 0, 1, 1, 0, 2])  # 通道混合
    cv.imshow("output4", dst)

    cv.imshow("result", result)
    cv.waitKey(0)  # 设置关闭窗口
    cv.destroyAllWindows()


def colorspace_demo():
    b1 = cv.imread("C:/Users/akaak/Pictures/OpenCV/csdn/12/greenback.jpg")  # BGR 0-255
    print(b1.shape)  # 打印维度
    cv.imshow("input", b1)
    hsv = cv.cvtColor(b1, cv.COLOR_BGR2HSV)  # BGR转换为HSV
    cv.imshow("hsv", hsv)
    mask = cv.inRange(hsv, (35, 43, 46), (77, 255, 255))  # 根据像素范围进行过滤,把符合像素范围的保留,赋成0黑色和1白色(其实就是将绿色背景变成白色背景)
    cv.imshow("mask", mask)
    cv.bitwise_not(mask, mask)  # 取反操作
    result = cv.bitwise_and(b1, b1, mask=mask)  # 原图与mask区域相与(mask大于0的区域)
    cv.imshow("result", result)
    cv.waitKey(0)  # 设置关闭窗口
    cv.destroyAllWindows()


def pixel_stat_demo():
    b1 = cv.imread("C:/Users/akaak/Pictures/OpenCV/1.png")  # BGR 0-255
    print(b1.shape)  # 打印维度
    cv.imshow("input", b1)
    means, dev = cv.meanStdDev(b1)  # 均值与方差
    print(means, "dev:", dev)
    cv.waitKey(0)  # 设置关闭窗口
    cv.destroyAllWindows()


def drawing_demo():
    b1 = cv.imread("C:/Users/akaak/Pictures/OpenCV/1.png")  #
    temp = np.copy(b1)
    cv.rectangle(b1, (140, 50), (260, 210), (0, 0, 255), 4, 8, 0)  # 左上角 右上角 颜色 线宽(<0填充,>0不填充) 领域
    # cv.circle(b1,(200,200),100,(255,0,0),-2,8,0)#中心位置 半径 颜色 线宽 领域
    # cv.line(b1,(50,50),(400,400),(0,255.0),4,8,0)
    # b1[:,:,:]=0#还原
    cv.putText(b1, "99% face", (50, 50), cv.FONT_HERSHEY_SIMPLEX, 1.0, (0, 255, 255), 2, 8)  # 位置坐标 字体 字号 颜色 线宽 领域
    cv.imshow("b1", b1)
    cv.waitKey(0)  # 设置关闭窗口
    cv.destroyAllWindows()


def random_color_demo():
    b1 = np.zeros((512, 512, 3), dtype=np.uint8)
    while True:  # 无休止的绘制
        xx = np.random.randint(0, 512, 2, dtype=np.int)  # 随机位置
        yy = np.random.randint(0, 512, 2, dtype=np.int)  # 随机位置
        bgr = np.random.randint(0, 255, 3, dtype=np.int32)  # 随机颜色
        print(bgr[0], bgr[1], bgr[2])
        cv.line(b1, (xx[0], yy[0]), (xx[1], yy[1]), (np.int(bgr[0]), np.int(bgr[1]), np.int(bgr[2])), 2, 8,
                0)  # 随机位置绘制 随机颜色绘制
        cv.imshow("input", b1)
        c = cv.waitKey(10)  # 设置关闭窗口
        if c == 27:
            break
    cv.destroyAllWindows()


def polyline_drawing_demo():
    canvas = np.zeros((512, 512, 3), dtype=np.uint8)
    pts = np.array([[100, 100], [350, 100], [450, 280], [320, 450], [80, 400]], dtype=np.int32)  # 五个点
    # cv.fillPoly(canvas,[pts],(255,0,255),8,0)#填充多边形
    # cv.polylines(canvas,[pts],True,(0,0,255),2,8,0);#绘制多边形
    cv.drawContours(canvas, [pts], -1, (255, 0, 0), -1)  # 万能操作 集合上个两个API优点 填充+绘制
    cv.imshow("poyline", canvas)
    c = cv.waitKey(0)  # 设置关闭窗口
    cv.destroyAllWindows()


# b1=np.zeros((512,512,3),dtype=np.uint8)
b1 = cv.imread("C:/Users/akaak/Pictures/OpenCV/1.png")
img = np.copy(b1)
x1 = -1
x2 = -1
y1 = -1
y2 = -1


def mouse_drawing(event, x, y, flags, param):  # 回调函数mouse_drawing
    global x1, y1, x2, y2  # 全局变量
    print(x, y)  # 回调函数(给系统)
    if event == cv.EVENT_LBUTTONDOWN:  # 按下
        x1 = x
        y1 = y
    if event == cv.EVENT_MOUSEMOVE:  # 移动
        if x1 < 0 or y1 < 0:
            return
        x2 == x
        y2 = y
        dx = x2 - x1
        dy = y2 - y1
        if dx > 0 or dy > 0:
            b1[:, :, :] = img[:, :, :]
            cv.rectangle(b1, (x1, y1), (x2, y2), (0, 0, 255), 2, 8, 0)  # 绘制矩形
    if event == cv.EVENT_LBUTTONUP:  # 抬起
        x2 == x
        y2 = y
        dx = x2 - x1
        dy = y2 - y1
        if dx > 0 or dy > 0:
            b1[:, :, :] = img[:, :, :]
            cv.rectangle(b1, (x1, y1), (x2, y2), (0, 0, 255), 2, 8, 0)
        x1 = -1  # 重置回原来的初始值
        x2 = -1
        y1 = -1
        y2 = -1


def mouse_demo():
    cv.namedWindow("mouse_demo", cv.WINDOW_AUTOSIZE)  # 创建一个窗口
    cv.setMouseCallback("mouse_demo", mouse_drawing)  # 调用鼠标操作
    while True:
        cv.imshow("mouse_demo", b1)
        c = cv.waitKey(10)
        if c == 27:
            break
    cv.destroyAllWindows()


def norm_demo():
    image = cv.imread("C:/Users/akaak/Pictures/OpenCV/1.png")
    cv.namedWindow("norm_demo", cv.WINDOW_AUTOSIZE)  # 创建一个窗口
    print(image / 255.0)
    # cv.imshow("norm_demo",image/255.0)#归一化演示 浮点数
    # cv.imshow("norm_demo", np.float32(image))#浮点数
    # cv.imshow("norm_demo", np.float32(image) / 255.0)#归一化0-1
    # cv.imshow("norm_demo", np.uint8(image))#正常显示

    # result=np.zeros_like(np.float32(image))
    # cv.normalize(np.float32(image),result,0,1,cv.NORM_MINMAX,dtype=cv.CV_32F)
    # cv.imshow("norm_demo", result)

    result = np.zeros_like(np.float32(image))
    cv.normalize(np.float32(image), result, 0, 1, cv.NORM_MINMAX, dtype=cv.CV_32F)
    cv.imshow("norm_demo", np.uint8(result * 255))  # 浮点数变字节 深度学习
    cv.waitKey(0)
    cv.destroyAllWindows()


def resize_demo():
    image = cv.imread("C:/Users/akaak/Pictures/OpenCV/1.png")
    h,w,c=image.shape
    cv.namedWindow("resize_demo", cv.WINDOW_AUTOSIZE)  # 创建一个窗口
    dst=cv.resize(image,(w//h,h//2),interpolation=cv.INTER_NEAREST)#放缩与插值
    dst = cv.resize(image,(0,0),fx=0.75,fy=0.75,interpolation=cv.INTER_NEAREST)  # 指定大小放缩与插值
    cv.imshow("resize_demo", dst)
    cv.waitKey(0)
    cv.destroyAllWindows()

def flip_demo():
    image = cv.imread("C:/Users/akaak/Pictures/OpenCV/1.png")
    cv.namedWindow("flip_demo", cv.WINDOW_AUTOSIZE)  # 创建一个窗口
    #dst=cv.flip(image,0)#0上下翻转
    #dst = cv.flip(image, 1)  # 1左右翻转
    dst = cv.flip(image, -1)  # -1对角线翻转
    cv.imshow("image", image)
    cv.imshow("flip_demo", dst)
    cv.waitKey(0)
    cv.destroyAllWindows()

def rotate_demo():
    src=cv.imread("C:/Users/akaak/Pictures/OpenCV/1.png")
    cv.imshow("image",src)
    h,w,c=src.shape
    #定义矩阵
    M=np.zeros((2,3),dtype=np.float32)
    #定义角度
    alpha=np.cos(np.pi/4.0)
    beta=np.sin(np.pi/4.0)
    print("alpha:",alpha)
    #初始化矩阵
    M[0,0]=alpha
    M[1,1] =alpha
    M[0,1] =beta
    M[1,0] =-beta
    cx=w/2
    cy=h/2
    tx=(1-alpha)*cx-beta*cy
    ty=beta*cx+(1-alpha)*cy
    M[0,2] = tx
    M[1,2] = ty

    #change with full size
    bound_w=int(h*np.abs(beta)+w*np.abs(alpha))
    bound_h = int(h * np.abs(alpha) + w * np.abs(beta))

    #添加中心位置迁移
    M[0, 2] +=bound_w/2-tx
    M[1, 2] +=bound_h/2-ty
    dst=cv.warpAffine(src,M,(bound_w,bound_h))
    cv.imshow("rotate without cropping",dst)

    cv.waitKey(0)
    cv.destroyAllWindows()

def video_demo():
    cap=cv.VideoCapture("C:/Users/akaak/Videos/01.mp4")#读视频 通过摄像头/路径
    w=cap.get(cv.CAP_PROP_FRAME_WIDTH)#获取宽度
    h=cap.get(cv.CAP_PROP_FRAME_HEIGHT)#获取高度
    fps=cap.get(cv.CAP_PROP_FPS)#获取帧率:1s中播放多少张图像

    #out=cv.VideoWriter("C:/Users/akaak/Videos/TEST.mp4",cv.VideoWriter_fourcc('P','I','M','1'),fps,(np.int(w),np.int(h)),True)
    out=cv.VideoWriter("C:/Users/akaak/Videos/TEST.mp4", cv.CAP_ANY,np.int(cap.get(cv.CAP_PROP_FOURCC)),fps,(np.int(w),np.int(h)),True)
    #out = cv.VideoWriter("C:/Users/akaak/Videos/TEST.mp4", cv.CAP_FFMPEG, np.int(cap.get(cv.CAP_PROP_FOURCC)), fps,(np.int(w), np.int(h)), True)#没有test生成
    print(w,h,fps)
    while True:
        ret,frame=cap.read()
        #frame=cv.flip(frame,1)
        if ret is not True:#读完视频自动关闭
            break
        cv.imshow("frame",frame)
        hsv=cv.cvtColor(frame,cv.COLOR_BGR2HSV)#hsv转换
        cv.imshow("result",hsv)#显示hsv
        out.write(hsv)#保存
        c=cv.waitKey(10)
        if c==27:
            break

    cv.destroyAllWindows()

    out.release()#写完释放
    cap.release()#相机用完也释放


def image_hist():
    image=cv.imread("C:/Users/akaak/Pictures/OpenCV/1.png")
    cv.imshow("input",image)
    color=('blue','green','red')#三通道
    for i,color in enumerate(color):#每个通道循环一次
        hist=cv.calcHist([image],[i],None,[256],[0,256])#计算直方图统计的API函数
        print(hist)#打印
        plt.plot(hist,color=color)
        plt.xlim([0,256])#可改参数【32】
    plt.show()
    cv.waitKey(0)
    cv.destroyAllWindows()

if __name__ == "__main__":
    image_hist()

三、运行结果

python从excel读数据绘制直方图 python读取csv数据画直方图_计算机视觉


python从excel读数据绘制直方图 python读取csv数据画直方图_python_02


python从excel读数据绘制直方图 python读取csv数据画直方图_计算机视觉_03

总结

本文介绍了笔者学习Python-opencv第二十四课:图像直方图,学习了cv.calcHist([image],[i],None,[256],[0,256])函数实现了对图片直方图统计的API函数的操作。