Python Opencv实践 - 简单的AR项目

这个简单的AR项目效果是,通过给定一张静态图片作为要视频中要替换的目标物品,当在视频中检测到图片中的物体时,通过单应矩阵做投影,将视频中的物体替换成一段视频播放。这个项目的所有素材来自自己的手机拍的视频。

静态图片:

当我在原视频中检测到这本书时,会将书替换成另一个视频里的内容。

关于opencv里的透视投影,单应矩阵等概念,请自行百度。下面是代码:

import cv2 as cv
import numpy as np

videoOriginal = cv.VideoCapture("../../SampleVideos/NationalGeography.mp4")
videoReplace = cv.VideoCapture("../../SampleVideos/Milo1.mp4")
targetImg = cv.imread("./book.png", cv.IMREAD_COLOR)
targetH,targetW,targetC = targetImg.shape

#创建ORB对象
orb = cv.ORB_create(nfeatures=1500)
#提取ORB关键点和特征描述符
kpImg,descsImg = orb.detectAndCompute(targetImg, None)
#调试:绘制关键点
#imgDebug = cv.drawKeypoints(targetImg, kpImg, None)
#cv.imshow("ORB Keypoints", imgDebug)
#匹配距离阈值
matchDistanceThr = 0.75

while True:
    ret,frame = videoOriginal.read()
    if ret == False:
        break;
    #frameAug表示最终合成的增强现实的结果图片
    frameAug = frame.copy()

    
    ret,frameReplace = videoReplace.read()
    if ret == False:
        break;
    #将视频大小调整到和待替换目标图片大小
    frameReplace = cv.resize(frameReplace, (targetW,targetH), interpolation=cv.INTER_AREA)
    
    kpVideo,descsVideo = orb.detectAndCompute(frame, None)
    #frame = cv.drawKeypoints(frame, kpVideo, None)
    #进行特征匹配
    bf = cv.BFMatcher()
    matches = bf.knnMatch(descsImg, descsVideo, k=2)
    goodMatches = []
    for m,n in matches:
        if m.distance < matchDistanceThr * n.distance:
            goodMatches.append(m)
    #print(len(goodMatches))
    #调试:绘制匹配结果
    imgFeatureMatching = cv.drawMatches(targetImg, kpImg, frame, kpVideo, goodMatches, None, flags=2)

    #找到单应矩阵
    #首先找到srcPts和dstPts
    if (len(goodMatches) > 20):
        srcPts = np.float32([kpImg[m.queryIdx].pt for m in goodMatches]).reshape(-1,1,2)
        dstPts = np.float32([kpVideo[m.trainIdx].pt for m in goodMatches]).reshape(-1,1,2)
        #找到单应矩阵
        matrix,mask = cv.findHomography(srcPts, dstPts, cv.RANSAC, 5)
        #print(matrix)
        #映射targetImg的四个角点到目标平面
        targetPts = np.float32([[0,0],[0,targetH],[targetW,targetH],[targetW, 0]]).reshape(-1,1,2)
        targetOnVideoPts = cv.perspectiveTransform(targetPts, matrix)
        #print("Target shape:", targetImg.shape)
        #print("Frame shape:", frame.shape)
        #print(targetPts)
        #print('maps to:')
        #print(targetOnVideoPts)
        #print()
        #绘制待替换目标图像的位置映射到视频帧后的边框结果
        imgTargetOnVideoBox = cv.polylines(frame, [np.int32(targetOnVideoPts)], True, (255,0,255), 3)
        #调用warpPerspective将要替换的视频文件帧图像投影到视频帧的图像
        imgWarp = cv.warpPerspective(frameReplace, matrix, (frame.shape[1],frame.shape[0]))

        #获得掩码图
        #首先将视频帧中要替换的区域内容的mask标记为全1(白色)
        maskForReplace = np.zeros((frame.shape[0],frame.shape[1]), np.uint8)
        cv.fillPoly(maskForReplace, [np.int32(targetOnVideoPts)], (255,255,255))
        #获得原视频帧内容的mask,将maskForReplace取反即可
        maskForVideo = cv.bitwise_not(maskForReplace)
        #生成增强现实的帧
        frameAug = cv.bitwise_and(frameAug, frameAug, mask = maskForVideo)
        frameAug = cv.bitwise_or(imgWarp, frameAug)

    cv.imshow('Augmented Video', frameAug)
    cv.moveWindow('Augmented Video',  imgFeatureMatching.shape[1],0)
    cv.imshow('FeatureMatchResult', imgFeatureMatching)
    cv.moveWindow('FeatureMatchResult', 0,0)
    #cv.imshow('Mask For Video', maskForVideo)
    #cv.imshow('Mask For Replace', maskForReplace)
    #cv.imshow('WarpImage', imgWarp)
    #cv.moveWindow("WarpImage", 800,0)
    #cv.imshow('TargetOnVideo', imgTargetOnVideoBox)
    
    #cv.imshow('VideoPlayer', frame)
    if cv.waitKey(33) & 0xFF == ord('q'):
        break;

videoOriginal.release()
videoReplace.release()
cv.destroyAllWindows()

运行结果:

Python Opencv实践简单的AR项目

相关推荐
小馒头学python2 分钟前
机器学习是什么?AIGC又是什么?机器学习与AIGC未来科技的双引擎
人工智能·python·机器学习
神奇夜光杯11 分钟前
Python酷库之旅-第三方库Pandas(202)
开发语言·人工智能·python·excel·pandas·标准库及第三方库·学习与成长
plmm烟酒僧15 分钟前
Windows下QT调用MinGW编译的OpenCV
开发语言·windows·qt·opencv
千天夜23 分钟前
使用UDP协议传输视频流!(分片、缓存)
python·网络协议·udp·视频流
测试界的酸菜鱼27 分钟前
Python 大数据展示屏实例
大数据·开发语言·python
羊小猪~~31 分钟前
神经网络基础--什么是正向传播??什么是方向传播??
人工智能·pytorch·python·深度学习·神经网络·算法·机器学习
AI小杨32 分钟前
【车道线检测】一、传统车道线检测:基于霍夫变换的车道线检测史诗级详细教程
人工智能·opencv·计算机视觉·霍夫变换·车道线检测
道可云38 分钟前
道可云人工智能&元宇宙每日资讯|2024国际虚拟现实创新大会将在青岛举办
大数据·人工智能·3d·机器人·ar·vr
放飞自我的Coder1 小时前
【python ROUGE BLEU jiaba.cut NLP常用的指标计算】
python·自然语言处理·bleu·rouge·jieba分词
正义的彬彬侠1 小时前
【scikit-learn 1.2版本后】sklearn.datasets中load_boston报错 使用 fetch_openml 函数来加载波士顿房价
python·机器学习·sklearn