OpenCV-Python中的图像处理-图像特征
OpenCV-Python中的图像处理-图像特征
- 图像特征
- Harris角点检测
- 亚像素级精度的角点检测
- Shi-Tomasi角点检测
- SIFT(Scale-Invariant Feature Transfrom)
- SURF(Speeded-Up Robust Features)
- FAST算法
- BRIEF(Binary Robust Independent Elementary Features)算法
- ORB (Oriented FAST and Rotated BRIEF)算法
- 特征匹配
- Brute-Force 蛮力匹配
- 对 ORB 描述符进行蛮力匹配
- 对 SIFT 描述符进行蛮力匹配和比值测试
- FLANN 匹配
图像特征
- 特征理解
- 特征检测
- 特征描述
Harris角点检测
- cv2.cornerHarris(img, blockSize, ksize, k, borderType=…)
- img:输入图像,数据类型为float32
- blockSize:角点检测中要考虑的领域大小
- ksize:Sobe求导中使用的窗口大小
- k:Harris角点检测方程中的自由参数,取值参数为 [0.04,0.06]
- borderType:边界类型
import numpy as np
import cv2
from matplotlib import pyplot as plt# img = cv2.imread('./resource/opencv/image/chessboard.png', cv2.IMREAD_COLOR)
img = cv2.imread('./resource/opencv/image/pattern.png', cv2.IMREAD_COLOR)gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)gray = np.float32(gray)# 输入图像必须是float32,最后一个参数在0.04到0.05之间
dst = cv2.cornerHarris(gray, 2, 3, 0.05)
dst = cv2.dilate(dst, None)img[dst>0.01*dst.max()] = [0, 0, 255]cv2.imshow('dst', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

亚像素级精度的角点检测
- cv2.cornerSubPix(img, corners, winSize, zeroZone, criteria)
最大精度的角点检测,首先要找到 Harris角点,然后将角点的重心传给这个函数进行修正。
import numpy as np
import cv2
from matplotlib import pyplot as pltimg = cv2.imread('./resource/opencv/image/subpixel.png', cv2.IMREAD_COLOR)
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('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Harris 角点用红色像素标出,绿色像素是修正后的角点。

Shi-Tomasi角点检测
- cv2.goodFeatureToTrack()
import numpy as np
import cv2
from matplotlib import pyplot as pltimg = cv2.imread('./resource/opencv/image/shitomasi_block.jpg', cv2.IMREAD_COLOR)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)corners = cv2.goodFeaturesToTrack(gray, 25, 0.01, 10)corners = np.int0(corners)for i in corners:x,y = i.ravel()cv2.circle(img, (x,y), 3, 255, -1)plt.imshow(img)
plt.show()

SIFT(Scale-Invariant Feature Transfrom)
-
SIFT,即尺度不变特征变换(Scale-invariant feature transform,SIFT),是用于图像处理领域的一种描述。这种描述具有尺度不变性,可在图像中检测出关键点,是一种局部特征描述子。
-
cv2.SIFT_create()
- kp = sift.detect(img, None):查找特征点
- kp, des = sift.compute(img, kp):计算特征点
- kp, des = sift.detectAndCompute(img, None) :直接找到特征点并计算描述符
-
cv2.drawKeypoints(img, kp, out_img, flags=cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS):画特征点
- img : 输入图像
- kp:图像特征点
- out_img:输出图像
- flags:
cv2.DRAW_MATCHES_FLAGS_DEFAULT
cv2.DRAW_MATCHES_FLAGS_DRAW_OVER_OUTIMG
cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS
cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS
import numpy as np
import cv2# 读取图片
# img = cv2.imread('./resource/opencv/image/home.jpg')
img = cv2.imread('./resource/opencv/image/AverageMaleFace.jpg')
key_points = img.copy()# 实例化SIFT算法
sift = cv2.SIFT_create()# 得到特征点
kp = sift.detect(img, None)
print(np.array(kp).shape)# 绘制特征点
cv2.drawKeypoints(img, kp, key_points, flags=cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS)# 图片展示
cv2.imshow("key points", key_points)
cv2.waitKey(0)
cv2.destroyAllWindows()# 保存图片
# cv2.imwrite("key_points.jpg", key_points)# 计算特征
kp, des = sift.compute(img, kp)# 调试输出
print(des.shape)
print(des[0])cv2.imshow('kp', key_points)
cv2.waitKey(0)
cv2.destroyAllWindows()

SURF(Speeded-Up Robust Features)
- 文章前面介绍了使用 SIFT 算法进行关键点检测和描述。但是这种算法的执行速度比较慢,人们需要速度更快的算法。在 2006 年Bay,H.,Tuytelaars,T. 和 Van Gool,L 共同提出了 SURF(加速稳健特征)算法。跟它的名字一样,这是个算法是加速版的 SIFT。
- 与 SIFT 相同 OpenCV 也提供了 SURF 的相关函数。首先我们要初始化一个 SURF 对象,同时设置好可选参数: 64/128 维描述符, Upright/Normal 模式等。所有的细节都已经在文档中解释的很明白了。就像我们在SIFT 中一样,我们可以使用函数 SURF.detect(), SURF.compute() 等来进行关键点搀着和描述。
img = cv2.imread(‘fly.png’, 0)
surf = cv2.SURF(400)
kp, des = surf.detectAndCompute(img, None)
len(kp) # 699
print(surf.hessianThreshold)
surf.hessianThreshold = 50000
kp, des = surf.detectAndCompute(img,None)
print(len(kp)) # 47
不检测关键点的方向
print(surf.upright) #False
surf.upright = True
FAST算法
import numpy as np
import cv2
from matplotlib import pyplot as pltimg = cv2.imread('./resource/opencv/image/fly.jpg', cv2.IMREAD_GRAYSCALE)# fast = cv2.FastFeatureDetector_create(threshold=100, nonmaxSuppression=False, type=cv2.FAST_FEATURE_DETECTOR_TYPE_5_8)
fast = cv2.FastFeatureDetector_create(threshold=400)
kp = fast.detect(img, None)
img2 = cv2.drawKeypoints(img, kp, img.copy(), color=(0, 0, 255), flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)cv2.imshow('fast', img2)
cv2.waitKey(0)
cv2.destroyAllWindows()

BRIEF(Binary Robust Independent Elementary Features)算法
- BRIEF(Binary Robust Independent Elementary Features)
import numpy as np
import cv2
from matplotlib import pyplot as pltimg = cv2.imread('./resource/opencv/image/fly.jpg', cv2.IMREAD_GRAYSCALE)# Initiate STAR detector
star = cv2.FeatureDetector_create("STAR")
# Initiate BRIEF extractor
brief = cv2.DescriptorExtractor_create("BRIEF")
# find the keypoints with STAR
kp = star.detect(img,None)
# compute the descriptors with BRIEF
kp, des = brief.compute(img, kp)
print(brief.getInt('bytes'))
print(des.shape)
ORB (Oriented FAST and Rotated BRIEF)算法
import numpy as np
import cv2
from matplotlib import pyplot as pltimg = cv2.imread('./resource/opencv/image/fly.jpg', cv2.IMREAD_GRAYSCALE)# ORB_create(nfeatures=..., scaleFactor=..., nlevels=..., edgeThreshold=..., firstLevel=..., WTA_K=..., scoreType=..., patchSize=..., fastThreshold=...)
orb = cv2.ORB_create()kp = orb.detect(img, None)kp, des = orb.compute(img, kp)img2 = cv2.drawKeypoints(img, kp, img.copy(), color=(255, 0, 0), flags=0)
plt.imshow(img2)
plt.show()

特征匹配
OpenCV 中的特征匹配
- 蛮力( Brute-Force)匹配
- FLANN 匹配
Brute-Force 蛮力匹配
对 ORB 描述符进行蛮力匹配
import numpy as np
import cv2
from matplotlib import pyplot as pltimg1 = cv2.imread('./resource/opencv/image/box.png', 0)
img2 = cv2.imread('./resource/opencv/image/box_in_scene.png', 0)orb = cv2.ORB_create()kp1, des1 = orb.detectAndCompute(img1, None)
kp2, des2 = orb.detectAndCompute(img2, None)bf = cv2.BFMatcher_create(cv2.NORM_HAMMING, crossCheck=True)matches = bf.match(des1, des2)# matches = bf:match(des1; des2) 返回值是一个 DMatch 对象列表。这个
# DMatch 对象具有下列属性:
# • DMatch.distance - 描述符之间的距离。越小越好。
# • DMatch.trainIdx - 目标图像中描述符的索引。
# • DMatch.queryIdx - 查询图像中描述符的索引。
# • DMatch.imgIdx - 目标图像的索引。# 距离排序
matches = sorted(matches, key = lambda x:x.distance)# 画出前30匹配
img3 = cv2.drawMatches(img1, kp1, img2, kp2, matches[:30], None, flags=2)cv2.imshow('img', img3)
cv2.waitKey(0)
cv2.destroyAllWindows()

对 SIFT 描述符进行蛮力匹配和比值测试
现在我们使用 BFMatcher.knnMatch() 来获得 k 对最佳匹配。在本例中我们设置 k = 2,这样我们就可以使用 D.Lowe 文章中的比值测试了。
import numpy as np
import cv2
from matplotlib import pyplot as pltimg1 = cv2.imread('./resource/opencv/image/box.png', 0)
img2 = cv2.imread('./resource/opencv/image/box_in_scene.png', 0)sift = cv2.SIFT_create()
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)bf = cv2.BFMatcher_create()
matches = bf.knnMatch(des1, des2, k=2)good = []
for m,n in matches:if m.distance < 0.75*n.distance:good.append([m])# drawMatchesKnn(img1, keypoints1, img2, keypoints2, matches1to2, outImg, matchColor=..., singlePointColor=..., matchesMask=..., flags: int = ...)
img3 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, good[:100], None, flags=2)
plt.imshow(img3)
plt.show()

FLANN 匹配
FLANN 是快速最近邻搜索包(Fast_Library_for_Approximate_Nearest_Neighbors)的简称。它是一个对大数据集和高维特征进行最近邻搜索的算法的集合,而且这些算法都已经被优化过了。在面对大数据集时它的效果要好于 BFMatcher。我们来对第二个例子使用 FLANN 匹配看看它的效果。
import numpy as np
import cv2
from matplotlib import pyplot as pltimg1 = cv2.imread('./resource/opencv/image/box.png', 0)
img2 = cv2.imread('./resource/opencv/image/box_in_scene.png', 0)sift = cv2.SIFT_create()
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)flann = cv2.FlannBasedMatcher_create()
matches = flann.knnMatch(des1, des2, k=2)matchesMask = [[0,0] for i in range(len(matches))]for i, (m, n) in enumerate(matches):if m.distance < 0.7*n.distance:matchesMask[i] = [1,0]draw_params = dict(matchColor = (0, 255, 0),singlePointColor = (255, 0, 0),matchesMask = matchesMask,flags = 0)img3 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, matches, None, **draw_params)
plt.imshow(img3)
plt.show()

相关文章:
OpenCV-Python中的图像处理-图像特征
OpenCV-Python中的图像处理-图像特征 图像特征Harris角点检测亚像素级精度的角点检测Shi-Tomasi角点检测SIFT(Scale-Invariant Feature Transfrom)SURF(Speeded-Up Robust Features)FAST算法BRIEF(Binary Robust Independent Elementary Features)算法ORB (Oriented FAST and R…...
Ajax入门+aixos+HTTP协议
一.Ajax入门 概念:AJAX是浏览器与服务器进行数据通信的技术 axios使用: 引入axios.js使用axios函数:传入配置对象,再用.then回调函数接受结果,并做后续处理 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>01.axios使用…...
conda创建虚拟环境
创建虚拟环境是在计算机上设置一个独立的空间,用于安装和运行特定版本的软件和依赖项,以避免与系统其他部分的冲突。 创建虚拟环境: conda create --name myenv python3.8 这将创建一个名为myenv的虚拟环境,并安装Python 3.8版本。…...
Golang服务的请求调度
文章目录 1. 写在前面2. SheddingHandler的实现原理3. 相关方案的对比4. 小结 1. 写在前面 最近在看相关的Go服务的请求调度的时候,发现在gin中默认提供的中间件中,不含有请求调度相关的逻辑中间件,去github查看了一些服务框架,发…...
Jenkins的流水线启动jar后未执行问题处理
现象 在流水线里配置了启动脚本例如,nohup java -jar xxx.jar >nohup.out 2>&1 & 但是在服务器发现服务并未启动,且nohup日志里没输出日志,这样的原因是jenkins在执行完脚本后,就退出了这个进程。 在启动脚本执行jar命令的上一步加入以下…...
智慧工地平台工地人员管理系统 可视化大数据智能云平台源码
智慧工地概述: 智慧工地管理平台是以物联网、移动互联网技术为基础,充分应用大数据、人工智能、移动通讯、云计算等信息技术,利用前端信息采通过人机交互、感知、决策、执行和反馈等,实现对工程项目內人员、车辆、安全、设备、材…...
外包干了2个月测试,技术退步明显...
先说一下自己的情况,大专生,18年通过校招进入湖南某软件公司,干了接近4年的功能测试,今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…...
神经网络基础-神经网络补充概念-19-向量化实现的解释
概念 向量化是一种优化技术,通过使用数组操作代替显式的循环,可以大大提高代码的性能和效率。在机器学习和数据分析领域,向量化是一种常见的实践,它允许你在处理大量数据时更快地进行计算。 一般操作 数组操作:向量…...
四层和七层负载均衡的区别
一、四层负载均衡 四层就是ISO参考模型中的第四层。四层负载均衡器也称为四层交换机,它主要时通过分析IP层和TCP/UDP层的流量实现的基于“IP端口”的负载均衡。常见的基于四层的负载均衡器有LVS、F5等。 以常见的TCP应用为例,负载均衡器在接收到第一个来…...
Scala 如何调试隐式转换--隐式转换代码的显示展示
方法1 在需要隐式转换的地方,把需要的参数显示的写出。 略方法2,查看编译代码 在terminal中 利用 scalac -Xprint:typer xxx.scala方法打印添加了隐式值的代码示例。 对于复杂的工程来说,直接跑到terminal执行 scalac -Xprint:typer xxx.…...
Rust交叉编译简述 —— Arm
使用系统:WSL2 —— Kali(Microsoft Store) 命令列表 rustup target list # 当前官方支持的构建目标架构列表 rustup target add aarch64-unknown-linux-gnu # 添加目标架构sudo apt-get install gcc-13-aarch64-linux-gnu gcc-13-aarch64-linux-gnu # 下载目标工具…...
算法与数据结构(二十三)动态规划设计:最长递增子序列
注:此文只在个人总结 labuladong 动态规划框架,仅限于学习交流,版权归原作者所有; 也许有读者看了前文 动态规划详解,学会了动态规划的套路:找到了问题的「状态」,明确了 dp 数组/函数的含义&a…...
相机的位姿在地固坐标系ECEF和ENU坐标系的转换
在地球科学和导航领域,通常使用地心地固坐标系(ECEF,Earth-Centered, Earth-Fixed)和东北天坐标系(ENU,East-North-Up)来描述地球上的位置和姿态。如下图所示: 地心地固坐标ecef和…...
RFID技术助力汽车零配件装配产线,提升效率与准确性
随着科技的不断发展,越来越多的自动化设备被应用到汽车零配件装配产线中。其中,射频识别(Radio Frequency Identification,简称RFID)技术凭借其独特的优势,已经成为了这一领域的重要技术之一。本文将介绍RF…...
应用高分辨率 GAN 对扰动文档图像去扭曲的深度Python实践
1. 引言 随着技术的不断发展,图像处理在各种场景中的应用也变得越来越广泛。高分辨率 GAN (Generative Adversarial Network) 是近年来图像处理领域的热点技术,它能够生成极高分辨率的图像,与此同时,它也可以用于各种修复和增强任…...
【BASH】回顾与知识点梳理(二十六)
【BASH】回顾与知识点梳理 二十六 二十六. 二十一至二十五章知识点总结及练习26.1 总结26.2 模拟26.3 简答题 该系列目录 --> 【BASH】回顾与知识点梳理(目录) 二十六. 二十一至二十五章知识点总结及练习 26.1 总结 Linux 操作系统上面,…...
React下载文件的两种方式
React下载文件的两种方式 - 代码先锋网 不知道有用没用看着挺整齐 没试过 1、GET类型下载 download url > {const eleLink document.createElement(a);eleLink.style.display none;// eleLink.target "_blank"eleLink.href url;// eleLink.href record;d…...
python入门知识:分支结构
前言 嗨喽,大家好呀~这里是爱看美女的茜茜呐 1.内容导图 👇 👇 👇 更多精彩机密、教程,尽在下方,赶紧点击了解吧~ python资料、视频教程、代码、插件安装教程等我都准备好了,直接在文末名片自…...
DNS协议及其工作原理
DNS是域名系统(Domain Name System)的缩写,它是一种用于将域名转换为IP地址的分布式数据库系统。它是因特网的基石,能够使人们通过域名方便地访问互联网,而无需记住复杂的IP地址。 DNS的历史可以追溯到1983年…...
调用被fishhook的原函数
OC类如果通过runtime被hook了,可以通过逆序遍历方法列表的方式调用原方法。 那系统库的C函数被fish hook了该怎么办呢? 原理和OC类异曲同工,即通过系统函数dlopen()获取动态库,以动态库为参数通过系统函数dlsym()即可获取目标系统…...
龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...
理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...
在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...
