前言
最近心血來潮,想著用OpenCV做一個AR的小應用,也是看知乎的回答,想到了識別二維碼,然后在二維碼上放視頻,就花了大概兩三天做出了這個小demo,完成度大概有70%,這篇文章簡單說明一下。
總體思路
實現這個AR demo,首先就是識別到二維碼,然后根據二維碼的位置信息,通過透視變換得到一個區(qū)域,然后用過掩碼的方式,將一段視頻疊加到實時場景中。根據上面所說的,用到的技術分為三點
1 二維碼檢測
在這個demo中,只需要檢測二維碼的位置就可以了,所以用的是這個API,用法也是很簡單的,第一個參數為待檢測的圖像,第二個參數為二維碼的四個頂點坐標,返回值表示是否含有二維碼
bool cv::QRCodeDetector::detect(InputArray img,
OutputArray points)
2 透視變換
得到二維碼的四個定點之后,隨著視角的移動,二維碼的四個定點肯定不是正方形的形狀,這就需要我們疊加的視頻區(qū)“適配”二維碼的視角,這就需要仿射變換和透視變換,
本項目使用的是透視變換,在OpenCV中,可以通過warpPerspective函數實現,具體的實現可以參考完整的代碼。
3 掩碼mask操作
得到了放射變換之后的圖,我們還需要把圖片貼上去,這就用到了很常見的mask掩碼操作,就是生成一個mask圖像,在mask圖像中(一般是灰度圖),只像copy素值不為0的像素點,簡單的實例如下:
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];//原圖中的四點 ,一個包含三維點(x,y)的數組,其中x、y是浮點型數
Point2f dstPoints[4];//目標圖中的三點
Mat frame_bg;
Mat frame_show;
Mat dst_warp;
QRCodeDetector qrcodedetector;
vector
反思改進
1 可以看出來,演示的視頻還是有很多誤檢測的,會出現一閃一閃的情況,這種情況就需要進行濾波,改善閃的情況。
2 其實AR的最重要一部分就是動畫的渲染,這個demo中只是通過類似于添加logo的方式渲染的,更加專業(yè)的話,其實是可以用專門的工具進行的,比如OpenGL等。
審核編輯:劉清
-
Ar
+關注
關注
24文章
5082瀏覽量
169173 -
OpenGL
+關注
關注
1文章
85瀏覽量
29204 -
OpenCV
+關注
關注
29文章
625瀏覽量
41218
發(fā)布評論請先 登錄
相關推薦
評論