Image Stitching using OpenCV
文章目录
- 简介
- 图像拼接管道
- 特征检测和提取
- 特征检测
- 特征提取
- 特征匹配
- 强力匹配
- FLANN(近似最近邻快速库)匹配
- 单应性估计
- 扭曲和混合
- 结论
使用opencv进行图像拼接
原为url:
https://medium.com/@paulsonpremsingh7/image-stitching-using-opencv-a-step-by-step-tutorial-9214aa4255ec
概述:在本文中,我们将介绍如何使用 OpenCV 将图像拼接在一起。为了创建更大的合成图像(例如全景图),图像拼接需要连接多张重叠的照片。我们将介绍图像拼接过程的每个阶段,包括特征匹配、单应性估计和混合。在本教程结束时,您将能够使用 OpenCV 将大量图像组合成壮观的全景图。
目录:
简介
- 图像拼接管道
- 特征检测和提取
- 特征匹配
- 单应性估计
- 扭曲和混合
- 结论
简介
图像拼接是一种从多张重叠照片创建合成图像(包括全景图)的方法。与仅使用一张图像相比,它可以捕获更多信息并创建更大的视野。许多行业(包括摄影、虚拟现实和机器人技术)都使用图像拼接。
通过使用图像拼接,可以制作全景图,为观众提供广阔景观或建筑奇迹的无缝视角。它们提供了一种保存和捕捉场景之美的方法,而这种美无法在单个帧中正确传达。摄影师可以使用图像拼接来展示山脉的壮丽、开阔田野的大小或建筑奇观的细微细节。
大比例尺地图、3D 场景重建,甚至医学成像(重叠的扫描切片被拼接在一起)都可以使用图像拼接进行。图像拼接可以帮助机器人专家创建全景地图以进行导航或视觉定位。
我们可以探索这项技术的各种用途,并通过理解图像拼接过程和使用 OpenCV 的功能来释放制作壮丽全景照片的潜力。无论您是从事机器人或测绘项目的工程师、计算机视觉研究人员还是摄影爱好者,了解使用 OpenCV 进行图片拼接都可以拓宽您的创意选择并打开通往迷人机会的大门。
图像拼接管道
通过将图像拼接过程分解为多个步骤,可以形成将多张单独的照片转换为无缝合成图的管道。要实现精确的对齐和混合,每个阶段都是必不可少的。在本节中,我们将概述分步图像拼接管道中使用的基本思想和方法。
图像拼接涉及的关键概念和技术包括:
- 关键点检测:识别图像中的独特特征。
- 描述符:用数字描述符表示关键点以进行匹配。
- 特征匹配:查找图像间关键点之间的对应关系。
- 单应性:描述图像之间几何关系的变换矩阵。
- RANSAC:一种稳健估计单应性矩阵的算法。
- 图像扭曲:根据估计的单应性变换图像。
- 混合:平滑地合并图像以创建无缝合成图。
为了成功进行图像拼接,理解这些思想和方法至关重要。我们将在接下来的章节中深入研究每个阶段,并提供真实示例和 OpenCV 代码示例。您可以使用此流程和适当的程序制作引人注目的全景照片并掌握图像拼接的技巧。
特征检测和提取
特征提取和检测是图像拼接流程中的第一个也是最重要的阶段。此阶段需要在每幅图像中定位不同的关键点并计算它们的描述。描述符给出了这些关键点的数值表示,以便在多张照片之间进行匹配,而关键点则反映了图像中独特的特征或兴趣点。我们可以使用 OpenCV 的几种特征检测技术(包括 SIFT、SURF 和 ORB)从图像中提取关键点和描述符。
特征检测
- 特征识别算法的目标是在图像中定位有趣且可识别的焦点区域。
- 这些关键点可以代表具有大量纹理差异、角落或边缘的位置。
- 为了检测特征,经常使用诸如 SIFT(尺度不变特征变换)、SURF(加速稳健特征)和 ORB(定向 FAST 和旋转 BRIEF)之类的算法。
- 这些算法考虑了关键点的比例和方向,使其能够抵抗比例和旋转的变化。
特征提取
- 使用已识别的关键点描述符计算每个关键点周围的局部图片数据。
- 关键点周围的补丁以数字形式表示为描述符,这些描述符对其外观或纹理进行编码。
- 描述符包括邻域纹理、颜色和梯度特征的详细信息。
- SIFT、SURF 和 ORB 算法中还包括特征描述符提取技术。
让我们练习使用 SIFT 进行特征检测和提取。
import cv2# Load the images
image1 = cv2.imread('image1.jpg')
image2 = cv2.imread('image2.jpg')# Initialize the SIFT feature detector and extractor
sift = cv2.SIFT_create()# Detect keypoints and compute descriptors for both images
keypoints1, descriptors1 = sift.detectAndCompute(image1, None)
keypoints2, descriptors2 = sift.detectAndCompute(image2, None)# Draw keypoints on the images
image1_keypoints = cv2.drawKeypoints(image1, keypoints1, None)
image2_keypoints = cv2.drawKeypoints(image2, keypoints2, None)# Display the images with keypoints
cv2.imshow('Image 1 with Keypoints', image1_keypoints)
cv2.imshow('Image 2 with Keypoints', image2_keypoints)
cv2.waitKey(0)
cv2.destroyAllWindows()
此代码片段首先加载图像 image1 和 image2。然后,使用 cv2.SIFT_create() 初始化 SIFT 特征检测器和提取器。
接下来,我们使用 SIFT 对象的 detectAndCompute 方法计算两张图片的描述符以识别关键点。描述符保存在 descriptors1 和 descriptors2 变量中,而关键点保存在 keypoints1 和 keypoints2 变量中。
drawKeypoints 函数用于在图像上绘制关键点以便查看它们。变量 image1_keypoints 和 image2_keypoints 包含最终图像的关键点。
这段代码演示了 SIFT 算法的特征检测和提取过程。只需将“筛选”对象替换为适当的检测器和提取器对象(例如,将 cv2.SURF_create() 替换为 SURF 或将 cv2.ORB_create() 替换为 ORB)并相应地修改代码,您就可以尝试其他特征检测技术,例如 SURF 或 ORB。
为了获得最佳结果,请记住尝试几种算法并根据您的独特用例修改其参数。
特征匹配
图像拼接中的一个关键阶段是特征匹配,它在各种图像中的关键点之间建立对应关系。为了确保图像的准确对齐和配准,它试图根据其描述符识别匹配的关键点。OpenCV 提供了许多特征匹配方法,包括基于 FLANN(近似最近邻快速库)的匹配和强力匹配,每种方法都具有独特的属性和优势。
强力匹配
- 特征匹配的一种简单直接的方法是强力匹配。
- 将一个图像中的每个描述符与第二个图像中的每个描述符进行比较。
- 计算描述符之间的距离或相似度(如欧几里得距离或余弦相似度)是匹配过程的一个步骤。
- OpenCV BFMatcher 类允许使用强力匹配。
- 尽管它很简单,但计算成本可能很高,尤其是对于大型特征集。
FLANN(近似最近邻快速库)匹配
- FLANN 匹配是一种实用的最近邻搜索算法,可用于有效特征匹配。
- 为了加快搜索速度,它采用基于树的索引结构,如 KD 树或随机树。
- 特别是对于大型特征集,FLANN 比强力匹配更快。
- 它提供了选择搜索算法和配置搜索条件的选项。
- OpenCV 中的 FlannBasedMatcher 类可用于进行 FLANN 匹配。
此代码片段演示了如何在 OpenCV 中使用强力匹配和 FLANN 匹配算法执行特征匹配
import cv2# Load the images
image1 = cv2.imread('image1.jpg', cv2.IMREAD_GRAYSCALE)
image2 = cv2.imread('image2.jpg', cv2.IMREAD_GRAYSCALE)# Initialize the feature detector and extractor (e.g., SIFT)
sift = cv2.SIFT_create()# Detect keypoints and compute descriptors for both images
keypoints1, descriptors1 = sift.detectAndCompute(image1, None)
keypoints2, descriptors2 = sift.detectAndCompute(image2, None)# Initialize the feature matcher using brute-force matching
bf = cv2.BFMatcher(cv2.NORM_L2, crossCheck=True)# Match the descriptors using brute-force matching
matches_bf = bf.match(descriptors1, descriptors2)# Sort the matches by distance (lower is better)
matches_bf = sorted(matches_bf, key=lambda x: x.distance)# Draw the top N matches
num_matches = 50
image_matches_bf = cv2.drawMatches(image1, keypoints1, image2, keypoints2, matches_bf[:num_matches], None)# Initialize the feature matcher using FLANN matching
index_params = dict(algorithm=0, trees=5)
search_params = dict(checks=50)
flann = cv2.FlannBasedMatcher(index_params, search_params)# Match the descriptors using FLANN matching
matches_flann = flann.match(descriptors1, descriptors2)# Sort the matches by distance (lower is better)
matches_flann = sorted(matches_flann, key=lambda x: x.distance)# Draw the top N matches
image_matches_flann = cv2.drawMatches(image1, keypoints1, image2, keypoints2, matches_flann[:num_matches], None)# Display the images with matches
cv2.imshow('Brute-Force Matching', image_matches_bf)
cv2.imshow('FLANN Matching', image_matches_flann)
cv2.waitKey(0)
cv2.destroyAllWindows()
从 L2 范数和 crossCheck=True 开始进行特征匹配,我们使用 cv2.BFMatcher() 初始化强力匹配器。然后使用 match() 函数查找两个图像描述之间的相似性。根据距离排列匹配项。
与此类似,我们使用 cv2.FlannBasedMatcher() 设置 FLANN 匹配器的索引设置和搜索参数。使用 FLANN 算法,我们调用 match() 方法来查找描述符之间的匹配项。再次根据距离排列匹配项。
我们使用 drawMatches() 函数在图像上绘制匹配项以可视化匹配项。为清晰起见,我们仅显示前 N 个匹配项(由 num_matches 确定)。
单应性估计
在将多张照片拼接在一起的过程中,单应性估计的基本步骤对于对齐和整合图像至关重要。为了将相似的点从一张图像转移到另一张图像,使用单应性矩阵来表示两个图像平面之间的变换。借助从特征匹配中获得的匹配关键点,OpenCV 提供了估计单应性矩阵的技术。
了解单应性及其在图像拼接中的作用
- 单应性描绘了两幅图像之间的平面映射,是一个 3x3 变换矩阵。
- 它显示了两幅图像对应点像素坐标之间的对应关系。
- 使用单应性可以进行包括平移、旋转、缩放和透视扭曲在内的几何变化。
- 单应性是图像拼接中使用的一种技术,用于将图像对齐并转换为单个坐标系。
使用匹配的关键点估计单应性矩阵
- OpenCV 中的 findHomography() 函数可用于计算单应性矩阵。
- 估计的单应性矩阵由 findHomography() 方法返回,该方法接受匹配的关键点作为输入。
- RANSAC(随机样本共识)是一种可靠的估计程序,用于处理异常值并提供准确的单应性矩阵。
- RANSAC 通过迭代选择匹配的关键点子集来估计单应性矩阵。在评估适合预测模型的内点数量后,选择具有最多内点的最佳单应性矩阵。
以下是使用匹配的关键点演示单应性估计的代码片段:
import cv2
import numpy as np# Load the images
image1 = cv2.imread('image1.jpg')
image2 = cv2.imread('image2.jpg')# Convert the images to grayscale
gray1 = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY)# Initialize the feature detector and extractor (e.g., SIFT)
sift = cv2.SIFT_create()# Detect keypoints and compute descriptors for both images
keypoints1, descriptors1 = sift.detectAndCompute(gray1, None)
keypoints2, descriptors2 = sift.detectAndCompute(gray2, None)# Initialize the feature matcher using brute-force matching
bf = cv2.BFMatcher(cv2.NORM_L2, crossCheck=True)# Match the descriptors using brute-force matching
matches = bf.match(descriptors1, descriptors2)# Extract the matched keypoints
src_points = np.float32([keypoints1[m.queryIdx].pt for m in matches]).reshape(-1, 1, 2)
dst_points = np.float32([keypoints2[m.trainIdx].pt for m in matches]).reshape(-1, 1, 2)# Estimate the homography matrix using RANSAC
homography, mask = cv2.findHomography(src_points, dst_points, cv2.RANSAC, 5.0)# Print the estimated homography matrix
print("Estimated Homography Matrix:")
print(homography)
扭曲和混合
以下步骤需要根据单应性扭曲图像,并在上一步估算单应性矩阵后将它们组合起来以生成无缝合成图像。通过此过程,拼接的照片将正确对齐,并且它们之间可以无缝过渡。
使用估计的单应性扭曲图像
- 估算单应性矩阵后,我们可以使用它来将一个图像的坐标系转换为另一个图像的坐标系。
- OpenCV 中的 cv2.warpPerspective() 函数允许您通过应用单应性变换来扭曲图像。
- 估计的单应性矩阵、输出图片的大小和输入图像都是该函数的输入参数。
- 输出图像的大小将与参考图像(或目标图像)的大小相匹配。
混合扭曲的图像以创建无缝合成
- 要生成平滑的合成图像,我们必须将扭曲的图像混合在一起。
- 简单的图片连接可能会在图像中产生明显的接缝或不和谐的变化。
- 可以使用多种混合方法来产生更平滑的混合效果,包括 alpha 混合、羽化和多波段混合。
- 为了实现无缝逼真的效果,这些策略尝试逐步转换图像之间的像素强度。
- 要拼接的照片的个性化需求和质量决定了要使用的最佳混合技术。
以下是使用估计的单应性对图像进行扭曲和混合的代码片段:
import cv2
import numpy as np# Load the images
image1 = cv2.imread('image1.jpg')
image2 = cv2.imread('image2.jpg')# Convert images to grayscale
gray1 = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY)# Initialize the feature detector and extractor (e.g., SIFT)
sift = cv2.SIFT_create()# Detect keypoints and compute descriptors for both images
keypoints1, descriptors1 = sift.detectAndCompute(gray1, None)
keypoints2, descriptors2 = sift.detectAndCompute(gray2, None)# Initialize the feature matcher using brute-force matching
bf = cv2.BFMatcher()# Match the descriptors using brute-force matching
matches = bf.match(descriptors1, descriptors2)# Select the top N matches
num_matches = 50
matches = sorted(matches, key=lambda x: x.distance)[:num_matches]# Extract matching keypoints
src_points = np.float32([keypoints1[match.queryIdx].pt for match in matches]).reshape(-1, 1, 2)
dst_points = np.float32([keypoints2[match.trainIdx].pt for match in matches]).reshape(-1, 1, 2)# Estimate the homography matrix
homography, _ = cv2.findHomography(src_points, dst_points, cv2.RANSAC, 5.0)# Warp the first image using the homography
result = cv2.warpPerspective(image1, homography, (image2.shape[1], image2.shape[0]))# Blending the warped image with the second image using alpha blending
alpha = 0.5 # blending factor
blended_image = cv2.addWeighted(result, alpha, image2, 1 - alpha, 0)# Display the blended image
cv2.imshow('Blended Image', blended_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
结论
在本教程中,我们探索了使用 OpenCV 进行图像拼接的过程。以下是所涉及步骤的摘要:
- 图像加载:加载要组合的单个图像。
- 特征提取和匹配:要查找关键点并生成描述符,请使用特征检测和提取方法(例如 SIFT 或 SURF)。要发现不同照片中关键点之间的对应关系,请使用特征匹配。
- 单应性估计:使用匹配的关键点,估计单应性矩阵。图像之间的几何变换由单应性矩阵表示。
- 扭曲和混合:要将一张图像与另一张图像对齐,请使用近似的单应性对其进行扭曲。要生成平滑的合成图像,请将扭曲的图像与第二张图像混合。
在整个教程中,我们介绍了图像拼接中涉及的关键概念和技术,包括特征匹配、单应性估计和图像扭曲。我们还提供了代码片段来说明使用 OpenCV 的实现。
进一步探索和潜在改进:
- 为了检验各种特征提取和检测技术对图像拼接的有效性,请进行实验。
- 为了获得更可靠的单应性估计,请研究 RANSAC(随机样本一致性)等尖端技术。
- 为了在照片之间实现更无缝的过渡,请考虑使用混合技术,如多波段混合和基于梯度的混合。
- 利用复杂的算法和技术,处理图像拼接困难,如视差、透视失真和遮挡。
- 为了提高特征匹配的准确性,请研究自动图片对齐方法,如尺度不变特征变换 (SIFT) 或稳健匹配算法。
虚拟现实、图片马赛克和全景摄影只是图像拼接的一些令人兴奋的用途。您可以通过额外的研究和开发来提高拼接图像的精度和质量,从而提供无缝和身临其境的视觉体验。
请随意尝试并探索使用 OpenCV 和其他相关库进行图像拼接的广泛可能性。祝您拼接愉快!
关于作者:
我是 Paulson Premsingh,新加坡国立大学人工智能研究生。我对视觉系统、3D 传感、机器人和移动性有着强烈的热情。我专注于这些领域,渴望探索人工智能和计算机视觉的交集,为机器人感知、物体识别和自主导航开发创新解决方案。我很高兴成为人工智能社区的一员,并为这些迷人领域的进步做出贡献。
相关文章:
Image Stitching using OpenCV
文章目录 简介图像拼接管道特征检测和提取特征检测特征提取 特征匹配强力匹配FLANN(近似最近邻快速库)匹配 单应性估计扭曲和混合结论 使用opencv进行图像拼接 原为url: https://medium.com/paulsonpremsingh7/image-stitching-using-opencv-a-step-by-s…...
CentOS7 安装Selenium(使用webdriver_manager自动安装ChromeDriver)
在 CentOS 7 上安装 Selenium 通常涉及几个步骤,包括安装 Python、安装 Selenium 库、安装 WebDriver 以及配置环境。以下是详细的步骤: 1. 安装 Python 和 pip 如果你的系统中还没有安装 Python 和 pip,可以使用以下命令进行安装ÿ…...
鸿蒙手机文件目录
最近在开发鸿蒙,想把文件从电脑上发送到鸿蒙上我的手机APP的根目录,但是试了几次目录都不对,最后终于找到了,在这里记录一下 鸿蒙手机路径: /storage/media/100/local/files/Docs 将文件从电脑发送到手机:hdc file s…...
泷羽Sec学习笔记-Bp中ip伪造、爬虫审计
ip伪造与爬虫审计 ip伪造 下载插件:burpFakeIP 地址:GitHub - TheKingOfDuck/burpFakeIP: 服务端配置错误情况下用于伪造ip地址进行测试的Burp Suite插件 python版需要配置jython:下载地址:Maven Central: org.python:jython-…...
电子电工一课一得
首语 在现代社会中,电子电工技术已经渗透到我们生活的方方面面,从家用电器到工业自动化,从通信设备到智能系统,无一不依赖于电子电工技术。因此,掌握电子电工的基础知识,不仅对理工科学生至关重要…...
Cesium 限制相机倾斜角(pitch)滑动范围
1.效果 2.思路 在项目开发的时候,有一个需求是限制相机倾斜角,也就是鼠标中键调整视图俯角时,不能过大,一般 pitch 角度范围在 0 至 -90之间,-90刚好为正俯视。 在网上查阅了很多资料,发现并没有一个合适的…...
配置ssh-key连接github
GitHub 通过在 2022 年 3 月 15 日删除旧的、不安全的密钥类型来提高安全性。 具体内容参考如下链接 https://docs.github.com/zh/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent mac配置 ssh-keygen -t ed25519 -C …...
Linux——进程控制模拟shell
1.进程创建 我们在之前的文章中介绍过进程创建的方法,可以通过系统调用接口fork来创建新的进程。 fork在创建完新的子进程之后,返回值是一个pid,对于父进程返回子进程的pid,对于子进程返回0。fork函数后父子进程共享代码ÿ…...
【HarmonyOS】鸿蒙应用实现手机摇一摇功能
【HarmonyOS】鸿蒙应用实现手机摇一摇功能 一、前言 手机摇一摇功能,是通过获取手机设备,加速度传感器接口,获取其中的数值,进行逻辑判断实现的功能。 在鸿蒙中手机设备传感器ohos.sensor (传感器)的系统API监听有以下…...
Kael‘thas Sunstrider Ashes of Al‘ar
Kaelthas Sunstrider 凯尔萨斯逐日者 <血精灵之王> Kaelthas Sunstrider - NPC - 魔兽世界怀旧服TBC数据库_WOW2.43数据库_70级《燃烧的远征》数据库 Ashes of Alar 奥的灰烬 (凤凰 310%速度) Ashes of Alar - Item - 魔兽世界怀旧服TBC数据…...
CNCF云原生生态版图
CNCF云原生生态版图 概述什么是云原生生态版图如何使用生态版图 项目和产品(Projects and products)会员(Members)认证合作伙伴与提供商(Certified partners and providers)无服务(Serverless&a…...
渐冻症:真的无药可治?
“渐冻症”,这个令人闻之色变的疾病,仿佛是生命的冷酷冰封者。一提到渐冻症,很多人脑海中立刻浮现出绝望的画面,认为它无药可治。但事实真的如此吗? 渐冻症,医学上称为肌萎缩侧索硬化症,是一种渐…...
`pg_wal` 目录
在 PostgreSQL 中,自动清理 pg_wal 目录主要通过配置参数 min_wal_size、max_wal_size 和 wal_keep_size 来实现。以下是如何配置 PostgreSQL 以自动清理 WAL 文件的详细步骤和建议: 配置 min_wal_size 和 max_wal_size: min_wal_size&#x…...
【信息系统项目管理师】论文:论信息系统项目的整合管理
文章目录 正文一、制定项目章程二、指定项目管理计划三、指导与管理项目工作四、管理项目知识五、监控项目工作六、实施整体变更控制七、结束项目或阶段 正文 根据省自然资源厅的总体部署,XX市决定于2023年8月开始全市不动产登记系统建设,要求在2024年8…...
MATLAB深度学习(七)——ResNet残差网络
一、ResNet网络 ResNet是深度残差网络的简称。其核心思想就是在,每两个网络层之间加入一个残差连接,缓解深层网络中的梯度消失问题 二、残差结构 在多层神经网络模型里,设想一个包含诺干层自网络,子网络的函数用H(x)来表示&#x…...
freeswitch(配置event_socket连接)
亲测版本centos 7.9系统–》 freeswitch1.10.9 本人freeswitch安装路径(根据自己的路径进入) /usr/local/freeswitch/etc/freeswitch场景说明: 如果想使用代码进行控制freeswitch添加账号、获取注册信息、强拆等,可以使用ESL控制vim autoload_configs/event_socket.conf.x…...
C++ SQLite轻量化数据库使用总结
官网下载:https://www.sqlite.org/download.html 示例1 #include <iostream> #include <sqlite3.h>int main() {sqlite3* db;char* zErrMsg 0;int rc;// 打开数据库连接(如果数据库不存在,则会自动创建)rc sqlite…...
docker打包当前使用的某个容器为镜像,导出,导入
容器打包成镜像 要将正在使用的 Docker 容器打包成镜像,你可以使用 docker commit 命令。这个命令会从运行中的容器创建一个新的镜像。以下是详细步骤: 查看正在运行的容器: 使用以下命令查看当前正在运行的容器: docker ps找到目…...
【刷题22】BFS解决最短路问题
目录 一、边权为1的最短路问题二、迷宫中离入口最近的出口三、最小基因变化四、单词接龙五、为高尔夫比赛砍树 一、边权为1的最短路问题 如图:从A到I,怎样走路径最短 一个队列一个哈希表队列:一层一层递进,直到目的地为止哈希表&…...
服务器重启:数字世界的短暂休憩与新生
在互联网的浩瀚海洋中,服务器犹如一座座灯塔,持续稳定地散发着光芒,为无数的网络活动提供着支撑与指引。而服务器重启,便是这数字灯塔周期性进行自我调整与修复的关键环节。 服务器重启是指对服务器进行重新启动的过程࿰…...
JavaEE 【知识改变命运】05 多线程(4)
文章目录 单例模式什么是单例模式饿汉模式懒汉模式多线程- 懒汉模式分析多线程问题第一种添加sychronized的方式第二种添加sychronized的方式改进第二种添加sychronized的方式(DCL检查锁) 阻塞队列什么是阻塞队列什么是消费生产者模型标准库中的阻塞队列…...
【CSS in Depth 2 精译_076】12.4 @font-face 的工作原理
当前内容所在位置(可进入专栏查看其他译好的章节内容) 第四部分 视觉增强技术 ✔️【第 12 章 CSS 排版与间距】 ✔️ 12.1 间距设置 12.1.1 使用 em 还是 px12.1.2 对行高的深入思考12.1.3 行内元素的间距设置 12.2 Web 字体12.3 谷歌字体12.4 font-fac…...
SQL Having用法
拿个业务场景说这个案例,比如我们有个表里面可能有批改过的数据,批改过得数据不会随着新批改的数据覆盖,而是逐条插入表中,如果想找出包含最早批改的数据和最新批改数据的话,那么我们就需要用到了havinng 用法,假设最开…...
@JsonNaming实现入参接口参数下划线驼峰自动转换
JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) 是用于 Jackson 库中的一个注解,作用是改变 Java 对象的字段命名策略,特别是在序列化和反序列化时。这可以帮助 Java 对象中的字段名从驼峰命名法(CamelCase)转换为蛇…...
使用PaliGemma2构建多模态目标检测系统:从架构设计到性能优化的技术实践指南
目标检测技术作为计算机视觉领域的核心组件,在自动驾驶系统、智能监控、零售分析以及增强现实等应用中发挥着关键作用。本文将详细介绍PaliGemma2模型的微调流程,该模型通过整合SigLIP-So400m视觉编码器与Gemma 2系列的高级语言模型,专门针对…...
MinerU:PDF文档提取工具
目录 docker一键启动本地配置下载模型权重文件demo.pyGPU使用情况 wget https://github.com/opendatalab/MinerU/raw/master/Dockerfile docker build -t mineru:latest .docker一键启动 有点问题,晚点更新 本地配置 就是在Python环境中配置依赖和安装包 根据需求…...
spark的共享变量
因为RDD在spark中是分布式存储 1、python中定义的变量仅仅在driver中运行,在excutor中是获取不到值的——广播变量 2、若定义了一个变量进行累加,先分别在driver和excutor中进行累加,但是结果是不会主动返回给driver的——累加器 Broadcas…...
Scrapy与MongoDB
Scrapy可以在非常短的时间里获取大量的数据。这些数据无论是直接保存为纯文本文件还是CSV文件,都是不可取的。爬取一个小时就可以让这些文件大到无法打开。这个时候,就需要使用数据库来保存数据了。 MongoDB由于其出色的性能,已经成为爬虫的首…...
爬虫基础与实践
爬虫技术基础与实践 在当今数字化的时代,数据成为了宝贵的资源。爬虫技术作为获取数据的重要手段,受到了广泛的关注和应用。本文将介绍爬虫的基本概念、工作原理以及一些常用的技术和工具。 一、爬虫的基本概念 爬虫,也称为网络蜘蛛或网络机器…...
快速上手Serverless架构与FastAPI结合实现自动化移动应用后端
快速上手Serverless架构与FastAPI结合实现自动化移动应用后端 引言 随着云计算技术的发展,Serverless架构已经成为构建现代应用的一种流行选择。它允许开发者将更多精力集中在核心业务逻辑上,而无需管理底层基础设施。本文将以AWS Lambda和API Gateway…...
网站如何做线上和线下推广/谷歌google地图
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼TC 2.0版#include#includeint main(){int key;while(1){keygetch();/*用于去掉第一个字节*/if(key27) break; /*如果是ESC退出*/if(key>31 && key<127) /*如果不是特殊键*/{printf("You have pressed %c Press …...
网站群如何做网站/站长推荐入口自动跳转
传送门:hdu4185 Oil Skimming 题意:n*n的方格里有字符*和#,只能在字符#上放1*2的板子且不能相交,求最多能放多少个。 分析:直接给#字符编号,然后相邻的可以匹配,建边后无向图跑匈牙利算法&#…...
南京设计公司前十名/深圳优化怎么做搜索
大家好,9月14日(周五)【免费送书】说说哪本书曾经让你爱不释手活动中获奖名单如下,排名1—10的留言读者免费赠送图书一本,图书从活动里的书单中任选,由电子工业出版社博文视点提供;排名11—20的…...
龙岗网站制作市场/网上营销的平台有哪些
昨天在做项目的时候,代码写完-编译-运行。然后出现了这个可爱的“HTTP Error 503。The service is unavailable”。 这是电脑术语!意思是“地址错误,主机没找到!(没看到主机)”~~~ 真晕,以前没有遇到过这个情况。唉&am…...
网站备案 论坛/百度云服务器官网
root-tools 项目地址:root-toolsRootToolsNeo 正式发布啦~ RootTools 是一款专注于给 root 后的用户提供方便的软件。主要提供: 应用冻结 不删除系统内的应用,而是将其冻结,在需要时可以解冻,但是别乱来哦,…...
旅游网站系统建设方案/线上营销课程
其实很早就知道 Request.QueryString["参数"]来得到URL中传递的参数,或者说是得到Get请求方式得到的数据;而Request.Form得到Form表单的提交的数据(这种理解是错误的),今天在使用Jquery的Ajax,当使用Post方式时候&#…...