图像浮雕效果的实现

1.原理
“浮雕就是把所要呈现的图像突起于石头表面,根据凹凸的程度不同从而形成三维的立体感。计算机产生浮雕效果原理与之类似,即通过勾画图像的轮廓,并且降低周围的像素值,从而产生一张具有立体感的浮雕效果图片。这里我们通过相邻元素相减的方法得到轮廓与边缘的差,从而获得凹凸的立体感觉。”[^1]最后,为了使图片不至于太黑,我们在差的基础上又加了128的偏移量,从而使图片便于观察。
相邻元素相减中“相邻”可以有很多种选择,比如可以用左上一个像素减右下一个像素,即I(x,y)= I(x-1,y-1)- I(x+1,y+1),也可以用左上三个像素减右下三个像素,即I(x,y)= I(x-1,y-1)+ I(x-1,y)+I(x,y-1) -I(x+1,y+1) -I(x+1,y) -I(x,y+1),甚至可以用左上五个像素减右下五个像素。但经过实践,用三个像素相减做出的浮雕不至于太浅,也不至于太深(这里的浅、深指凹凸程度),所以接下来就用三个像素相减的方法。
围绕着相邻元素相减这个中心,我们有一下三种解决办法:
(1)从I(2,2)遍历到I(m-1,n-1)([m,n]=size(I)),图片最外围一圈可以用0或原像素替代。
(2)使用[-1,-1,0;-1,0,1;0,1,1]这个卷积核,至于为什么左上角为-1,右下角为1,这是因为卷积时会先把这个核翻转180°,如果对卷积操作不熟悉的话,可以看看https://blog.csdn.net/hs_hss/article/details/75676202?depth_1-utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-6&utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-6 (这里面核的翻转有点错误,注意一下)。而在matlab中,我们可以直接使用conv2这个函数就可以搞定图像跟核的卷积操作了,为了不改变图像的大小,我们在conv2的shape参数中使用’same’就可以了,具体原因可以参考上面那篇Blog。
(3)如果老师让你用傅里叶的知识做怎么办?由上面的卷积操作我们首先会想到傅里叶变换的一个性质——时域中的卷积等于频域里的乘积,所以我们自然而然地想到可以先把图像以及上面提到的卷积核变换到频域,然后相乘即可,不过这里的相乘是指对应元素相乘,而一张图片的大小往往比3 X 3的卷积核要大很多,那用ffft2变换到频域后也就没办法相乘了。那这条路是不是就走不通了呢,非也!Padding这时候就要派上用途了,如果我们用补0的方式将他们补成一样大小的矩阵不就OK了吗,因为是补0,所以既没有实质性地影响结果,又在形式上达到了统一,简直完美。那么补成多大呢,因为一个a x b 地矩阵与一个c x d的矩阵卷积将得到一个(a+c-1,b+d-1)的矩阵,所以我们可以把图像矩阵(m x n)与卷积核都补成(m+2,n+2)大小的。具体的补0方式在matlab中有两种实现方式,一个是先I(m+2,n+2)=0,kernel(m+2,n+2)=0,然后再用fft2变换到频域,另一是利用fft2(I,m+2,n+2)让他帮你自动扩展,经过实践这两种方式是等价的。但这样先傅里叶再相乘最后再逆傅里叶得到的结果还是(m+2,n+2)的矩阵,为了不改变大小,我们只取去掉外围一圈的子矩阵即可(如果核是5x5的,就要去掉外围两圈,具体原因可以看看卷积的计算过程)。
2.matlab源码:
(1)

I=imread('D:\\photo\kongjun.jpg');
I=rgb2gray(I);
I=double(I);  %这样I相减才能得到负数
[m,n]=size(I);
R=zeros(m,n);
for x=2:m-1
    for y=2:n-1
        R(x,y)=I(x-1,y-1)+I(x,y-1)+I(x-1,y)-I(x+1,y+1)-I(x,y+1)-I(x+1,y);
    end
end
R=R+128;
R=uint8(R);
figure;
imshow(R);

(2)

image=imread('D:\\photo\\kongjun.jpg');
image=rgb2gray(image);
kernel =[-1,-1,0;-1,0,1;0,1,1];
result0=conv2(image,kernel, 'same');
result=uint8(result0+128);
figure
imshow(result);

(3)

image=imread('D:\\photo\\kongjun.jpg');
image=rgb2gray(image);
[m,n]=size(image);
kernel=[-1,-1,0;-1,0,1;0,1,1];
I=fft2(image,m+2,n+2);
K=fft2(kernel,m+2,n+2);
IK=I.*K;
result0=ifft2(IK);
result0=result0(2:m+1,2:n+1);
result=uint8(result0+128);
figure;
imshow(result);

3.效果图
在这里插入图片描述
在这里插入图片描述
(1)代码
在这里插入图片描述
(2)代码
在这里插入图片描述
(3)代码

参考链接:
1.https://zhuanlan.zhihu.com/p/51183305

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值