CV(4)--边缘提取和相机模型

前言

仅记录学习过程,有问题欢迎讨论

边缘提取(涉及语义分割):

图象的边缘是指图象局部区域亮度变化显著的部分,也有正负之分,暗到亮为正

  • 求边缘的幅度:sobel,Canny算子

  • 图像分高频分量和低频分量,高频分量就是灰度变化剧烈的地方(显眼)

图像锐化:目的是使图像的边缘更加清晰,细节部分更加突出,常用拉普拉斯变化核函数。

边缘检测的步骤:边缘检测就是提取高频分量。在边缘像素值会出现"跳跃"或者较大的变化

  1. 滤波:边缘检测的算法主要是基于图像强度的一阶和二阶导数(为0,一阶极值),但导数通常对噪声很敏感,
    所以采用滤波减弱噪声。常见的滤波方法主要有高斯滤波。
  2. 增强:增强边缘的基础是确定图像各点邻域强度的变化值并凸显出显著变化点。
  3. 检测:经过增强的图像,往往邻域中有很多点的梯度值比较大,可以采用用阈值化方法来检测方法来对这些点进行取舍。

Canny边缘检测算法:

  1. 灰度化后高斯滤波:消除噪声
    高斯卷积核大小影响Canny检测的性能,越大,检测对噪声敏感越低,定位误差也会增大,5*5还行

  2. 检测图像的水平/垂直边缘:计算梯度---Sobel算子
    用类似于-1,0,1-2,0,2-1,0,1的矩阵来求梯度的幅值,幅值较大的像素点的为边缘

  3. 非极大值抑制:去除边缘检测带来的杂散响应

    • 搜素局部最大值,抑制非极大值,去除冗余的边缘。通俗就是找到像素局部最大值,其他值置为0,就可以剔除大部分非边缘点。
    • 沿着梯度方向比较像素点的值,保留最大像素点
  4. 双阈值检测和连接边缘:滞后阈值法

    • 大于高阈值为强边缘,小于低阈值不是边缘。介于中间是弱边缘。
    • 阈值的选择取决于给定输入图像的内容,和噪声点的区别就是是否连续:

相机模型(实际就是坐标系转化):

针孔相机模型存在四个坐标系:世界坐标系、摄像机坐标系、图像物理坐标系和图像像素坐标系。

  • 世界坐标系的坐标为Pw(Xw,Yw,Zw),
  • 对应的摄像机坐标系坐标为Po(x,y,z),--齐次方程做坐标系变化
  • 对应的图像物理坐标系的坐标为P'(x',y'),--相似三角的原理等比例
  • 对应的图像像素坐标系的坐标为p(u,v)。--转化为长度为像素单位!

镜头畸变

  • 畸变是由于透镜形状和制造工艺的误差造成的,分为径向畸变和切向畸变。
  • 径向畸变是由于透镜形状的曲线造成,分为枕形畸变和桶形畸变。
  • 切向畸变是由于透镜制造工艺的误差造成的,分为对称畸变和非对称畸变。
  • 可以通过透视变化(投影为新平面)来矫正畸变图片
    通过4个点(两组x,y)来确定关系,然后投影新平面图片

Canny算法和透视变化

py 复制代码
"""
1-实现canny算法

2-实现透视变换
"""
import cv2
import numpy as np

# 实现Canny
def CannyDemo(img, low, high):
    # 灰度化
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # 高斯滤波
    blur = cv2.GaussianBlur(gray, (5, 5), 0)
    # 采用sobel 算子求梯度[x,y方向求梯度,找出变化最大的像素点]
    grad_x = cv2.Sobel(blur, cv2.CV_16S, 1, 0, ksize=3)
    grad_y = cv2.Sobel(blur, cv2.CV_16S, 0, 1, ksize=3)
    # 转回uint8
    abs_grad_x = cv2.convertScaleAbs(grad_x)
    abs_grad_y = cv2.convertScaleAbs(grad_y)
    # 合并梯度
    dst = cv2.addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0)
    # 非极大值抑制
    dst = cv2.Canny(dst, low, high)
    return dst


# 实现透视变化
def getWarpPerspectiveMatrix(img, dst):
    nums = img.shape[0]
    x = np.zeros((2 * nums, 8))  # x*warpMatrix=y
    y = np.zeros((2 * nums, 1))
    for i in range(0, nums):
        x_i = src[i, :]
        y_i = dst[i, :]
        x[2 * i, :] = [x_i[0], x_i[1], 1, 0, 0, 0,
                       -x_i[0] * y_i[0], -x_i[1] * y_i[0]]
        y[2 * i] = y_i[0]

        x[2 * i + 1, :] = [0, 0, 0, x_i[0], x_i[1], 1,
                           -x_i[0] * y_i[1], -x_i[1] * y_i[1]]
        y[2 * i + 1] = y_i[1]
    x = np.mat(x)
    # 用x.I求出x的逆矩阵,然后与y相乘,求出warpMatrix
    matrix = x.I * y  # 求出a_11, a_12, a_13, a_21, a_22, a_23, a_31, a_32

    # 之后为结果的后处理
    matrix = np.array(matrix).T[0]
    matrix = np.insert(matrix, matrix.shape[0], values=1.0, axis=0)  # 插入a_33 = 1
    matrix = matrix.reshape((3, 3))
    return matrix


if __name__ == '__main__':
    img = cv2.imread('lenna.png')

    # canny边缘检测
    # canny = CannyDemo(img, 50,150)
    # cv2.imshow('canny', canny)
    # cv2.waitKey(0)

    # 实现透视变化
    img1 = cv2.imread('photo1.jpg')
    src = np.float32([[207, 151], [517, 285], [17, 601], [343, 731]])
    dst = np.float32([[0, 0], [337, 0], [0, 488], [337, 488]])
    print(img.shape)
    # 生成透视变换矩阵;进行透视变换
    result = getWarpPerspectiveMatrix(src, dst)
    print("warpMatrix:")
    print(result)
    img_perspective = cv2.warpPerspective(img1, result, (337, 488))
    cv2.imshow("img_perspective", img_perspective)
    cv2.waitKey(0)
相关推荐
我没胡说八道4 小时前
高校论文AI检测优化工具对比研究与实测分析(2026)
人工智能·深度学习·机器学习·计算机视觉·aigc·论文
探物 AI6 小时前
把 MambaOut 塞进 YOLOv11:会有什么样的反应
python·yolo·计算机视觉
_李小白10 小时前
【android opencv学习笔记】Day 32:直线检测之霍夫变换
android·opencv·学习
我最爱吃鱼香茄子13 小时前
终极方案:JetBrains IDE永久解放C盘空间
计算机视觉·性能优化·电脑·笔记本电脑·intellij-idea·程序员创富·webstorm
玖釉-13 小时前
Vulkan 离屏渲染详解:从 Framebuffer 到后处理、阴影贴图与 Render Texture
c++·windows·计算机视觉·图形渲染
路人甲32614 小时前
SONIC: Supersizing Motion Tracking for Natural Humanoid Whole-Body Control
人工智能·深度学习·计算机视觉·机器人·具身智能
程序员正茂15 小时前
EasyAR使用OpenCV下USB摄像头作为自定义相机
opencv·unity·easyar
_李小白15 小时前
【android opencv学习笔记】Day 31:提取轮廓之Canny算法
android·opencv·学习
armwind15 小时前
openISP学习8-GC — Gamma Correction(Gamma 校正)
图像处理·计算机视觉
大江东去浪淘尽千古风流人物15 小时前
【VGGT-Ω】前馈式3D重建的规模化之路:Register Attention、自监督训练与10B参数Scaling Law深度解析
深度学习·计算机视觉·transformer·slam·vio·3d重建