IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> opencv31:哈里斯角检测|Harris Corner -> 正文阅读

[人工智能]opencv31:哈里斯角检测|Harris Corner

目标

在本章中,将学习

  • "Harris Corner Detection”背后的思想
  • 函数:cv2.cornerHarris(),cv.2cornerSubPix()

理论

在上一章中看到,角是图像中各个方向上强度变化很大的区域。Chris Harris和Mike Stephens在1988年的论文《 A Combined Corner and Edge Detector 》中做了一次找到这些角点的早期尝试,所以现在将该方法称为哈里斯角点检测器。他把这个简单的想法变成了数学形式。它基本上找到了 ( u , v ) (u,v) (u,v)在所有方向上位移的强度差异。表示如下:

E ( u , v ) = ∑ x , y w ( x , y ) ? window?function ? [ I ( x + u , y + v ) ? shifted?intensity ? I ( x , y ) ? intensity ] 2 E(u,v) = \sum_{x,y} \underbrace{w(x,y)}_\text{window function} \, [\underbrace{I(x+u,y+v)}_\text{shifted intensity}-\underbrace{I(x,y)}_\text{intensity}]^2 E(u,v)=x,y?window?function w(x,y)??[shifted?intensity I(x+u,y+v)???intensity I(x,y)??]2
?

窗口函数可以是一个矩形窗口,也可以是一个高斯窗口,它在下面赋予了值。

必须最大化这个函数 E ( u , v ) E(u,v) E(u,v)用于角点检测。这意味着,必须最大化第二个项。将泰勒扩展应用于上述方程,并使用一些数学步骤,得到最后的等式:

E ( u , v ) ≈ [ u v ] M [ u v ] E(u,v) \approx \begin{bmatrix} u & v \end{bmatrix} M \begin{bmatrix} u \\ v \end{bmatrix} E(u,v)[u?v?]M[uv?]
其中

M = ∑ x , y w ( x , y ) [ I x I x I x I y I x I y I y I y ] M = \sum_{x,y} w(x,y) \begin{bmatrix}I_x I_x & I_x I_y \\ I_x I_y & I_y I_y \end{bmatrix} M=x,y?w(x,y)[Ix?Ix?Ix?Iy??Ix?Iy?Iy?Iy??]

I x I_x Ix? I y I_y Iy? 分别是在x和y方向上的图像导数。(可以使用cv2.Sobel()获得)

在此之后,他们定义了一个分数,用等式表示,这将决定窗口是否包含角点。

R = d e t ( M ) ? k ( t r a c e ( M ) ) 2 R = det(M) - k(trace(M))^2 R=det(M)?k(trace(M))2

其中

  • d e t ( M ) = λ 1 λ 2 det(M) = \lambda_1 \lambda_2 det(M)=λ1?λ2?(行列式值)
  • t r a c e ( M ) = λ 1 + λ 2 trace(M) = \lambda_1 + \lambda_2 trace(M)=λ1?+λ2?(迹,主对角线元素和)
  • λ 1 \lambda_1 λ1? λ 2 \lambda_2 λ2? 是M矩阵的特征值

因此,这些特征值的值决定了区域是拐角,边缘还是平坦。

  • ∣ R ∣ ∣R∣ R较小,这在 λ 1 \lambda_1 λ1? λ 2 \lambda_2 λ2?较小时发生,该区域平坦。
  • R < 0 R < 0 R<0时,这是在 λ 1 > > λ 2 \lambda_1 >>\lambda_2 λ1?>>λ2? 时发生,反之亦然),该区域为边
  • R R R很大时,这是在 λ 1 \lambda_1 λ1? λ 2 \lambda_2 λ2?比较大且 λ 1 \lambda_1 λ1? ~ λ 2 \lambda_2 λ2?时,该区域是角点。

可以用如下图来表示:
在这里插入图片描述

因此,Harris Corner Detection的结果是具有这些分数的灰度图像。合适的阈值可提供图像的各个角落。

OpenCV中的哈里斯角检测

在OpenCV中有实现哈里斯角点检测,cv2.cornerHarris()。其参数为:

dst = cv2.cornerHarris(src, blockSize, ksize, k[, dst[, borderType]] )

  • src - 输入图像,灰度和float32类型
  • blockSize - 是拐角检测考虑的邻域大小
  • ksize- 使用的Sobel导数的光圈参数
  • k- 等式中的哈里斯检测器自由参数
import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('chessboard.png')
img_copy = img.copy()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

dst = cv2.cornerHarris(gray, 2, 3, 0.04)

# result is dilated for marking the corners, not important
dst = cv2.dilate(dst, None)

# Threshold for an optimal value, it may vary depending on the image.
img[dst >0.01*dst.max()]=[255,0,0]

# plot
plt.subplot(121)
plt.imshow(img_copy, cmap='gray')
plt.xticks([])
plt.yticks([])

plt.subplot(122)
plt.imshow(img, cmap='gray')
plt.xticks([])
plt.yticks([])
plt.show()

以下是结果:

在这里插入图片描述
可以看到,各个角点已经标红。

SubPixel精度的转角

有时候可能需要找到最精确的角点。OpenCV附带了一个函数cv2.cornerSubPix(),它进一步细化了以亚像素精度检测到的角点。下面是一个例子。

  • 和之前一样,首先需要先找到哈里斯角点
  • 然后通过这些角的质心(可能在一个角上有一堆像素,取它们的质心)来细化它们
  • Harris角用红色像素标记,SubPixel角用绿色像素标记

对于cv2.cornerSubPix()函数,必须定义停止迭代的条件。我们可以在特定的迭代次数或达到一定的精度后停止它。此外,还需要定义它将搜索角点的邻居的大小。

corners = cv.cornerSubPix( image, corners, winSize, zeroZone, criteria )

  • image: 输入图像,单通道
  • corners: 输入的初始坐标和为输出提供的精制坐标
  • winSize: 搜索窗口的一半侧面长度
  • zeroZone: 搜索区域中间的死区大小的一半在下面的公式中的求和,有时用于避免自相关矩阵的可能奇点。 ( ? 1 , ? 1 ) (-1,-1) (?1,?1) 的值表示没有这样的尺寸
  • criteria: 终止角点细化过程的条件
# sub pixel更精度角点
import cv2
import numpy as np

img = cv2.imread('chessboard2.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# find Harris corners
dst = cv2.cornerHarris(gray,2, 3, 0.04)
dst = cv2.dilate(dst, None)
ret, dst = cv2.threshold(dst, 0.01*dst.max(), 255,0)
dst = np.uint8(dst)

# find centroids
ret, labels, stats, centroids = cv2.connectedComponentsWithStats(dst)

# define the criteria to stop and refine the corners
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.001)
corners = cv2.cornerSubPix(gray, np.float32(centroids), (5, 5), (-1, -1), criteria)

# Now draw them
res = np.hstack((centroids,corners))
res = np.int0(res)
img[res[:,1],res[:,0]]=[0,0,255]
img[res[:,3],res[:,2]] = [0,255,0]

cv2.imshow('subpixel', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

以下是结果, 可以看到SubPixel更精确一点:
在这里插入图片描述

附加资源

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-11-17 12:45:44  更:2021-11-17 12:48:01 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/28 19:39:14-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码