当前位置: 首页 > news >正文

OpenCV 特征点检测与匹配

一 OpenCV特征场景

①图像搜索,如以图搜图;
②拼图游戏;
③图像拼接,将两长有关联得图拼接到一起;

1 拼图方法

寻找特征
特征是唯一的
可追踪的
能比较的

二 角点

在特征中最重要的是角点
灰度剃度的最大值对应的像素
两条线的角点
极值点(一阶导数最大值,但二阶导数为0)

三 Harris角点

哈里斯角点检测
在这里插入图片描述
Harris点
① 光滑地区,无论向哪里移动,衡量系数不变;
②边缘地址,垂直边缘移动时,衡量系统变换剧烈;
③在交点处,往哪个方向移动,衡量系统都变化剧烈;

1 Harris角点检测API

cornerHarris(img,dst,blockSize,ksize,k)
blockSize:检测窗口大小
ksize:Sobel的卷积核
k:权重系数,经验值,一般取0.02~0.04之间。
import cv2
import numpy as npblockSize=2ksize=1k=0.04img=cv2.imread('chess.jpg')#灰度化
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#Harris角点检测
dst=cv2.cornerHarris(gray,blockSize,ksize,k)#Harris角点的展示
img[dst>0.04*dst.max()]=[0,0,255]
cv2.imshow('img',img)
cv2.waitKey(0)

四 Shi_Tomasi交点检测

Shi-Tomasi是Harris角点检测的改进;
Harris角点检测的稳定性和K有关,而k是个经验值,不好设定最佳值。

1 Shi-Tomasi角点检测API

goodFeaturesToTrack(img,maxCorners,...)
maxCorners:角点的最大数,值为0表示无限制
qualityLevel:小于1.0的正数,一般在0.01~0.1之间
minDistance:角之间最小欧式距离,忽略小于此距离的点。
mask:感兴趣的区域
blockSize:检测窗口
useHarrisDetector:是否使用Harris算法
k:默认是0.04
import cv2
import numpy as npmaxCorners=100
ql=0.01img=cv2.imread('./chess.jpg')
cv2.imshow('img',img)
#灰度化
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)# Shi-Tomasi
corners=cv2.goodFeaturesToTrack(gray,maxCorners,ql,10)
print(corners)
corners=np.int32(corners)
# Shi-Tomasi绘制角点
for i in corners:x,y=i.ravel()cv2.circle(img,(x,y),3,(255,0,0),-1)cv2.imshow('img',img)
cv2.waitKey(0)

五 SIFT(Scale-Invariant Feature Transform)

SIFT出现的原因:
harris 角点具有旋转不变的特性;
但缩放后,原来的角点有可能就不是角点了;

图放大
在这里插入图片描述

使用SIFT的步骤

①创建SIFT对象
②进行检测,kp=sift.detect(img,…)
③绘制关键点,drawKeypoints(gray,kp,img)

from email.mime import imageimport cv2
import numpy as npimg=cv2.imread('./chess.jpg')gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)sift=cv2.xfeatures2d.SIFT_create()kp=sift.detect(gray,None)cv2.drawKeypoints(gray,kp,img)cv2.imshow('img',img)
cv2.waitKey(0)

在这里插入图片描述

六 SIFT计算描述子

关键点和描述子
关键点:位置,大小和方向
关键点描述子:记录了关键点周围对其有贡献的像素点的一组向量值,其不受仿射变换、光照变换等影响。

计算描述子

kp,des=sift.compute(img,kp)
其作用是进行特征匹配

同时计算关键点和描述

kp,des=sift.detectAndCompute(img,...)
mask:指明对img中哪个区域进行计算
import cv2
import numpy as npimg=cv2.imread('./chess.jpg')gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)sift=cv2.xfeatures2d.SIFT_create()kp,des=sift.detectAndCompute(gray,None)
print(des)
cv2.drawKeypoints(gray,kp,img)cv2.imshow('img',img)
cv2.waitKey(0)

在这里插入图片描述

七 SURF特征检测

SURF的优点
SIFT最大的问题是速度慢,因此才有SURF

使用SURF的步骤

surf=cv2.xfeatures2d.SUFR_create()
kp,des=surf.detectAndCompute(img,mask)
import cv2
import numpy as npimg=cv2.imread('./chess.jpg')gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)surf=cv2.xfeatures2d.SURF_create()kp,des=surf.detectAndCompute(gray,None)print(des[0])cv2.drawKeypoints(gray,kp,img)cv2.imshow('img',img)
cv2.waitKey(0)

八 ORB(Oriented FAST and Rotated BRIEF)特征检测

1 ORB 优势

①ORB可以做到实时检测
②ORB=Oriented FAST+Rotated BRIEF

2 FAST

可以做到特征点的实时检测

3 BRIEF

BRIEF是对已检测到的特征点进行描述,它加快了特征描述符建立的速度。同时也极大的降低了特征匹配的时间。

3 ORB使用步骤

orb=cv2.ORB_create()
kp,des=orb.detectAndCompute(img,mask)
import cv2
import numpy as npimg=cv2.imread('./chess.jpg')gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)orb=cv2.ORB_create()kp,des=orb.detectAndCompute(gray,None)cv2.drawKeypoints(gray,kp,img)cv2.imshow('img',img)
cv2.waitKey(0)

在这里插入图片描述

九 暴力特征匹配

1 特征匹配方法

①BF(Brute-Force),暴力特征匹配方法;
②FLANN最快邻近区特征匹配方法;
它使用第一组中的每个特征的描述子与第二组中的所有特征描述子进行匹配计算它们之间的差距,然后将最接近一个匹配返回。

2 OpenCV特征匹配步骤

创建匹配器,BFMatcher(normType,crossCheck)
进行特征匹配,bf.match(des1,des2)
绘制匹配点,cv2.drawMatches(img1,kp1,img2,k2,...)
BFMatcher
normType:NORM_L1,NORM_L2,HAMMING1....
crossCheck:是否进行交叉匹配,默认为false
Match方法
参数为SIFT,SURF,OBR等计算的描述子
对两幅图的描述子进行计算
drawMatches
搜索img,kp
匹配图img,kp
match()方法返回的匹配结果
import cv2
import numpy as npimg=cv2.imread('./opencv_search.png')
img1=cv2.imread('./opencv_orig.png')gray=cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray1=cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)sift=cv2.xfeatures2d.SIFT_create()kp1,des1=sift.detectAndCompute(gray,None)
kp2,des2=sift.detectAndCompute(gray1,None)bf=cv2.BFMatcher(cv2.NORM_L1)
match=bf.match(des1,des2)img3=cv2.drawMatches(img,kp1,img1,kp2,match,None)cv2.imshow('img3',img3)
cv2.waitKey(0)

在这里插入图片描述

十 FLANN特征匹配

1 FLANN优缺点

在进行批量特征匹配时,FLANN速度更快;
由于它使用的是邻近近似值,所以精度较差;

2 使用FLANN特征匹配的步骤

①创建FLANN匹配器,FlannBasedMatcher(...)
②进行特征匹配,flann.match/knnMatch(...)
③绘制匹配点,cv2.drawMathes/drawMatchesKnn(...)
FlannBasedMathcer
index_params字典:匹配算法KDTREE、LSH
search_params字典:指定KETREE算法中遍历树的次数
KDTREE
index_params=dict(algorithmFLANN_INDEX_KETREE,trees=5)
search_params
search_params=dict(checks=50)
knnMatch方法
参数为SIFT、SURF、ORB等计算的描述子;
k,表示取欧式距离最近的前k个关键点;
返回的是匹配的结果DMatch对象;
DMatch的内容
distance,描述子之间的距离,值越低越好;
queryIdx,第一个图像的描述子索引值;
trainIdx,第二个图的描述子索引值;
imgIdx,第二个图的索引值;drawMatchesKnn
搜索img,kp
匹配图img,kp
match()方法返回的匹配结果

十一 实战FLANN特征匹配

import cv2
import numpy as npimg1=cv2.imread('opencv_search.png')
img2=cv2.imread('opencv_orig.png')gray1=cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)
gray2=cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)#创建SIFT特征
sift=cv2.xfeatures2d.SIFT_create()#计算描述子与特征
kp1,des1=sift.detectAndCompute(img1,None)
kp2,des2=sift.detectAndCompute(img2,None)# 创建匹配器
index_params=dict(algorithm=1,trees=5)
search_params=dict(checks=50)
flann=cv2.FlannBasedMatcher(index_params,search_params)#对描述子进行匹配计算
matchs=flann.knnMatch(des1,des2,k=2)good=[]
for i,(m,n)in enumerate(matchs):if m.distance<0.7*n.distance:good.append(m)ret=cv2.drawMatchesKnn(img1,kp1,img2,kp2,[good],None)cv2.imshow('result',ret)
cv2.waitKey(0)

在这里插入图片描述

十二 图像查找

1 图像查找

特征匹配+单应性矩阵

什么是单应性矩阵
在这里插入图片描述

import cv2
import numpy as npimg1=cv2.imread('opencv_search.png')
img2=cv2.imread('opencv_orig.png')gray1=cv2.cvtColor(img1,cv2.COLOR_BGR2GRAY)
gray2=cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)#创建SIFT特征
sift=cv2.xfeatures2d.SIFT_create()#计算描述子与特征
kp1,des1=sift.detectAndCompute(img1,None)
kp2,des2=sift.detectAndCompute(img2,None)# 创建匹配器
index_params=dict(algorithm=1,trees=5)
search_params=dict(checks=50)
flann=cv2.FlannBasedMatcher(index_params,search_params)#对描述子进行匹配计算
matchs=flann.knnMatch(des1,des2,k=2)good=[]for i,(m,n) in enumerate(matchs):if m.distance<0.7*n.distance:good.append(m)if len(good)>=4:#print(len(good.trainIdx))srcPts = np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1, 1, 2)dstPts = np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1, 1, 2)H, _ = cv2.findHomography(srcPts, dstPts, cv2.RANSAC, 5.0)h, w = img1.shape[:2]pts = np.float32([[0, 0], [0, h - 1], [w - 1, h - 1], [w - 1, 0]]).reshape(-1, 1, 2)dst = cv2.perspectiveTransform(pts, H)cv2.polylines(img2, [np.int32(dst)], True, (0, 0, 255))
else:print('the number of god is less than 4')exit()ret=cv2.drawMatchesKnn(img1,kp1,img2,kp2,[good],None)cv2.imshow('resutl',ret)cv2.waitKey(0)

十三 图像拼接

1 图像合并的步骤

读文件并重置尺寸;
根据特征点和计算描述子,得到单应性矩阵;
图像变换;
图像拼接并输出图像;

import cv2
import numpy as np#第一步 读取文件,将图片设置成一样大小640x640
#第二步 找特征点,描述子,计算单应性矩阵
#第三步 根据单应性矩阵对图像进行变换,然后平移
#第四步 拼接并输出最终结果#读取两张图片
img1=cv2.imread('map1.png')
img2=cv2.imread('map2.png')#将两张同样图片设置成同样大小
img1=cv2.resize(img1,(640,480))
img2=cv2.resize(img2,(640,480))inputs=np.hstack((img1,img2))
cv2.imshow('input img',inputs)
cv2.waitKey(0)
import cv2
import numpy as npdef stitch_image(img1,img2,H):
#获得每张图片的四个角点
#对图片进行变换(单应性矩阵使图进行旋转,平移)
#创建一张大图,将两张图拼接到一起
#将结果输出#获得原始图的高/宽h1,w1=img1.shape[:2]h2,w2=img2.shape[:2]img1_dims=np.float32([[0,0],[0,h1],[w1,h1],[w1,0]]).reshape(-1,1,2)img2_dims=np.float32([[0,0],[0,h2],[w2,h2],[w2,0]]).reshape(-1,1,2)img1_transform=cv2.perspectiveTransform(img1_dims,H)result_dims=np.concatenate((img2_dims,img1_transform),axis=0)[x_min, y_min] = np.int32(result_dims.min(axis=0).ravel() - 0.5)[x_max, y_max] = np.int32(result_dims.max(axis=0).ravel() + 0.5)#平移的距离transform_dist=[-x_min,-y_min]transform_array=np.array([[1,0,transform_dist[0]],[0,1,transform_dist[1]],[0,0,1]])result_img=cv2.warpPerspective(img1,transform_array.dot(H),(x_max-x_min,y_max-y_min))result_img[transform_dist[1]:transform_dist[1]+h2,transform_dist[0]:transform_dist[0]+w2]=img2return result_img#第一步 读取文件,将图片设置成一样大小640x640
#第二步 找特征点,描述子,计算单应性矩阵
#第三步 根据单应性矩阵对图像进行变换,然后平移
#第四步 拼接并输出最终结果def get_homo(img1,img2):
#创建特征转换对象
#通过特征转换对象获得特征点和描述子
#创建特征匹配器
#进行特征匹配
#过滤特征,找出有效的特征匹配点sift=cv2.xfeatures2d.SIFT_create()k1,d1=sift.detectAndCompute(img1,None)k2,d2=sift.detectAndCompute(img2,None)#创建特征匹配bf=cv2.BFMatcher()matches=bf.knnMatch(d1,d2,k=2)
#过滤特征,找出有效的特征匹配点verify_ratio=0.8verify_matches=[]for m1,m2 in matches:if m1.distance<0.8*m2.distance:verify_matches.append(m1)min_matches=8if len(verify_matches)>min_matches:img1_pts=[]img2_pts=[]for m in verify_matches:img1_pts.append(k1[m.queryIdx].pt)img2_pts.append(k2[m.trainIdx].pt)img1_pts=np.float32(img1_pts).reshape(-1,1,2)img2_pts=np.float32(img2_pts).reshape(-1,1,2)H,mask=cv2.findHomography(img1_pts,img2_pts,cv2.RANSAC,5.0)return Helse:print("err:Not enough matches!")exit()
#第一步 读取文件,将图片设置成一样大小640x480
#第二步 找特征点,描述子,计算单应性矩阵
#第三步 根据单应性矩阵对图像进行变换,然后平移
#第四步 拼接并输出最终结果#读取两张图片
img1=cv2.imread('map1.png')
img2=cv2.imread('map2.png')#将两张同样图片设置成同样大小
img1=cv2.resize(img1,(640,480))
img2=cv2.resize(img2,(640,480))inputs=np.hstack((img1,img2))#获得单应性矩阵
H=get_homo(img1,img2)#进行图像拼接
result_image=stitch_image(img1,img2,H)cv2.imshow('input img',inputs)
cv2.waitKey(0)

相关文章:

OpenCV 特征点检测与匹配

一 OpenCV特征场景 ①图像搜索&#xff0c;如以图搜图&#xff1b; ②拼图游戏&#xff1b; ③图像拼接&#xff0c;将两长有关联得图拼接到一起&#xff1b; 1 拼图方法 寻找特征 特征是唯一的 可追踪的 能比较的 二 角点 在特征中最重要的是角点 灰度剃度的最大值对应的…...

css布局之flex应用

/*父 100*/.parent-div {/* 这里添加你想要的属性 */display: flex;flex-direction: row; //行justify-content: space-between; //左右对齐align-items: center;flex-wrap: wrap; //换行}/*中 90 10 */.middle-div {/* 这里添加你想要的属性 */display: flex;flex-direction:…...

树莓派4B设置AP热点步骤

树莓派4B设置AP热点步骤&#xff1a;先进入root模式 预先进行apt-get update 第1步&#xff1a;安装network-manager ​sudo apt-get install network-manager第2步&#xff1a;安装git apt-get install git apt-get install util-linux procps hostapd iproute2 iw haveged …...

Java程序之百鸡百钱问题

题目&#xff1a; 百钱买百鸡的问题算是一套非常经典的不定方程的问题&#xff0c;题目很简单&#xff1a;公鸡5文钱一只&#xff0c;母鸡3文钱一只&#xff0c;小鸡3只一文钱&#xff0c;用100文钱买一百只鸡,其中公鸡&#xff0c;母鸡&#xff0c;小鸡都必须要有&#xff0c;…...

Mybatis——动态sql

if标签 用于判断条件是否成立。使用test属性进行条件判断&#xff0c;如果条件为true&#xff0c;则拼接sql。 <where>标签用于识别语句是否需要连接词and&#xff0c;识别sql语句。 package com.t0.maybatisc.mapper;import com.t0.maybatisc.pojo.Emp; import org.a…...

可视化大屏开发系列——页面布局

页面布局是可视化大屏的基础&#xff0c;想要拥有一个基本美观的大屏&#xff0c;就得考虑页面整体模块的宽高自适应&#xff0c;我们自然就会想到具有强大灵活性flex布局&#xff0c;再借助百分比布局来辅助。至此&#xff0c;大屏页面布局问题即可得到解决。 可视化大屏开发系…...

Python statistics 模块

Python 的 statistics 模块提供了一组用于执行各种统计计算的函数&#xff0c;包括平均值、中位数、标准差、方差以及其他统计量。让我来简单介绍一下。 首先&#xff0c;你可以使用以下方式导入 statistics 模块&#xff1a; python import statistics 接下来&#xff0c;…...

wireshark常见使用表达式

目录 1. 捕获过滤器 (Capture Filters)基本捕获过滤器组合捕获过滤器 2. 显示过滤器 (Display Filters)基本显示过滤器复杂显示过滤器协议特定显示过滤器 3. 进阶显示过滤器技巧使用函数和操作符逻辑操作符 4. 常见网络协议过滤表达式示例HTTP 协议HTTPS 协议DNS 协议DHCP 协议…...

用Java获取键盘输入数的个十百位数

这段Java代码是一个简单的程序&#xff0c;用于接收用户输入的一个三位数&#xff0c;并将其分解为个位、十位和百位数字&#xff0c;然后分别打印出来。下面是代码的详细解释&#xff1a; 导入所需类库: import java.util.Scanner;&#xff1a;导入Scanner类&#xff0c;用于从…...

第10章 启动过程组 (制定项目章程)

第10章 启动过程组 9.1制定项目章程&#xff0c;在第三版教材第356~360页&#xff1b; 文字图片音频方式 视频12 第一个知识点&#xff1a;主要输出 1、项目章程&#xff08;重要知识点&#xff09; 项目目的 为了稳定与发展公司的客户群(抽象&#xff0c;非具体) 可测量的项目…...

html侧导航栏客服栏

ico 替换 ICO <html xmlns"http://www.w3.org/1999/xhtml"><head><meta http-equiv"Content-Type" content"text/html; charsetutf-8"><title>返回顶部</title><script src"js/jquery-2.0.3.min.js"…...

Clonable接口和拷贝

Hello~小伙伴们&#xff01;本篇学习Clonable接口与深拷贝&#xff0c;一起往下看吧~(画图水平有限&#xff0c;两张图&#xff0c;&#xff0c;我真的画了巨久&#xff0c;求路过的朋友来个3连~阿阿阿~~~) 目录 1、Clonable接口概念 2、拷贝 2、1浅拷贝 2、2深拷贝 1、Clon…...

关于小蛋の编程和小蛋编程为同一作者的说明

小蛋の编程和小蛋编程的作品为同一人制作&#xff0c;因前者为父母的手机号进行注册&#xff0c;现用本人手机号注册了新账号小蛋编程&#xff0c;后续文章将在新账号小蛋编程上进行刊登&#xff0c;同时在小蛋编程上对原账号文章进行转载。此账号不再发布帖子&#xff0c;请大…...

大数据平台之Spark

Apache Spark 是一个开源的分布式计算系统&#xff0c;主要用于大规模数据处理和分析。它由UC Berkeley AMPLab开发&#xff0c;并由Apache Software Foundation维护。Spark旨在提供比Hadoop MapReduce更快的处理速度和更丰富的功能&#xff0c;特别是在处理迭代算法和交互式数…...

How to use ModelSim

How to use ModelSim These are all written by a robot Remember, you can only simulate tb files....

【专业英语 复习】第8章 Communications and Networks

1. 单选题 One of the most dramatic changes in connectivity and communications in the past few years has been ____. A. widespread use of mobile devices with wireless Internet connectivity B. chat rooms C. satellite uplinks D. running programs on rem…...

运行vue3项目相关报错

1. VSCode打开TSVue3项目很多地方报错 报错内容 几乎所有文件都会出现未知飘红 error Delete CR prettier/prettier报错原因 插件冲突&#xff0c;Windows系统回车换行符与MAC不一致&#xff08;所以这个问题Windows系统才会出现&#xff09; 解决 需要安装Vue - Official…...

2024年6月计算机视觉论文推荐:扩散模型、视觉语言模型、视频生成等

6月还有一周就要结束了&#xff0c;我们今天来总结2024年6月上半月发表的最重要的论文&#xff0c;重点介绍了计算机视觉领域的最新研究和进展。 Diffusion Models 1、Autoregressive Model Beats Diffusion: Llama for Scalable Image Generation LlamaGen&#xff0c;是一个…...

Centos Stream9 和Centos Stream10的下载网址

Index of /https://mirror.stream.centos.org/...

chrome 录制器及性能分析工具的使用

需求背景&#xff1a; 对比不同VPN方案网络延迟的差异。 验证工具&#xff1a; chrome浏览器自带的录制器、性能插件可以完美的解决这个问题。 注意&#xff1a;录制的操作都在当前页面&#xff0c;不存在新开标签页的场景 解决方案&#xff1a; 使用chrome录制器&#xf…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

遍历 Map 类型集合的方法汇总

1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

3.3.1_1 检错编码(奇偶校验码)

从这节课开始&#xff0c;我们会探讨数据链路层的差错控制功能&#xff0c;差错控制功能的主要目标是要发现并且解决一个帧内部的位错误&#xff0c;我们需要使用特殊的编码技术去发现帧内部的位错误&#xff0c;当我们发现位错误之后&#xff0c;通常来说有两种解决方案。第一…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...