一直對視頻或者圖像添加水印很感興趣,查找資料后用OpenCV嘗試了一下。
記錄下來。
1.首先是打開攝像頭。
找到OpenCV官方文檔給出的例子。
例子中實現的是,打開攝像頭,並對畫面進行高斯濾波,使用canny算子檢測直線邊緣。
#include "opencv2/opencv.hpp" using namespace cv; int main(int, char**) { VideoCapture cap(0); // open the default camera if(!cap.isOpened()) // check if we succeeded return -1; Mat edges; namedWindow("edges",1); for(;;) { Mat frame; cap >> frame; // get a new frame from camera cvtColor(frame, edges, CV_BGR2GRAY); GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5); Canny(edges, edges, 0, 30, 3); imshow("edges", edges); if(waitKey(30) >= 0) break; } // the camera will be deinitialized automatically in VideoCapture destructor return 0; }
2.打開攝像頭后,接下來是想在畫面上添加水印,圖片之類。類似於電視畫面上的台標。
查找到addWeighted函數。
如下是OpenCV官方文檔給出的關於addWeighted的例子。
能夠將兩幅圖像添加到一起,但是要求尺寸是一樣的。
如下分別是原圖像,要添加的圖像,最后效果圖像。
#include <cv.h> #include <highgui.h> #include <iostream> using namespace cv; int main( int argc, char** argv ) { double alpha = 0.5; double beta; double input; Mat src1, src2, dst; /// Ask the user enter alpha std::cout<<" Simple Linear Blender "<<std::endl; std::cout<<"-----------------------"<<std::endl; std::cout<<"* Enter alpha [0-1]: "; std::cin>>input; /// We use the alpha provided by the user if it is between 0 and 1 if( input >= 0.0 && input <= 1.0 ) { alpha = input; } /// Read image ( same size, same type ) src1 = imread("../../images/LinuxLogo.jpg"); src2 = imread("../../images/WindowsLogo.jpg"); if( !src1.data ) { printf("Error loading src1 \n"); return -1; } if( !src2.data ) { printf("Error loading src2 \n"); return -1; } /// Create Windows namedWindow("Linear Blend", 1); beta = ( 1.0 - alpha ); addWeighted( src1, alpha, src2, beta, 0.0, dst); imshow( "Linear Blend", dst ); waitKey(0); return 0; }
有了上邊的例子后,經過修改,最終如下。
int opencvcamera() { VideoCapture cap(0); // open the default camera if (!cap.isOpened()) // check if we succeeded return -1; Mat edges; namedWindow("bjuttv", 1); Mat logo = imread("Arcteryx_logo.jpg"); pyrDown(logo, logo, Size(logo.cols / 2, logo.rows / 2)); Mat graylogo = imread("Arcteryx_logo.jpg", 0); pyrDown(graylogo, graylogo, Size(graylogo.cols / 2, graylogo.rows / 2)); for (;;) { Mat frame; cap >> frame; // get a new frame from camera Mat imageROI = frame(Rect(0, 0, graylogo.cols, graylogo.rows)); addWeighted(imageROI, 0.7, logo, 0.3, 0., imageROI); //logo.copyTo(imageROI, graylogo); //logo.copyTo(imageROI); imshow("bjuttv", frame); if (waitKey(30) >= 0) break; } }
程序中其實也可以用copyTo,將logo拷貝到感興趣區域imageROI中。
pyrDown()是OpenCV提供的圖像金字塔函數,用來下采樣,減小圖片尺寸。
稍微調節以后就得到如下效果。
參考:
http://docs.opencv.org/2.4/doc/tutorials/core/adding_images/adding_images.html