目录
📅大四是整个大学期间最忙碌的时光,一边要忙着备考或实习为毕业后面临的就业升学做准备,一边要为毕业设计耗费大量精力。近几年各个学校要求的毕设项目越来越难,有不少课题是研究生级别难度的,对本科同学来说是充满挑战。为帮助大家顺利通过和节省时间与精力投入到更重要的就业和考试中去,学长分享优质的选题经验和毕设项目与技术思路。
🚀对毕设有任何疑问都可以问学长哦!
大家好,这里是海浪学长毕设专题,本次分享的课题是
🎯机器视觉深度学习的视频去水印算法
随着短视频风口的到来。越来越多的人想着如何通过短视频吸粉,如何通过视频变现,从而分享风口上的这块蛋糕。视频搬运自然就变成了一种职业,这是时代的产物。从素材网站下载的视频大多都留有水印,使用这些视频对使用者有较大干扰,很不方便,需要运用一定的方法尽可能去掉。
我们知道添加水印方法是
![]()
其中I是原图、W是logo图,J分别是添加logo之后的水印图,α是原图的透明度,α=0时完全看不到水印,α=1时,水印将完全覆盖原图,在没有水印的区域α=0,因此,求解原图的公式为
![]()
若已知W和α,就能求I。
一般情况下透明度是一个常数,即logo的各个位置的α相同,本文中遇到的水印图片皆为灰白色,各颜色通道的值相同(不同也OK),假设水印为白色透明的文字,很自然可以想到利用纯黑色背景的图像获得该文字水印,可以进一步假设白色文字的颜色为255,即W=255,α(logo在水印图的占比)也就是正在上传…重新上传取消,相反,如果水印强度不一致,则可以假设一个α(可以选择该图中较大的灰度值除以255,不是最大的灰度值,因为图片和视频压缩产生噪声的缘故,见下文),正在上传…重新上传取消,本文中的水印图W,alpha通道图以及消减后结果(以下简称消减图)

水印强度不一致的Logo,有时候仅从黑色背景下提取亮色区域是不够,还需要从白色背景下提取暗色背景。
为了处理边缘这些区域,考虑使用中值滤波修复这些区域,如果直接对整个水印区域进行中值滤波,虽然可以将水印去除干净,但信息损失量很大,使原本分辨率不高的视频变得更加模糊,如图12;另一方面,如果能够定位这些区域,仅替换这些坏的区域,则能得到一个折中的效果

定位这些区域的简单办法是将消减图和其中值滤波图像相减,取绝对值,得到差值图,目标区域则是这些差值较大的像素,为了减少误差,可以用多个差值图求中值或均值,取一个阈值,将较小的噪声置零,得到最终差值图如图13,利用该差值图替换消减图中的像素点,获得接近原图的处理结果,如图14,如此形成了一个不甚完美的简单解决方案。

为什么消减图的边缘处理效果不好?因为制作水印图时抗锯齿处理会使我们绘制的黑白图像中存在其他颜色像素,我们得到的时不纯的水印图。什么是抗锯齿?抗锯齿就是修改图像边界的像素值,使看起来更加圆润,为什么要抗锯齿?因为显示器的像素是离散的,与真实世界不同,坚持非黑即白会让图像很难看,抗锯齿能减少这种缺陷的影响,玩过很多视频游戏的人肯定不陌生。 举个例子,假设你要制作一个logo水印图,内容是“Dove”,外面包裹一个椭圆,打开windows画图板,制作该图如图15,理想情况下会以为整个图像中除了黑色像素就是白色像素,其实不然,将图像放大三倍如图16,发现“Dove”附近有许多其他颜色的像素,而椭圆的边缘是明显的锯齿状,反过来从原图中也可以看出来,“Dove”的字母很圆润,这种对于边界的处理叫抗锯齿,许多图片编辑工具都会默认抗锯齿处理,比如在画图板中的铅笔工具没有抗锯齿,但刷子工具会做抗锯齿处理,有空可以试一下Photoshop。

若纯黑背景下水印图Logo的灰度看起来一致,在计算alpha时为什么不选择最高灰度值除以255?因为图像压缩产生了其他分量,这些分量比原来更亮或更暗。 举个例子,打开windows画图板,填充背景为纯黑,画一个无需抗锯齿的图像,选择矩形,填充选择纯色,颜色1(前景色)取黑色RGB=(0,0,0),颜色2(背景色)取接近白色的灰色RGB=(230,230,230),随手画一个矩形,如图17所示,分别另存为bmp、jpg图像,然后重新打开bmp图像另存为png图像(否则是在jpg图像的基础上另存为png),用软件查看图片几乎是一模一样的,但是bmp图像的大小是jpg的几十倍,bmp是未经压缩的原图,逐个像素保存,体积较大,而jpg和png都使用了图像压缩算法。
- >>> import cv2 as cv
- >>> import numpy as np
- >>> img_bmp = cv.imread("imgs/image_format.bmp")
- >>> img_jpg = cv.imread("imgs/image_format.jpg")
- >>> img_png = cv.imread("imgs/image_format.png")
- >>> np.bincount(img_bmp.reshape(-1),minlength=256)
- array([24969, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,
- ... 23行0 ...
- 0, 0, 0, 0, 0, 4212, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0], dtype=int64)
-
- >>> np.bincount(img_jpg.reshape(-1),minlength=256)
- array([24738, 189, 33, 6, 3, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,
- ... 23行0 ...
- 0, 6, 3, 21, 309, 3816, 27, 18, 6,
- 3, 3, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0], dtype=int64)
-
- >>> np.bincount(img_png.reshape(-1),minlength=256)
- array([24969, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,
- ... 23行0 ...
- 0, 0, 0, 0, 0, 4212, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0], dtype=int64)
常见的视频编码如mp4格式等,也是有损压缩的,与图像压缩一样,原来图像中的灰度分量一般都会泄露到邻近的分量上去,视频压缩中更重要的是帧间压缩,比如每10帧为一段,每段只存1个关键帧以及帧间信息,其余9帧依靠关键帧还原回来,在播放时需要持续不断地解压,需要大量的计算支持,有专门的硬件解码器会很快,软件解码器也可以,如果没有硬件和软件的支持,就打不开这种格式的视频文件。

我是海浪学长,创作不易,欢迎点赞、关注、收藏、留言。
毕设帮助,疑难解答,欢迎打扰!