news 2026/5/3 18:13:32

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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():按位与操作
  • 作用:使用掩码提取原图中的对应区域
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/3 18:12:39

TOURISE在达沃斯重新定义旅游业:迈向16万亿美元规模的全球经济引擎

TOURISE在达沃斯世界经济论坛年会上深化并提升旅游业的战略地位,凸显其作为关键产业在联结不同行业、经济体与地区、协同应对全球共同挑战中的重要作用。 长期以来,旅游业常被视为各自为政、相对孤立的产业。TOURISE强调,应将旅游业重新定位…

作者头像 李华
网站建设 2026/5/2 15:12:42

Python命名空间-作用域-类型注解

本文主要讲解 Python 的命名空间、作用域和类型注解。 参考链接: 命令空间和作用域参考文档:https://www.runoob.com/python3/python3-namespace-scope.html类型注解参考文档:https://www.runoob.com/python3/python-type-hints.html 1 Py…

作者头像 李华
网站建设 2026/5/2 17:14:42

【2026最新】网络安全从入门到精通(超详细)学习路线!

首先看一下学网络安全有什么好处: 1、可以学习计算机方面的知识 在正式学习网络安全之前是一定要学习计算机基础知识的。只要把网络安全认真的学透了,那么计算机基础知识是没有任何问题的,操作系统、网络架构、网站容器、数据库、前端后端等…

作者头像 李华
网站建设 2026/5/1 11:01:01

软著代办公司vs AI工具,2026年哪种方式更省钱

800块,这是我上个月找代理公司办一个软著的报价。后来我用AI工具自己弄,39块钱搞定,材料质量还更好。 先说结论:2026年申请软著,AI工具比代办公司省钱太多了。语流软著宝(www.llmove.com)39元/…

作者头像 李华
网站建设 2026/5/3 3:50:45

2026毕业季降AI全攻略:从检测到通过只需3步

先说结论:3步搞定,花费不超过50块 毕业季到了,群里每天都有人问降AI的事。 作为上个月刚通过检测的过来人,我把2026毕业生降AI攻略整理出来:从检测到通过,其实只需要3步,整个流程1-2天搞定&am…

作者头像 李华
网站建设 2026/5/1 7:46:24

【课程设计/毕业设计】基于springboot的宠物医院管理系统 宠物商城购物系统【附源码、数据库、万字文档】

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

作者头像 李华