云计算百科
云计算领域专业知识百科平台

opencv计算机视觉--图形旋转&图形可视化&均衡化

一、图形旋转

1. NumPy的np.rot90()方法

  • 功能:专门用于90度倍数的旋转

  • 参数k的含义:

    • k=1:逆时针旋转90度

    • k=-1:顺时针旋转90度

    • k=2:旋转180度(顺时针或逆时针效果相同)

    • k=3:顺时针旋转270度(等同于逆时针90度)

  • 特点:

    • 通过数组转置和翻转实现

    • 只能做90度的整数倍旋转

    • 旋转中心是图像中心

import cv2
import numpy as np

# 方法一
img = cv2.imread('./kele.png')
# 旋转90度,k=-1表示顺时针旋转90度
rotated_image1 = np.rot90(img, k=-1)
# 旋转90度,k=1表示逆时针旋转90度
rotated_image2 = np.rot90(img, k=1)

cv2.imshow('yuantu', img)
cv2.waitKey(0)
cv2.imshow('rotated_image1', rotated_image1)
cv2.waitKey(0)
cv2.imshow('rotated_image2', rotated_image2)
cv2.waitKey(0)
cv2.destroyAllWindows()

2. OpenCV的cv2.rotate()方法

  • 功能:提供标准化的旋转操作

  • 三种预定义旋转模式:

    • cv2.ROTATE_90_CLOCKWISE:顺时针90度

    • cv2.ROTATE_90_COUNTERCLOCKWISE:逆时针90度

    • cv2.ROTATE_180:旋转180度

  • 特点:

    • 接口更直观

    • 底层可能优化了性能

    • 语义更清晰

import cv2
import numpy as np
img = cv2.imread('./kele.png')
cv2.imshow('yuan',img)
cv2.waitKey(0)
rotated_image = cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE) # 顺时针90度
rotated_image1 = cv2.rotate(img, cv2.ROTATE_90_COUNTERCLOCKWISE) # 逆时针90度
rotated_image2 = cv2.rotate(img, cv2.ROTATE_180) # 旋转180度
cv2.imshow('shun90', rotated_image)
cv2.waitKey(0)
cv2.imshow('ni90', rotated_image1)
cv2.waitKey(0)
cv2.imshow('180', rotated_image2)
cv2.waitKey(0)
cv2.destroyAllWindows()

3.旋转的数学概念

1. 二维旋转矩阵

对于90度旋转,数学上对应:

  • 顺时针90度:(x', y') = (y, -x)

  • 逆时针90度:(x', y') = (-y, x)

  • 180度:(x', y') = (-x, -y)

2. 图像坐标系
  • OpenCV图像坐标系:原点在左上角

  • x轴向右为正,y轴向下为正

  • 旋转时需要考虑坐标系方向

3.两种方法的区别
特性np.rot90()cv2.rotate()
灵活性 可通过k参数控制任意90度倍数旋转 只有三种固定模式
可读性 参数需要记忆(k的正负含义) 语义更明确
性能 NumPy数组操作,通常很快 OpenCV优化,可能更快
适用性 适合需要动态计算旋转次数的场景 适合固定的标准旋转
4.注意事项
  • 插值问题:这两种方法都是精确的90度倍数旋转,不需要插值计算

  • 边界处理:旋转后图像边界完整保留

  • 颜色通道:RGB/BGR颜色通道信息完全保留

  • 内存布局:旋转后像素数据重新排列,但数值不变

  • 二、图形可视化

    1、可视化层次分析

    1)像素级数据可视化
    • people.ravel():将二维图像矩阵展平为一维数组

    • 把图像的空间结构信息转换为数值分布信息

    • 这是从空间域到统计域的转换

    2) 统计分布可视化(直方图)
    • 直方图展示像素值的频率分布

    • bins(区间)的概念:256个区间 vs 16个区间

      • 256 bins:精细分布,显示每个像素值的具体频率

      • 16 bins:概览分布,显示像素值范围的趋势

    2、颜色通道可视化

    color=('b','g','r') # 蓝、绿、红

    • 通道分离:将彩色图像的BGR通道分别提取

    • 颜色编码:用对应通道颜色绘制其直方图

    • 多变量对比:同时展示三个相关变量的分布

    3、空间选择性可视化(掩码技术)

    区域选择的可视化:
  • 掩码创建:定义感兴趣区域(ROI)

  • 区域提取:bitwise_and操作隔离特定区域

  • 局部统计:只分析选定区域的像素分布

  • 这种可视化体现了:
    • 全局vs局部对比分析

    • 空间约束下的数据分布

    • 交互式分析的思想:用户可以定义分析区域

    4、可视化传达的信息

    通过直方图可以判断:
  • 图像对比度:直方图的宽度

  • 图像亮度:直方图的中心位置

  • 曝光情况:是否集中在某一段

  • 颜色平衡:各通道分布是否均衡

  • 图像质量:是否有过多噪声(毛刺)

  • import cv2
    import matplotlib.pyplot as plt
    import numpy as np
    people=cv2.imread('peopleone.jpg',cv2.IMREAD_GRAYSCALE)
    a=people.ravel()

    plt.hist(a,bins=256)
    plt.show()
    people_hist=cv2.calcHist([people],[0],None,[16],[0,256])
    plt.plot(people_hist)
    plt.show()

    img=cv2.imread('peopleone.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.show()

    people=cv2.imread('peopleone.jpg',cv2.IMREAD_GRAYSCALE)
    cv2.imshow('people',people)
    cv2.waitKey(0)

    mask=np.zeros(people.shape[:2],np.uint8)
    mask[50:600,50:700]=255
    cv2.imshow('mask',mask)
    cv2.waitKey(0)

    people_mask=cv2.bitwise_and(people,people,mask=mask)
    cv2.imshow('peolpe_mask',people_mask)
    cv2.waitKey(0)

    people_hist_mask=cv2.calcHist([people],[0],mask,[256],[0,256])
    plt.plot(people_hist_mask)
    plt.show()
    cv2.destroyAllWindows()

    三、整体目标

    通过直方图均衡化技术改善图像对比度,展示全局和局部均衡化的效果差异。

    1.核心概念:直方图均衡化

    基本原理:

    重新分布图像像素的强度值,使直方图在整个强度范围内更加均匀,从而增强图像对比度。

    2.代码执行流程分析

    1. 读取和显示原始图像直方图

    renwu = cv2.imread('renwu.jpg', cv2.IMREAD_GRAYSCALE)
    plt.hist(renwu.ravel(), bins=256)

    • 读取灰度图像

    • 显示原始像素强度分布

    • 通常低对比度图像的直方图会集中在某个狭窄范围内

    2. 全局直方图均衡化

    renwu_equalize = cv2.equalizeHist(renwu)
    plt.hist(renwu_equalize.ravel(), bins=256)

    • cv2.equalizeHist():对整个图像应用均衡化

    • 效果:将原始直方图拉伸到整个0-255范围

    • 缺点:可能过度增强某些区域的对比度,丢失细节

    3. 可视化对比

    res = np.hstack((renwu, renwu_equalize))

    • 并排显示原图和处理后图像

    • 直观展示对比度改善效果

    4. 自适应直方图均衡化(局部处理)

    clahe = cv2.createCLAHE(clipLimit=10, tileGridSize=(8, 8))
    renwu_clahe = clahe.apply(renwu)

    • CLAHE(Contrast Limited Adaptive Histogram Equalization)

    • 工作原理:

      • 将图像分成多个小区域(tileGridSize指定,如8×8网格)

      • 对每个小区域独立进行直方图均衡化

      • 使用clipLimit限制对比度增强程度,防止噪声过度放大

    5. 最终对比展示

    res = np.hstack((renwu, renwu_equalize, renwu_clahe))

    • 同时显示:原始图像、全局均衡化、自适应均衡化

    • 直观比较三种处理效果

    完整代码

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

    # 读取灰度图像
    renwu = cv2.imread('renwu.jpg', cv2.IMREAD_GRAYSCALE)

    # 显示原图直方图
    plt.hist(renwu.ravel(), bins=256) # numpy中的ravel将数组多维度拉成一维数组
    plt.show()

    # 全局直方图均衡化
    renwu_equalize = cv2.equalizeHist(renwu)

    # 显示均衡化后的直方图
    plt.hist(renwu_equalize.ravel(), bins=256)
    plt.show()

    # 对比原图和均衡化后的图像
    res = np.hstack((renwu, renwu_equalize)) # 横向拼接
    cv2.imshow('renwu_rese', res)
    cv2.waitKey(0)

    # 自适应直方图均衡化(局部直方图处理)
    # 当需要保存细节特征,需要做局部处理
    # clipLimit: 颜色对比度的阈值,可选项,默认值 8
    # tileGridSize: 局部直方图均衡化的模板(邻域)大小,可选项,默认值 (8,8)
    clahe = cv2.createCLAHE(clipLimit=10, tileGridSize=(8, 8)) # 创建局部均衡化对象
    renwu_clahe = clahe.apply(renwu)

    # 对比三种图像
    res = np.hstack((renwu, renwu_equalize, renwu_clahe))
    cv2.imshow('renwu_equalize', res)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    3、两种方法的对比

    特性全局均衡化自适应均衡化(CLAHE)
    处理范围 整个图像 局部小区域
    对比度控制 无限制 有限制(clipLimit)
    细节保留 可能丢失 较好保留
    噪声影响 可能放大噪声 受控放大
    适用场景 整体低对比度图像 局部对比度差异大的图像

    4.关键参数说明

    1. clipLimit
    • 对比度限制阈值

    • 防止局部区域对比度过度增强

    • 值越大,对比度增强越强

    • 默认值2-3,这里设为10(较强增强)

    2. tileGridSize
    • 划分图像的小区域大小

    • (8, 8)表示将图像分为8×8=64个小区域

    • 每个小区域独立进行均衡化

    5.实际应用效果

    处理后的直方图特征:
  • 全局均衡化:直方图大致均匀分布在整个0-255范围

  • 自适应均衡化:保持了原始直方图的某些特征,但整体更加均衡

  • 视觉改善:
  • 暗部细节显现:原本太暗的区域变亮

  • 亮部细节恢复:原本太亮的区域变暗

  • 整体对比度提升:图像更加清晰

  • 赞(0)
    未经允许不得转载:网硕互联帮助中心 » opencv计算机视觉--图形旋转&图形可视化&均衡化
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!