opencv视频处理

在计算机视觉领域,视频处理是应用场景最广泛的方向之一,无论是日常办公中的文档数字化,还是安防场景的运动目标检测,都离不开核心的图像处理技术。本文将结合OpenCV与Python实战,详细拆解两大经典视频处理案例------基于摄像头的实时文档扫描,以及运动目标检测中的背景建模技术,帮助开发者快速掌握核心原理与实现思路。

一、实时文档扫描:从透视矫正到二值增强

实时文档扫描功能通过摄像头捕获画面,自动识别文档轮廓并矫正透视变形,最终输出类似扫描仪的清晰文档图像,核心依赖于轮廓检测与透视变换技术。

1.1 核心原理

文档在摄像头画面中常因拍摄角度产生透视变形,扫描的核心是通过以下步骤还原文档正射视角:首先对视频帧进行预处理降噪与边缘检测,提取文档的四边形轮廓;然后对轮廓顶点排序,确保坐标顺序统一;最后通过透视变换将四边形映射为标准矩形,再经二值化增强文档对比度。

1.2 实现流程拆解(附完整代码)

首先给出实时文档扫描的完整核心代码,后续按流程分段解析关键逻辑:

python 复制代码
import numpy as np
import cv2

def order_points(pts):
    # 初始化4个顶点的有序存储数组
    rect = np.zeros((4, 2), dtype="float32")
    # 按x+y和排序,定位左上(和最小)、右下(和最大)顶点
    s = pts.sum(axis=1)
    rect[0] = pts[np.argmin(s)]
    rect[2] = pts[np.argmax(s)]
    # 按y-x差排序,定位右上(差最小)、左下(差最大)顶点
    diff = np.diff(pts, axis=1)
    rect[1] = pts[np.argmin(diff)]
    rect[3] = pts[np.argmax(diff)]
    return rect

def four_point_transform(image, pts):
    # 获取排序后的顶点坐标
    rect = order_points(pts)
    (tl, tr, br, bl) = rect
    # 计算目标矩形的宽高(取两组对边最大值,避免变形)
    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))
    return warped

def cv_show(name, img):
    cv2.imshow(name, img)
    cv2.waitKey(1)  # 适配视频实时刷新,避免卡顿

# 初始化摄像头
cap = cv2.VideoCapture(0)
if not cap.isOpened():
    print("Cannot open camera")
    exit()

while True:
    flag = 0  # 标记是否检测到文档
    ret, image = cap.read()
    orig = image.copy()  # 保留原图用于透视变换
    if not ret:
        print("不能读取摄像头")
        break

    # 1. 视频帧预处理
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray, ksize=(5, 5), sigmaX=0)
    edged = cv2.Canny(gray, threshold1=15, threshold2=45)
    cv_show('边缘检测结果', edged)

    # 2. 文档轮廓检测与筛选
    cnts = cv2.findContours(edged, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]
    cnts = sorted(cnts, key=cv2.contourArea, reverse=True)[:3]  # 按面积取前3个轮廓
    for c in cnts:
        peri = cv2.arcLength(c, closed=True)  # 计算轮廓周长
        approx = cv2.approxPolyDP(c, 0.05 * peri, closed=True)  # 轮廓近似
        area = cv2.contourArea(approx)
        # 筛选条件:面积>40000(排除小物体)、顶点数=4(四边形)
        if area > 40000 and len(approx) == 4:
            screenCnt = approx
            flag = 1
            break

    # 3. 透视变换与二值化增强
    if flag == 1:
        # 绘制文档轮廓
        image_contours = cv2.drawContours(image, [screenCnt], 0, (0, 255, 0), 2)
        cv_show("文档轮廓", image_contours)
        # 执行透视变换(需将轮廓顶点重塑为(4,2)格式)
        warped = four_point_transform(orig, screenCnt.reshape(4, 2))
        cv_show("矫正后文档", warped)
        # 二值化增强
        warped = cv2.cvtColor(warped, cv2.COLOR_BGR2GRAY)
        ref = cv2.threshold(warped, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
        cv_show("二值化文档", ref)

# 释放资源
cap.release()
cv2.destroyAllWindows()
(1)视频帧预处理

预处理的核心目的是降噪并强化文档边缘,为后续轮廓检测铺路,对应代码中"1. 视频帧预处理"模块:

  • 灰度化:通过cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)将3通道BGR彩色帧转为单通道灰度图,既减少了计算量,又消除了色彩对边缘检测的干扰,让后续操作更高效。

  • 高斯模糊:cv2.GaussianBlur(gray, ksize=(5, 5), sigmaX=0)使用5×5大小的滤波核对灰度图进行平滑处理,核心作用是消除图像噪声------若不做模糊,后续Canny边缘检测会将噪声误判为边缘,影响轮廓提取精度。

  • 边缘检测:cv2.Canny(gray, threshold1=15, threshold2=45)调用Canny算子,通过双阈值筛选有效边缘:低于15的像素视为非边缘,高于45的视为确定边缘,介于两者之间的仅当与确定边缘相连时保留,最终得到文档轮廓的清晰边缘图。

(2)文档轮廓检测与筛选

对应代码中"2. 文档轮廓检测与筛选"模块,核心是从边缘图中精准定位文档轮廓,排除干扰:

  • 轮廓提取:cv2.findContours(edged, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]用于提取边缘图中的轮廓,参数cv2.RETR_EXTERNAL表示只保留最外层轮廓(忽略轮廓内部的小缝隙),cv2.CHAIN_APPROX_SIMPLE会压缩轮廓点(如矩形仅保留4个顶点),大幅减少内存占用和后续计算量。由于OpenCV3.x与4.x版本返回值不同,取[-2]可兼容两个版本,确保代码通用性。

  • 轮廓排序与筛选:先通过sorted(cnts, key=cv2.contourArea, reverse=True)[:3]按轮廓面积降序排序,取前3个轮廓------文档通常是画面中面积较大的物体,这样能减少遍历次数,提升实时性。再通过cv2.approxPolyDP(c, 0.05 * peri, closed=True)进行轮廓近似,将不规则轮廓拟合为多边形(精度为周长的5%,可根据场景调整),最终筛选出"面积>40000(排除小卡片、噪声等干扰)且顶点数=4(四边形,符合文档形状)"的轮廓,判定为目标文档。

(3)透视变换矫正

这是文档扫描的核心功能,对应代码中order_pointsfour_point_transform函数及主循环中的透视变换调用,核心是将倾斜透视的文档转为正射视角:

  • 顶点排序:order_points函数解决轮廓顶点无序问题------四边形顶点无固定顺序,直接用于透视变换会导致矫正变形。函数通过两个维度排序:x+y和最小的是左上顶点,和最大的是右下顶点;y-x差最小的是右上顶点,差最大的是左下顶点,最终输出"左上、右上、右下、左下"的固定顺序顶点,为透视变换提供统一坐标。

  • 变换矩阵计算:cv2.getPerspectiveTransform(rect, dst)根据"原四边形顶点(rect)"和"目标矩形顶点(dst)"生成3×3的透视变换矩阵M。目标矩形顶点定义为[[0,0], [maxWidth-1,0], [maxWidth-1,maxHeight-1], [0,maxHeight-1]],即从坐标原点开始的标准矩形,宽高取原四边形两组对边的最大值,避免矫正后文档被截断。

  • 执行变换:cv2.warpPerspective(image, M, (maxWidth, maxHeight))将透视变换矩阵M应用到原图,按目标宽高输出矫正后的图像,实现文档的正射还原,此时文档已和扫描件效果一致。

(4)二值化增强

对应代码中"3. 透视变换与二值化增强"的二值化模块,核心是提升文档对比度,让文字更清晰:

矫正后的文档先通过cv2.cvtColor(warped, cv2.COLOR_BGR2GRAY)转回灰度图,再用cv2.threshold(warped, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]执行二值化。其中cv2.THRESH_OTSU是大津法,能自动计算最优阈值(无需手动调整参数),适配不同光照下的文档------光照强时阈值自动调高,光照弱时自动调低,最终将文字转为白色、背景转为黑色,实现类似扫描仪的清晰效果。

(1)视频帧预处理

预处理的核心目的是降噪并强化文档边缘,为后续轮廓检测铺路。步骤如下:

  • 灰度化:将BGR彩色帧转为单通道灰度图,减少计算量,消除色彩干扰,通过cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)实现。

  • 高斯模糊:使用5×5滤波核对灰度图进行模糊处理,平滑图像噪声,避免边缘检测时产生误检,对应代码cv2.GaussianBlur(gray, ksize=(5, 5), sigmaX=0)

  • 边缘检测:通过Canny算子提取图像边缘,设置双阈值(15/45)筛选有效边缘,得到文档轮廓的初步轮廓,代码为cv2.Canny(gray, threshold1=15, threshold2=45)

(2)文档轮廓检测与筛选

边缘检测后需提取轮廓并筛选出文档区域,关键在于排除小物体干扰,精准定位四边形轮廓:

  • 轮廓提取:采用cv2.findContours函数检测最外层轮廓(参数cv2.RETR_EXTERNAL),并压缩轮廓点(参数cv2.CHAIN_APPROX_SIMPLE),减少计算开销。

  • 轮廓排序与筛选:按轮廓面积降序排序,取前3个轮廓提高效率;通过轮廓近似(cv2.approxPolyDP)将不规则轮廓拟合为多边形,筛选出面积大于40000且顶点数为4的轮廓(判定为文档)。

(3)透视变换矫正

透视变换是文档矫正的核心,需先对四边形顶点排序,再计算变换矩阵并映射为标准矩形:

  • 顶点排序:通过order_points函数,利用顶点x+y的和与y-x的差,将无序顶点按"左上、右上、右下、左下"固定顺序排列,确保透视变换的坐标一致性。

  • 变换矩阵计算:通过cv2.getPerspectiveTransform函数,根据原四边形顶点与目标矩形顶点(从(0,0)到(maxWidth-1, maxHeight-1))生成3×3透视变换矩阵。

  • 执行变换:调用cv2.warpPerspective函数,应用变换矩阵将透视角度的文档矫正为正射视角,得到平整的文档图像。

(4)二值化增强

矫正后的文档需进行二值化处理,增强文字与背景的对比度。采用OTSU大津法自动计算最优阈值,无需手动调参,适配不同光照场景,代码为cv2.threshold(warped, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]

二、背景建模:运动目标检测的核心技术

背景建模是运动目标检测的基础,核心逻辑是区分视频中的静止背景与运动前景,常见于安防监控、行为分析等场景。本文将解析两种主流方法,并对比各类背景建模技术的优劣。

2.1 两种核心实现方法(附完整代码)

以下分别给出帧差法与MOG2背景建模的完整代码,结合代码解析实现逻辑与关键细节:

(1)帧差法:简单直观的入门方案

帧差法适合光照稳定场景,核心是通过相邻帧像素差异定位运动目标,完整代码如下:

python 复制代码
import cv2
import numpy as np

# 1. 初始化视频捕获对象(读取本地视频,替换为0可读取摄像头)
cap = cv2.VideoCapture('test.avi')
if not cap.isOpened():
    print("Error: 无法打开视频文件!")
    exit()

# 2. 读取第一帧并预处理(作为初始背景帧)
ret, prev_frame = cap.read()
if not ret:
    print("Error: 无法读取视频帧!")
    cap.release()
    exit()
prev_gray = cv2.cvtColor(prev_frame, cv2.COLOR_BGR2GRAY)
prev_gray = cv2.GaussianBlur(prev_gray, (5, 5), 0)  # 高斯模糊降噪

# 3. 创建形态学结构元素(用于后续去噪)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))

# 4. 逐帧处理视频
while True:
    ret, curr_frame = cap.read()
    if not ret:  # 视频读取完毕/失败,退出循环
        break

    # 4.1 预处理当前帧(与初始帧预处理一致,保证一致性)
    curr_gray = cv2.cvtColor(curr_frame, cv2.COLOR_BGR2GRAY)
    curr_gray = cv2.GaussianBlur(curr_gray, (5, 5), 0)

    # 4.2 核心:帧差法提取前景掩码
    frame_diff = cv2.absdiff(prev_gray, curr_gray)  # 计算相邻帧绝对差
    _, fgmask = cv2.threshold(frame_diff, 30, 255, cv2.THRESH_BINARY)  # 二值化

    # 4.3 形态学操作优化前景掩码
    fgmask = cv2.morphologyEx(fgmask, cv2.MORPH_CLOSE, kernel)  # 闭运算填补空洞
    fgmask = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel)   # 开运算去除噪点

    # 4.4 轮廓检测(提取运动目标轮廓)
    _, contours, hierarchy = cv2.findContours(
        fgmask.copy(),  # 复制掩码,避免原数据被修改
        cv2.RETR_EXTERNAL,  # 只检测最外层轮廓
        cv2.CHAIN_APPROX_SIMPLE  # 压缩轮廓点
    )

    # 4.5 筛选有效轮廓并绘制外接矩形
    for cnt in contours:
        area = cv2.contourArea(cnt)
        if area > 500:  # 过滤面积小于500的小噪点轮廓
            x, y, w, h = cv2.boundingRect(cnt)  # 计算最小外接矩形
            cv2.rectangle(curr_frame, (x, y), (x + w, y + h), (0, 255, 0), 2)  # 绘制绿色矩形

    # 4.6 显示结果+更新前一帧
    cv2.imshow('原始帧+运动目标标注', curr_frame)
    cv2.imshow('帧差法前景掩码', fgmask)
    prev_gray = curr_gray  # 更新前一帧,为下一次帧差做准备

    # 按键控制:按ESC(27)退出
    key = cv2.waitKey(30)
    if key == 27:
        break

# 5. 释放资源
cap.release()
cv2.destroyAllWindows()

代码核心逻辑解析,对应上述流程步骤:

  • 帧预处理:curr_gray = cv2.cvtColor(...) + cv2.GaussianBlur(...),与初始帧预处理逻辑完全一致------只有相邻帧的预处理方式统一,后续像素差计算才准确,避免因预处理差异导致的误检。

  • 帧差计算:cv2.absdiff(prev_gray, curr_gray)是核心,逐像素计算相邻两帧的灰度差值,运动区域因像素值变化大,差值会显著高于静止区域(背景),最终输出的frame_diff中,运动区域呈亮斑,背景呈黑色。

  • 二值化:cv2.threshold(frame_diff, 30, 255, cv2.THRESH_BINARY)设置阈值30(经验值,可按需调整),将差值>30的像素标记为前景(255,白色),≤30的标记为背景(0,黑色),得到前景掩码fgmask,明确区分前景与背景。

  • 形态学优化:帧差法的固有缺陷是易产生小噪点和前景空洞,因此需两步形态学操作:MORPH_CLOSE(先膨胀后腐蚀)填补前景区域的小空洞(如运动目标内部的小黑点),MORPH_OPEN(先腐蚀后膨胀)去除背景中的孤立小噪点,让前景掩码更规整。

  • 目标标注:cv2.contourArea(cnt) > 500筛选有效轮廓,排除小噪点;cv2.boundingRect(cnt)计算轮廓的最小外接矩形,再用cv2.rectangle在原始彩色帧上绘制绿色矩形,实现运动目标的可视化标注。

(2)MOG2混合高斯模型:抗干扰强的进阶方案

MOG2能自适应更新背景,抗光照变化能力更强,完整代码如下(含注释解析):

python 复制代码
import cv2

# 1. 初始化视频捕获对象
cap = cv2.VideoCapture('test.avi')
if not cap.isOpened():
    print("Error: 无法打开视频文件!")
    exit()

# 2. 创建形态学结构元素(3×3十字形核,适合小噪点去除)
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, ksize=(3,3))

# 3. 创建MOG2背景建模器(核心:自动学习并更新背景)
# detectShadows=True(默认):会将阴影标记为灰色,可设为False提升速度
fgbg = cv2.createBackgroundSubtractorMOG2()

# 4. 逐帧处理视频
while True:
    ret, frame = cap.read()
    if not ret:  # 视频读取完毕,退出循环
        break

    # 4.1 核心:MOG2提取前景掩码(自动区分背景与前景)
    fgmask = fgbg.apply(frame)  # 建模器自动更新背景,输出前景掩码

    # 4.2 开运算去噪(MOG2仍有少量噪点,需优化)
    fgmask_new = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel)

    # 4.3 轮廓检测(提取运动目标轮廓)
    _, contours, h = cv2.findContours(
        fgmask_new, 
        cv2.RETR_EXTERNAL, 
        cv2.CHAIN_APPROX_SIMPLE
    )

    # 4.4 筛选有效轮廓并绘制矩形(用周长筛选,替代面积)
    for c in contours:
        perimeter = cv2.arcLength(c, closed=True)  # 计算轮廓周长
        if perimeter > 188:  # 周长阈值,过滤小噪点轮廓
            x, y, w, h = cv2.boundingRect(c)
            # 在原始帧上绘制绿色外接矩形
            cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)

    # 4.5 显示结果+按键控制
    cv2.imshow('原始帧+目标标注', frame)
    cv2.imshow('MOG2前景掩码', fgmask_new)
    k = cv2.waitKey(60)  # 60ms/帧,适配视频帧率
    if k == 27:  # 按ESC退出
        break

# 5. 释放资源
cap.release()
cv2.destroyAllWindows()

代码核心差异与解析:

  • 建模初始化:cv2.createBackgroundSubtractorMOG2()是核心API,创建混合高斯模型建模器------该模型会将每个像素的灰度值拟合为多个高斯分布(背景像素的分布更稳定,前景像素分布波动大),自动区分背景与前景,且能动态更新背景(如光照缓慢变化、背景轻微抖动时,模型会调整背景参数,避免误检)。

  • 前景提取:fgbg.apply(frame)无需手动计算帧差,只需将当前帧输入建模器,建模器会对比自身维护的背景模型,直接输出前景掩码------掩码中,前景为白色(255),背景为黑色(0),若开启阴影检测(默认),阴影会被标记为灰色(127),可根据需求设detectShadows=False关闭阴影检测,提升处理速度。

  • 去噪与标注:MOG2生成的掩码仍有少量孤立噪点,通过cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel)开运算去除;筛选逻辑用轮廓周长(cv2.arcLength)替代面积,本质都是过滤小噪点,周长阈值188需根据视频分辨率和目标大小调整,适配不同场景。

(1)帧差法:简单直观的入门方案

帧差法通过相邻两帧的像素差异判定运动区域,原理简单、计算量小,适合光照稳定的简单场景,实现流程如下:

  • 帧预处理:对相邻两帧分别进行灰度化与高斯模糊,降低噪声与光线波动的影响。

  • 帧差计算:通过cv2.absdiff函数计算两帧灰度图的像素级绝对差,运动区域表现为亮斑,静止区域为黑色。

  • 二值化:设置阈值(如30),将差值超过阈值的像素标记为前景(255),其余为背景(0),得到前景掩码。

  • 形态学优化:帧差法易产生噪点与空洞,需通过闭运算(先膨胀后腐蚀)填补空洞,再通过开运算(先腐蚀后膨胀)去除孤立噪点,优化前景掩码质量。

  • 目标标注:对优化后的掩码进行轮廓检测,筛选面积大于阈值的轮廓(过滤小噪点),通过cv2.boundingRect计算外接矩形并绘制,实现运动目标标注。

(2)MOG2混合高斯模型:抗干扰强的进阶方案

MOG2(Mixture of Gaussians)通过建立混合高斯模型对背景进行动态建模,能自适应更新背景(如光照缓慢变化、背景轻微抖动),抗干扰能力优于帧差法,实现步骤更简洁:

  • 建模初始化:通过cv2.createBackgroundSubtractorMOG2()创建背景建模器,自动学习背景特征。

  • 前景提取:调用fgbg.apply(frame)函数,将当前帧输入建模器,直接输出前景掩码,无需手动计算帧差。

  • 去噪与标注:通过开运算去除噪点,再进行轮廓检测与筛选,绘制运动目标外接矩形,完成检测。

2.2 常见背景建模方法对比

除上述两种方法外,还有KNN、GMG等主流背景建模技术,不同方法在鲁棒性、计算复杂度等方面差异显著,具体对比如下:

建模方法 核心原理 光照鲁棒性 计算复杂度 抗阴影能力 适用场景
帧差法 相邻帧像素差值判定前景 弱(易受光照突变干扰) 低(仅帧差+阈值运算) 弱(阴影易被误判为前景) 光照稳定、简单场景(如室内监控)
MOG2 混合高斯模型动态更新背景 中强(自适应光照缓慢变化) 中(模型参数更新需额外计算) 中(可通过参数优化抑制阴影) 光照渐变、普通复杂场景(如户外监控)
KNN背景建模 K近邻算法分类背景与前景 强(对光照变化适应性好) 中高(需维护样本集) 强(自带阴影抑制功能) 光照多变、复杂场景(如交通监控)
GMG(高斯混合梯度) 结合高斯模型与梯度信息建模 中(依赖初始背景样本) 中(梯度计算增加开销) 中弱(阴影抑制效果一般) 静态背景、低帧率场景

2.3 方法选型建议

新手入门可优先掌握帧差法,理解运动目标检测的底层逻辑;实际项目中,若场景光照稳定、对实时性要求极高,帧差法是最优选择;若面临光照变化、阴影干扰等复杂情况,建议选用MOG2或KNN方法,其中KNN的阴影抑制能力更出色,但需平衡计算资源开销。

三、总结与拓展

本文解析的两大视频处理案例,分别对应文档数字化与运动目标检测的核心场景,核心技术可总结为:实时文档扫描的关键是轮廓检测与透视变换,背景建模的核心是前景与背景的精准区分。

拓展方向:实时文档扫描可增加光照补偿、自动保存功能;背景建模可结合目标跟踪算法(如KCF、CSRT),实现运动目标的持续追踪。开发者可根据实际场景,优化参数与流程,提升功能的鲁棒性与实用性。

相关推荐
KG_LLM图谱增强大模型2 小时前
ARK投资2026年度大创意报告:把握颠覆性创新的未来十年
人工智能·知识图谱
沉淅尘2 小时前
Context Engineering: 优化大语言模型性能的关键策略与艺术
数据库·人工智能·语言模型
救救孩子把2 小时前
59-机器学习与大模型开发数学教程-5-6 Adam、RMSProp、AdaGrad 等自适应优化算法
人工智能·算法·机器学习
王莽v22 小时前
LLM 分布式推理:切分、通信与优化
人工智能·分布式
HZjiangzi2 小时前
文物古董如何实现高保真三维数字化?思看科技3DeVOK MT彩色扫描+智能贴图方案权威解析
人工智能·科技·制造·三维扫描仪
救救孩子把2 小时前
58-机器学习与大模型开发数学教程-5-5 牛顿法与拟牛顿法(BFGS、L-BFGS)
人工智能·机器学习
junziruruo2 小时前
三叉预测头Trident prediction head(RGBT目标跟踪以MTNET为例)
人工智能·计算机视觉·目标跟踪
光羽隹衡2 小时前
计算机视觉--Opencv(图像形态学)
人工智能·opencv·计算机视觉
懈尘2 小时前
基于Spring Boot与LangChain4j的AI驱动新闻系统设计与工程实现
java·大数据·人工智能·spring boot·后端·langchain