一直对视频或者图像添加水印很感兴趣,查找资料后用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/modules/highgui/doc/reading_and_writing_images_and_video.html#videocapture

http://docs.opencv.org/2.4/doc/tutorials/core/adding_images/adding_images.html

版权声明:本文为hellowooorld原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/hellowooorld/p/6980108.html