C++ OPENCV给视频添加水印
时间: 2025-03-28 16:18:01 浏览: 56
### 使用 C++ 和 OpenCV 实现给视频添加水印功能
以下是基于提供的引用内容以及相关技术知识,详细介绍如何使用 C++ 和 OpenCV 给视频文件添加水印。
#### 1. 准备工作
为了实现该功能,需要加载目标视频和水印图像。通过 `cv::VideoCapture` 类可以读取视频帧,并逐帧处理每一帧数据[^2]。每帧都可视为一张静态图像,在其上叠加水印即可完成操作。
#### 2. 加载视频与水印图像
利用 `cv::imread` 函数加载水印图片,并将其尺寸调整至适合嵌入的位置大小。如果水印过大,则可能遮挡过多画面;过小则难以辨认。因此需调用水印缩放方法 `cv::resize` 来控制比例。
```cpp
// 载入水印图像
cv::Mat watermark = cv::imread("watermark.png", cv::IMREAD_UNCHANGED);
if (watermark.empty()) {
std::cerr << "无法打开水印图像!" << std::endl;
return -1;
}
// 设置水印的目标宽度高度
int targetWidth = 200; // 假设设定为固定值
double aspectRatio = static_cast<double>(watermark.cols) / watermark.rows;
int targetHeight = static_cast<int>(targetWidth / aspectRatio);
// 缩放水印
cv::resize(watermark, watermark, cv::Size(targetWidth, targetHeight));
```
#### 3. 处理视频流
创建一个循环结构用于遍历整个视频中的所有帧。对于每一个提取出来的帧,都需要执行如下几个步骤:
- 将当前帧转换成四通道格式(如果有透明度需求的话),以便能够正确混合颜色;
- 定义好放置水印的具体位置坐标;
- 应用 alpha 混合算法把水印融合到原图之上。
下面是完整的代码片段展示这一过程:
```cpp
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
int main() {
// 打开输入视频文件
VideoCapture cap("input_video.mp4");
if (!cap.isOpened()) {
std::cerr << "Error opening video stream or file" << std::endl;
return -1;
}
// 获取视频属性
int frame_width = static_cast<int>(cap.get(CAP_PROP_FRAME_WIDTH));
int frame_height = static_cast<int>(cap.get(CAP_PROP_FRAME_HEIGHT));
double fps = cap.get(CAP_PROP_FPS);
// 创建输出视频写入器
VideoWriter outputVideo("output_with_watermark.avi",
VideoWriter::fourcc('M', 'J', 'P', 'G'),
fps,
Size(frame_width, frame_height));
// 载入水印图像
Mat watermark = imread("watermark.png", IMREAD_UNCHANGED);
if (watermark.empty()) {
std::cerr << "Could not open or find the watermarked image..." << std::endl;
return -1;
}
resize(watermark, watermark, Size(200, 50)); // 自定义水印大小
while(true){
Mat frame;
bool success = cap.read(frame);
if(!success || frame.empty()){
break;
}
// 如果原始帧不是RGBA模式,则转为BGR+A形式
if (frame.channels() != 4) {
cvtColor(frame, frame, COLOR_BGR2BGRA);
}
// 计算水印左下角起点坐标
Point origin((frame.cols - watermark.cols)/2 , frame.rows - watermark.rows - 10 );
// Alpha Blending 进行覆盖绘制
float alpha = 0.7f; // 可调节不透明度参数
Rect roi(origin.x, origin.y, watermark.cols, watermark.rows);
Mat overlayROI = frame(roi);
addWeighted(overlayROI, 1-alpha, watermark, alpha, 0., overlayROI);
// 写入带水印的新帧到输出视频
outputVideo.write(frame);
imshow("Frame with Watermark", frame);
char c=(char)waitKey(25);
if(c==27)
break;
}
cap.release();
outputVideo.release();
destroyAllWindows();
return 0;
}
```
上述程序实现了从读取源视频开始直到保存最终带有水印效果版本为止的整体流程。
---
阅读全文
相关推荐



















