行业知识
全景图拼接和视频行人检测(Python + opencv)
计算机视觉相关实验
实验任务:
1、全景图拼接
实验目标:基于多幅图像(3幅及以上),运用基于2D特征的配准方法,制作全景图。多幅图像,运用基于2D特征的配准方法,制作全景图。
实验方法:建议使用OpenCV库相应函数;图像自己拍摄。
提交:实验报告。实验数据、实验代码和实验结果均放入到实验报告中。
2、行人检测
实验目标:运用HOG+SVM方法识别视频中的行人。
实验方法:建议使用OpenCV库相应函数,如HOGDescripter()等函数。录制一段几秒钟的视频,视频中含有多个行人。
提交:实验报告。实验数据、实验代码和实验结果均放入到实验报告中。
全景图拼接
opencv中提供了图像拼接算法,该算法主要有两个阶段组成,分别是图像对齐/配准 与图像合成/融合。其主要步骤分别为:
1. 检测两张图像的关键点特征(DoG, Harris等)
2. 计算不变特征描述符(SIFT, SURF或ORB等)
3. 根据关键点特征和描述符, 对两张图像进行匹配, 得到若干匹配点对, 并移除错误匹配
4. 使用Ransac算法和匹配的特征来估计单应矩阵(homography matrix)
5. 通过单应矩阵来对图像进行仿射变换
6. 两图像拼接,重叠部分融合
7. 裁剪以获得美观的最终图像
本次实验通过拍摄多组不同的图片来实现图像的拼接.
# 参考自https://cloud.tencent.com/developer/article/2214756 并作修改import numpy as npimport cv2import imutilsfrom imutils import pathsimages = '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为0if 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/651533995import 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运行结果如下(输入视频来自行人检测测试视频_哔哩哔哩_bilibili)。选取一段道路行人视频作为输入视频,提取视频中每一帧的图像并进行行人检测,在帧图像中加入检测框后,替换视频中的原图像,并保存了视频中的每一帧作为检测的图形结果.
根据图像, HoG行人检测器能够检测出画面中较为居中且突出的行人, 对于画面边缘的行人不能很好地检测. 此外,同一人物在不同帧画面也不一定能够准确地检测到, 如该图组左侧为视频的第七帧,检测到中部的三名行人,而视频的第九帧则只检测到左侧的行人.
根据图像, 左侧行人被行人检测器多次检测, 检测框和检测中心点都有明显的重复
从图像可得当前设置下的HoG检测器在行人较为密集的地方会发生错误检测的现象
总结
本次实验对计算机视觉有了进一步的了解,学习到图像拼接和行人检测相关算法的原理和基本使用方式,能够简单的对图像进行拼接,以及视频取帧并做行人检测。这次实验仍然存在一些问题,如部分cv知识点的不了解导致了实验完成较为缓慢。这些都是以后需要继续学习的地方
下一篇:怀旧服如何退出新服务器?