该项目为数字图像处理课程的期末大项目,主要内容是用matlab软件实现一些美图秀秀相关功能,比如对图像进行水平垂直翻转,旋转,裁剪,抠图等基础功能;对图像添加浮雕,艺术噪声,灰度胶片,动感模糊,素描,油画,羽化等滤镜的功能;以及祛痘祛痣,白牙,大眼,磨皮,美白,增强等美化功能。在实现以上功能的基础上,还使用了GUI图像用户界面,增强了用户交互式体验感。
GUI界面的一些使用方法可看之前我发的两篇博客:
Matlab GUI界面使用方法(一):打开GUI&GUI常用控件(最基础)
Matlab GUI界面使用方法(二):GUI控件功能实现
这是该简易版美图秀秀的GUI界面:
以下是一些功能的原理步骤以及代码和部分注释:
1.导入图像和从摄像头获取图像
原理步骤:
从摄像头获取:通过imaqhwinfo函数获取摄像头信息,再在videoinput函数中创建一个视频对象,用preview函数创建预览窗口,即可完成使用matlab调用摄像头获取图像了。
从文件夹中选择图片:用uigetfile函数打开文件对话框,选择指定格式的图片,这时会返回图像的名称和路径信息,如果选择成功就将编辑文本的string设置为文件的名称和路径,并将名称和路径存储在handles中,最后在确认按钮中从handles获取到名称路径信息,并用imshow函数读取即可。
从摄像头获取:
% --- Executes on button press in pushbuttoncam.
function pushbuttoncam_Callback(hObject, eventdata, handles)
% hObject handle to pushbuttoncam (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
vid=videoinput('winvideo',1);%创建视频输入对象
h=preview(vid);%显示视频输入对象
while ishandle(h)
img=getsnapshot(vid);
imshow(img);
end从文件夹选取:
% 主界面选择图片按钮
% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
[filename, filepath]=uigetfile({'*.png;*.jpg'},'选择图片文件');
% 打开文件对话框,返回相应格式文件的名称和路径
if isequal(filename,0)||isequal(filepath,0)
% 若未选择到图片
errouglg('没有选中文件,请重新选择');
% 弹窗提示
return;
else
str=[filepath filename];
set(handles.edit1,'string',str)
% 若选择成功,就将edit1的string文本设置为选择文件的路径和名称
end
% 复制文本路径
road=get(handles.edit1,'string');
% 获取文本路径
handles.road=road;
guidata(hObject,handles);
% 存储路径
% 主界面图像确认按钮
% --- Executes on button press in pushbuttonsure.
function pushbuttonsure_Callback(hObject, eventdata, handles)
% hObject handle to pushbuttonsure (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
axes(handles.axes2);%清除第二个坐标轴上的图像
cla reset;
road=handles.road;%获取存储的路径
axes(handles.axes1);%在第一个坐标轴上显示原图像
imshow(road);
2.图像旋转
原理步骤:
用户点击图像旋转按钮就可使图像逆时针旋转90度,再点击一次就在已旋转的基础上再旋转90度。实现原理是先用getframe函数获取当前坐标轴的图像,方便进行多次旋转操作,然后将图像转化为double型调用matlab自带的imrotate函数进行图像旋转,并显示即可。而旋转图像本质上就是将图像构成的矩阵乘一个旋转矩阵从而得到一个旋转后的新矩阵。
文章来源地址https://www.toymoban.com/news/detail-487917.html
功能键-图像旋转
% --- Executes on button press in pushbuttontrun.
function pushbuttontrun_Callback(hObject, eventdata, handles)
% hObject handle to pushbuttontrun (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
img=getframe;%获取当前坐标轴的图像
axes(handles.axes2);%第二个坐标轴
imshow(img.cdata);%显示图像
img=img.cdata;%原图像
imgdou=im2double(img);%将原图像转化为double类型
img2=imrotate(imgdou,90);%用imrotate函数将图像选择90度
axes(handles.axes2);%第二个坐标轴
imshow(img2);%显示旋转后的图像
3.图像水平竖直旋转
原理步骤:
点击水平或竖直翻转按钮可使图片左右或上下翻转,实现原理是利用fliplr函数会将矩阵围绕垂直轴左右方向翻转各其列,flipud函数围绕矩阵水平轴上下方向翻转各行,fliper函数和flipud函数处理多维数组时均只处理前两个维度构成的平面,所以可以对图像每个通道都进行一次翻转。
功能键-水平翻转
% --- Executes on button press in pushbuttonfanzhuan.
function pushbuttonfanzhuan_Callback(hObject, eventdata, handles)
% hObject handle to pushbuttonfanzhuan (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
img=getframe;%获取当前坐标轴的图像
axes(handles.axes2);%第二个坐标轴
imshow(img.cdata);%显示图像
img=img.cdata;%原图像
for k=1:3
img2(:,:,k)=fliplr(img(:,:,k));%将每一个通道都进行翻转
end
axes(handles.axes2);
imshow(img2);%显示水平翻转后的图像
功能键-竖直翻转
% --- Executes on button press in pushbuttonshufanhzuan.
function pushbuttonshufanhzuan_Callback(hObject, eventdata, handles)
% hObject handle to pushbuttonshufanhzuan (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA).
img=getframe;%获取当前坐标轴的图像
axes(handles.axes2);%第二个坐标轴
imshow(img.cdata);%显示图像
img=img.cdata;%原图像
for k=1:3
img2(:,:,k)=flipud(img(:,:,k));%将每一个通道都进行翻转
end
axes(handles.axes2);
4.裁剪
原理步骤:
用户根据交互式裁剪区域选择裁剪图像,右键crop image就可在新窗口显示裁剪的图像。基本原理是:在选取裁剪区域的时候,使用的是自带函数imcrop函数,它可以返回用户绘制的选择区域的大小以及各个点的像素值J和矩形的位置向量rect[xmin ymin width height],其中(xmin,ymin)表示矩形区域左上角坐标,width,height表示矩形区域的宽和高,这里要实现图片裁剪功能,只需返回J并显示即可。但此函数的rect在实现后面一些功能的时候有用到。
% 功能键-图像裁剪
% --- Executes on button press in pushbuttoncut.
function pushbuttoncut_Callback(hObject, eventdata, handles)
% hObject handle to pushbuttoncut (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
road=handles.road;%读取原图像
img=imread(road);
[J,rect]=imcrop(img);%打开裁剪工具,rect为绘制的矩形四像素位置向量
axes(handles.axes2);%显示选择的裁剪区域
imshow(J);
5.添加文字
原理步骤:
用户在添加文字后面的输入框中输入需要添加的文字,并点击添加文字按钮,再在图像中选取添加文字的位置,crop image后即可实现添加文字效果。实现原理是我们可以通过text函数像图片添加文字,需要的参数有显示文字的位置坐标以及显示的文字,显示的文字可以通过用户在edittext输入框中输入,然后get输入的文字即可,但是由于用户想要添加文字的位置不唯一,所以不能我们指定位置,需要用户指定位置,这时,上个功能键裁剪imcrop函数返回的rect就有用了,用户可以自主选择需要添加文字的地方,imcrop函数会返回rect,利用rect返回的前两个参数作为text函数显示文字位置的参数,这样就可以实现该功能了。
功能键-添加文字
% --- Executes on button press in pushbuttontext.
function pushbuttontext_Callback(hObject, eventdata, handles)
% hObject handle to pushbuttontext (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
img=getframe;%获取当前坐标轴的图像
img=img.cdata;%原图像
axes(handles.axes2);%先将原图像显示在第二个坐标轴上
imshow(img);
str=get(handles.edit2,'string');%先获取输入的文字
[J,rect]=imcrop(img);%选取文字框
posx=round(rect(1));%返回位置
posy=round(rect(2));
text(posx,posy,str);%添加文本
6.增强
图像增强就是图像的亮度和饱和度对比要增强,hsv颜色空间中颜色参数H代表色调,用角度度量,不同角度代表不同颜色;S代表饱和度,表示颜色接近光谱色的程度,值越大,饱和度越高,颜色就越深艳;V代表明度,就是颜色的明暗程度。因此就可以将原图像的rgb颜色空间转化为hsv颜色空间,通过调整图像的饱和度通道和明度通道就可实现图像增强效果。
功能键-增强
% --- Executes on button press in pushbuttonmeibai.
function pushbuttonmeibai_Callback(hObject, eventdata, handles)
% hObject handle to pushbuttonmeibai (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
road=handles.road;%读取原图像
RGB=imread(road);
HSV=rgb2hsv(RGB);%将原图像rgb转化成hsv通道
H=HSV(:,:,1);
S=HSV(:,:,2);
V=HSV(:,:,3);
V=imadjust(V);%对明度通道进行增强
S=imadjust(S);%对饱和度通道进行增强
HSV(:,:,1)=H;
HSV(:,:,2)=S;
HSV(:,:,3)=V;
img2=hsv2rgb(HSV);%再将hsv转回rgb
axes(handles.axes2);%显示图像
imshow(img2);
7.磨皮
原理步骤:
磨皮就是为了去除皮肤上的瑕疵,如不均匀的色差等,通过磨皮可以使皮肤看上去光滑,平整。所以可以用滤波器对图像进行处理,由于高斯滤波没有考虑到图像边缘,所以会将图像中的边缘也一并模糊,效果不太好,所以可以采用双边滤波,它能够同时达到保边和去噪的效果。双边滤波的原理和高斯滤波相似,它将图像中每个像素的灰度值替换为相邻像素灰度值的加权平均值,权重取决于灰度差异和像素点之间的欧式距离。根据这个原理,就可在matlab中用双边滤波器处理图像了,即先构造高斯滤波器,再遍历需卷积的区域,得到灰度差值矩阵,并用高斯函数处理为权重矩阵,差值越大,权重越小,接着用权重矩阵与高斯滤波器相乘,就可得到双边滤波器,并将权值和化为一,最后用双边滤波器进行卷积求和即可。为了实现该功能,还需在功能键中用双边滤波器依次处理三个色彩通道,至此,磨皮效果就能实现了。
功能键-磨皮
% --- Executes on button press in pushbuttonmopi.
function pushbuttonmopi_Callback(hObject, eventdata, handles)
% hObject handle to pushbuttonmopi (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
road=handles.road;%读取原图像
img0=imread(road);
tempsize = 5;%高斯滤波器大小
sigma1 = 5;%高斯滤波器标准差
sigma2 = 0.08;%灰度敏感性
img = double(padarray(img0,[tempsize,tempsize],0))/255;%模板补零,避免出现黑边
imgr = img(:,:,1);%提取出三个通道
imgg = img(:,:,2);
imgb = img(:,:,3);
[m,n] = size(imgr);%获取大小
img(:,:,1) = B_filter(imgr,tempsize,sigma1,sigma2);%滤波器依次处理三个通道
img(:,:,2) = B_filter(imgg,tempsize,sigma1,sigma2);
img(:,:,3) = B_filter(imgb,tempsize,sigma1,sigma2);
g=img(tempsize+1:m-tempsize,tempsize+1:n-tempsize,:);%只显示彩色区域,去除黑边
axes(handles.axes2);%显示效果图
imshow(g);
双边滤波器函数
function out = B_filter(Img,tempsize,sigma0,sigma1)
%模板定义
gauss = fspecial('gauss',2*tempsize+1,sigma0);%构造高斯滤波器
[m,n] = size(Img);%获取图像大小
for i = 1+ tempsize : m - tempsize%遍历需要卷积区域
for j = 1+ tempsize : n - tempsize
%提取处理区域得到灰度差值矩阵
temp = abs(Img(i - tempsize:i + tempsize,j - tempsize:j + tempsize) - Img(i,j));%调整因子
temp = exp(-temp.^2/(2*sigma1^2));%像素值权重
%得到双边滤波器并将权值和化为一
filter = gauss.*temp;
filter = filter/sum(filter(:));
%用双边滤波器进行卷积运算
Img(i,j) = sum(sum((Img(i - tempsize:i + tempsize,j - tempsize:j + tempsize).*filter)));
end
end
out = Img;
end
8.美白
原理步骤:
将彩色RGB图像转化为L*a*b*颜色空间,其中L表示图像亮度层,a表示红绿层,b表示黄蓝层,为了实现美白效果,只需对亮度层进行操作,由于亮度层的亮度值范围是0-100,先将亮度值归一化再用imadjust函数增强图像亮度值,乘100之后返回RGB颜色空间,只影响了像素的强度,会保留图像原始颜色,从而达到美白的效果。
功能键-美白
% --- Executes on button press in pushbuttonzengqiang.
function pushbuttonzengqiang_Callback(hObject, eventdata, handles)
% hObject handle to pushbuttonzengqiang (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
road=handles.road;%读取原图像
img=imread(road);
img2=rgb2lab(img);%将RGB转换为L*a*b* L表示亮暗,A表示红绿,B表示黄蓝
max_lum=100;%亮度值的范围是0-100
L=img2(:,:,1)/max_lum;%将亮度值归一化
img2(:,:,1)=imadjust(L)*max_lum;%增强亮度通道的值
img3=lab2rgb(img2);%将图像转回RGB颜色空间
axes(handles.axes2);%显示效果图像
imshow(img3);
9.祛痘祛痣
原理步骤:
用户自主选择需要祛痘祛痣的地方,然后右键crate mask就可显示处理后的效果,实现过程是通过roipoly函数选取痘痘范围作为蒙版,然后将蒙版和原图像的三个通道进行相乘,再将这三个通道连接,得到选取区域的图像。遍历某一个通道,找到第一个像素不为0的点,获取该像素值作为采样得到的像素值,在该像素值±5个像素值区间内获取随机数产生填充图像并分别对三个通道进行处理,再将三个通道连接起来得到处理后的选取区域图像,最后只需将两部分图像想加即可。
功能键-祛痘祛痣
% --- Executes on button press in pushbuttonqudou.
function pushbuttonqudou_Callback(hObject, eventdata, handles)
% hObject handle to pushbuttonqudou (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
img=getframe;%获取当前坐标轴的图像
img=img.cdata;%原图像
img2=qudou(img);%调用祛痘函数
axes(handles.axes2);%显示效果图像
imshow(img2);
祛痘祛痣函数:
function [ f ] = qudou(img)
%UNTITLED Summary of this function goes here
% Detailed explanation goes here
img2= img;
[ M,N,~ ] = size(img);%得到原图像的大小
%进行交互选择处理区域
mask = roipoly( img2 );%roipoly函数选取指定多边形
x1 = immultiply( mask,img2( :,:,1 ) );%将选取的范围和原图通道相乘
x2 = immultiply( mask,img2( :,:,2 ) );
x3 = immultiply( mask,img2( :,:,3 ) );
x = cat( 3,x1,x2,x3 );%将三个通道连接在一起,得到选取的部分图像
f1 = zeros( M,N );%f1,f2,f3存储三个通道的运算结果
f2 = zeros( M,N );
f3 = zeros( M,N );
%找到第一个像素值不为0的点,得到该点像素值,作为采样后填充的像素
for i = 1:M
for j = 1:N
if( x1( i,j ) ~= 0 )
r = x( i,j,: );%得到采样的像素值
end
end
end
%随机产生填充图像
y = zeros(3,3,3);
y( :,:,1 ) = randi([r(1)-5,r(1)+5],[3,3]);%randi函数-随机整数--在采样到的±5的区间中找随机数
y( :,:,2 ) = randi([r(2)-5,r(2)+5],[3,3]);%并返回3*3大小的矩阵
y( :,:,3 ) = randi([r(3)-5,r(3)+5],[3 3]);
%类型转换
y = double(y);
%对于三个通道分别进行处理,用采样得到的像素点取代原来的像素点
for i = 2:3:M-1
for j = 2:3:N-1
f1( i-1:i+1,j-1:j+1 ) = mask( i-1:i+1,j-1:j+1 ).* y( :,:,1 );
f2( i-1:i+1,j-1:j+1 ) = mask( i-1:i+1,j-1:j+1 ).* y( :,:,2 );
f3( i-1:i+1,j-1:j+1 ) = mask( i-1:i+1,j-1:j+1 ).* y( :,:,3 );
end
end
f = cat( 3,f1,f2,f3 );%将三个通道连接在一起,得到选取区域处理后的图像
f = uint8( f );%类型转换
%得到处理后图像
a = img2 - x;%原图中除了选取区域的图像
f = f + a;%叠加
end
10.抠图
原理步骤:
用户根据需要点击一系列点,这些点连接起来形成的图像就是需要抠出来的图。实现过程是先逐个接受用户点击图像中某个点的位置,用line函数在图像中显示连接起来的线,再生成一个蒙版,也就是和原图像同样大小的全零矩阵,再写一个具有连线功能的函数,该函数通过取整确定线段覆盖的像素位置并将其赋值为1,用这个函数将这些点逐个连接起来,并让收尾相连,此时该矩阵就一条封闭的曲线了,接着填充这个闭合的曲线,蒙版就变成了只有选取的区域是白色,其余是黑色,最后将该蒙版与原图像相乘,即可得到选取的图像区域,也就实现了抠图的功能。
受祛痘功能的启发,该算法可以使用matlab自带函数roipoly函数进行处理,还会简单方便很多,用roipoly函数可直接返回蒙版,只需将每个通道和原图像相乘再连接起来就可实现抠图功能了。
功能键-抠图
% --- Executes on button press in pushbuttonkoutu.
function pushbuttonkoutu_Callback(hObject, eventdata, handles)
% hObject handle to pushbuttonkoutu (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
road=handles.road;%读取原图像
img=imread(road);
im=double(img);
[out,mask,p]=manseg(im);%调用抠图函数
out=uint8(out);%输出结果
axes(handles.axes2);%显示效果图
imshow(out);
抠图函数:
function [ out,mask,p ] = manseg( im )
%UNTITLED Summary of this function goes here
% Detailed explanation goes here
% 准备工作
[M,N,D]=size(im);
k=0;
p=[];
% 手动选点
hold on
while 1
[x,y,flag]=ginput(1);%返回点击时的坐标
if flag==1
k=k+1;%计算共点击了几次
plot(x,y,'b.','MarkerSize',20)%绘制选中的这些点
p(k,1:2)=round([y,x]);%四舍五入去整--取反是因为图像像素坐标索引与xy坐标系相反
if k>1
line([p(k-1,2),p(k,2)],[p(k-1,1),p(k,1)],'LineWidth',2) %将点和上一个点用2榜直线连起来
end
else
line([p(1,2),p(k,2)],[p(1,1),p(k,1)],'LineWidth',2) %将点和上一个点用2榜直线连起来
break
end
end
hold off
% 生成蒙板
mask=zeros(M,N);%生成一个和原图像同样大小的蒙版
for i=1:k%遍历每个选取的点
if i<k
mask=pixelcontect(mask,p(i,:),p(i+1,:));%依次连接所有点
else
mask=pixelcontect(mask,p(i,:),p(1,:));%末尾与起点相连
end
end
mask=imfill(mask,'hole');
if D>1
mask=cat(3,mask,mask,mask);
end
% 提取目标
out=mask.*im;% mask类型是double,所以输入的im也改成double,否则报错类型不匹配。
end
具有连线功能的函数:
% 其中 p0,p1为两个点的坐标,a为蒙板
function a=pixelcontect(a,p0,p1)
%UNTITLED Summary of this function goes here
% Detailed explanation goes here
a(p0(1),p0(2))=1;%输入点像素值设为0
a(p1(1),p1(2))=1;%输入点像素值设为0
dis=p1-p0;%dy,dx
gap=((-1).^double(dis<0));%取正
absdis=abs(dis);%取正
more=max(absdis);%变化大的
less=min(absdis);%变化小的
if absdis(1)>=absdis(2)%如果y方向变化比x方向变化大
dir1=[gap(1),0];%向y方向走
dir2=[0,gap(2)];
else
dir2=[gap(1),0];%向x方向走
dir1=[0,gap(2)];
end
lmp=less/more;%斜率
i=0;j=0;
while i<more%将线段覆盖的点的像素值设为1
p0=p0+dir1;
a(p0(1),p0(2))=1;
i=i+1;
if i<more
p1=p1-dir1;
a(p1(1),p1(2))=1;
i=i+1;
end
if j/i<lmp%若比斜率小
if j<less
p0=p0+dir2;
a(p0(1),p0(2))=1;
j=j+1;
end
if j<less
p1=p1-dir2;
a(p1(1),p1(2))=1;
j=j+1;
end
end
end
11.白牙
原理步骤:
用户通过选取牙齿部分右键create mask就可在效果图中看到牙齿的效果了,实现原理受抠图功能的影响,既然白牙功能的目的是只将牙齿部分美白,其他部分不变,而抠图可以选取感兴趣的区域图像f,并只显示该区域,其余部分像素值均为0,那么就可以用原图像减去该区域得到img2,即除了该区域的图像。随后遍历f当像素值不为0时,即只作用于选取的区域,用imadd函数增加其亮度,最后将处理后的f和img2相加,就可以得到只增亮牙齿的图像了,从而实现了该功能。
功能键-白牙
% --- Executes on button press in pushbuttonwhite.
function pushbuttonwhite_Callback(hObject, eventdata, handles)
% hObject handle to pushbuttonwhite (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
road=handles.road;%读取图像
img=imread(road);
mask = roipoly(img);%蒙版选择
[ M,N,~ ] = size(mask);%获取蒙版大小
x1 = immultiply( mask,img( :,:,1 ) );%将选取的范围和原图通道叠加
x2 = immultiply( mask,img( :,:,2 ) );
x3 = immultiply( mask,img( :,:,3 ) );
f = cat( 3,x1,x2,x3 );%将三个通道连接在一起,得到选取的图像
img2=img-f;%原图减去选取的区域
for i=1:M%遍历选取的图像,若像素值不为0,就增亮
for j=1:N
if(f(i,j)~=0)
f(i,j,:)=imadd(f(i,j,:),30);
end
end
end
f=imadd(f,img2);%将选取区域增亮后和除该区域的图像相加
axes(handles.axes2);%显示效果图
imshow(f);
12.大眼
原理步骤:
大眼功能就是为了放大眼部,让眼睛看起来比之前更大,为了增加交互式体验感,也同时受到截图功能中imcrop函数的影响,所以用户可以通过选择眼部区域,特别是眼球区域,右键crop image进行放大眼睛。而基本实现过程是在用户进行选区的时候会返回rect即选区的左上角坐标和选取长宽,通过这四个参数,我们就可以得到该选区的中点位置,将原图像和选取中点位置以及大眼半径参数传入大眼函数,大眼函数就可以得到需要放大区域的上下左右坐标,遍历这个区域,如果该点像素到中点的距离小于传入的半径,那么就等用最近邻插值算法比例放大,经过这一系列操作就可实现手动眼部放大了。
功能键-大眼
% --- Executes on button press in pushbuttonbigeyes.
function pushbuttonbigeyes_Callback(hObject, eventdata, handles)
% hObject handle to pushbuttonbigeyes (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
img=getframe;%获取当前坐标轴的图像
img=img.cdata;
[J,rect]=imcrop(img);%选取框
posx=round(rect(3)/2+rect(2));%选取框中点
posy=round(rect(1)+rect(4)/2);
img2=bigger(img,posx,posy,25);%调用大眼函数
axes(handles.axes2);%显示放大眼睛后的图像
imshow(img2);
大眼函数:
function [ J ] = bigger(I,pointx,pointy,r)
%UNTITLED2 Summary of this function goes here
% Detailed explanation goes here
%I为原图像,pointx和pointy为放大中心点坐标,r为放大半径
im=I;
left=round(pointy-r);%分别得到放大区域的上下左右坐标
right=round(pointy+r);
top=round(pointx-r);
bottom=round(pointx+r);
space = r * r;%放大区域面积
strength=25; %放大强度
fr=im(:,:,1);%原图像为彩色图像,要分成RGB三个分量进行处理
fg=im(:,:,2);
fb=im(:,:,3);
im2fr=fr;
im2fg=fg;
im2fb=fb;
%插值算法
for x=top:bottom%遍历需要放大的区域
offsetx=x-pointx;%当前点距中点的在x上的距离
for y=left:right
offsety=y-pointy;
xy=offsetx*offsetx+offsety*offsety;%当前点距中点的距离
if xy<=space%若当前点在需放大的圆形区域内
%等比例放大
scale=1-xy/space;
scale=1-strength/100*scale;
%posy和posx为放大后坐标值
%采用最近邻插值算法
posy=round(offsety*scale+pointy);
posx=round(offsetx*scale+pointx);
im2fr(x,y)=fr(posx,posy);
im2fg(x,y)=fg(posx,posy);
im2fb(x,y)=fb(posx,posy);
end
end
end
J=cat(3,im2fr,im2fg,im2fb);%将RGB三个分量整合,得到彩色图像
end
13.特征点检测
原理步骤:
特征点检测主要检测的是人脸及眼睛,鼻子,嘴巴,这里使用的是matlab自带的分类器进行直接检测,不需要额外的训练。使用时输入参数有原图像,分类模型,存储对象等,输出参数包括检测结果和一个输出矩阵。
功能键-特征点检测
% --- Executes on selection change in popupmenu3.
function popupmenu3_Callback(hObject, eventdata, handles)
% hObject handle to popupmenu3 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: contents = cellstr(get(hObject,'String')) returns popupmenu3 contents as cell array
% contents{get(hObject,'Value')} returns selected item from popupmenu3
num=get(handles.popupmenu3,'value');%获取下拉列表选择的序列
switch num
case 1
case 2
%定位人脸
road=handles.road;%读取原图像
I=imread(road);
FDetect = vision.CascadeObjectDetector; %创建人脸检测器对象
face_dtect = step(FDetect,I); %检测人脸
axes(handles.axes2); %显示图像
imshow(I);
hold on
for i = 1:size(face_dtect,1) %遍历检测到的人脸个数,画矩形框
rectangle('Position',face_dtect(i,:),'LineWidth',5,'LineStyle','-','EdgeColor','m');
end
case 3
%定位眼睛
road=handles.road;%读取原图像
input_image=imread(road);
detector=vision.CascadeObjectDetector('LeftEyeCART');%创建检测眼部检测器对象
eyes=step(detector,input_image);%检测眼睛
axes(handles.axes2);%显示图像
imshow(input_image);
size_eyes = size(eyes);%眼睛的狂
hold on;
for i =1:size_eyes(1); %遍历检测到的眼睛个数,画矩形框
rectangle('Position',eyes(i,:),'LineWidth',5,'LineStyle','-','EdgeColor','m');
end
case 4
road=handles.road;%读取原图像
I=imread(road);
mouth_detect = vision.CascadeObjectDetector('Mouth','MergeThreshold',16); %创建检测嘴巴检测器对象
face_dtect=step(mouth_detect,I); %检测嘴巴
axes(handles.axes2);%显示图像
imshow(I);
hold on
for i = 1:size(face_dtect,1) %遍历检测到的嘴巴个数,画矩形框
rectangle('Position',face_dtect(i,:),'LineWidth',4,'LineStyle','-','EdgeColor','r');
end
case 5
road=handles.road;%读取原图像
I=imread(road);
NoseDetect = vision.CascadeObjectDetector('Nose','MergeThreshold',16); %创建检测鼻子检测器对象
face_dtect=step(NoseDetect,I); %检测鼻子
axes(handles.axes2);%显示图像
imshow(I);
hold on
for i = 1:size(face_dtect,1) %遍历检测到的鼻子个数,画矩形框
rectangle('Position',face_dtect(i,:),'LineWidth',4,'LineStyle','-','EdgeColor','m');
end
end
14.贴纸
原理步骤:
这儿的贴纸功能没有采用人脸特征点定位,大家可以自行结合13和14功能点进行特征点定位贴图。
在图像上添加贴纸的原理就是将两张图片叠加起来,但是很明显原图像和贴纸大小不同,而原图像大小也不确定。所以我们就可以通过先构造一个和原图像同样大小的全零矩阵,再将贴纸放进这个矩阵作为和原图像同样大小的新图像与原图像叠加,就实现了贴纸的功能。
功能键-添加贴纸
% --- Executes on selection change in popupmenu2.
function popupmenu2_Callback(hObject, eventdata, handles)
% hObject handle to popupmenu2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: contents = cellstr(get(hObject,'String')) returns popupmenu2 contents as cell array
% contents{get(hObject,'Value')} returns selected item from popupmenu2
tiezhi=get(handles.popupmenu2,'value');%获取下拉列表选择的序列
road=handles.road;%读取原图像
im1=imread(road);
switch tiezhi%添加不同贴纸
case 1
case 2
im2 = imread('fagu1.png');%小图
case 3
im2 = imread('srat.png');%小图
case 4
im2 = imread('moon.png');%小图
end
% 显示大尺寸的彩色风景图和小尺寸彩色照片的原始图
axes(handles.axes2);
imshow(im1);
imshow(im2);
% 小尺寸彩色照片在风景图当中的居中处理
[m1,n1,l1] = size(im1);
[m2,n2,l2] = size(im2);
t = zeros(m1,n1,l1);
t = uint8(t);
t((m1/2-m2/2+1):(m1/2+m2/2),(n1/2-n2/2+1):(n1/2+n2/2),:) = im2 ;%做居中处理
C = imadd(0.5*t,im1);%乘以0.5对中间小照片做透明处理
axes(handles.axes2);%显示原图像
imshow(C);
15.油画
原理步骤:
油画就是用快干性的植物油调和出的颜料画出来的画。而油画滤镜就是将图片处理成油画出来的效果,算法思想是用当前点四周一定范围内的任意一点的颜色来代替该点的颜色,所以就需要确定四周范围的大小并用rand函数随机找到某一点。滑动条可以控制随机像素点的范围,值越大,油画效果就越模糊,反之,就越清晰。
滤镜-油画
% --- Executes on button press in pushbuttonyouhua.
function pushbuttonyouhua_Callback(hObject, eventdata, handles)
% hObject handle to pushbuttonyouhua (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
road=handles.road;%读取原图像
img=imread(road);
[height,width,k]=size(img);%获取原图像大小
N=10;
out=zeros(height,width,3);
for i=1:height%遍历每个像素点
for j=1:width
temp=uint8(rand()*(N^2-1));%生成随机数
m=temp/N;%取商
n=mod(temp,N);%取余
h=mod(double(i-1)+double(m),double(height));%找到随机对应的原图像像素
w=mod(double(j-1)+double(n),double(width));
if w==0;
w=width;%若找到了上方和左方像素点就用下方和右方的代替
end
if h==0
h=height;
end
out(i,j,:)=img(h,w,:);%将找到的原图像像素点的值赋给输出图像
end
end
axes(handles.axes2);%显示效果图
imshow(out/255)
滑动条-油画
% --- Executes on slider movement.
function slideryouhua_Callback(hObject, eventdata, handles)
% hObject handle to slideryouhua (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'Value') returns position of slider
% get(hObject,'Min') and get(hObject,'Max') to determine range of slider
N=get(hObject,'value');
road=handles.road;%读取原图像
img=imread(road);
[height,width,k]=size(img);%获取原图像大小
% N=10;
out=zeros(height,width,3);
for i=1:height%遍历每个像素点
for j=1:width
temp=uint8(rand()*(N^2-1));%生成随机数
m=temp/N;%取商
n=mod(temp,N);%取余
h=mod(double(i-1)+double(m),double(height));%找到随机对应的原图像像素
w=mod(double(j-1)+double(n),double(width));
if w==0;
w=width;%若找到了上方和左方像素点就用下方和右方的代替
end
if h==0
h=height;
end
out(i,j,:)=img(h,w,:);%将找到的原图像像素点的值赋给输出图像
end
end
axes(handles.axes2);%显示效果图
imshow(out/255)
16.艺术噪声
原理步骤
艺术噪声是一种滤镜,可以增加图片的质感。实现原理是用imnoise函数给图片添加高斯噪声,因为高斯噪声在图像上出现的位置是一定的,但是幅值是随机的,用高斯噪声处理图像就可以实现有噪点的滤镜效果。
滤镜-艺术噪声
% --- Executes on button press in pushbuttonvoice.
function pushbuttonvoice_Callback(hObject, eventdata, handles)
% hObject handle to pushbuttonvoice (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
road=handles.road;%读取原图像
img=imread(road);
img2=imnoise(img,'gauss',0.03);%添加高斯噪声
axes(handles.axes2);%显示添加了高斯噪声后的图像
imshow(img2);
17.灰度胶片
原理步骤
灰度胶片滤镜就是将彩色图像变为灰度图像,实现原理是先将彩色图像的三个通道转成double型,否则uint8在大于255时会溢出,然后取三个通道灰度的平均值作为新图像img2的灰度值,这种方法就是彩色图像灰度化的平均值法,最后将原图像RGB三个通道的值都取成Img2,也就是将三通道RGB值相同的灰度图作为结果图显示。
滤镜-灰度胶片
% --- Executes on button press in pushbuttongray.
function pushbuttongray_Callback(hObject, eventdata, handles)
% hObject handle to pushbuttongray (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
road=handles.road;%读取原图像
img=imread(road);
imR=im2double(img(:,:,1));%将每个通道转成double型,否则uint8>255会溢出
imG=im2double(img(:,:,2));
imB=im2double(img(:,:,3));
imRGB=round((imR+imG+imB)/3*255);%去三个通道的灰度均值--平均值法
img(:,:,1)=imRGB;%灰度图的三通道RGB值相同
img(:,:,2)=imRGB;
img(:,:,3)=imRGB;
axes(handles.axes2);%显示处理后的灰度图
imshow(img);
18.动感模糊
原理步骤:
动感模糊滤镜就是对图像进行运动模糊处理,该功能的运动模糊就是模拟了由于成像过程中相机运动或场景变化时造成不同空间位置信息的混叠。实现过程是先用fspecial函数创建运动模糊滤波器,也就是滤波算子,用motion类型的滤波器更加接近相机的线性运动,接着设定运动位移和运动角度参数,之后在imfilter函数中该算子会对图像进行卷积运算,最后就可得到运动模糊的效果图了。
滤镜-动感模糊
% --- Executes on button press in pushbuttonmohu.
function pushbuttonmohu_Callback(hObject, eventdata, handles)
% hObject handle to pushbuttonmohu (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
road=handles.road;%读取原图像
img=imread(road);
PSF=fspecial ('motion',25,11);%创建运动模糊滤波器
Blurred=imfilter (img,PSF, 'conv' , 'circular') ;%进行滤波
axes(handles.axes2);%显示结果图
imshow(Blurred);
19.素描
原理步骤:
素描滤镜就是将图像的效果处理成通过黑白素描画画出来的效果,在ps中将彩色图片变成素描效果需要先将图像去色,复制该图层后反色,接着向反色图像添加高斯模糊,最后叠加图像选择颜色减淡效果。根据这个过程,也可在matlab实现彩色图像素描化,图像去色就是去某一个通道的灰度值进行处理;而图像反色就是遍历每个像素点然后将该点像素值设为255-原像素值;添加高斯模糊就是同上一个功能先用fspecial函数构造一个滤波器,再用imfilter函数进行高斯模糊处理;最后颜色减淡就是根据C =MIN( A +(A×B)/(255-B),255)进行处理,PS官方对颜色减淡的解释是通过混合色及基色的各通道颜色值进行对比,减少二者的对比度使基色的变量来反映混合色。至此,就可用matlab实现彩色图像素描化的效果了。
该功能还可以通过拖动滑动条改变素描的效果,原理同上,滑动条的参数代表构造高斯滤波器时的标准差,值越大,越模糊,模糊程度越高,得到的素描结果就越清晰,框架纹理颜色就越深。
滤镜-素描
% --- Executes on button press in pushbuttonsumiao.
function pushbuttonsumiao_Callback(hObject, eventdata, handles)
% hObject handle to pushbuttonsumiao (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
road=handles.road;%读取图像
I=imread(road);
[height,width,k]=size(I); %获取原图像大小
N=zeros(height,width); %取反之后值
rc = I(:,:,1);%三通道
gc = I(:,:,2);
bc = I(:,:,3);
channel = gc;%选择一个通道进行处理
out=zeros(height,width);
for i=1:height %遍历每一个像素,将像素值取反
for j=1:width
N(i,j)=uint8(255-channel(i,j));
end
end
%高斯模糊
gausize = 9; %滤波器大小,越大越模糊
gausigma = 10; %越大越模糊
GH = fspecial('gaussian', gausize, gausigma);%构造高斯模糊滤波器
G = imfilter(N, GH);%对图像进行滤波处理
for i=1:height
for j=1:width
b=double(G(i,j)); %高斯模糊后的图像
a=double(channel(i,j)); %原图某一个通道
temp=a+a*b/(255-b); %叠加,颜色减淡
out(i,j)=uint8(min(temp,255));
end
end
axes(handles.axes2);%显示图像
imshow(out/255);
滑动条-素描
% --- Executes on slider movement.
function slidersumiao_Callback(hObject, eventdata, handles)
% hObject handle to slidersumiao (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'Value') returns position of slider
% get(hObject,'Min') and get(hObject,'Max') to determine range of slider
gausigma=get(hObject,'value');%获取活动条的数值
road=handles.road;
I=imread(road);
[height,width,k]=size(I); %获取原图像大小
N=zeros(height,width); %取反之后值
rc = I(:,:,1);%三通道
gc = I(:,:,2);
bc = I(:,:,3);
%选择一个通道进行处理
channel = gc;
out=zeros(height,width);
%颜色取反
for i=1:height
for j=1:width
N(i,j)=uint8(255-channel(i,j)); %double
end
end
%高斯模糊
gausize = 9; %滤波器大小,越大越模糊
% gausigma = 10; %越大越模糊
GH = fspecial('gaussian', gausize, gausigma);%构造高斯模糊滤波器
G = imfilter(N, GH);%对图像进行滤波处理
for i=1:height
for j=1:width
b=double(G(i,j)); %高斯模糊后的图像
a=double(channel(i,j)); %原图某一个通道
temp=a+a*b/(255-b); %叠加,颜色减淡
out(i,j)=uint8(min(temp,255));
end
end
axes(handles.axes2);%显示图像
imshow(out/255);
20.浮雕
原理步骤:
浮雕滤镜就是通过勾勒图像的轮廓和降低周围颜色值来生成凹陷或凸起的浮雕效果。在这里可通过相邻元素相减的方法得到轮廓与边缘的差,从而获得凹凸的立体感。而浮雕算法为Y(i,j)=X(i-1,j-1)-X(i+1,j+1)+128,+128是为了不让效果图太黑,采用的算子是[1 0 0,0 0 0,0 0 -1],也就是对图像中的每个像素进行卷积处理从而实现浮雕效果。
滤镜-浮雕
% --- Executes on button press in pushbuttonfudiao.
function pushbuttonfudiao_Callback(hObject, eventdata, handles)
% hObject handle to pushbuttonfudiao (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
road=handles.road;%读取原图像
img=imread(road);
[height,width,k]=size(img);%获取原图像大小
img2=zeros(height,width,3);
imggray=rgb2gray(img);%将原图像灰度化
for i=2:height-1%遍历每个像素点进行卷积处理
for j=2:width-1
img2(i,j,:)=double(imggray(i-1,j-1,:))-double(imggray(i+1,j+1,:))+128;
end
end
axes(handles.axes2);%显示结果图
imshow(img2/255);
21.羽化
原理步骤:
羽化滤镜就是让图像边缘有朦胧的效果,羽化值越大,朦胧的范围越宽,反之,朦胧范围越窄。具体思想就是通过对图像的像素值增加一个V值实现朦胧效果,而V = 255 × (当前点Point距中点距离的平方)s1 / (顶点距中点的距离平方 × mSize)s2;不过乘255的效果过于明显了,所以该功能换成了乘128,当前点距中点的距离平方就是通过遍历像素点,用中点横纵坐标减当前点横纵坐标得到dx,dy,再将dx,dy的平方和相加得到。通过滑动条可控制羽化值mSize从而控制朦胧效果。
文章来源:https://www.toymoban.com/news/detail-487917.html
滤镜-羽化
% --- Executes on button press in pushbuttonyuhua.
function pushbuttonyuhua_Callback(hObject, eventdata, handles)
% hObject handle to pushbuttonyuhua (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
road=handles.road;%读取图像
img=imread(road);
[m,n,k]=size(img);%获取原图像大小
mSize = 0.6;%羽化值
centerX = n/2;%顶点距中点的距离平方
centerY = m/2;
diff = (centerX*centerX + centerY*centerY) * mSize;
for i=1:m
for j=1:n
dx = centerX - j;%当前点距中点的距离
dy = centerY - i;
dstSq = dx * dx + dy * dy;%当前点距中点距离的平方
V = 128 * dstSq / diff;
img8(i,j,1) = img(i,j,1) + V;%额外增加V实现朦胧效果
img8(i,j,2) = img(i,j,2) + V;
img8(i,j,3) = img(i,j,3) + V;
end
end
img2=cat(3,img8(:,:,1),img8(:,:,2),img8(:,:,3));%将三个通道连接起来
axes(handles.axes2);%显示图像
imshow(img2);
滑动条-羽化
% --- Executes on slider movement.
function slideryuhua_Callback(hObject, eventdata, handles)
% hObject handle to slideryuhua (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'Value') returns position of slider
% get(hObject,'Min') and get(hObject,'Max') to determine range of slider
mSize=get(hObject,'Value');
road=handles.road;%读取图像
img=imread(road);
[m,n,k]=size(img);%获取原图像大小
centerX = n/2;%顶点距中点的距离平方
centerY = m/2;
diff = (centerX*centerX + centerY*centerY) * mSize;
for i=1:m
for j=1:n
dx = centerX - j;%当前点距中点的距离
dy = centerY - i;
dstSq = dx * dx + dy * dy;%当前点距中点距离的平方
V = 128 * dstSq / diff;
img8(i,j,1) = img(i,j,1) + V;%额外增加V实现朦胧效果
img8(i,j,2) = img(i,j,2) + V;
img8(i,j,3) = img(i,j,3) + V;
end
end
img2=cat(3,img8(:,:,1),img8(:,:,2),img8(:,:,3));%将三个通道连接起来
axes(handles.axes2);%显示图像
imshow(img2);
msgbox('羽化滤镜设置成功');%显示弹窗
到了这里,关于Matlab简易版美图秀秀(GUI界面实现)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!