文档库 最新最全的文档下载
当前位置:文档库 › 浮雕与油画效果实现(matlab)

浮雕与油画效果实现(matlab)

浮雕与油画效果实现(matlab)
浮雕与油画效果实现(matlab)

利用滤波实现油画的浮雕和油画效果

一.浮雕效果

1.原理:

将图片的颜色或灰度变换较大的像素部分突出出来,而将灰度或颜色变换不大的部分淡化,使图像出现纵深感,从而达到浮雕效果。利用matlab的线性滤波函数filter2(),以及水平,垂直,45度,135度方向的算子进行滤波,最后叠加起来可以得到较好的浮雕效果。

2.matlab代码:(main1.m)

[filename, pathname] = uigetfile({'*.bmp;*.jpg;*.png;*.jpeg', 'Image Files (*.bmp, *.jpg, *.png,*.jpeg)'; ...

'*.*', 'All Files (*.*)'},'Pick an image');

if isequal(filename,0) || isequal(pathname,0),

return;

end %获取图片路径

path=fullfile([pathname,filename]);

RGB=imread(path);%读取一张图片

R=RGB(:,:,1);%红色分量表示的图像

G=RGB(:,:,2);%绿色分量表示的图像

B=RGB(:,:,3);%蓝色分量表示的图像

h1=[-1,-4,-1;0,0,0;1,4,1];%水平方向算子

IR1=filter2(h1,R);%对红色分量进行浮雕效果处理

IG1=filter2(h1,G);%对绿色分量进行浮雕效果处理

IB1=filter2(h1,B);%对蓝色分量进行浮雕效果处理

h2=[1,0,-1;4,0,-1;1,0,-1];%垂直方向算子

IR2=filter2(h2,R);

IG2=filter2(h2,G);

IB2=filter2(h2,B);

h3=[0,-1,-4;1,0,-1;1,4,0];%45度方向算子

IR3=filter2(h3,R);

IG3=filter2(h3,G);

IB3=filter2(h3,B);

h4=[4,1,0;1,0,-1;0,-1,-4];%135度方向算子

IR4=filter2(h4,R);

IG4=filter2(h4,G);

IB4=filter2(h4,B);

IR=IR1+IR2+IR3+IR4;

IG=IG1+IG2+IG3+IG4;

IB=IB1+IB2+IB3+IB4;

IMG=IR+IG+IB;%对rgb 三个分量单独处理后的图像进行叠加

subplot(1,2,1),imshow(RGB),title('原图');

subplot(1,2,2),imshow(IMG,[]),title('浮雕效果图');

3.实验结果:

4.问题与思考:

通过以上算法只能实现水平,垂直,45度和135度这四个方向上的浮雕效果,如何实现其它任意方向的浮雕效果?根据任意方向的导数算法,

我们可以使用多方向的梯度算法和拉普拉斯变换算法输出任意原

图浮雕效果图

方向最佳的边缘响应。其实,梯度算法和拉普拉斯算法输出的是

0~180度范围垂直方向对的最大响应,即:

B=max(|dn/dx |+|dn/dy|)

B=max(|d2n/dx2|+|d2n/dy2|)

二.油画效果

1.基本原理:检测图像每个像素的邻域,计算每个邻域像素的强度(亮度),取重复出现最多的值相对应的像素作为输出,分别取这些像素的r,g,b分量的平均值作为当前像素输出的r,g,b值,最终得到的图像会损失一些信息,得到类似油画的效果。

2.具体算法分析:

对于一副图像,例如:

(1)确定当前像素位置为(x,y),取邻域半径为2,则邻域范围

是从[x-2,y-2]到[x+2,y+2],如图:图中标出每个像素的r,g,b值。

(2)计算每个邻域像素的强度值,计算公式为:

强度值=[(r值+g值+b值)/3*强度范围]/255,其中强度范围是可调整的参数(该例子取值为20)。结果如图:

其中,强度值8出现次数最多,为7次,对应的像素位置分别为:[x-1,y-2],[x,y-1],[x,y+1],[x+1,y-1],[x+1,y],[x+1,y+2],[x+2,y+2]

(3)取这7个像素r分量的平均值作为输出像素r分量的值:R=(124+120+158+129+108+170+140)/7=135,

同理,可求出输出像素g分量和b分量的值,分别为128,65. (4)则当前像素(x,y)对应的输出值为:RGB(135,128,65)。

(5)改变当前像素位置,重复以上步骤等到每一个像素的输出值,最终输出的图像就具有油画效果。

3.算法参数分析:

邻域半径:确定邻域范围,取3到7可以得到较好的油画效果

强度范围:用来计算邻域像素的强度,从而达到筛选输出的目的

4.matlab代码:

oilpaint.m:

function [outputimage]=oilpaint(image,radius,intensity_level)

%image 输入的图片数组

%radius 滤波邻域的半径

%intensity_level 强度范围,由于计算像素强度

%outputimage 输出的图片数组

image=uint16(image);

%将输入的图片数组转为uint16型,避免计算时超出范围

image_size=size(image);

height=image_size(1); %图片的高度

width=image_size(2); %图片的宽度

outputimage=zeros(height,width,3);

%用一个同样大小的数组记录输出图像的数据,初始化为零

for x=1:height

for y=1:width

intensity_counter=zeros(intensity_level,1);

%强度计数器,记录邻域每个强度出现次数

sum_r=uint16(zeros(intensity_level,1));

%r分量累加器,记录每个强度r分量的和

sum_g=uint16(zeros(intensity_level,1)); %g分量累加器

sum_b=uint16(zeros(intensity_level,1)); %b分量累加器

for i=(x-radius):(x+radius)

for j=(y-radius):(y+radius) %邻域的遍历

if i>0&&i<=height&&j>0&&j<=width

intensity=(image(i,j,1)+image(i,j,2)+image(i,j,3))/3*intensity_level/255;

%计算每一像素的强度

if intensity==0

intensity=1;

end %强度不能为零,避免数组下标出现零

intensity_counter(intensity)=intensity_counter(intensity)+1;

%统计强度出现的次数

sum_r(intensity)=sum_r(intensity)+image(i,j,1);

%同一强度的r分量求和

sum_g(intensity)=sum_g(intensity)+image(i,j,2);

sum_b(intensity)=sum_b(intensity)+image(i,j,3);

end

end

end

intensity_counter_max=max(intensity_counter);

%找出同一强度出现最多的次数

for i=1:intensity_level

if intensity_counter(i)==intensity_counter_max

index=i;

end

end

%若出现最多的次数有重复,则取强度大的像素作为输出

outputimage(x,y,1)=sum_r(index)/intensity_counter(index);

%出现最多次的强度值对应像素的r分量取平均值,作为当前像素输出的r分量

outputimage(x,y,2)=sum_g(index)/intensity_counter(index);

%输出的g分量

outputimage(x,y,3)=sum_b(index)/intensity_counter(index);

%输出的b分量

end

end

outputimage=uint8(outputimage);%将uint16图像转化为matlab 默认的uint8型

main.m:

[filename, pathname] = uigetfile({'*.bmp;*.jpg;*.png;*.jpeg', 'Image Files (*.bmp, *.jpg, *.png,*.jpeg)'; ... '*.*', 'All Files (*.*)'},'Pick an image');

if isequal(filename,0) || isequal(pathname,0),

return;

end %获取图片路径

path=fullfile([pathname,filename]);

image=imread(path);%读取一张图片

outputimage=oilpaint(image,5,100);%通过滤波进行油画效果处理

subplot(1,2,1)

imshow(image);

title('原图');

subplot(1,2,2);

imshow(outputimage);

title('油画效果图');

5.实验结果:

图油画效果图

6.实现过程中的问题与思考:

(1)边界问题:这是一个非线性滤波,关键是强度重复像素的计算,不必进行边界的扩展。如果边界上补零,那么输出图片会有黑边;如果采用复制外边界来扩展,那么输出边界就是原图的边界;如果边界采用对称扩展或周期扩展,输出的油画效果和不采用边界扩展几乎没有是一样的。

(2)数据类型问题 :matlab 读取图片时默认为uint8类型的数组,但是在计算像素强度的过程中出现了远大于255的值,所以必须将uint8数组转换为uint16的数组进行计算分析,最后的结果再转换为uint8性的数组输出。

图油画效果图

相关文档