[Computer Vision]实验二:图像特征点提取

目录

一、实验内容

二、实验过程及结果

2.1 Harris角点检测

2.2 SIFT算法

三、实验小结


一、实验内容

  1. 采用Harris与SIFT分别提取特征点及对应的描述子,对比两者的区别(特征点数量、分布、描述子维度、图像变化对二者的影响等)
  2. 利用特征匹配算法实现两幅相近图像的特征匹配,打印匹配点数量级结果

二、实验过程及结果

2.1 Harris角点检测

以下是Harris.py文件

from PIL import Image
from pylab import *
import matplotlib.pyplot as plt 
from scipy.ndimage import filters
def compute_harris_response(im,sigma=3):imx = zeros(im.shape)filters.gaussian_filter(im, (sigma,sigma), (0,1), imx)imy = zeros(im.shape)filters.gaussian_filter(im, (sigma,sigma), (1,0), imy)Wxx = filters.gaussian_filter(imx*imx,sigma)Wxy = filters.gaussian_filter(imx*imy,sigma)Wyy = filters.gaussian_filter(imy*imy,sigma)Wdet = Wxx*Wyy - Wxy**2Wtr = Wxx + Wyyreturn Wdet / Wtrdef get_harris_points(harrisim, min_dist=10, threshold=0.1):corner_threshold = harrisim.max() * thresholdharrisim_t = (harrisim > corner_threshold) * 1coords = array(harrisim_t.nonzero()).Tcandidate_values = [harrisim[c[0], c[1]] for c in coords]index = argsort(candidate_values)allowed_locations = zeros(harrisim.shape)allowed_locations[min_dist:-min_dist, min_dist:-min_dist] = 1filtered_coords = []for i in index:if allowed_locations[coords[i, 0], coords[i, 1]] == 1:filtered_coords.append(coords[i])allowed_locations[(coords[i, 0] - min_dist):(coords[i, 0] + min_dist),(coords[i, 1] - min_dist): (coords[i, 1] + min_dist)] = 0return filtered_coordsdef plot_harris_points(image, filtered_coords):figure()gray()imshow(image)plot([p[1] for p in filtered_coords], [p[0] for p in filtered_coords], '*')show()def get_descriptors(image,filtered_coords,wid=5):desc = []for coords in filtered_coords:patch = image[coords[0]-wid:coords[0]+wid+1,coords[1]-wid:coords[1]+wid+1].flatten()desc.append(patch)return descdef match(desc1,desc2,threshold=0.5):n = len(desc1[0])d = -ones((len(desc1),len(desc2)))for i in range(len(desc1)):for j in range(len(desc2)):d1 = (desc1[i] - mean(desc1[i])) / std(desc1[i])d2 = (desc2[j] - mean(desc2[j])) / std(desc2[j])ncc_value = sum(d1*d2) / (n-1) if ncc_value > threshold:d[i,j] = ncc_value          ndx = argsort(-d)matchscores = ndx[:,0]return matchscoresdef match_twosided(desc1,desc2,threshold=0.5):matches_12 = match(desc1,desc2,threshold)matches_21 = match(desc2,desc1,threshold)ndx_12 = where(matches_12 >= 0)[0]for n in ndx_12:if matches_21[matches_12[n]] != n:matches_12[n] = -1  return matches_12def appendimages(im1,im2):rows1 = im1.shape[0]    rows2 = im2.shape[0]if rows1 < rows2:im1 = concatenate((im1,zeros((rows2-rows1,im1.shape[1]))),axis=0)elif rows1 > rows2:im2 = concatenate((im2,zeros((rows1-rows2,im2.shape[1]))),axis=0)return concatenate((im1,im2), axis=1)def plot_matches(im1,im2,locs1,locs2,matchscores,show_below=True):im3 = appendimages(im1,im2)if show_below:im3 = vstack((im3,im3)) imshow(im3)cols1 = im1.shape[1]for i,m in enumerate(matchscores):if m>0:plot([locs1[i][1],locs2[m][1]+cols1],[locs1[i][0],locs2[m][0]],'c')
axis('off')

以下是test.py文件

from pylab import *
from PIL import Image
import harris
import sift
import cv2 
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)def harris_points(im):harrisim = harris.compute_harris_response(im)harrisim1 = 255 - harrisimfigure()gray()suptitle("Harris")subplot(2,3,1)title("test picture")imshow(im)subplot(2,3,2)title("harris response")imshow(harrisim1)print (harrisim1.shape)threshold1 = 0.01threshold2 = 0.05threshold3 = 0.1filtered_coord1 = harris.get_harris_points(harrisim, 6, threshold1)filtered_coord2 = harris.get_harris_points(harrisim, 6, threshold2)filtered_coord3 = harris.get_harris_points(harrisim, 6, threshold3)print (im.shape)subplot(2, 3, 4)title("thres=0.01")imshow(im)plot([p[1] for p in filtered_coord1], [p[0] for p in filtered_coord1], '+c')subplot(2, 3, 5)title("thres=0.05")imshow(im)plot([p[1] for p in filtered_coord2], [p[0] for p in filtered_coord2], '+c')subplot(2, 3, 6)title("thres=0.1")imshow(im)plot([p[1] for p in filtered_coord3], [p[0] for p in filtered_coord3], '+c')axis('off')axis('equal')show() def harris_match(im1,im2,wid):harrisim1=harris.compute_harris_response(im1,5)filtered_coords1=harris.get_harris_points(harrisim1,wid+1)d1=harris.get_descriptors(im1,filtered_coords1,wid)harrisim2=harris.compute_harris_response(im2,5)filtered_coords2=harris.get_harris_points(harrisim2,wid+1)d2=harris.get_descriptors(im2,filtered_coords2,wid)print("starting harris matching")matches=harris.match_twosided(d1,d2)figure()gray()harris.plot_matches(im1,im2,filtered_coords1,filtered_coords2,matches)show()
if __name__ == '__main__':im = array(Image.open('D:\Computer vision\School picture\school1.jpg').convert('L'))im1 = array(Image.open('D:\Computer vision\School picture\school1.jpg').convert('L'))im2 = array(Image.open('D:\Computer vision\School picture\school11.jpg').convert('L'))wid=5harris_points(im)harris_match(im1,im2,wid)

实验结果如下所示:

(1)绘制角点

如图1所示,左上角图片为实验使用的灰度图像,第一行第二幅图代表使用Harris角点检测器的Harris响应函数,第二行三幅图分别为使用阈值为0.01检测出的角点图像,使用阈值为0.05检测出的角点图像,使用阈值为0.1检测出的角点图像,通过对比可以发现,使用的阈值越小,检测出的角点数量越多,使用的阈值越大,检测出的角点数量越少。当使用其他测试图像时,运行后的结果如图2、图3所示。对比图2、图3可以看到,当图像放大后,原来能检测到的角点就变成边线了,就检测不到了(对比图2、图3的红色标记框)这是Harris角点检测最大的缺陷,Harris角点检测不具有尺度不变性。

图 1 Harris绘制角点
图 2 Harris绘制角点(其他图像1)
图 3 Harris绘制角点(其他图像2)

(2)图像的特征匹配

 如图4所示,将归一化的互相关矩阵应用于Harris角点周围图像块,来寻找匹配对应点,图中以关键点为中心的邻域的大小,即descriptor描述符的窗口宽度wid=5,对于每一个关键点坐标 coords,都会提取以该点为中心、宽度为 wid 的邻域作为特征描述符。最后,所有的描述符被添加到一个列表 desc 中并返回。当修改窗口宽度wid=8时,结果如图5所示。当使用其他两幅相似的匹配图像时,结果如图6所示。当使用两幅内容不相似的图像时结果如图7所示。

图 4 wid=5
图 5 wid=8
图 6 匹配其他相似图像
图 7 匹配不相似图像
2.2 SIFT算法

以下是sift.py文件

import cv2
import numpy as np
import matplotlib.pyplot as pltdef sift_compute(img1,img2):sift = cv2.SIFT_create()kp1, des1 = sift.detectAndCompute(img1, None)kp2, des2 = sift.detectAndCompute(img2, None)FLANN_INDEX_KDTREE = 1index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)search_params = dict(checks=50)flann = cv2.FlannBasedMatcher(index_params, search_params)matches = flann.knnMatch(des1, des2, k=2)goodMatch = []for m, n in matches:if m.distance < 0.75*n.distance:goodMatch.append(m)goodMatch = np.expand_dims(goodMatch, 1)print("匹配点数量级结果: " + str(len(goodMatch)))#print(goodMatch[:50])img_out = cv2.drawMatchesKnn(img1, kp1, img2, kp2, goodMatch, None, flags=2)img_out_rgb = cv2.cvtColor(img_out, cv2.COLOR_BGR2RGB)plt.figure()plt.imshow(img_out_rgb)plt.show()

以下是test.py文件

def sift_process(img):gray= cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)sift = cv2.SIFT_create()kp,des=sift.detectAndCompute(gray,None)cv2.drawKeypoints(img,kp,img,flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)plt.figure(figsize=(8,6),dpi=100)plt.imshow(img[:,:,::-1]),plt.title('sift检测描述子',fontproperties=font)plt.xticks([]), plt.yticks([])plt.show()def sift_match(img1,img2):sift.sift_compute(img1,img2)if __name__ == '__main__':img = cv2.imread('School picture/school1.jpg')img1 = cv2.imread('D:/Computer vision/School picture/school1.jpg', cv2.IMREAD_GRAYSCALE)img2 = cv2.imread('D:/Computer vision/School picture/school11.jpg', cv2.IMREAD_GRAYSCALE)sift_process(img)sift_match(img1,img2)

实验结果如下所示:

(1)绘制描述子

图8为通过opencv使用SIFT算法检测绘制描述子的结果,结果图中显示描述子的方向、尺度信息。当使用其他测试图像时,运行后的结果如图9、图10所示,对比Harris检测,SIFT特征提取具有一定的鲁棒性,即使在图像发生较大变化的情况下,仍然能够找到相似的特征点并生成相应的描述子(对比图2、图3的红色标记框)。

图 8 SIFT描述子
图 9 SIFT描述子
图 10 SIFT描述子

(2)图像的特征匹配

如图11所示,使用OpenCV库中的SIFT算法来检测和计算图像的特征点和描述符,然后使用FLANN匹配器进行特征点匹配。最后将匹配结果绘制在一幅图像上并显示出来。当使用其他两幅相似的匹配图像时,结果如图12所示。当使用两幅不相似的图像时,结果如图13所示。当如果第一个匹配的距离小于第二个匹配距离的0.75倍,即(m.distance < 0.75*n.distance),匹配结果良好,当匹配距离的倍数过大或过小,会导致匹配结果较差(如图14、15)

图 11  m.distance < 0.75*n.distance
图 12 SIFT其他相似匹配图像
图 13 SIFT特征匹配不相似图像
图 14  m.distance < 0.2*n.distance
图 15  m.distance < 0.9*n.distance

三、实验小结

Harris角点检测产生的特征点为角点的位置信息,SIDT特征提取为每个特征点生成描述子,包括特征点的方向、尺度等信息。实验中发现,当图像发生缩放、亮度等变换时,Harris角点检测可能会丢失一些角点或产生新的角点,SIFT特征提取具有一定的鲁棒性。

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

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

相关文章

自动化实现的思路变化

阶段一&#xff1a; 1、成功调用。第一步&#xff0c;一般是用现用的工具&#xff0c;或者脚本成功调用接口 2、解决关联接口的参数传递。有的接口直接&#xff0c;存在参数的传递&#xff0c;一般的思路&#xff0c;就是将这个参数设置为变量。 3、简化代码。总会有些东西是重…

【AI非常道】二零二五年一月,AI非常道

经常在社区看到一些非常有启发或者有收获的话语&#xff0c;但是&#xff0c;往往看过就成为过眼云烟&#xff0c;有时再想去找又找不到。索性&#xff0c;今年开始&#xff0c;看到好的言语&#xff0c;就记录下来&#xff0c;一月一发布&#xff0c;亦供大家参考。 有关AI非…

牛客周赛 Round 78 A-C

A.时间表查询&#xff01; 链接&#xff1a;https://ac.nowcoder.com/acm/contest/100671/A 来源&#xff1a;牛客网 题目描述 今天是2025年1月25日&#xff0c;今年的六场牛客寒假算法基础集训营中&#xff0c;前两场比赛已经依次于 20250121、20250123 举行&#xff1b;而…

网安加·百家讲坛 | 樊山:数据安全之威胁建模

作者简介&#xff1a;樊山&#xff0c;锦联世纪教育能源工业互联网数字安全CSM(新能源运维师)课程特聘培训讲师&#xff0c;哈尔滨工业大学&#xff08;深圳&#xff09;信飞合创数据合规联合实验室特聘专家&#xff0c;武汉赛博网络安全人才研究中心资深专家&#xff1b;近24年…

java后端之登录认证

基础登录功能&#xff1a;根据提供的用户名和密码判断是否存在于数据库 LoginController.java RestController Slf4j public class LoginController {Autowiredprivate UserService userService;PostMapping("/login")public Result login(RequestBody User user) {…

【MCAL实战】MCU模块配置实践

目录 前言 正文 1.硬件分析 1.1 MCU系统模式分析 1.2MCU晶振使用分析 2.MCU通用配置 2.1 McuGeneralConfiguration 2.2 McuModuleConfiguration 2.3 McuResetSettingConf 2.4 McuTrapSettingConf 2.4 其他 3.MCU模式配置 3.1 McuModeSettingConf_0 3.2 McuModeSe…

基于SpringBoot的网上考试系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

Elastic Agent 对 Kafka 的新输出:数据收集和流式传输的无限可能性

作者&#xff1a;来 Elastic Valerio Arvizzigno, Geetha Anne 及 Jeremy Hogan 介绍 Elastic Agent 的新功能&#xff1a;原生输出到 Kafka。借助这一最新功能&#xff0c;Elastic 用户现在可以轻松地将数据路由到 Kafka 集群&#xff0c;从而实现数据流和处理中无与伦比的可扩…

【ROS2】RViz2界面类 VisualizationFrame 详解

1、简述 VisualizationFrame 继承自 QMainWindow 和 WindowManagerInterface; 窗口顶部是常规布局:菜单栏 和 工具栏 窗口中心是 RenderPanel,用来渲染3D画面 周围是dock区域,包括:DisplaysPanel、ViewsPanel、TimePanel、SelectionPanel 和 ToolPropertiesPanel Windo…

poi在word中打开本地文件

poi版本 5.2.0 方法1&#xff1a;使用XWPFFieldRun&#xff08;推荐&#xff09; 比如打开当前相对路径的aaaaa.docx XWPFFieldRun run paragraph.createFieldRun();CTRPr ctrPr run.getCTR().addNewRPr();CTFonts font ctrPr.addNewRFonts();// 设置字体font.setAscii(&quo…

Spring Boot应用中实现基于JWT的登录拦截器,以保证未登录用户无法访问指定的页面

目录 一、配置拦截器进行登录校验 1. 在config层设置拦截器 2. 实现LoginInterceptor拦截器 3. 创建JWT工具类 4. 在登录时创建JWT并存入Cookie 二、配置JWT依赖和环境 1. 添加JWT依赖 2. 配置JWT环境 本篇博客将为大家介绍了如何在Spring Boot应用中实现基于JWT的登录…

「 机器人 」扑翼飞行器控制的当前挑战与后续潜在研究方向

前言 在扑翼飞行器设计与控制方面,虽然已经取得了显著的进步,但在飞行时间、环境适应性、能量利用效率及模型精度等方面依旧存在亟待解决的挑战。以下内容概括了这些挑战和可能的改进路径。 1. 当前挑战 1.1 飞行时间短 (1)主要原因 能源存储有限(电池容量小)、驱动系…

pandas:loc索引器

loc索引器 使用的索引可能不是整数&#xff0c;而是自定义的&#xff01;&#xff01;&#xff01; 表的列索引 列索引是最常见的索引形式&#xff0c;一般通过[]来实现。通过[列名]可以从DataFrame中取出相应的列&#xff0c;返回值为Series。 import pandas as pd import…

3.2 Go 返回值详解

在 Go 语言中&#xff0c;函数调用完成后会产生一个返回值&#xff0c;该值的类型和数量取决于函数定义。返回值在函数调用结束时通过 return 语句返回&#xff0c;具体规则如下&#xff1a; 一. 返回值的基本规则 1.返回值类型&#xff1a; 返回值必须有类型&#xff0c;类…

PCIE模式配置

对于VU系列FPGA&#xff0c;当DMA/Bridge Subsystem for PCI Express IP配置为Bridge模式时&#xff0c;等同于K7系列中的AXI Memory Mapped To PCI Express IP。

关注搜索引擎蜘蛛压力

以前在建站的时候&#xff0c;他们说蜘蛛来抓取的频率越多越好&#xff0c;因为蜘蛛来抓取说明了网站更新速度快&#xff0c;受搜索引擎的欢迎&#xff0c;但是在最近的网站统计中&#xff0c;发现很多蜘蛛爬取的频次非常的高&#xff0c;比如有的蜘蛛一天能来网站几万次&#…

【Uniapp-Vue3】request各种不同类型的参数详解

一、参数携带 我们调用该接口的时候需要传入type参数。 第一种 路径名称?参数名1参数值1&参数名2参数值2 第二种 uni.request({ url:"请求路径", data:{ 参数名:参数值 } }) 二、请求方式 常用的有get&#xff0c;post和put 三种&#xff0c;默认是get请求。…

4070s显卡部署Deepseek R1

电脑配置&#xff1a; 处理器&#xff1a;AMD 7950X 内存&#xff1a;32G 硬盘&#xff1a;致态tiplus7100 2t 显卡&#xff1a;4070 super 12G 部署方法&#xff1a; 1. 到ollama官网下载安装ollama https://ollama.com/https://ollama.com/https://ollama.com/https://…

工业相机 SDK 二次开发-Sherlock插件

本文介绍了 sherlock 连接相机时的插件使用。通过本套插件可连接海康的工业相机。 一&#xff0e;环境配置 1. 拷贝动态库 在用户安装 MVS 目录下按照如下路径 Development\ThirdPartyPlatformAdapter 找到目 录为 DalsaSherlock 的文件夹&#xff0c;根据 Sherlock 版本找到…

three.js+WebGL踩坑经验合集(4.1):THREE.Line2的射线检测问题(注意本篇说的是Line2,同样也不是阈值方面的问题)

上篇大家消化得如何了&#xff1f; 笔者说过&#xff0c;1级编号不同的两篇博文相对独立&#xff0c;所以这里笔者还是先给出完整代码&#xff0c;哪怕跟&#xff08;3&#xff09;没有太大区别。 这里我们把线的粗细调成5&#xff08;排除难选中的因素&#xff09;&#xff…