该项目为数字图像处理课程的期末大项目,主要内容是用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;
elsestr=[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函数进行图像旋转,并显示即可。而旋转图像本质上就是将图像构成的矩阵乘一个旋转矩阵从而得到一个旋转后的新矩阵。

功能键-图像旋转
% --- 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:3img2(:,:,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:3img2(:,:,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:Mfor j = 1:Nif( x1( i,j ) ~= 0 )r = x( i,j,: );%得到采样的像素值endendend%随机产生填充图像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-1for j = 2:3:N-1f1( 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 );endendf = 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==1k=k+1;%计算共点击了几次plot(x,y,'b.','MarkerSize',20)%绘制选中的这些点p(k,1:2)=round([y,x]);%四舍五入去整--取反是因为图像像素坐标索引与xy坐标系相反if k>1line([p(k-1,2),p(k,2)],[p(k-1,1),p(k,1)],'LineWidth',2) %将点和上一个点用2榜直线连起来endelseline([p(1,2),p(k,2)],[p(1,1),p(k,1)],'LineWidth',2) %将点和上一个点用2榜直线连起来breakend
end
hold off
% 生成蒙板
mask=zeros(M,N);%生成一个和原图像同样大小的蒙版
for i=1:k%遍历每个选取的点if i<kmask=pixelcontect(mask,p(i,:),p(i+1,:));%依次连接所有点elsemask=pixelcontect(mask,p(i,:),p(1,:));%末尾与起点相连end
end
mask=imfill(mask,'hole');if D>1mask=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)];
elsedir2=[gap(1),0];%向x方向走dir1=[0,gap(2)];
endlmp=less/more;%斜率
i=0;j=0;
while i<more%将线段覆盖的点的像素值设为1p0=p0+dir1;a(p0(1),p0(2))=1;i=i+1;if i<morep1=p1-dir1;a(p1(1),p1(2))=1;i=i+1;endif j/i<lmp%若比斜率小if j<lessp0=p0+dir2;a(p0(1),p0(2))=1;j=j+1;endif j<lessp1=p1-dir2;a(p1(1),p1(2))=1;j=j+1;endendend

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:Nif(f(i,j)~=0)f(i,j,:)=imadd(f(i,j,:),30);endendend     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:rightoffsety=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);endend
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 numcase 1case 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');endcase 4road=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 5road=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 1case 2im2 = imread('fagu1.png');%小图case 3im2 = imread('srat.png');%小图case 4im2 = 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:widthtemp=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;%若找到了上方和左方像素点就用下方和右方的代替endif h==0h=height;endout(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 sliderN=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:widthtemp=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;%若找到了上方和左方像素点就用下方和右方的代替endif h==0h=height;endout(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 slidergausigma=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));   %doubleend
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-1img2(i,j,:)=double(imggray(i-1,j-1,:))-double(imggray(i+1,j+1,:))+128;end
endaxes(handles.axes2);%显示结果图
imshow(img2/255);

21.羽化

原理步骤:

羽化滤镜就是让图像边缘有朦胧的效果,羽化值越大,朦胧的范围越宽,反之,朦胧范围越窄。具体思想就是通过对图像的像素值增加一个V值实现朦胧效果,而V = 255 × (当前点Point距中点距离的平方)s1 / (顶点距中点的距离平方 × mSize)s2;不过乘255的效果过于明显了,所以该功能换成了乘128,当前点距中点的距离平方就是通过遍历像素点,用中点横纵坐标减当前点横纵坐标得到dx,dy,再将dx,dy的平方和相加得到。通过滑动条可控制羽化值mSize从而控制朦胧效果。

滤镜-羽化
% --- 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:mfor j=1:ndx = 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:mfor j=1:ndx = 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界面实现)相关推荐

  1. java美图秀秀_[Java教程]简易版美图秀秀_星空网

    简易版美图秀秀 2016-10-30 0 简易板美图秀秀灰度 黑白 底片 模糊 马赛克 简单的实现了 灰度,黑白,底片,模糊,马赛克(代码比较简单,通过canvas实现的) 感觉挺有意思的,上面解释很 ...

  2. MATLAB大作业——美图秀秀

    基于APP Designer完成MATLAB大作业之简易版美图秀秀设计 目录​​​​​​​ 一.基础功能 二.添加效果 三.调色 四.美颜 五.贴图 六.相框 一.基础功能 1 导入图片 functi ...

  3. android 图片排版,Android版美图秀秀优化拼图排版

    看完了<北京爱情故事>,那留下太多悬念的结局,让人不由思考着关于爱的故事还会怎样延续?陈思成佟丽娅相恋却在戏外给了我们一个满意的答案.正巧,美图秀秀安卓v1.4.5新版上线,优化拼图版式和 ...

  4. 美图秀秀首页界面设计(一)

    本文设计了美图秀秀官方版的界面,从中可以学到自定义View,自动布局,启动界面设置.代码有点凌乱,我在一步步改善.[声明:本博客只能用作学习用途,不得用于商业用途,图片资源均来自官方,产生纠纷,本人不 ...

  5. 美图秀秀首页界面按钮设计(二)

    本文实现美图秀秀首页中的按钮,它包含3张图片和一个文本.通过开发按钮,我们可以学到iOS的自定义控件,绘制图片和文本的知识.[声明:本博客只能用作学习用途,不得用于商业用途,图片资源均来自官方,产生纠 ...

  6. 微信小程序版“美图秀秀”源码

    使用代码 下载并安装微信开发者工具,使用微信号扫码登录开发者工具. 打开微信开发者工具,点击"小程序项目"按钮,输入小程序 AppID,项目目录选择下载的代码目录,点击确定创建小程 ...

  7. 数字图像处理期末大作业-美图秀秀

    本项目是以matlab为主语言并设计GUI界面的一款简易美图秀秀,包含基础的图像处理和一些常见美颜算法 对于一些matlab较难实现的算法采用C++或python来实现 ⭐️ github地址:htt ...

  8. MATLAB美图秀秀系统GUI设计[完美运行,GUI界面,详细教程,万字文稿]

    课题名称 基于MATLAB的美图秀秀系统GUI设计 GUI框架链接:matlab美图秀秀[GUI,磨皮,白平衡,特效].zip_matlabGUI制作美图秀秀界面-专业指导文档类资源-CSDN下载 课 ...

  9. android 相机智能补光,美图秀秀智能补光功能应用详解

    晚上拍照时最容易遇见"曝光不足"和"曝光过度"的问题,使得照片看起来明暗不协调,缺乏应有的美感.不过,如果你的手机中 装有"美图秀秀",这些 ...

最新文章

  1. 美多商城之用户中心(收货地址2)
  2. 用800行代码做个行为树(Behavior Tree)的库(2
  3. 统计并输出某给定字符在给定字符串中出现的次数_查找常用字符
  4. exchange 删除邮件
  5. PostgreSQL 函数调试、诊断、优化 auto_explain
  6. java代码连接redis_java代码连接redis
  7. thymealf如何实现传单个变量给html_纯前端使用JavaScript发送电子邮件,5个步骤图文教程...
  8. 就编程而言,可移植性意味着什么?
  9. ios开发 方形到圆的动画_3Blue1Brown 动画制作教程(1)--制作第一个自己的动画
  10. 核心网upf作用_高性能5G核心网,动力从何而来? 核心网,是整个通信网络的大脑,是不可或缺的重要组成部分。 网络的管理控制、鉴权认证等关键功能,主要由核心网负责。核心网的... - 雪球...
  11. 这个是我学习的所有sql语句的写法
  12. tomcat/redis/dubbo/netty
  13. 人工智能AI系列 - 问答系统
  14. NAT技术与代理服务器
  15. python绘图矩阵散点图_Python数据可视化:用Seaborn绘制高端玩家版散点图
  16. redis 删除操作命令
  17. switch中的PVID、VID、untag、tag概念
  18. Java序列中如果有些字段不想被序列化,怎么办
  19. WIN10 注册.dll regsvr32.exe错误 VC6添加插件
  20. less和sass的定义和区别

热门文章

  1. 网易云易盾验证码海外版发布,支持12种主流语言
  2. 实战演练 Navicat 中英文模式切换
  3. 计算机退出用户登陆,电脑退出微软账户登录不了怎么办
  4. 深入理解类加载机制:拨开迷雾见真章
  5. 利用反射模拟Tomcat类加载器的toString方法
  6. 【JS篇】禁止手机默认键盘弹出
  7. C++ std map unordered_map hash_map 的查找性能测试代码及结果
  8. php 模拟蜘蛛,PHP模拟百度蜘蛛,伪造IP爬行网站,附源代码
  9. Matlab车牌识别
  10. PySide应用无法调出输入法输入中文