【OpenCV-Python】教程:4-2 Harris角点检测

news2024/11/22 15:55:26

OpenCV Python Harris 角点检测

【目标】

  • 理解Harris角点检测背后的概念;
  • cv2.cornerHarris(), cv2.cornerSubPix()

【理论】

上一章节中,我们看到在图像中每个方向变化都很大的区域就是角点,一个早期的尝试是由 Chris Harris & Mike Stephens 在1998年的论文 A Combined Corner and Edge Detector 完成的。所以现在称之为 Harris 角点检测。他讲这些思想转换为数学公式形式,通过寻找不同方向上位移的亮度差异。

E ( u , v ) = ∑ x , y w ( x , y ) [ I ( x + u , y + v ) − I ( x , y ) ] 2 E(u,v)=\sum\limits_{x,y}w(x,y) [I(x+u,y+v)-I(x,y)]^2 E(u,v)=x,yw(x,y)[I(x+u,y+v)I(x,y)]2

w ( x , y ) w(x,y) w(x,y) 是窗口函数,可以是矩形窗口,也可以是高斯窗口,对应像素不同的权重。
I ( x + u , y + v ) I(x+u,y+v) I(x+u,y+v) 是移动区域的亮度,
I ( x , y ) I(x,y) I(x,y) 是亮度函数;

我们需要最大化函数 E ( u , v ) E(u,v) E(u,v)进行角点检测,这就需要我们最大化 [ I ( x + u , y + v ) − I ( x , y ) ] 2 [I(x+u,y+v)-I(x,y)]^2 [I(x+u,y+v)I(x,y)]2,将泰勒展开应用于上述方程,并使用一些数学步骤(请参考您喜欢的任何标准教科书以获得完整推导),我们得到最终方程为:
E ( u , v ) ≈ [ u v ] M [ u v ] E(u,v)\approx[u \quad v] M \begin{bmatrix} u \\ v \end{bmatrix} E(u,v)[uv]M[uv]

其中

M = ∑ x , y w ( x , y ) [ I x I x I x I y I y I x I y I y ] M=\sum\limits_{x,y}w(x,y)\begin{bmatrix} I_xI_x & I_xI_y \\ I_yI_x & I_yI_y \end{bmatrix} M=x,yw(x,y)[IxIxIyIxIxIyIyIy]

其中 I x I_x Ix I y I_y Iy 是图像在 x x x y y y 方向上的梯度(可以通过 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 M M的特征值

因此,这些特征值的大小决定了这个区域是角点,边还是平坦区域。

  • ∣ R ∣ |R| R 很小,当 λ 1 \lambda_1 λ1 λ 2 \lambda_2 λ2 很小时,区域平坦;
  • R < 0 R<0 R<0,当 λ 1 ≫ λ 2 \lambda_1\gg \lambda_2 λ1λ2 λ 1 ≪ λ 2 \lambda_1 \ll \lambda_2 λ1λ2 时,区域是边缘;
  • R R R 很大,当 λ 1 \lambda_1 λ1 λ 2 \lambda_2 λ2很大时并且 λ 1 ≈ λ 2 \lambda_1 \approx \lambda_2 λ1λ2 时,区域是角点。

在这里插入图片描述

【代码】

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

import cv2
import numpy as np 

# 读入图片并灰度化
# img = cv2.imread("assets/blox.jpg")
img = cv2.imread("assets/left08.jpg")
# img = cv2.imread("assets/chessboard(1).png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 检测角点
gray = np.float32(gray)
dst = cv2.cornerHarris(gray, 2, 3, 0.04)

# 膨胀
dst = cv2.dilate(dst, None)

# 找到计算值比较大的,并显示
img[dst>0.01*dst.max()] = [0, 0, 255]

cv2.imshow('dst', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
  • 亚像素精度角点检测

在这里插入图片描述

  • 局部图
    在这里插入图片描述
import numpy as np
import cv2

# 读入图片并灰度化
img = cv2.imread("assets/left08.jpg")
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

# 寻找角点
gray = np.float32(gray)
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)

# 找到连通域中心
ret, labels, stats, centroids = cv2.connectedComponentsWithStats(dst)

# 寻找亚像素角点
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)

# 显示
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("res", img)
cv2.imshow("dst", dst)

cv2.waitKey(0)
cv2.destroyAllWindows()

cv2.imwrite('subpixel5.png', img)

【接口】

  • cornerHarris
cv2.cornerHarris(	src, blockSize, ksize, k[, dst[, borderType]]	) ->	dst

在这里插入图片描述

Harris 角点检测

  • src: 单通道8位图像或者浮点图像
  • dst: 存储 harris 角点检测响应, CV_FC1 大小与源图像一致;
  • blocksize: 领域大小
  • ksize: sobel算子的直径
  • k: harris角点检测的自由参数里的 k k k
  • borderType: 扩边参数,BORDER_WRAP 不支持
  • borderType

在这里插入图片描述

  • cornerSubPix
cv2.cornerSubPix(	image, corners, winSize, zeroZone, criteria	) ->	corners

优化角点位置

  • image: 输入的单通道图像,8位或者浮点数
  • corners: 初始化的角点位置,并且可以接受输出
  • winSize: 搜寻窗口的半径,如果设置为 (5, 5),则搜索区域为 (52+1, 52+1) =(11,11)的窗口;
  • zeroZone: (-1,-1) 表示没有这个尺寸
  • criteria: 迭代准则,要么次数达到了,要么移动的距离很小了。
  • connectedComponentsWithStats
cv.connectedComponentsWithStats(	image[, labels[, stats[, centroids[, connectivity[, ltype]]]]]	) ->	retval, labels, stats, centroids
cv.connectedComponentsWithStatsWithAlgorithm(	image, connectivity, ltype, ccltype[, labels[, stats[, centroids]]]	) ->	retval, labels, stats, centroids

计算二值图像连通区域,并返回一系列的统计值

  • image: 8位单通道需要标记的图像
  • labels: 输出的标签图像
  • stats: 统计每一个标签的输出,包含背景标签
  • centroids: 每个区域的中心,可以通过 centroids(label, 0) 访问 x, centroids(label, 1) 访问 y;
  • connectivity: 4邻域或8邻域
  • ltype: 输出标签类型 CV_32S 或者 CV_16U
  • ccltype: 连通区域类型
  • ConnectedComponentsAlgorithmsTypes

在这里插入图片描述

【参考】

  1. OpenCV 官方文档

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

关闭图片窗口

关闭图片窗口 结果演示 概述 通过事件的绑定来实现&#xff0c;关闭网页中某个图片窗口的效果。 构建HTML框架 <body><div class"box">图片<img src"https://upload-bbs.mihoyo.com/upload/2021/03/11/73281682/f810fbc2e4806aab8176e96feee…

关于数据分析知识的干货分享

数据分析的出现是因为人类难以理解海量数据所呈现出来的信息&#xff0c;不能从中找到相应的规律来对现实中的事物进行对应&#xff0c;我们都知道数据有很高的价值&#xff0c;但不能利用的价值&#xff0c;没有任何意义。 为了解决这一问题&#xff0c;数据分析在长期的数据…

超透镜与超表面全息

超透镜和超表面因其操纵电磁场的独特特性而在科学上声名鹊起&#xff0c;如今它们的制造已经变得可行。但它们的设计难度远远超过了传统镜片&#xff0c;因为必须考虑到纳米级构件的特性。 VirtualLab Fusion的优势  统一的平台&#xff1a;具有将纳米级构建模块和大尺…

JAVA-GUI工具的编写-----事件篇

上一节介绍了HTTP以及HTTPS请求&#xff0c;那么这里我们就接着讲解事件与请求联动。 关于POC以及EXP最大的区别就是&#xff0c;EXP是附带利用功能&#xff0c;而POC仅仅是检测功能&#xff0c;所以这里我们需要动起来&#xff0c;GUI小工具能用上的事件功能其实就两个&#…

【vue3】代码自动格式化和volar卡顿问题解决

一、格式化策略 用eslint做代码检查和格式化是很方便的东西&#xff1b; 这里我们使用vscode完成这些操作&#xff1b; 在代码保存的时候&#xff0c;顺便完成格式化操作 1)装上eslint和prettier插件 2)装完插件之后&#xff0c;我们需要配置一下 打开 文件 > 首选项 >…

为什么阿里巴巴建议HashMap初始化时需要指定容量大小?

为什么阿里巴巴建议HashMap初始化时需要指定容量大小&#xff1f; 为什么&#xff1f; 关于集合类&#xff0c;《阿里巴巴Java开发手册》中写道&#xff1a; 我们先来写一段代码在JDK 1.7 &#xff08;jdk1.7.0_80&#xff09;下面来分别测试下&#xff0c;在不指定初始化容量…

Docker harbor私有仓库部署与管理

Docker harbor私有仓库部署与管理Docker harbor私有仓库部署与管理一、Docker 私有仓库1、下载registry镜像2、修改配置文件/etc/docker/daemon.json &#xff0c;添加私有仓库配置&#xff0c;修改完后重启docker3、创建私有仓库容器4、推送镜像到私有仓库中5、查看当前仓库的…

使用 Lua 脚本和海康 VisionMaster 进行 TCP 通信

说明&#xff1a;因任务需求&#xff0c;需要进行海康VisionMaster服务端和Lua脚本客户端进行TCP通信传输数据。因为之前从未接触过Lua语言&#xff0c;所以也趁机学习一波。 内容Lua教程手册LuaSocket使用方法一方法二报错&#xff1a;“attempt to compare number with strin…

高级_09.性能分析工具的使用

第09章_性能分析工具的使用 1. 数据库服务器的优化步骤 当我们遇到数据库调优问题的时候&#xff0c;该如何思考呢&#xff1f;这里把思考的流程整理成下面这张图。 整个流程划分成了观察&#xff08;Show status&#xff09;和行动&#xff08;Action&#xff09;两个部分。…

Service详解「2」

Service详解「2」 文章目录Service详解「2」Service介绍kube-proxy目前支持三种工作模式:userspace 模式iptables 模式ipvs 模式Service类型Service使用实验环境准备ClusterIP类型的ServiceEndpoint负载分发策略HeadLiness类型的ServiceNodePort类型的ServiceLoadBalancer类型的…

407. 接雨水 II

给你一个 m x n 的矩阵&#xff0c;其中的值均为非负整数&#xff0c;代表二维高度图每个单元的高度&#xff0c;请计算图中形状最多能接多少体积的雨水。 示例 1: 输入: heightMap [[1,4,3,1,3,2],[3,2,1,3,2,4],[2,3,3,2,3,1]] 输出: 4 解释: 下雨后&#xff0c;雨水将会被上…

24节气- ||大雪|| 文案、海报分享,冬寒雪落,归家愈暖。

大雪降至 一年中最寒冷的时候也将到来 大家注意保暖防护 过个温暖的冬天吧&#xff01; 下面是我整理的关于大雪的文案、海报&#xff0c;希望对大家有帮助&#xff01; 更多设计素材免费下载&#xff1a; https://www.sucai999.com/?vNTYxMjky 01 大雪至&#xff0c;人…

跨越专业翻译的语言之墙:百度翻译的技术攀登

作为一个科技从业者&#xff0c;阅读AI顶会的最新论文、浏览国内外创新的最新动向&#xff0c;是我工作的重要部分。平时接触的开发者、科学家、企业研究人员等&#xff0c;工作生活中也涉及大量专业阅读。于是乎&#xff0c;我就会经常听到这样的抱怨&#xff1a;PDF格式的论文…

第42讲:MySQL数据库索引的基本使用规则以及在正确使用索引的方式

文章目录1.索引规则之最左前缀法则1.1.最左前缀法则的概念1.2.最左前缀法则的验证案例2.索引规则之范围查询3.使用索引时会导致索引失效的几种情况3.1.索引列使用运算导致索引失效3.2.索引列的值不加引号导致索引失效3.3.索引列模糊查询可能会导致索引失效3.4.OR连接条件使用不…

Excel中如何用计算公式或表达式直接计算出结果?

Excel中如何用计算公式或表达式直接计算出结果&#xff1f; 目录 Excel中如何用计算公式或表达式直接计算出结果&#xff1f; 1、例如&#xff1a;我们需要用E列的计算公式&#xff08;表达式&#xff09;&#xff0c;直接计算出结果填至F列 2、另一种方法&#xff1a;在菜…

什么是接口测试?接口测试的流程步骤

目录 一、什么是接口测试&怎么测 二、接口测试的好处 三、怎么做好接口测试 四、接口测试的原理 五、接口测试流程&用例设计 5.1.接口文档分析 5.1.1.接口构成图解 5.2.制定接口测试计划 5.3.编写接口测试用例&评审 5.3.1.接口测试用例模板 5.4.接口测试…

普通人如何不被 OpenAI 取代?

Datawhale干货 Tw93&#xff0c;前端工程师&#xff0c;Datawhale邀约作者知乎&#xff1a;https://www.zhihu.com/people/tw93Github&#xff1a;https://github.com/tw93今天试了试OpenAI的一些功能&#xff0c;通过主题来记录一下使用场景&#xff0c;发现了不少它强于普通人…

R语言缺失数据变量选择LASSO回归:Bootstrap重(再)抽样插补和推算

全文链接&#xff1a;http://tecdat.cn/?p30726在存在缺失数据的情况下&#xff0c;需要根据缺失数据的机制和用于处理缺失数据的统计方法定制变量选择方法。我们专注于可以与插补相结合的随机和变量选择方法的缺失方法&#xff08;点击文末“阅读原文”获取完整代码数据&…

nginx解析漏洞复现

学习积累&#xff1a; 存在该漏洞的原因&#xff1a;是一种用户配置不当造成的漏洞 这里我是部署了vulhub靶场 直接执行docker-compose up -d启动容器&#xff0c;无需编译。 造成该漏洞的配置条件&#xff1a; &#xff08;不受php、nginx的版本限制&#xff09; &#…

计算机毕业设计java基于springboot的在线动漫平台

项目介绍 开发语言:Java 开发工具:IDEA /Eclipse 数据库:MYSQL5.7 应用服务:Tomcat7/Tomcat8 使用框架:springbootvue 在线动漫信息平台主要是为了会员方便对动漫信息的了解以及查看今日论坛信息和查看热门动漫、文章专栏等信息&#xff0c;也是为了更好的让管理员进行更好存…