参考课程:

黑马程序员 OpenCV入门教程】

[https://www.bilibili.com/video/BV1Fo4y1d7JL]

@ZZHow(ZZHow1024)

1.1几何变换

  • 图像缩放

    • 对图像的大小进行调整,即使图像放大或缩小
    cv2.resize(src, dsize, fx=0, fy=0, interpolation=cv2.INTER_LINEAR)
    
    • 参数
      • src:输入图像

      • dsize:绝对尺寸,直接指定调整后图像的大小

      • fx, fy:相对尺寸,将 dsize 设置为 None,然后将 fx 和 fy 设置为比例因子即可

      • interpolation:插值方法

        插值含义
        cv2.INTER_LINEAR双线性插值法
        cv2.INTER_NEAREST量近邻插值
        cv2.INTER_AREA像素区域重采样**(默认)**
        cv2.INTER_CUBIC双三次插值
  • 图像平移

    • 将图像按照指定方向和距离,移动到相应的位置
    cv2.warpAffine(image, M, dsize)
    
    • 参数
      • image:输入图像
      • M:2 × 3 移动矩阵
        • 对于 (x,y)(x, y)(x,y) 处的像素点,要把它移动到 (x+tx,y+ty)(x + t_x, y + t_y)(x+tx,y+ty) 处时,MMM 矩阵应如下设置

          M=[10tx01ty]M = \begin{bmatrix} 1 & 0 & t_x \\ 0 & 1 & t_y \end{bmatrix}M=[1001txty]

        • 注意:将 MMM 设置为 np.float32 类型的 NumPy 数组

      • dsize:输出图像的大小
    • 注意:输出图像的大小应该是 (宽度, 高度) 的形式,width=列数,height=行数
  • 图像旋转

    • 将图像按照某个位置转动一定角度的过程,旋转中图像仍保持这原始尺寸

    • 假设图像逆时针旋转 θ\thetaθ,则根据坐标转换可得旋转转换为

      {x′=rcos(α−θ)y′=rsin(α−θ)\begin{cases}   x' = r cos(\alpha - \theta) \\   y' = r sin(\alpha - \theta)\end{cases}{  x=rcos(αθ)  y=rsin(αθ)

      其中 r=x2+y2,sinα=yx2+y2,cosα=xx2+y2r = \sqrt{x^2 + y^2}, sin\alpha = \frac{y}{\sqrt{x^2 + y^2}}, cos\alpha = \frac{x}{\sqrt{x^2 + y^2}}r=x2+y2,sinα=x2+y2y,cosα=x2+y2x

      代入公式有

      {x′=xcosθ+ysinθy′=−xsinθ+ycosθ\begin{cases} x' = x cos\theta + y sin\theta \\ y' = -x sin\theta + ycos\theta\end{cases}{x=xcosθ+ysinθy=xsinθ+ycosθ

      也可以写成

      [x′y′1]=[xy1][cosθ−sinθ0sinθcosθ0001]\begin{bmatrix}   x' & y' & 1\end{bmatrix} = \begin{bmatrix}   x & y & 1\end{bmatrix}\begin{bmatrix}   cos\theta & -sin\theta & 0 \\   sin\theta & cos\theta & 0 \\   0 & 0 & 1\end{bmatrix}[  xy1] = [  xy1]  cosθ  sinθ  0sinθcosθ0001

      原点修正

      [x′′y′′1]=[x′y′1][1000−10lefttop1]=[xy1][cosθ−sinθ0sinθcosθ0001][1000−10lefttop1]\begin{bmatrix}   x'' & y'' & 1\end{bmatrix} = \begin{bmatrix}   x' & y' & 1\end{bmatrix}\begin{bmatrix}   1 & 0 & 0 \\   0 & -1 & 0 \\   left & top & 1\end{bmatrix} = \begin{bmatrix}   x & y & 1\end{bmatrix}\begin{bmatrix}   cos\theta & -sin\theta & 0 \\   sin\theta & cos\theta & 0 \\   0 & 0 & 1\end{bmatrix}\begin{bmatrix}   1 & 0 & 0 \\   0 & -1 & 0 \\   left & top & 1\end{bmatrix}[  x′′y′′1] = [  xy1]  1  0  left01top001 = [  xy1]  cosθ  sinθ  0sinθcosθ0001  1  0  left01top001

    cv2.getRotationMatrix2D(center, angle, scale)
    
    • 参数
      • center:旋转中心
      • angle:旋转角度
      • scale:缩放比例
    • 返回
      M:旋转矩阵,调用 cv.warpAffine() 完成图像的旋转
  • 仿射变换

    • 图像的仿射变换涉及到图像的形状位置角度的变化,是深度学习预处理中常到的功能,仿射变换主要是对图像的缩放,旋转,翻转和平移等操作的组合

    • 在OpenCV中,仿射变换的矩阵是一个 2 × 3 的矩阵

      M=[AB]=[a00a01b0a10a11b1]M = \begin{bmatrix}   A & B\end{bmatrix} = \begin{bmatrix}   a_{00} & a_{01} & b_0 \\   a_{10} & a_{11} & b_1 \\\end{bmatrix}M = [  AB] = [  a00  a10a01a11b0b1]

    • 其中左边的 2 × 2 子矩阵 AAA 是线性变换矩阵,右边的 2 × 1 子矩阵 BBB 是平移项

      A=[a00a01a10a11],B=[b0b1]A = \begin{bmatrix}   a_{00} & a_{01} \\   a_{10} & a_{11} \\\end{bmatrix},B = \begin{bmatrix}   b_0 \\   b_1 \\\end{bmatrix}A = [  a00  a10a01a11],B = [  b0  b1]

    • 对于图像上的任一位置 (x,y)(x, y)(x,y),仿射变换执行的是如下的操作

      Taffine=A[xy]+B=M[xy1]T_{affine} =A\begin{bmatrix}   x \\   y \\\end{bmatrix} + B = M\begin{bmatrix}   x \\   y \\   1 \\\end{bmatrix}Taffine =A[  x  y] + B = M  x  y  1

    • 注意:对于图像而言,宽度方向是 x,高度方向是 y,坐标的顺序和图像像素对应下标一致,原点的位置不是左下角而是右上角,y 的方向也不是向上,而是向下

    • 在 OpenCV 中 cv2.getAffineTransform 会创建一个 2 × 3 的矩阵,最后这个矩阵会被传给函数 cv2.warpAffine

  • 透射变换

    • 透射变换是视角变化的结果,是指利用透视中心、像点、目标点三点共线的条件,按透视旋转定律使承影面(透视面)绕迹线(透视轴)旋转某一角度,破坏原有的投影光线束,仍能保持承影面上投影几何图形不变的变换

    • 它的本质将图像投影到一个新的视平面,其通用变换公式为

      [x′y′z′]=[uvw][a00a01a02a10a11a12a20a21a22]\begin{bmatrix}   x' & y' & z'\end{bmatrix} = \begin{bmatrix}   u & v & w\end{bmatrix}\begin{bmatrix}   a_{00} & a_{01} & a_{02} \\   a_{10} & a_{11} & a_{12} \\   a_{20} & a_{21} & a_{22} \\\end{bmatrix}[  xyz] = [  uvw]  a00  a10  a20a01a11a21a02a12a22

      其中,(u,v)(u, v)(u,v) 是原始的图像像素坐标,www 取值为 1,(x=x′/z′,y=y’/z’)(x = x' / z', y = y’ / z’)(x=x/z,y=y’/z) 是透射变换后的结果

      后面的矩阵称为透视变换矩阵,一般情况下,我们将其分为三部分

      T=[a00a01a02a10a11a12a20a21a22]=[T1T2T3a22]T = \begin{bmatrix}   a_{00} & a_{01} & a_{02} \\   a_{10} & a_{11} & a_{12} \\   a_{20} & a_{21} & a_{22} \\\end{bmatrix} = \begin{bmatrix}   T_1 & T_2 \\   T_3 & a_{22} \\\end{bmatrix}T =   a00  a10  a20a01a11a21a02a12a22 = [  T1  T3T2a22]

      其中,T1T_1T1 表示对图像进行线性变换,T2T_2T2 对图像进行平移,T3T_3T3 表示对图像进行投射变换,a22a_{22}a22 一般设为 1

    • 在 OpenCV 中,我们要找到四个点,其中任意三个不共线,然后获取变换矩阵 TTT,再进行透射变换

      • 通过函数 cv2.getPerspectiveTransform 找到变换矩阵,将 cv2.warpPerspective 应用于此 3 × 3 变换矩阵
  • 图像金字塔

    • 图像多尺度表达的一种,最主要用于图像的分割,是一种以多分辨率来解释图像的有效但概念简单的结构
    • 金字塔的底部是待处理图像的高分辨率表示,而顶部是低分辨率的近似,层级越高,图像越小,分辨率越低
    cv2.pyrUp(image) # 对图像进行上采样
    cv2.pyrDown(image) # 对图像进行下采样
    
  • 案例演示:geometric_transformation.ipynb

1.2形态学操作

  • 连通性

    • 在图像中,最小的单位是像素,每个像素周围有 8 个邻接像素,常见的邻接关系有 3 种
      • 4 邻接:像素 p(x,y)p(x, y)p(x,y) 的 4 邻域是:(x+1,y);(x−1,y);(x,y+1);(x,y−1)(x+1, y); (x-1, y); (x, y+1); (x, y-1)(x+1,y);(x1,y);(x,y+1);(x,y1),用 N4(P)N_4(P)N4(P) 表示像素 ppp 的 4 邻接
      • 8 邻接:像素 p(x,y)p(x, y)p(x,y) 的 8 邻域是:4 邻域的点 + D 邻域的点,用 N8(p)N_8(p)N8(p) 表示像素 p 的 8 邻域
      • D 邻接:像素 p(x,y)p(x, y)p(x,y) 的 D 邻域是:(x+1,y+1);(x−1,y−1);(x−1,y+1);(x+1,y−1)(x+1, y+1); (x-1, y-1); (x-1, y+1); (x+1, y-1)(x+1,y+1);(x1,y1);(x1,y+1);(x+1,y1),用 ND(P)N_D(P)ND(P) 表示像素 pppDDD 邻接
    • 连通性是描述区域和边界的重要概念,两个像素连通的两个必要条件是
      1. 两个像素的位置是否相邻
      2. 两个像素的灰度值是否满足特定的相似性准则
    • 根据连通性的定义,有 4 联通、8 联通和 mmm 联通三种
      • 4 连通:对于具有值 VVV 的像素 pppqqq,如果 qqq 在集合 N4(p)N_4(p)N4(p) 中,则称这两个像素是 4 连通
      • 8 连通:对于具有值 VVV 的像素 pppqqq,如果 qqq 在集合 N8(p)N_8(p)N8(p) 中,则称这两个像素是 8 连通
      • mmm 连通:对于具有值 VVV 的像素 pppqqq,如果 qqq 在集合 N4(p)N_4(p)N4(p) qqq 在集合 ND(p)N_D(p)ND(p) 中,并且 N4(P)N_4(P)N4(P)N4(g)N_4(g)N4(g) 的交集为空(没有值 VVV 的像素),则称这两个像素是 mmm 连通的,即 4 连通和 DDD 连通的混合连通
  • 腐蚀和膨胀

    • 腐蚀:时原图中的高亮区域被蚕食,效果图拥有比原图更小的高亮区域,是求局部最小值的操作

    • 膨胀:使图像中高亮部分扩张,效果图拥有比原图更大的高亮区域,是求局部最大值的操作

    • 腐蚀

      • 用一个结构元素扫描图像中的每一个像素,用结构元素中的每一个像素与其覆盖的像素做“”操作,如果都为 1,则该像素为 1,否则为 0
      cv2.erode(image, kernel, iterations)
      
      • 参数
        • image:要处理的图像
        • kernel:核结构
        • iterations:腐蚀的次数,默认是 1
    • 膨胀

      • 用一个结构元素扫描图像中的每一个像素,用结构元素中的每一个像素与其覆盖的像素做“”操作,如果都为 0,则该像素为 0,否则为 1
      cv2.dilate(image, kernel, iterations)
      
      • 参数
        • image:要处理的图像
        • kernel:核结构
        • iterations:腐蚀的次数,默认是 1
  • 开闭运算

    • 开运算
      • 开运算是先腐蚀后膨胀
      • 作用:分离物体,消除小区域
      • 特点:消除噪点,去除小的干扰块,而不影响原来的图像
    • 闭运算
      • 与开运算相反,是先膨胀后腐蚀
      • 作用:是消除/闭合物体里面的孔洞
      • 特点:可以填充闭合区域
    cv2.morphologyEx(image, op, kernel)
    
    • 参数
      • img:要处理的图像
      • op:处理方式,开运算 cv.MORPH_OPEN,闭运算 cv.MORPH_CLOSE
      • kernel:核结构
  • 礼帽和黑帽

    • 礼帽运算
      • 原图像与 “开运算“ 的结果图之差
      • 数学表达式:dst=tophat(src,element)=src−open(src,element)dst = tophat(src, element) = src - open(src, element)dst=tophat(src,element)=srcopen(src,element)
      • 作用:
        • 用来分离比邻近点亮一些的斑块
        • 当一幅图像具有大幅的背景的时候,而微小物品比较有规律的情况下,可以使用顶帽运算进行背景提取
    • 黑帽运算
      • ”闭运算“ 的结果图与原图像之差
      • 数学表达式:dst=blackhat(src,element)=close(src,element)−srcdst = blackhat(src, element) = close(src, element) - srcdst=blackhat(src,element)=close(src,element)src
      • 作用:用来分离比邻近点暗一些的斑块
    cv2.morphologyEx(image, op, kernel)
    
    • 参数
      • image:要处理的图像

      • op:处理方式

        参数功能
        cv.MORPH_CLOSE闭运算
        cv.MORPH_OPEN开运算
        cv.MORPH_TOPHAT礼帽运算
        cv.MORPH_BLACKHAT黑帽运算
      • kernel:核结构

  • 案例演示:morphological_operations.ipynb

1.3图像平滑

  • 图像噪声
    • 椒盐噪声(脉冲噪声)
      • 是一种随机出现的白点或者黑点,可能是亮的区域有黑色像素或是在暗的区域有白色像素(或是两者皆有)
      • 成因:影像讯号受到突如其来的强烈干扰而产生、类比数位转换器或位元传输错误等
        • 例如
          • 失效的感应器导致像素值为最小值
          • 饱和的感应器导致像素值为最大值
    • 高斯噪声(正态噪声)
      • 是指噪声密度函数服从高斯分布的一类噪声
      • 高斯随机变量 zzz 的概率密度函数:p(z)=12πσe−(z−μ)22σ2p(z) = \frac{1}{\sqrt{2\pi}σ} e^{\frac{-(z - μ)^2}{2σ^2}}p(z)=2πσ1e2σ2(zμ)2
        • 其中,zzz 表示灰度值, 表示 zzz 的平均值或期望值,σσσ 表示 zzz 的标准差;标准差的平方 σ2σ^2σ2 称为 zzz 的方差
  • 滤波器
    • 均值滤波

      • 采用均值滤波模板对图像噪声进行滤除
      • SxyS_{xy}Sxy 表示中心在 (x,y)(x, y)(x,y) 点,尺寸为 m×nm×nm×n 的矩形子图像窗口的坐标
      • 数学表达式:f^(x,y)=1mn∑(s,t)∈Sxyg(s,t)\hat{f}(x, y) = \frac{1}{mn}\sum_{(s, t) ∈ S_{xy}}g(s, t)f^(x,y)=mn1(s,t)Sxyg(s,t)
      • 优点:算法简单,计算速度较快
      • 缺点:去噪的同时去除了很多细节部分,将图像变得模糊
      cv2.blur(src, ksize, anchor, borderType)
      
      • 参数
        • src:输入图像
        • ksize:卷积核的大小
        • anchor:默认值 (−1,−1)(-1, -1)(1,1),表示核中心
        • borderType:边界类型
    • 高斯滤波

      • 二维高斯是构建高斯滤波器的基础
      • 概率分布函数:G(x,y)=12πσ2exp{−x2+y22σ2}G(x, y) = \frac{1}{2\piσ^2}exp\{-\frac{x^2 + y^2}{2σ^2}\}G(x,y)=2πσ21exp{2σ2x2+y2}
      • 高斯平滑在从图像中去除高斯噪声方面非常有效
      • 高斯平滑的流程
        1. 确定权重矩阵
        2. 计算高斯模糊
      cv2.GaussianBlur(src, ksize, sigmaX, sigmaY, borderType)
      
      • 参数
        • src:输入图像
        • ksize:高斯卷积核的大小
          • 注意:卷积核的宽度和高度都应为奇数,且可以不同
        • sigmaX:水平方向的标准差
        • sigmaY:垂直方向的标准差,默认值为 0,表示与 sigmaX 相同
        • borderType:填充边界类型
    • 中值滤波

      • 中值滤波是一种典型的非线性滤波技术,基本思想是用像素点邻域灰度值的中值来代替该像素点的灰度值
      • 中值滤波对椒盐噪声来说尤其有用,因为它不依赖于邻域内那些与典型值差别很大的值
      cv2.medianBlur(src, ksize)
      
      • 参数
        • src:输入图像
        • ksize:卷积核的大小
  • 案例演示:image_smoothing.ipynb

1.4直方图

  • 灰度直方图

    • 原理

      • 直方图是对数据进行统计的一种方法,并且将统计值组织到一系列实现定义好的 bin 当中
        • 其中,bin 为直方图中经常用到的一个概念,可以译为直条组距,其数值是从数据中计算出的特征统计量,这些数据可以是诸如梯度、方向、色彩或任何其他特征
      • 注意:直方图是根据灰度图进行绘制的,而不是彩色图像
      • 直方图的一些术语细节
        • dims:需要统计的特征数目
        • bins:每个特征空间子区段的数目,可译为直条组距
        • range:要统计特征的取值范围
      • 直方图的意义
        • 直方图是图像中像素强度分布的图形表达方式
        • 它统计了每一个强度值所具有的像素个数
        • 不同的图像的直方图可能是相同的
    • 直方图的计算和绘制

      • 使用 OpenCV 中的方法统计直方图,并使用 matplotlib 将其绘制出来
      cv2.calcHist([image], [channel], mask, [histSize], [range])
      
      • image:原图像,当传入函数时应该用中括号口括起来
      • channel:通道
        • 如果输入图像是灰度图,它的值就是[1]
        • 如果是彩色图像的话,传入的参数可以是 [0], [1], [2] 它们分别对应着通道 B, G, R
      • mask:掩模图像
      • histSize:bin 的数目
      • range:像素值范围,通常为 [0, 256]
  • 掩膜的应用

    • 掩膜是用选定的图像、图形或物体,对要处理的图像进行挡,来控制图像处理的区域
    • 用途
      • 提取感兴趣区域
      • 屏蔽作用
      • 结构特征提取
      • 特殊形状图像制作
  • 直方图均衡化

    • 原理:把原始图像的灰度直方图从比较集中的某个灰度区间变成在更广泛灰度范围内的分布
    • 应用:扩大图像像素值的分布范围,提高图像的对比度
    cv2.equalizeHist(image)
    
    • 参数
      • image:灰度图像
  • 自适应的直方图均衡化

    • 对整个图像进行直方图均衡化效果并不好
    • 自适应的直方图均衡化:整幅图像被分成很多小块,这些小块被称为 tiles(在 OpenCV 中 tiles 的大小默认是 8 × 8),然后再对每一个小块分别进行直方图均衡化,最后为了去除每一个小块之间的边界,再使用双线性差值对每一小块进行拼接
    cl = cv2.createCLAHE(clipLimit, tileGridSize)
    result = cl.apply(image)
    
    • createCLAHE 参数
      • clipLimit:对比度限制,默认是 40
      • tileGridSize:分块的大小,默认为 8 × 8
    • apply 参数
      • image:灰度图像
  • 案例演示:histogram.ipynb

1.5边缘检测

  • 概述

    • 目的:标识数字图像中亮度变化明显的点
    • 作用:大幅度地减少了数据量,并且剔除了可以认为不相关的信息,保留了图像重要的结构属性
    • 边缘检测方法
      • 基于搜索
        • 通过寻找图像一阶导数中的最大值来检测边界,然后利用计算结果估计边缘的局部方向,通常采用梯度的方向,并利用此方向找到局部梯度模的最大值
        • 代表算法:Sobel 算子和 Scharr 算子
      • 基于零穿越
        • 通过寻找图像二阶导数零穿越来寻找边界
        • 代表算法:Laplacian 算子
  • Sobel 算子

    • Sobel 边缘检测算法比较简单,实际应用中效率比 Canny 效率更高,但是边缘不如Canny 检测的准确
    • 注意:当内核大小为 3 时,Sobel 内核可能产生比较明显的误差,为解决这一问题,我们使用 Scharr 函数,但该函数仅作用于大小为 3 的内核
    • Scharr 函数该函数的运算与 Sobel 函数一样快,但结果却更加精确
    cv2.Sobel(src, ddepth, dx, dy, dst, ksize, scale, delta, borderType)
    
    • 参数
      • src:传入的图像
      • ddepth:图像的深度
      • dx 和 dy:指求导的阶数,0 表示这个方向上没有求导,取值为0、1
      • ksize:是 Sobel 算子的大小,即卷积核的大小,必须为奇数 1、3、5、7,默认为 3
        • 注意:如果 ksize=-1,就演变成为 3 × 3 的 Scharr 算子
      • scale:缩放导数的比例常数,默认情况为没有伸缩系数
      • borderType:图像边界的模式,默认值为 cv2.BORDER_DEFAULT
    Scale_abs = cv2.convertScaleAbs(x) # 格式转换
    result = cv2.addWeighted(src1, alpha, src2, beta) # 图像混合
    
  • Laplacian 算子

    • Laplacian 是利用二阶导数来检测边缘
    cv2.Laplacian(src, ddepth, ksize)
    
    • 参数
      • src:需要处理的图像
      • ddepth:图像的深度,-1 表示采用的是原图像相同的深度,目标图像的深度必须大于等于原图像的深度
      • ksize:算子的大小,即卷积核的大小,必须为 1, 3, 5, 7
  • Canny 边缘检测

    • Canny 边缘检测算法是一种非常流行的边缘检测算法,是 John F. Canny 于 1986 年提出的,被认为是最优的边缘检测算法
    • 原理
      1. 噪声去除:高斯滤波
      2. 计算图像梯度:sobel 算子,计算梯度大小和方向
      3. 非极大值抑制:利用梯度方向像素来判断当前像素是否为边界点
      4. 滞后阈值:设置两个阈值,确定最终的边界
    cv2.Canny(image, threshold1, threshold2)
    
    • 参数
      • image:灰度图
      • threshold1:minval,较小的阈值将间断的边缘连接起来
      • threshold2:maxval,较大的阈值检测图像中明显的边缘
  • 案例演示:edge_detection.ipynb

1.6模板匹配

  • 在给定的图片中查找和模板最相似的区域,该算法的输入包括模板和图片,整个任务的思路就是按照滑窗的思路不断的移动模板图片,计算其与图像中对应区域的匹配度,最终将匹配度最高的区域选择为最终的结果
cv2.matchTemplate(image, template, method)
  • 参数
    • img:要进行模板匹配的图像
    • template:模板
    • method:实现模板匹配的算法
      1. 平方差匹配(cv.TM_SQDIFF):利用模板与图像之间的平方差进行匹配,最好的匹配是 0,匹配越差,匹配的值越大
      2. 相关匹配(cv.TM_CCORR):利用模板与图像间的乘法进行匹配,数值越大表示匹配程度较高,越小表示匹配效果差
      3. 利用相关系数匹配(cv.TM_CCOEFF):利用模板与图像间的相关系数匹配,1 表示完美的匹配,-1 表示最差的匹配
  • 完成匹配
    • 使用 cv.minMaxLoc 方法查找最大值所在的位置即可
    • 如果使用平方差作为比较方法,则最小值位置是最佳匹配位置
  • 案例演示:template_matching.ipynb

1.7霍夫变换

  • 霍夫变换常用来提取图像中的直线和圆等几何形状

  • 霍夫线检测

    cv2.HoughLines(image, rho, theta, threshold)
    
    • 参数
      • img:检测的图像,要求是二值化的图像,所以在调用霍夫变换之前首先要进行二值化,或者进行 Canny 边缘检测
      • rho:ρρρ 的精确度
      • theta:θθθ 的精确度
      • threshold:阈值,只有累加器中的值高于该阈值时才被认为是直线
  • 霍夫圆检测

    • OpenCV 中使用霍夫梯度法进行圆形的检测
    • 霍夫梯度法将霍夫圆检测范围两个阶段
      1. 检测圆心
      2. 利用圆心推导出圆半径
    cv2.HoughCircles(image, method, dp, minDist, param1=100, param2=100, minRadius=0, maxRadius=0)
    
    • 参数
      • image:输入图像,应输入灰度图像
      • method:使用霍夫变换圆检测的算法,参数为 cv.HOUGH_GRADIENT
      • dp:霍夫空间的分辦率,dp=1 时表示霍夫空间与输入图像空间的大小一致,dp=2 时霍夫空间是输入图像空间的一半,以此类推
      • minDist:圆心之间的最小距离,如果检测到的两个圆心之间距离小于该值,则认为它们是同一个圆心
      • param1:边缘检测时使用 Canny 算子的高阈值,低阈值是高阈值的一半
      • param2:检测圆心和确定半径时所共有的阈值
      • minRadius:所检测到的圆半径的最小值
      • maxRadius:所检测到的圆半径的最大值
  • 案例演示:hough_transform.ipynb

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/95896.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/95896.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/95896.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UE5 C++ 第三方动态库的使用

一. 首先要拷贝对应的 第三方库 bin里有dll动态库,include里有动态库需要的头文件。 二.在Target.cs里,进行设置 头文件前面的路径为公共路径 设置需要一起打包的三方库文件 三.加载这个库 FPlatformProcess::GetDllHandle将他解析为 任意类型&#x…

C++进阶——多态

ʕ • ᴥ • ʔ づ♡ど 🎉 欢迎点赞支持🎉 个人主页:励志不掉头发的内向程序员; 专栏主页:C语言; 文章目录 前言 一、多态的概念 二、多态的定义及实现 2.1、多态的构成条件 (1)虚函…

Swift 语法学习指南 - 与 Kotlin 对比

Swift 语法学习指南 - 与 Kotlin 对比 本指南专为有 Android/Kotlin 开发经验的开发者设计,通过对比学习快速掌握 Swift 语法 目录 语言基础对比变量与常量数据类型函数定义类与结构体继承与协议可选类型集合类型控制流闭包与Lambda扩展与Extension错误处理内存管理…

嵌入式C语言笔记十七——构造数据类型

一.结构体:1.类型定义:struct 结构体名 {数据类型1 成员变量1;数据类型2 成员变量2;数据类型3 成员变量3;... };struct student {char name[32];char sex;int age;int score; };2.结构体变量定义:存储类型 数据类型 变量名;3.结构体元素初始化…

深入实践G1垃圾收集器调优:Java应用性能优化实战指南

深入实践G1垃圾收集器调优:Java应用性能优化实战指南 一、技术背景与应用场景 随着微服务和海量并发请求的普及,Java应用在生产环境中对低延迟和高吞吐的需求日益显著。传统的CMS和Parallel GC 在大内存场景下常出现Full GC 停顿时间长、吞吐下降等问题…

【JobScheduler】Android 后台任务调度的核心组件指南

JobScheduler 是 Android 平台上原生支持在直接启动模式(Direct Boot Mode)下执行任务的调度器。 相比 WorkManager 需要复杂的配置才能勉强支持直接启动,JobScheduler 在这方面有着天生的优势和明确的 API 支持。如果你面临的硬性要求是必须…

c# 调用basler 相机

目录 一联合halcon: 二 c# 原生 一联合halcon: 环境配置 下载安装pylon软件 下载安装halcon 创建 winform项目 test_basler 添加引用 打开pylon可以连接相机 可以看到我的相机id为23970642 ( c#联合halcon的基础教程(案例…

《2025年AI产业发展十大趋势报告》四十六

《2025年AI产业发展十大趋势报告》四十六随着科技的迅猛发展,人工智能(AI)作为引领新一轮科技革命和产业变革的战略性技术,正逐步渗透到各个行业和领域,成为推动经济社会发展的重要引擎。2023年,生成式AI的…

c++ 杂记

1. 为什么返回*this?2. 3. 友元函数的使用&#xff1a;需要头文件中类内外声明&#xff0c;cpp文件中实现定义哦// Sales_data.h #ifndef SALES_DATA_H #define SALES_DATA_H#include <string>class Sales_data {std::string bookNo;int units_sold 0;double revenue …

PDF文件基础-计算机字体

计算机字体的原理包含了字符编码、字形渲染和字体文件存储三个关键技术。 字符编码负责将每个字符映射到一个唯一的数字码&#xff1b;字形渲染则将这些数字码转换成屏幕或纸张上可识别的图形&#xff1b;字体文件存储则包含了字符的编码、图形描述信息以及字体的其他属性&…

华为IP(9)

OSPF的基本配置OSPF路由计算前言&#xff1a;1)同一区域内的OSPF路由器拥有完全一致的LSDB&#xff0c;在区域内部&#xff0c;OSPF采用SPF算法完成路由计算。2&#xff09;随着网络规模不断扩大&#xff0c;路由器为了完成路由计算所消耗的内存、CPU资源也越来越多。通过区域划…

java.nio.file.InvalidPathException异常

一.问题概述 本人在ubuntu22.04的操作系统上&#xff0c;运行java程序时创建一个文件时&#xff0c;由于文件名称中包含了中文&#xff0c;所以导致了程序抛出了java.nio.file.InvalidPathException的异常。 java.nio.file.InvalidPathException: Malformed input or input co…

Next系统总结学习(一)

下面我按题号逐条 详细 解释并给出示例与最佳实践。为便于阅读&#xff0c;我会同时给出关键代码片段&#xff08;伪代码/实用例子&#xff09;&#xff0c;并指出常见坑与解决方案。 1. 你是如何理解服务端渲染&#xff08;SSR&#xff09;的&#xff1f;它的核心工作流程是怎…

房屋安全鉴定需要什么条件

房屋安全鉴定需要什么条件&#xff1a;专业流程与必备要素解析房屋安全鉴定是保障建筑使用安全的重要环节&#xff0c;它通过对建筑结构、材料性能及使用状况的全面评估&#xff0c;为房屋的安全使用、改造或维护提供科学依据。随着城市建筑老化及自然灾害频发&#xff0c;房屋…

现代C++:现代C++?

C语言正在走向完美&#xff0c;所以&#xff0c;C语言值得学习&#xff08;甚至研究&#xff09;&#xff0c;这些知识可以成为一切编程的基础。然而在实践中&#xff0c;不必全面的使用C语言的各种特性&#xff0c;而应根据工程项目的实际情况&#xff0c;适当取舍&#xff08…

【C++】哈希表实现

1. 哈希概念 哈希(hash)又称散列&#xff0c;是⼀种组织数据的方式。从译名来看&#xff0c;有散乱排列的意思。本质就是通过哈希 函数把关键字Key跟存储位置建立一个映射关系&#xff0c;查找时通过这个哈希函数计算出Key存储的位置&#xff0c;进行快速查找 1.1 直接定址法…

ai 玩游戏 llm玩街霸 大模型玩街霸 (3)

1. 开源代码地址&#xff1a; https://github.com/OpenGenerativeAI/llm-colosseum 2. 架构&#xff1a; 3. 图片&#xff1a; 4. 感觉还是下面的步骤&#xff1a; a. 实时理解游戏当前环境&#xff0c;英雄角色&#xff0c;英雄状态 b. 根据当前状态感知&#xff0c;生成英雄…

2025年渗透测试面试题总结-59(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 一、SQL注入全解 二、XSS与文件漏洞 三、服务端漏洞专题 四、职业经验与能力评估 1、注入攻击原理是什么…

GPT系列--类GPT2源码剖析

无需多言&#xff0c;大家应该都用过了&#xff0c;如今都更新到GPT-5了。1. GPT-1回到2018年的NLP&#xff0c;神仙打架&#xff0c;BERT与GPT不分先后。GPT是“Generative Pre-Training”的简称&#xff0c;生成式的预训练。BERT和GPT肯定是GPT难训练&#xff0c;引用量也是B…

这是一款没有任何限制的免费远程手机控制手机的软件

这是一款没有任何限制的免费远程手机控制手机的软件支持安卓和苹果1.安装1.1被控制端安装airdroid1.2控制端air mirror2.登录账号控制端和被控制端登录同一个账号3.控制打开控制端软件选择要控制的机器直接点“远程控制“