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()即可获取目标系统…...

java语言B/S架构云HIS医院信息系统源码【springboot】
医院云HIS全称为基于云计算的医疗卫生信息系统( Cloud- Based Healthcare Information System),是运用云计算、大数据、物联网等新兴信息技术,按照现代医疗卫生管理要求,在一定区域范围内以数字化形式提供医疗卫生行业数据收集、存储、传递、…...

go文件基本操作
一、文件读操作 文件内容如下: 水陆草木之花,可爱者甚蕃。 晋陶渊明独爱菊。自李唐来,世人甚爱牡丹。 予独爱莲之出淤泥而不染,濯清涟而不妖,中通外直,不蔓不枝,香远益清,亭亭净植…...

每日一学——应用层
以下是一份关于应用层协议的学习资料: DNS (Domain Name System):DNS是互联网上最常用的应用层协议之一,它将域名转换为对应的IP地址。你可以了解DNS的工作原理、域名解析过程和常见的DNS记录类型。 DHCP (Dynamic Host Configuration Proto…...

blender的快捷键记录
按键作用备注R旋转物体移动、旋转或缩放物体时,按下X、Y或Z键:按X、Y或Z轴方向移动、旋转或缩放S缩放物体G移动物体TAB键切换为编辑模式CTRL A弹出应用菜单物体模式旋转缩放后应用旋转与缩放,再进入编辑模式SHIFT 鼠标右键移动游标位置SHIF…...

3D- vista:预训练的3D视觉和文本对齐Transformer
论文:https://arxiv.org/abs/2308.04352 代码: GitHub - 3d-vista/3D-VisTA: Official implementation of ICCV 2023 paper "3D-VisTA: Pre-trained Transformer for 3D Vision and Text Alignment" 摘要 三维视觉语言基础(3D- vl)是一个新兴领域&…...

SAP ABAP 直接把内表转换成PDF格式(smartform的打印函数输出OTF格式数据)
直接上代码: REPORT zcycle055.DATA: lt_tab TYPE TABLE OF zpps001. DATA: ls_tab TYPE zpps001.ls_tab-werks 1001. ls_tab-gamng 150.00. ls_tab-gstrp 20201202. ls_tab-aufnr 000010000246. ls_tab-auart 标准生产. ls_tab-gltrp 20201205. ls_tab-matn…...

侯捷 C++ part2 兼谈对象模型笔记——7 reference、const、new/delete
7 reference、const、new/delete 7.1 reference x 是整数,占4字节;p 是指针占4字节(32位);r 代表x,那么r也是整数,占4字节 int x 0; int* p &x; // 地址和指针是互通的 int& r x;…...

C++学习笔记总结练习:primer 学习日志
文章目录 针对自己的引言学习内容c语言基础知识1.为什么要声明变量2.cout ,cin3.c 不容许一个函数定义嵌套到另一个函数的定义中。4.编译指令using5.c基本类型长度6.在定义常量时尽可能使用const 关键字而不用#define9.前缀递增符与后缀递增符的区别10.c中的cctype库11.c 中的s…...

发布一个开源的新闻api(整理后就开源)
目录 说明: 基础说明 其他说明: 通用接口: 登录: 注册: 更改密码(需要token) 更换头像(需要token) 获取用户列表(需要token): 上传文件(5000端口): 获取文件(5000端口)源码文件,db文件均不能获取: 验证token(需要token): 获取系统时间: 文件…...

3d max省时插件CG MAGIC功能中的材质参数可一键优化!
渲染的最终结果就是为了让渲染效果更加真实的体现。 对于一些操作上,可能还是费些时间,VRay可以说是在给材质做加法的路上越走越远,透明度、凹凸、反射等等参数细节越做越多。 对于材质参数调节的重要性大家都心里有数的。 VRay材质系统的每…...