大致问题是原视频添加盲水印之后,原视频添加盲水印所在的图像帧有影响
这部分是原GitHub上面作者写的但是没有使用下面第二段代码,不知道是什么操作
Mat WatermarkAdder::proceedFrame(Mat frame,int information) {
Picture pic(frame);
Mat informationGraph = getInformationGraph(information, energy);
vectordctResult = pic.pictureDct();
for (int i = 0; i < 64; i++) {
for (int j = 0; j < 64; j++) {
dctResult[0].at<float>(i + verticalBias, j + horizontalBias) +=
informationGraph.at(i, j);
dctResult[1].at<float>(i + verticalBias, j + horizontalBias) +=
informationGraph.at(i, j);
dctResult[2].at<float>(i + verticalBias, j + horizontalBias) +=
informationGraph.at(i, j);
}
}
Picture res;
res.pictureIdct(dctResult);
return res.img;
}
Mat WatermarkAdder:: getInformationGraph(int information, int energy) {
Mat res(64,64, CV_8UC1);
int pos = 31;
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 4; j++) {
int bit = ((1 << pos) & information);
for (int k = 0; k < 8; k++) {
for (int l = 0; l < 16; l++) {
res.at(i * 8 + k,j * 16 + l) = (bit == 0 ? 0 : (uchar)energy);
}
}
pos--;
}
}
return res;
}
这是我改的直接对图像帧进行操作,导致最后合成出来的时候有明显缺陷
Mat WatermarkAdder::proceedFrame(Mat frame,Mat information) {
//得到帧
Picture pic(frame);
int wigh;
int high;
wigh=information.rows;
high=information.cols;
// 对一维或二维数组进行正向或逆向离散余弦变换
vectordctResult = pic.pictureDct();
for (int i = 0; i < wigh; i++) {
for (int j = 0; j < high; j++) {
dctResult[0].at<float>(i + verticalBias, j + horizontalBias) +=
information.at(i, j);
dctResult[1].at<float>(i + verticalBias, j + horizontalBias) +=
information.at(i, j);
dctResult[2].at<float>(i + verticalBias, j + horizontalBias) +=
information.at(i, j);
}
}
// 返回新图
Picture res;
//反余弦变换
res.pictureIdct(dctResult);
return res.img;
}
第二段我猜测应该是盲水印的最低位运算啥的,但是具体的不是很清楚
这大概是在添加盲水印时直接对图像帧进行操作,而不是使用第二段代码中给出的方法进行处理,导致最后合成出来的图像有明显缺陷。
提供参考实例:https://juejin.cn/post/7000307768263442468
你这个问题看起来是水印图片和视频帧的位数没有对齐导致的。
源码中getInformationGraph这一步应该就是把水印做了位数扩展,可视频帧对齐才能正常使用。
这段代码的第一个错误信息是:没有提供。
*disc
Picture pic(frame);
Mat informationGraph = getInformationGraph(information, energy);
vector<Mat>dctResult = pic.pictureDct();
for (int i = 0; i < 64; i++) {
for (int j = 0; j < 64; j++) {
dctResult[0].at<float>(i + verticalBias, j + horizontalBias) +=
informationGraph.at<uchar>(i, j);
dctResult[1].at<float>(i + verticalBias, j + horizontalBias) +=
informationGraph.at<uchar>(i, j);
dctResult[2].at<float>(i + verticalBias, j + horizontalBias) +=
informationGraph.at<uchar>(i, j);
}
}
Picture res;
res.pictureIdct(dctResult);
return res.img;
}
Mat WatermarkAdder:: getInformationGraph(int information, int energy) {
Mat res(64,64, CV_8UC1);
int pos = 31;
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 4; j++) {
int bit = ((1 << pos) & information);
for (int k = 0; k < 8; k++) {
for (int l = 0; l < 16; l++) {
res.at<uchar>(i * 8 + k,j * 16 + l) = (bit == 0 ? 0 : (uchar)energy);
}
}
pos--;
}
}
return res;
}