HDU数字图像处理实验二——去水印(网安)

一、实验目的

通过自行编程实现图像增强,包括实现直方图均衡化以及滤波。具体要求为:1)使用老师提供的图片进行直方图均衡化,比较原图与处理后图片的区别;2)使用老师提供的程序,输入自己名字中的一个字生成随机水印。自行编程尝试将水印去除,并就得到的效果进行讨论。对于要求2,使用tic,toc函数测量函数运行时间。

要求一

实现直方图均衡化以及滤波的文章很多,请自行搜索

要求二

老师所提供的代码:

function [hdu_new]=figure_generator(name_former)
% 生成需要处理的图像
% 图片的路径需要根据自己存储的路径进行修改
hdu = imread('');
[m,n,~] = size(hdu);
posi_x = rand();
posi_y = rand();
name_box = ["的题","的迷思","的纠结","的考虑","的想法","的创意","的挑战","的攀登","的机遇","的满绩"];
name_latter = name_box(randi(10));
mask = zeros(m,n);
figure()
imshow(mask)
text(floor((n-100)*posi_x),floor((m-20)*posi_y),strcat(name_former,name_latter),'FontSize',10,'color',[0,0,1])
f = getframe();
close figure 1
f.cdata(f.cdata(:,:,3)>0)=1;
mask=f.cdata(1:m,:,3);
hdu_blue=hdu(:,:,3);
hdu_blue(mask>0)=255;
hdu_new=hdu;
hdu_new(:,:,3)=hdu_blue;
figure(4)
imshow(hdu_new)

老师所的提供图片:
在这里插入图片描述

分析代码可知,此水印是在图片的蓝色图层上某个随机位置将要加入的字体的值赋值为255所产生的,那我们就从问题的产生入手。

去除水印,博主很自然的就想到应用中值滤波器或均值滤波器方法,但单次的均值滤波和中值滤波效果不是很好,最后博主采用了针对此问题最简单粗暴的方法,用水印像素点的上一个点,代替水印像素点

在讲述解决方法之前,先做几个知识点科普(已知道的大佬请自动略过):

知识点1:二阶矩阵索引问题

有同学可能问什么是索引?拿生活中的一个实例来说,你去参加比赛,会对选手进行编号,你是2号选手,这个2号就是索引。

二阶矩阵既可用双索引来定位,也可以用单索引来定位

例:矩阵

5  7  10
20 6  9
8  3  1

双索引:

5 索引(1,1) 8 索引(3,1)

单索引:

5 索引(1) 8 索引(3) 6 索引(5) (按列从上至下排)

知识点2:矩阵遍历问题

代码:

n = [10,20,31;9,25,16;4,19,28];
z = [1;2;3;4;5;6;7;8];
for k=z
    fprintf('%d ',n(k));
    fprintf('\n');
    n(k)=n(k+1);
    fprintf('%d\n',n(k));
end

运行结果:

10 9 4 20 25 19 31 16 
9
4
20
25
19
31
16
28

由运行结果可知,在Matlab中对于矩阵的遍历是直接将整个矩阵一次输入,并不是一个一个输入

知识点3:已知像素点值返回索引的方法

代码:

n = [10,20,31;9,25,10;4,19,28];
n(n==10)=20;
fprintf('%d ',n);

运行结果:

20 9 4 20 25 19 31 20 28 

由结果可知可以用“n(n==10)”这样的语句直接更改矩阵中等于某个值的点,更由结果可以推知“n==10”返回的是矩阵n中像素值等于10的像素点的索引,但是事实真的是这样吗?让我们用代码检验一下

代码:

n = [10,20,31;9,25,10;4,19,28];
fprintf('%d ',(n==10));

运行结果:

1 0 0 0 0 0 0 1 0

从结果我们看到“n==10”的返回值是将矩阵n中像素值等于10的像素点返回1,对于此问题博主也是很迷惑,就结果来看返回1是不合理的

所以已知像素点值想要返回索引就需要别的方法,博主找到了find()函数

代码:

n = [10,20,31;9,25,10;4,19,28];
fprintf('%d ',find(n==10));

运行结果:

1 8 

find()返回指定像素点值的单索引

说完知识点要回到问题上,去除水印!

解决方法一:循环所有点,将像素值等于255的点替换

代码:

clc;clear;close all;
h = figure_generator('睿珺');
tic
hdu_new1 = h;
hdu_blue1=hdu_new1(:,:,3);
[x,y] = size(hdu_new1(:,:,3));
for i=1:1:x
     for j=1:1:y
         if (hdu_blue1(i,j)==255)
             hdu_blue1(i,j) = hdu_blue1(i-1,j);
         end
     end
end
hdu_new1(:,:,3)=hdu_blue1;
figure();
imshow(hdu_new1);
toc

解决方法二:获得像素值等于255点的像素点的索引,循环索引

代码:

clc;clear;close all;
w = figure_generator('睿珺');
tic
hdu_new3 = w;
hdu_blue3=hdu_new3(:,:,3);
[m]=find(hdu_blue3==255);
[s,z]=size(m);
for j=1:s
    hdu_blue3(m(j))=hdu_blue3(m(j)-1);
end
hdu_new3(:,:,3)=hdu_blue3;
figure();
imshow(hdu_new3);
toc

因为本实验有时间要求,分析来看,法二所用时间应该是比法一短的,但是博主真实运行起来并没有差别,所以考虑到耗费时间多的并不是循环导致,所以博主将老师所给代码中的“figure(4);imshow(hdu_new)”还有自己代码法一中
“figure();imshow(hdu_new1);”法二中“figure();imshow(hdu_new3);”注释掉,经运行,法二比法一快0.001s左右

文章写作时间仓促,如有错误请指正,如有问题请在评论区中提问。

加油!

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值