news 2026/6/10 19:18:20

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/6/10 13:24:24

毕业论文AI率从90%降到10%,这5款工具亲测有效

结论先行:从90%到10%,靠的是这两款工具 92%。 这是我用DeepSeek辅助写完初稿后,知网检测给我的AI率。当时离提交只剩一周,我整个人都慌了。 后来花了三天时间,把市面上能找到的降AI工具都试了一遍。最终结论&#x…

作者头像 李华
网站建设 2026/6/10 13:23:55

如何评估大模型在垂直应用中的真实效果?

在大模型技术迅猛发展的当下,从医疗诊断、金融风控到工业质检,越来越多垂直领域开始探索大模型的落地应用。但很多开发者和企业都会面临一个核心困惑:通用基准榜单分数亮眼的模型,在实际业务场景中却频频“翻车”。事实上&#xf…

作者头像 李华
网站建设 2026/6/10 13:19:44

11.BTC-问答-北大肖臻老师客堂笔记

北京大学肖臻老师《区块链技术与应用》公开课第 11 讲实际上是**“问答环节”**(Q&A)。在这一讲中,肖老师集中回答了学生们关于前几节课(共识协议、挖矿、分叉等)提出的各种核心疑问。 这些问题非常具有代表性&am…

作者头像 李华
网站建设 2026/6/10 13:24:01

计算机毕业设计springboot高校毕业生信息管理系统 基于SpringBoot的高校毕业生就业与档案数字化服务平台 SpringBoot框架下的大学生学业与离校事务一体化管理系统

计算机毕业设计springboot高校毕业生信息管理系统(配套有源码 程序 mysql数据库 论文) 本套源码可以在文本联xi,先看具体系统功能演示视频领取,可分享源码参考。二十一世纪信息技术高速发展,高等教育机构面临着数字化转型的迫切需…

作者头像 李华
网站建设 2026/6/10 13:04:43

计算机毕业设计springboot高等院校学生会办公平台 基于SpringBoot的高校学生组织数字化协同管理系统设计与实现 高校学生会事务一体化管理平台的设计与开发

计算机毕业设计springboot高等院校学生会办公平台(配套有源码 程序 mysql数据库 论文) 本套源码可以在文本联xi,先看具体系统功能演示视频领取,可分享源码参考。 随着信息技术的飞速发展和教育信息化建设的深入推进,高等院校越来越…

作者头像 李华