前言
最近心血來潮,想著用OpenCV做一個AR的小應(yīng)用,也是看知乎的回答,想到了識別二維碼,然后在二維碼上放視頻,就花了大概兩三天做出了這個小demo,完成度大概有70%,這篇文章簡單說明一下。
總體思路
實(shí)現(xiàn)這個AR demo,首先就是識別到二維碼,然后根據(jù)二維碼的位置信息,通過透視變換得到一個區(qū)域,然后用過掩碼的方式,將一段視頻疊加到實(shí)時場景中。根據(jù)上面所說的,用到的技術(shù)分為三點(diǎn)
1 二維碼檢測
在這個demo中,只需要檢測二維碼的位置就可以了,所以用的是這個API,用法也是很簡單的,第一個參數(shù)為待檢測的圖像,第二個參數(shù)為二維碼的四個頂點(diǎn)坐標(biāo),返回值表示是否含有二維碼
bool cv::QRCodeDetector::detect(InputArray img,
OutputArray points)
2 透視變換
得到二維碼的四個定點(diǎn)之后,隨著視角的移動,二維碼的四個定點(diǎn)肯定不是正方形的形狀,這就需要我們疊加的視頻區(qū)“適配”二維碼的視角,這就需要仿射變換和透視變換,
本項(xiàng)目使用的是透視變換,在OpenCV中,可以通過warpPerspective函數(shù)實(shí)現(xiàn),具體的實(shí)現(xiàn)可以參考完整的代碼。
3 掩碼mask操作
得到了放射變換之后的圖,我們還需要把圖片貼上去,這就用到了很常見的mask掩碼操作,就是生成一個mask圖像,在mask圖像中(一般是灰度圖),只像copy素值不為0的像素點(diǎn),簡單的實(shí)例如下:
dst_warp.copyTo(frame_bg, mask);
完整代碼
#include
#include
using namespace cv;
using namespace std;
int main(int argc, char* argv[]) {
if (argc != 2) {
std::cout << "eg. " << argv[0] << " video" << std::endl;
return 0;
}
// bg is camera
VideoCapture cap_bg(2); // 2 is camera index
// cap_bg.set(CAP_PROP_FRAME_WIDTH, 1280);
// cap_bg.set(CAP_PROP_FRAME_HEIGHT, 720);
VideoCapture cap_show(argv[1]);
if (!cap_show.isOpened()) {
std::cout << "open video failed!" << std::endl;
return 0;
}
Point2f srcPoints[4];//原圖中的四點(diǎn) ,一個包含三維點(diǎn)(x,y)的數(shù)組,其中x、y是浮點(diǎn)型數(shù)
Point2f dstPoints[4];//目標(biāo)圖中的三點(diǎn)
Mat frame_bg;
Mat frame_show;
Mat dst_warp;
QRCodeDetector qrcodedetector;
vector
反思改進(jìn)
1 可以看出來,演示的視頻還是有很多誤檢測的,會出現(xiàn)一閃一閃的情況,這種情況就需要進(jìn)行濾波,改善閃的情況。
2 其實(shí)AR的最重要一部分就是動畫的渲染,這個demo中只是通過類似于添加logo的方式渲染的,更加專業(yè)的話,其實(shí)是可以用專門的工具進(jìn)行的,比如OpenGL等。
審核編輯:劉清
-
Ar
+關(guān)注
關(guān)注
24文章
5095瀏覽量
169466 -
OpenGL
+關(guān)注
關(guān)注
1文章
85瀏覽量
29243 -
OpenCV
+關(guān)注
關(guān)注
31文章
634瀏覽量
41337
發(fā)布評論請先 登錄
相關(guān)推薦
評論