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

OpenCV 学习:文档扫描与视频运动检测与跟踪

文章目录

    • 一、文档扫描与实时矫正
      • 1.1 核心思路
      • 1.2 关键代码分析
    • 二、视频运动检测与跟踪
      • 2.1 核心思路
      • 2.2 关键代码分析
    • 三、特定物体提取与分割
      • 3.1 核心思路
      • 3.2 关键代码分析

一、文档扫描与实时矫正

1.1 核心思路

通过摄像头实时捕捉图像,自动检测文档轮廓,并进行透视变换将其矫正为正面视角。整个过程包含以下步骤:

  1. 图像采集与预处理
  2. 边缘检测
  3. 轮廓查找与筛选
  4. 透视变换矫正
  5. 二值化处理

1.2 关键代码分析

# 图像显示函数defcv_show(name,img):"""显示图像"""cv2.imshow(name,img)cv2.waitKey(1)# 使用1ms等待,适合视频流

参数说明:

  • name:显示窗口的名称
  • img:要显示的图像矩阵
  • waitKey(1):等待1毫秒,适合视频流的连续显示
# 坐标点排序函数deforder_points(pts):# 一共4个坐标点rect=np.zeros((4,2),dtype="float32")# 用来存储排序之后的坐标位置# 按顺序找到对应坐标0123分别是:左上、右上、右下、左下s=pts.sum(axis=1)# 对pts矩阵的每一行进行求和操作。(x+y)rect[0]=pts[np.argmin(s)]rect[2]=pts[np.argmax(s)]diff=np.diff(pts,axis=1)# 对pts矩阵的每一行进行求差操作。(y-x)rect[1]=pts[np.argmin(diff)]rect[3]=pts[np.argmax(diff)]returnrect

功能说明:
这个函数将检测到的四个角点按照"左上、右上、右下、左下"的顺序排列,为后续的透视变换提供正确的坐标顺序。

# 透视变换函数deffour_point_transform(image,pts):# 获取输入坐标点rect=order_points(pts)(tl,tr,br,bl)=rect# 计算输入的w和h值widthA=np.sqrt(((br[0]-bl[0])**2)+((br[1]-bl[1])**2))widthB=np.sqrt(((tr[0]-tl[0])**2)+((tr[1]-tl[1])**2))maxWidth=max(int(widthA),int(widthB))heightA=np.sqrt(((tr[0]-br[0])**2)+((tr[1]-br[1])**2))heightB=np.sqrt(((tl[0]-bl[0])**2)+((tl[1]-bl[1])**2))maxHeight=max(int(heightA),int(heightB))# 变换后对应坐标位置dst=np.array([[0,0],[maxWidth-1,0],[maxWidth-1,maxHeight-1],[0,maxHeight-1]],dtype="float32")# 透视变换矩阵M=cv2.getPerspectiveTransform(rect,dst)warped=cv2.warpPerspective(image,M,(maxWidth,maxHeight))returnwarped

关键函数分析:

  • cv2.getPerspectiveTransform(rect, dst):计算透视变换矩阵
    • rect:原始图像的四个点坐标
    • dst:目标图像的四个点坐标
  • cv2.warpPerspective():应用透视变换
    • image:输入图像
    • M:变换矩阵
    • (maxWidth, maxHeight):输出图像尺寸
# 图像预处理与轮廓检测gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)# 转换为灰度图gray=cv2.GaussianBlur(gray,ksize=(5,5),sigmaX=0)# 高斯滤波edged=cv2.Canny(gray,15,45)# Canny边缘检测# 轮廓检测cnts=cv2.findContours(edged,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[-2]cnts=sorted(cnts,key=cv2.contourArea,reverse=True)[:3]

参数说明:

  • GaussianBlur():高斯模糊,减少噪声
    • ksize=(5,5):高斯核大小
    • sigmaX=0:X方向标准差
  • Canny():边缘检测
    • 15:低阈值
    • 45:高阈值
  • findContours():查找轮廓
    • RETR_EXTERNAL:只检测外轮廓
    • CHAIN_APPROX_SIMPLE:压缩轮廓点
# 轮廓近似与筛选forcincnts:peri=cv2.arcLength(c,True)# 计算轮廓周长approx=cv2.approxPolyDP(c,0.05*peri,True)# 轮廓近似area=cv2.contourArea(approx)ifarea>40000andlen(approx)==4:screenCnt=approx flag=1break

函数分析:

  • arcLength():计算轮廓周长
    • c:轮廓点集
    • True:轮廓是否闭合
  • approxPolyDP():多边形近似
    • 0.05*peri:近似精度(周长百分比)
    • True:轮廓是否闭合

二、视频运动检测与跟踪

2.1 核心思路

通过分析视频帧间的差异来检测运动物体,主要包含:

  1. 背景建模与前景提取
  2. 形态学处理去除噪声
  3. 轮廓检测与目标框选

2.2 关键代码分析

# 创建结构元素kernel=cv2.getStructuringElement(cv2.MORPH_CROSS,ksize=(3,3))

参数说明:

  • MORPH_CROSS:十字形结构元素
  • ksize=(3,3):核大小为3×3
# 创建背景减除模型fgbg=cv2.createBackgroundSubtractorMOG2()

功能说明:
创建混合高斯背景模型,用于分离前景(运动物体)和背景。

# 应用背景减除fgmask=fgbg.apply(frame)# 获取前景掩码

工作流程:

  1. 模型学习视频的背景
  2. 将当前帧与背景模型比较
  3. 提取出运动的前景物体
# 形态学开运算fgmask_new=cv2.morphologyEx(fgmask,cv2.MORPH_OPEN,kernel)

功能说明:

  • MORPH_OPEN:开运算(先腐蚀后膨胀)
  • 作用:去除小的噪声点,平滑前景区域
# 轮廓查找与框选contours=cv2.findContours(fgmask_new,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[-2]forcincontours:perimeter=cv2.arcLength(c,True)ifperimeter>188:x,y,w,h=cv2.boundingRect(c)frame_rect=cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)

函数分析:

  • boundingRect():计算轮廓的外接矩形
  • rectangle():绘制矩形框
    • (0,255,0):绿色(BGR格式)
    • 2:线宽

三、特定物体提取与分割

3.1 核心思路

从图像中提取特定物体(扇子),主要步骤:

  1. 图像预处理(缩放、旋转)
  2. 边缘检测
  3. 轮廓查找与掩码生成
  4. 物体提取

3.2 关键代码分析

# 图像尺寸调整与旋转img_resized=cv2.resize(img,(640,480))img_rotated=cv2.rotate(img_resized,cv2.ROTATE_90_COUNTERCLOCKWISE)

参数说明:

  • resize():调整图像尺寸
  • ROTATE_90_COUNTERCLOCKWISE:逆时针旋转90度
# 边缘检测gray=cv2.cvtColor(img_rotated,cv2.COLOR_BGR2GRAY)edges=cv2.Canny(gray,threshold1=50,threshold2=150)

Canny参数:

  • threshold1=50:低阈值,低于此值的边缘被丢弃
  • threshold2=150:高阈值,高于此值的边缘被保留
# 轮廓查找与掩码生成contours=cv2.findContours(edges,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)[-2]mask=np.zeros_like(gray)ifcontours:contour_areas=[cv2.contourArea(cnt)forcntincontours]max_area_idx=np.argmax(contour_areas)max_contour=contours[max_area_idx]cv2.drawContours(mask,[max_contour],-1,(255),thickness=cv2.FILLED)# 形态学闭运算kernel=np.ones((5,5),np.uint8)mask=cv2.morphologyEx(mask,cv2.MORPH_CLOSE,kernel)

功能说明:

  1. 查找所有轮廓
  2. 选择面积最大的轮廓(假设为扇子)
  3. 绘制填充轮廓作为掩码
  4. 闭运算填充空洞
# 物体提取mask_3ch=cv2.cvtColor(mask,cv2.COLOR_GRAY2BGR)extracted=cv2.bitwise_and(img_rotated,mask_3ch)

位运算:

  • bitwise_and():按位与操作
  • 作用:使用掩码提取原图中的对应区域
http://www.jsqmd.com/news/309945/

相关文章:

  • 学会这两个方法,你能读懂所有生信文献图表
  • AI都能读文献了,我们还需要自己读吗?
  • 【2026最新】网络安全从入门到精通(超详细)学习路线!
  • 航电oj:统计字符串中汉字的个数
  • 深入解析:tauri:tauri2.0+vue3+vite打包案例
  • 剑桥大学人工智能领域有影响力人物
  • Python命名空间-作用域-类型注解
  • Java全栈工程师的面试实战:从基础到微服务
  • 动能丨揭榜挂帅——共赢逻辑激活协同新动能
  • TCP并发实现
  • 24位AD测温模块1-100米自动补偿滤波稳采适配各类工控场景
  • 铂电阻温度模块的应用边界?多行业场景汇总告诉你
  • 如何选择靠谱的IT外包公司?这3个核心标准是关键
  • ArcGIS Python零基础脚本开发教程---Python入门
  • 一库统管全域数据:金仓 KingbaseES 多模融合架构与全栈替代实践
  • 树拍易购崩盘:“创新”商业模式下,这些“怪味儿”藏着致命陷阱
  • 初见Vibe Coding:前置准备,在Windows上安装WSL2和终端和npm
  • 大数据领域数据架构的性能监控与优化
  • MathCAD多用户管理策略
  • RAG落地不是拼乐高:三层架构才是知识库的真正骨架
  • RAG不是魔法,是工程:从知识库到企业部署的硬核实践
  • 网络安全年薪天花板92万!2025年缺口破百万,小白如何快速入门拿高薪?(珍藏版)
  • 【必收藏】30个网络安全黑话详解:从小白到专家的进阶指南
  • 亲测好用10个AI论文软件,本科生搞定毕业论文!
  • 让你的 AIPC “能听会说”:Fun-ASR-Nano × Fun-CosyVoice 3.0 全链路加速实战
  • C#+SQL:轻量级员工管理系统实战
  • 为什么几乎所有大厂,都在选 Go ?
  • Java计算机毕设之基于springboot-vue城市宠物医院管理系统springboot的宠物医院管理系统(完整前后端代码+说明文档+LW,调试定制等)
  • 关于视频剪辑工具的调查问卷
  • ‌视频转音频不求人,这几种方法零基础也能学会!