2024.9.13 Python与图像处理新国大EE5731课程大作业,SIFT 特征和描述符,单应性矩阵透视变换

news2024/9/20 6:06:15

1.SIFT特征点和描述符

import cv2
import numpy as np
import matplotlib.pyplot as plt
# read image
img =cv2.imread('im01.jpg',cv2.IMREAD_COLOR)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
plt.imshow(gray,plt.cm.gray)

在这里插入图片描述
提取图片,以灰度图像输出

#SIFT
sift = cv2.SIFT_create()
# keypoints detection
kp,des = sift.detectAndCompute(gray,None)
# plot keypoints
cv2.drawKeypoints(img,kp,img,flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)

# plot
plt.figure(figsize=(8,6),dpi=100)
plt.imshow(img[:,:,::-1])
plt.title('SIFT')
plt.xticks([])
plt.yticks([])
plt.show

这段代码使用了 OpenCV 库中的 SIFT(Scale-Invariant Feature Transform)算法来检测图像的关键点(keypoints)并绘制它们。SIFT 是一种非常强大的图像特征提取算法,它能够检测图像中的局部特征,并且对缩放、旋转、亮度等变换具有鲁棒性。
代码逻辑:
1.创建 SIFT 对象
2.detectAndCompute() 是 SIFT 处理图像的关键函数。它接受一个灰度图像作为输入,并返回两个值:
kp (keypoints): 关键点,表示图像中的某些局部特征点的位置、尺度、方向等。每个关键点都有不同的属性,如坐标位置、尺度(表示特征点的大小)、方向等。
des (descriptors): 描述符,是关于每个关键点的特征向量。描述符是一个 128 维的向量,用于描述该特征点周围区域的特征信息。这些向量可以用于图像匹配或分类。
3.绘制关键点flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS: 使用这个标志,关键点会被以圆圈的形式绘制,并且每个圆圈的大小和方向会根据每个关键点的尺度和角度进行调整,使得你可以看到关键点的特性(即关键点的大小和方向)。
效果如下:
在这里插入图片描述
什么样的点会被认为是 SIFT 特征点?
角点(Corners): 图像中像素强度发生急剧变化的地方,比如边缘的交汇处。角点具有良好的局部不变性。
纹理丰富的区域: 图像中具有明显方向性或模式的区域,比如斑点或条纹。
图像中的独特结构: 比如物体的某些显著部分、边缘的转折点等。
SIFT 计算每个特征点周围的梯度信息,生成 128 维的描述符向量。这些描述符不仅能表示特征点周围的图像特征,还具有 旋转、缩放、光照不变性。这些描述符用于后续的图像匹配和识别。
在 SIFT 中,圈圈的大小代表每个关键点的 尺度(scale)。具体来说,SIFT 会在不同的尺度(即图像的不同分辨率)下检测图像中的特征点,这使得它可以检测到图像中大小不同的结构或特征。在绘制关键点时,圈圈的大小越大,表示该关键点的特征在更大的尺度上被检测到,也就是说,它代表了图像中较大的局部结构。

2.编写代码显示一个 GUI(图形用户界面),用户可以单击图像上的 4 个点。让用户选择 h1.jpg 上的 4 个点和 h2.jpg 上的 4 个点

%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from scipy import linalg
import random as rm
import math
import cv2
from tkinter import *
from tkinter import messagebox
from PIL import Image, ImageTk

# the interchange of window axis to image axis
event2canvas = lambda e, c: (c.canvasx(e.x), c.canvasy(e.y))

#function to be called when mouse is clicked
def printcoords(event):
    #outputting x and y coords to console
    cx, cy = event2canvas(event, canvas)
    # the axis of window and image is on the contrast
    click = [event.y,event.x,cy,cx]
    print ("(%d, %d) / (%d, %d)" % (event.y,event.x,cy,cx))
    points.append(click)
    i = len(points)
    canvas.create_text(300+i*50, 670, text="(%d,%d)"%(event.y,event.x),font=("Arial",10))

这段代码的主要工作是在引入合适的库,然后图像缩放与保存,坐标转换函数,用于在鼠标点击事件发生时,将窗口坐标系的坐标 e.x 和 e.y 转换为画布上的坐标然后是鼠标点击事件处理函数:
event.x 和 event.y 是鼠标点击的窗口坐标。
使用 event2canvas 函数将窗口坐标 event.x 和 event.y 转换为画布坐标 cx 和 cy。
click = [event.y, event.x, cy, cx] 将窗口坐标和转换后的画布坐标存储在 click 变量中,表示点击的位置。
print() 输出坐标到控制台。
points.append(click) 将点击的坐标点保存到 points 列表中,用于后续处理。
canvas.create_text() 在画布的指定位置(图像下方)显示鼠标点击的坐标,i 是点击的次数。

# build a window object
root = Tk()

#box for points
points=[]

#size of the window
root.geometry("900x700")
root.title("CA1 Part3")
canvas=Canvas(root,bg='white',width=900,height=700)
canvas.pack()
# label = Label(root,text="You need to click 4 points on h1",font=("Arial",25),fg="black")

#setting up a tkinter canvas with scrollbars
# not use in this task
# frame = Frame(root, bd=2, relief=SUNKEN)
# frame.grid_rowconfigure(0, weight=1)
# frame.grid_columnconfigure(0, weight=1)
# xscroll = Scrollbar(frame, orient=HORIZONTAL)
# xscroll.grid(row=1, column=0, sticky=E+W)
# yscroll = Scrollbar(frame)
# yscroll.grid(row=0, column=1, sticky=N+S)
# canvas = Canvas(frame, bd=0, xscrollcommand=xscroll.set, yscrollcommand=yscroll.set)
# canvas.grid(row=0, column=0, sticky=N+S+E+W)
# xscroll.config(command=canvas.xview)
# yscroll.config(command=canvas.yview)
# frame.pack(fill=BOTH,expand=1)

#adding the image
img_h1 = Image.open('h1_1.jpg')
img_h1_photo = ImageTk.PhotoImage(img_h1)
img_h2 = Image.open('h2.jpg')
img_h2_photo = ImageTk.PhotoImage(img_h2)

Im = canvas.create_image(0,0,image=img_h1_photo,anchor=NW)
canvas.config(scrollregion=canvas.bbox(ALL))
Tx = canvas.create_text(200, 620, text="You need to click 4 points on h1",font=("Arial",20))
canvas.create_text(180, 670, text="The position of the points:",font=("Arial",20))

#mouseclick event
canvas.bind("<ButtonPress-1>",printcoords)

def change_img():
    # set the event of button
    canvas.itemconfig(Im,image=img_h2_photo) 
    canvas.itemconfig(Tx,text="You need to click 4 points on h2")


# set button
button = Button(root, text='Change to h2', command=change_img)  
button.place(x=750, y=650)

# start
root.mainloop()

代码逻辑:
1.这里创建了一个 Tkinter 的根窗口 root,并将其大小设置为 900x700 像素。canvas 是一个 Tkinter 的画布对象,用于在窗口中绘制图像和文本,并作为鼠标点击事件的区域。
2.载入与显示图像,并转换成Tkingter的格式
3.显示提示信息
4.鼠标点击事件的绑定
5.图像切换功能
6.mainloop() 方法启动 Tkinter 的事件循环,等待用户的操作,并保持窗口持续运行。
初始状态下,窗口中显示 h1_1.jpg 图像,并在底部提示用户点击四个点。每次点击鼠标左键后,程序会输出点击的坐标。
窗口下方有一个按钮,点击该按钮后,画布上的图像会从 h1_1.jpg 切换为 h2.jpg,提示信息也会随之改变为“你需要在 h2 上点击 4 个点”。
注释掉的部分是窗口滑轮的部分

3.单应性矩阵

计算h1.jpg到h2.jpg的单应性矩阵,并显示单应性矩阵。利用单应性矩阵将h1.jpg转换为h2.jpg,并显示结果:

# H: homography computing
def hmat(points):
    A = np.zeros([8,9])
    b = []
    for i in range(0,4):
        # A matrix
        h1_x = points[i][2]
        h1_y = points[i][3]
        h2_x = points[i+4][2]
        h2_y = points[i+4][3]
        A[2*i][:] = [h1_x,h1_y,1,0,0,0,-h2_x*h1_x,-h2_x*h1_y,-h2_x]
        A[2*i+1][:] = [0,0,0,h1_x,h1_y,1,-h2_y*h1_x,-h2_y*h1_y,-h2_y]

    # SVD 
    _, _, vt = linalg.svd(A)
    H = vt[-1].reshape(3,3)
    # H(3,3) = 1
    H = H / H[2,2] 

    return H

这段代码用于计算单应性矩阵(Homography matrix),它用于在两个图像平面之间进行变换。单应性矩阵是一种 3x3 的矩阵,通常用于将一个平面的点映射到另一个平面,比如从图像 h1 上的四个点映射到图像 h2 上的四个对应点。通过给定的 4 对对应点,代码可以计算出用于变换的单应性矩阵 H。points 是一个包含 8 个点击点的数组,前 4 个点对应图像 h1,后 4 个点对应图像 h2
这时候我们已经可以计算单应性矩阵了,接下来就是计算环节。

# import image
h1 = cv2.imread('h1_1.jpg',cv2.IMREAD_COLOR)
h2 = cv2.imread('h2.jpg',cv2.IMREAD_COLOR)
# from BGR to RGB, CV2 default reading BGR
h1 = cv2.cvtColor(h1, cv2.COLOR_BGR2RGB)
h2 = cv2.cvtColor(h2, cv2.COLOR_BGR2RGB)

# compute the size of the image after transmitting
def get_size(h1,H):
    [row,col,c] = h1.shape
    
    # 4 cornor of the image h1
    lt = np.array([[0,0,1]])
    rt = np.array([[0,col,1]])
    lb = np.array([[row,0,1]])
    rb = np.array([[row,col,1]])
    
    # edge matrix
    edge = np.concatenate((lt,rt,lb,rb),axis = 0).T

    T_edge = np.dot(H,edge)
    # normalize
    T_edge = T_edge[0:2,:]/T_edge[2,:]
    T_edge = T_edge
    print(T_edge)
    
    return np.max(T_edge[0,:]),np.min(T_edge[0,:]),np.max(T_edge[1,:]),np.min(T_edge[1,:])

# transform h1 to h2
def transfer(h1,H):
    
    # get output size
    [max_x, min_x, max_y, min_y] = get_size(h1,H)
    print([max_x, min_x, max_y, min_y])
    x_diff = int(round(max_x - min_x+10))
    y_diff = int(round(max_y - min_y+10))

    [row,col,c] = h1.shape
    # initialize the output image 
    h12h2 = np.zeros([x_diff+100,y_diff+100,c])
#     print(h1.shape,h12h2.shape)

    for j in range(0,row):
        for k in range(0,col):
            # h1 positon
            p = np.array([[j,k,1]]).T
            Tp = np.dot(H,p)
            
            # normalize and move the image to the central
            x = int(round(Tp[0,0]/Tp[2,0])-min_x)
            y = int(round(Tp[1,0]/Tp[2,0])-min_y)

            h12h2[x,y] = h1[j,k][:]

    return h12h2.astype(int)

# show the original image h1

plt.imshow(h1)
# transfer h1 to h2 plane
h12h2 = transfer(h1,H)
plt.imshow(h12h2)
  1. 图像读取与颜色空间转换
  2. 计算转换后的图像尺寸(get_size 函数)
  3. 图像转换(transfer 函数)
  4. 可视化原始图像

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

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

相关文章

【免费分享】OpenHarmony鸿蒙物联网开发板资料包一网打尽,附教程/视频/项目/源码...

想要深入学习鸿蒙设备开发及鸿蒙物联网开发吗&#xff1f;现在机会来了&#xff01;我们为初学者们准备了一份全面的资料包&#xff0c;包括原理图、教程、视频、项目、源码等&#xff0c;所有资料全部免费领取&#xff0c;课程视频可试看&#xff08;购买后看完整版&#xff0…

带你深入了解C语言指针(二)

目录 前言一、数组名的理解二、使用指针访问数组三、⼀维数组传参的本质四、冒泡排序五、二级指针六、指针数组七、 指针数组模拟⼆维数组总结 前言 前面我们基本了解了C语言指针的概念&#xff0c;也初步开启了指针的用处&#xff0c;这期我们主要围绕数 组展开&#xff0c;也…

学生请假管理系统

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 学生请假管理系统拥有两种角色 管理员&#xff1a;班级管理、课程管理、学生管理、审核请假信息、导出请假单 学生&#xff1a;填写请假单、查看请假审核情况 1.1 背景描述 学生请假管…

GIS应届生不考研,不考公,不考编,未来要怎么安排?

01 考公考研or就业 一直以来&#xff0c;大学生毕业去向的话题就居高不下。 近日&#xff0c;便有“不考研不考公&#xff0c;未来要怎么样&#xff1f;”的话题&#xff0c;出现在某社交媒体热榜&#xff0c;迅速引起54.5万人围观。 国内本科毕业后大学生的出路无外乎&…

什么空气净化器可以除猫毛?范罗士、希喂、小米、IAM、安德迈横测谁是毛克星

秋季掉毛季来咯&#xff0c;每入掉毛季&#xff0c;我们医院鱼油销量都暴涨。都是被家里猫猫、狗狗掉毛折腾得没办法了&#xff0c;想喂点鱼油&#xff0c;减少点掉毛。鱼油含有丰富的Ω-3&#xff0c;能够调节皮脂分泌&#xff0c;减轻炎症反应。平时喂点对宠物身体是有好处的…

矩阵引流助手有试用吗

矩阵引流助手有试用吗 还在为内容和流量曝光发愁吗&#xff1f;来了解一下矩阵工具让你事半功倍 #矩阵工具 #矩阵管理 #矩阵引流 推荐阅读&#xff1a; 短视频代运营代发 短视频代运营代发帖https://www.bsw80.com/post/111.html 抖音通过矩阵获客&#xff0c;我告诉大家新上…

Qt/C++ 了解NTFS文件系统,解析盘符引导扇区数据获取MFT(Master File Table)主文件表偏移地址

系列文章目录 一、Qt/C 了解NTFS文件系统&#xff0c;了解MFT(Master File Table)主文件表&#xff08;一&#xff09; 二、Qt/C 了解NTFS文件系统&#xff0c;解析盘符引导扇区数据获取MFT(Master File Table)主文件表偏移地址 目录导读 系列文章目录前言BOOTICE工具介绍读取…

防止文件外发泄密有什么方法?这7防外发方式可以看下!

防止文件外发泄密有什么方法&#xff1f; 一、使用防泄密软件外发&#xff1a;可对发送的文件进行权限设定。接收&#xff1a;可查看次数、可查看时间复制、修改、打印、外发受到限制。文件外发控制&#xff1a;以对外发的文件进行权限设定&#xff0c;如可打开的次数、可打开时…

基于JavaWeb开发的java ssm springboot+VUE疫情防疫系统系统前后端分离设计和实现

基于JavaWeb开发的java ssm springbootVUE疫情防疫系统系统前后端分离设计和实现 &#x1f345; 作者主页 网顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取…

【深度学习】【OnnxRuntime】【Python】模型转化、环境搭建以及模型部署的详细教程

【深度学习】【OnnxRuntime】【Python】模型转化、环境搭建以及模型部署的详细教程 提示:博主取舍了很多大佬的博文并亲测有效,分享笔记邀大家共同学习讨论 文章目录 【深度学习】【OnnxRuntime】【Python】模型转化、环境搭建以及模型部署的详细教程前言模型转换--pytorch转on…

文件系统(磁盘 磁盘文件 inode)

文章目录 磁盘看看物理磁盘磁盘的存储结构 对磁盘的储存进行逻辑抽象inode号文件名 -> inode判断文件在哪个分区 磁盘 电脑中存在非常多的文件&#xff0c;被打开的文件只是少量的。 没有被打开的文件&#xff0c;在磁盘中放着&#xff0c;那么文件是如何存取&#xff1f; …

Unity 之 【Android Unity FBO渲染】之 [Unity 渲染 Android 端播放的视频] 的一种方法简单整理

Unity 之 【Android Unity FBO渲染】之 [Unity 渲染 Android 端播放的视频] 的一种方法简单整理 目录 Unity 之 【Android Unity FBO渲染】之 [Unity 渲染 Android 端播放的视频] 的一种方法简单整理 一、简单介绍 二、FBO 简单介绍 三、案例实现原理 四、注意事项 五、简…

深度盘点PLM 项目管理系统哪家强?优缺点一目了然!

本文将盘点10款知名的PLM 项目管理系统&#xff0c;为企业选型提供参考&#xff01; 想象一下&#xff0c;在一个企业的产品研发过程中&#xff0c;各种数据、文档四处散落&#xff0c;不同部门之间沟通不畅&#xff0c;项目进度难以把控。这时&#xff0c;PLM 项目管理系统就如…

在线压缩图片地址

https://squoosh.app/editor这个是免费的&#xff0c;并且不限制图片数量 https://tinypng.com/ 这个限制图片的大小&#xff0c;如果单张图片超过5M需要收费 https://www.jpeg-optimizer.com/ https://imagecompressor.com/

再次进阶 舞台王者 第八季完美童模全球赛形象大使【于洪森】赛场秀场超燃合集!

7月20-23日&#xff0c;2024第八季完美童模全球总决赛在青岛圆满落幕。在盛大的颁奖典礼上&#xff0c;一位才能出众的少年——于洪森&#xff0c;迎来了他舞台生涯的璀璨时刻。 形象大使——于洪森&#xff0c;以璀璨童星之姿&#xff0c;优雅地踏上完美童模盛宴的绚丽舞台&am…

WPF实现Hammer 3D入门学习

代码下载&#xff1a;https://download.csdn.net/download/bjhtgy/89748674

springboot Web基础开发

Spring Boot 是一个用于简化 Spring 应用开发的框架&#xff0c;它通过自动配置和开箱即用的功能&#xff0c;使得创建和部署 Spring 应用变得更为高效。以下是 Spring Boot 基础 Web 开发的一些关键点和实操总结&#xff1a; 1. 项目搭建 使用 Spring Initializr: 访问 Spring…

代码随想录刷题day31丨56. 合并区间,738.单调递增的数字,总结

代码随想录刷题day31丨56. 合并区间&#xff0c;738.单调递增的数字&#xff0c;总结 1.题目 1.1合并区间 题目链接&#xff1a;56. 合并区间 - 力扣&#xff08;LeetCode&#xff09; 视频讲解&#xff1a;贪心算法&#xff0c;合并区间有细节&#xff01;LeetCode&#x…

源代码加密软件有哪些?2024常用的10款好用的企业源代码加密软件分享!

源代码作为企业的核心资产&#xff0c;一旦泄露&#xff0c;将可能导致技术被窃取、产品被复制&#xff0c;甚至引发法律纠纷。 一、企业源代码泄密的危害详情描述 企业源代码泄密事件频发&#xff0c;其危害不容小觑。 一方面&#xff0c;源代码的泄露可能导致企业的核心技术…

国内领先线上运动平台:如何借助AI技术实现业务腾飞与用户体验升级

“ 从智能训练到身体分析&#xff0c;再到辅助判决&#xff0c;AI技术正以惊人的速度渗透进体育和健身领域&#xff0c;为运动员和健身爱好者提供了前所未有的个性化体验。 ” AI&#xff0c;运动的智能伴侣 在巴黎奥运会上&#xff0c;AI技术的运用成为了焦点。它不仅为运动…