3. 根据关键点特征和描述符, 对两张图像进行匹配, 得到若干匹配点对, 并移除错误匹配
4. 使用Ransac算法和匹配的特征来估计单应矩阵(homography matrix)
5. 通过单应矩阵来对图像进行仿射变换
6. 两图像拼接,重叠部分融合
7. 裁剪以获得美观的最终图像
本次实验通过拍摄多组不同的图片来实现图像的拼接.
# 参考自https://cloud.tencent.com/developer/article/2214756 并作修改
import numpy as np
import cv2
import imutils
from imutils import paths
images = 'image' # 输入图像路径
output = 'res/mix.png' # 输出图像
crop = True
# 使用imutils.path.list_images获取输入图像路径中所有图像的路径并排序
imagePaths = sorted(list(paths.list_images(images)))
images = []
# 读取图像
for imagePath in imagePaths:
image = cv2.imread(imagePath)
images.append(image)
# 创建图像缝合器
stitcher = cv2.Stitcher_create()
(status, stitched) = stitcher.stitch(images)
# status 代表拼接状态,成功时status为0
if status == 0:
# 进入裁剪图像
if crop:
# 在拼图周围添加2像素
stitched = cv2.copyMakeBorder(stitched, 2, 2, 2, 2,
cv2.BORDER_CONSTANT, (0, 0, 0))
# 图像灰度化处理
gray = cv2.cvtColor(stitched, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY)[1]
# 查找阈值图像的轮廓
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
c = max(cnts, key=cv2.contourArea)
# 绘制该轮廓下最大的矩形
mask = np.zeros(thresh.shape, dtype="uint8")
(x, y, w, h) = cv2.boundingRect(c)
cv2.rectangle(mask, (x, y), (x + w, y + h), 255, -1)
# 创建两个遮罩
# minRect作为不断腐蚀的矩形
# sub作为阈值图像和minRect的插值来进行判断
# 利用掩码和腐蚀操作来裁剪图像,以得到最小的外接矩形
minRect = mask.copy()
sub = mask.copy()
while cv2.countNonZero(sub) > 0:
minRect = cv2.erode(minRect, None)
sub = cv2.subtract(minRect, thresh)
# 得到最小矩形,提取其范围坐标
cnts = cv2.findContours(minRect.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
c = max(cnts, key=cv2.contourArea)
(x, y, w, h) = cv2.boundingRect(c)
# 使用该范围坐标对原图进行裁剪
stitched = stitched[y: y + h, x: x + w]
# 保存处理后的照片
cv2.imwrite(output, stitched)
else:
print("error with code:{}".format(status))
这里拼接的结果如下图
这里获得的图像为拼接后的公共部分,拼接效果并不明显。
以下实验用例来自https://github.com/samggggflynn/image-stitching-opencv
HoG是一种基于图像梯度的特征提取方法,被广泛应用于计算机视觉和机器学习领域。HOG特征是一种在计算机视觉和图像处理中用来进行物体检测的特征描述子,是与SIFT、SURF、ORB属于同一类型的描述符。HOG不是基于颜色值而是基于梯度来计算直方图的,它通过计算和统计图像局部区域的梯度方向直方图来构建特征。
算法将图像分为很多很小的连通区域(cell),采集cell中各像素点的梯度大小和方向,然后在每个cell中通过某种方式绘制一个一维的梯度方向直方图,并对直方图进行对比度归一化。使用SVM分类器进行行人检测。
# 代码结合了以下的代码
# https://blog.csdn.net/m0_75114882/article/details/134405127?spm=1001.2014.3001.5502
# https://zhuanlan.zhihu.com/p/651533995
import cv2
# 检测矩形框是否会重叠或包含
def is_inside(o, i):
ox, oy, ow, oh = o
ix, iy, iw, ih = i
return (ox > ix and oy > iy
and ox + ow < ix + iw
and oy + oh < iy + ih)
# 输入视频
input_video_path = 'video/people.mp4'
# 输出视频
output_video_path = 'person_detect.mp4'
# 帧图像计数器
cnt = 1
# 读取视频
cap = cv2.VideoCapture(input_video_path)
# 获取视频帧率
fps = cap.get(cv2.CAP_PROP_FPS)
# 获取视频尺寸信息
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# 定义视频编码方式为MPEG-4
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
# 创建VideoWriter对象,将行人检测的帧序列写入视频文件中
out = cv2.VideoWriter(output_video_path, fourcc, fps, (width, height))
while True:
# 不断读取视频并捕获帧图像, 保存在frame, 当成功读取帧后, ret将会被赋值为True, 否则为False
ret, frame = cap.read()
if not ret:
break
# 将当前帧图像转换为灰度图像
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 使用默认的HOG特征描述符
hog = cv2.HOGDescriptor()
# 获取行人检测分类器的系数
detector = cv2.HOGDescriptor_getDefaultPeopleDetector()
# 使用默认行人分类器
hog.setSVMDetector(detector)
# 使用detectMultiScale检测帧图像中的行人并返回相关信息
found, weight = hog.detectMultiScale(gray, scale=1.02)
found_filtered = []
# 判断检测到的行人框是否有重叠或者包含关系
for ri, r in enumerate(found):
for qi, q in enumerate(found):
if ri != qi and is_inside(r, q):
break
else:
found_filtered.append(r)
# 将检测框写入帧图像中, 绘制检测框和行人中心点
for person in found_filtered:
x, y, w, h = person
**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**
**深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**
**因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**
![img](https://img-blog.csdnimg.cn/img_convert/a10c29d2d5be150a52e571a2f9e9ee7a.png)
![img](https://img-blog.csdnimg.cn/img_convert/1204c34253a1dc68337995975e0811c3.png)
![img](https://img-blog.csdnimg.cn/img_convert/bd3bd9ff68e3fd582718e127960ea098.png)
![img](https://img-blog.csdnimg.cn/img_convert/33076513d7798f4e370d4e81c3f88939.png)
![img](https://img-blog.csdnimg.cn/img_convert/6c361282296f86381401c05e862fe4e9.png)
![img](https://img-blog.csdnimg.cn/img_convert/9f49b566129f47b8a67243c1008edf79.png)
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!**
**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**
**如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注Python)**
edf79.png)
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!**
**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**
**如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注Python)**
<img src="https://img-community.csdnimg.cn/images/fd6ebf0d450a4dbea7428752dc7ffd34.jpg" alt="img" style="zoom:50%;" />
文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib
文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang
文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些
文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器
文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距
文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器
文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn
文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios
文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql
文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...
文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120
文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数