基于matlab的人脸识别系统设计与仿真

第一章 绪论

本章提出了本文的研究背景及应用前景。首先阐述了人脸图像识别意义;然后介绍了人脸图像识别研究中存在的问题;接着介绍了自动人脸识别系统的一般框架构成;最后简要地介绍了本文的主要工作和章节结构。

1.1 研究背景

自70年代以来.随着人工智能技术的兴起.以及人类视觉研究的进展.人们逐渐对人脸图像的机器识别投入很大的热情,并形成了一个人脸图像识别研究领域,.这一领域除了它的重大理论价值外,也极具实用价值。

在进行人工智能的研究中,人们一直想做的事情就是让机器具有像人类一样的思考能力,以及识别事物、处理事物的能力,因此从解剖学、心理学、行为感知学等各个角度来探求人类的思维机制、以及感知事物、处理事物的机制,并努力将这些机制用于实践,如各种智能机器人的研制。人脸图像的机器识别研究就是在这种背景下兴起的,因为人们发现许多对于人类而言可以轻易做到的事情,而让机器来实现却很难,如人脸图像的识别,语音识别,自然语言理解等。如果能够开发出具有像人类一样的机器识别机制,就能够逐步地了解人类是如何存储信息,并进行处理的,从而最终了解人类的思维机制。

同时,进行人脸图像识别研究也具有很大的使用价依。如同人的指纹一样,人脸也具有唯一性,也可用来鉴别一个人的身份。现在己有实用的计算机自动指纹识别系统面世,并在安检等部门得到应用,但还没有通用成熟的人脸自动识别系统出现。人脸图像的自动识别系统较之指纹识别系统、DNA鉴定等更具方便性,因为它取样方便,可以不接触目标就进行识别,从而开发研究的实际意义更大。并且与指纹图像不同的是,人脸图像受很多因素的干扰:人脸表情的多样性;以及外在的成像过程中的光照,图像尺寸,旋转,姿势变化等。使得同一个人,在不同的环境下拍摄所得到的人脸图像不同,有时更会有很大的差别,给识别带来很大难度。因此在各种干扰条件下实现人脸图像的识别,也就更具有挑战性。

国外对于人脸图像识别的研究较早,现己有实用系统面世,只是对于成像条件要求较苛刻,应用范围也就较窄,国内也有许多科研机构从事这方而的研究,并己取得许多成果。

1.2 人脸图像识别的应用前景

人脸图像识别除了具有重大的理论价值以及极富挑战性外,还其有许多潜在的应用前景,利用人脸图像来进行身份验证,可以不与目标相接触就取得样本图像,而其它的身份验证手段,如指纹、眼睛虹膜等必须通过与目标接触或相当接近来取得样木,在某些场合,这些识别手段就会有不便之处。

就从目前和将来来看,可以预测到人脸图像识别将具有广阔的应用前景,如表1-1中所列举就是其中已经实现或逐步完善的应用。

表1-1 人脸识别的应用

|-----------------------|---------------------|------------------|
| 应用 | 优点 | 存在问题 |
| 信信用卡、汽车驾照、护照以及个人身份验证等 | 图像摄取可控 图像分割可控 图像质量好 | 需要建立庞大的数据库 |
| 嫌疑犯照片匹配 | 图像质量不统一 多幅图像可用 | 潜在的巨大图像库 |
| 互联网应用 | 视频信息价值高多人参与 | 存在虚假 |
| 银行/储蓄安全 | 监控效果好 | 图像分割不可控 图像质量较差 |
| 人群监测 | 图像质量高 可利用摄像图像 | 图像分割自由 图像质量低、实时性 |

1.3 本文研究的问题

本文介绍了人脸图像识别中所应用MATLAB对图像进行预处理,应用该工具箱对图像进行经典图像处理,通过实例来应用matlab图像处理功能,对某一特定的人脸图像处理,进而应用到人脸识别系统。本文在总结分析人脸识别系统中几种常用的图像预处理方法基础上,利用MATLAB实现了一个集多种预处理方法于一体的通用的人脸图像预处理仿真系统,将该系统作为图像预处理模块可嵌入在人脸识别系统中,并利用灰度图像的直方图比对来实现人脸图像的识别判定。

其中涉及到图像的选取,脸部定位,特征提取,图像处理和识别几个过程。

1.4 识别系统构成

人类似乎具有"与生俱来"的人脸识别能力,赋予计算机同样的能力是人类的梦想之一,这就是所谓的"人脸识别"系统。假设我们把照相机、摄像头、扫描仪等看作计算机的"眼睛",数字图像可以看作计算机观察到的"影像",那么AFR赋予计算机根据其所"看到"的人脸图片来判断人物身份的能力。

广义的讲,自动人脸识别系统具有如图1.1所示的一般框架并完成相应功能的任务。

图1.1 人脸识别系统一般框架

(1)人脸图像的获取

一般来说,图像的获取都是通过摄像头摄取,但摄取的图像可以是真人,也可以是人脸的图片或者为了相对简单,可以不考虑通过摄像头来摄取头像,而是直接给定要识别的图像。

(2)人脸的检测

人脸检测的任务是判断静态图像中是否存在人脸。若存在人脸,给出其在图像中的坐标位置、人脸区域大小等信息。而人脸跟踪则需要进一步输出所检测到的人脸位置、大小等状态随时间的连续变化情况。

(3)特征提取

通过人脸特征点的检测与标定可以确定人脸图像中显著特征点的位置(如眼睛、眉毛、鼻子、嘴巴等器官),同时还可以得到这些器官及其面部轮廓的形状信息的描述。

根据人脸特征点检测与标定的结果,通过某些运算得到人脸特征的描述(这些特征包括:全局特征和局部特征,显式特征和统计特征等)。

(4)基于人脸图像比对的身份识别

即人脸识别(Face Identification)问题。通过将输入人脸图像与人脸数据库中的所有已知原型人脸图像计算相似度并对其排序来给出输入人脸的身份信息。这包括两类识别问题:一类是闭集(Close Set)人脸识别问题,即假定输入的人脸一定是人脸库中的某个个体;另一类是开集(Open Set)识别,即首先要对输入人脸是否在已知人脸库中做出判断,如果是,则给出其身份。

(5)基于人脸图像比对的身份验证

即人脸确认(Face Verification)问题。系统在输入人脸图像的同时输入一个用户宣称的该人脸的身份信息,系统要对该输入人脸图像的身份与宣称的身份是否相符作出判断。

1.5 论文的内容及组织

第二章主要介绍人脸识别系统中所用到的仿真软件Matlab,介绍了在人脸图像识别过程中所需要的图像处理技术,包括:一些基本操作、格式转换、图像增强等。并做了一个Matlab图像处理功能的实例

第三章主要始涉三个方面:首先是对人脸识别系统的构成做详细论述;其次就是对人脸识别过程中的关键环节人脸检测、特征提取和图像预处理做详细介绍;最后就是Matlab在人脸识别系统中的具体应用,即人脸图像识别的具体技术,并用Matlab进行仿真试验并得到结果。

第四章是对人脸图像识别体系构架的设计,并给出了人脸识别用到的理论知识即直方图差异对比,并编写matlab代码实现人脸图像识别。

第五章总结了全文的工作并对以后的需要进一步研究的问题进行了展望。

运用matlab仿真进行人脸检测定位实例:

人脸检测定位程序:

%%%%% Reading of a RGB image

i=imread('face1.jpg');

I=rgb2gray(i);

BW=im2bw(I);

figure,imshow(BW)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%% minimisation of background portion

[n1 n2]=size(BW);

r=floor(n1/10);

c=floor(n2/10);

x1=1;x2=r;

s=r*c;

for i=1:10

y1=1;y2=c;

for j=1:10

if (y2<=c | y2>=9*c) | (x1==1 | x2==r*10)

loc=find(BW(x1:x2, y1:y2)==0);

[o p]=size(loc);

pr=o*100/s;

if pr<=100

BW(x1:x2, y1:y2)=0;

r1=x1;r2=x2;s1=y1;s2=y2;

pr1=0;

end

imshow(BW);

end

y1=y1+c;

y2=y2+c;

end

x1=x1+r;

x2=x2+r;

end

figure,imshow(BW)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%%%% detection of face object

L = bwlabel(BW,8);

BB = regionprops(L, 'BoundingBox');

BB1=struct2cell(BB);

BB2=cell2mat(BB1);

[s1 s2]=size(BB2);

mx=0;

for k=3:4:s2-1

p=BB2(1,k)*BB2(1,k+1);

if p>mx & (BB2(1,k)/BB2(1,k+1))<1.8

mx=p;

j=k;

end

end

figure,imshow(I);

hold on;

rectangle('Position',[BB2(1,j-2),BB2(1,j-1),BB2(1,j),BB2(1,j+1)],'EdgeColor','r' )

原始图片 灰度图片

均衡化灰度图片 人脸定位

3.4 人脸图像的预处理

不同的人脸识别系统根据其采用的图像来源和识别算法需要不同,采用的预处理方法也不同。常用的人脸图像预处理方法有:滤波去噪、灰度变换、图像二值化、边缘检测、尺寸归一化、灰度归一化等。用在同一系统中的可能只有其中一种或几种预处理方法,但一旦库中采集到的原始图像质量发生较大变化(如人脸大小、光照强度、拍摄条件、成像系统等方面变化),原有的预处理模块便不能满足特征提取的需要,还要更新,这是极不方便的。鉴于此,作者在总结分析了滤波去噪、边缘检测、灰度变换三种广泛应用于不同人脸识别系统中的预处理方法基础上,设计了一个通用的人脸图像预处理仿真系统。该系统可对不同条件下的原始图像进行相应的预处理。如,用户可根据需要选择使用不同的滤波方法去除噪声、不同的边缘检测算子检测人脸边缘、选择不同的灰度变换算法实现图像的灰度校正和灰度归一化,仿真系统同时还实现了尺寸归一化、二值化等其他常用的图像预处理算法。

3.4.1 仿真系统中实现的人脸图像预处理方法

根据所查阅文献资料,常应用于人脸图像的预处理方法有:图像类型转换、滤波去噪、灰度变换、边缘检测及二值化、尺寸归一化、灰度归一化等。作为通用人脸图像预处理模块,要能够充分适应不同人脸库中图像在人脸大小、光照强度、成像系统等方面的任意性和差异性,不能单独采用某种单一的滤波、灰度变换和边缘检测方法。所以,在本仿真系统中,对上述的每种预处理方法全部加以实现的同时,还对三种最常用预处理方法:滤波去噪、灰度变换、边缘检测,提供了多种不同的具体算法供用户比较、选择之用。

1)滤波去噪

由于噪声给图像带来的失真和降质,在特征提取之前采用滤波的方式来去除噪声是实际人脸识别系统中所必须的步骤。滤波的方法有很多,如各种平滑滤波、各种锐化滤波等,关于各种滤波方法的原理和分类可参考文献[2]。下面对本文实现的滤波方法及其选择依据加以说明。在人脸图像预处理中使用较多的滤波是平滑滤波,方法可分为以下三类:线性滤波、中值滤波、自适应滤波。

(1)线性滤波最典型的线性滤波方法如,采用邻域平均法的均值滤波器、采用邻域加权平均的高斯滤波和维纳滤波。对图像进行线性滤波可以去除图像中某些特定类型的噪声,如图像中的颗粒噪声,高斯噪声、椒盐噪声等。对扫描得到的人脸图像根据其噪声类型一般采用此种滤波方法。考虑滤波模板大小对滤波效果影响较大,仿真系统选择算法时对同种滤波算法提供了不同模板大小的情况。

(2)中值滤波法中值滤波法是一种非线性滤波方法,它把像素及其邻域中的像素按灰度级进行排序,然后选择该组的中间值作为输出像素值。中值滤波方法的最大优点是抑制噪声效果明显且能保护边界。对于使用基于整体的人脸识别算法的系统中,由于失掉小区域的细节对特征提取影响较小,所以这种滤波方法最受欢迎。

(3)自适应滤波自适应滤波能够根据图像的局部方差来调整滤波器的输出,其滤波效果要优于线性滤波,同时可以更好地保存图像的边缘和高频细节信息。

2)灰度变换

灰度变换是图像增强技术中的一种。通过灰度变换,可对原始图像中的光照不均进行补偿,使得待识别人脸图像遵循同一或相似的灰度分布。只有这样,不同图像在特征提取和识别时才具有可比性。这一过程,也被称作灰度归一化。常用在人脸识别系统中的灰度变换方法主要有:基于图像统计特征的直方图均衡化、直方图规定化和灰度均值方差标准化三种方法。直方图均衡化和直方图规定化的灰度变换原理和实现方法可由matlab仿真来实现。

三种灰度变换方法,均能在一定程度上消除由于光照条件不同而对人脸识别带来的影响。故在仿真系统中提供了三种灰度变换效果比较及选择界面,用户可根据需要选用。

3)边缘检测

对输入人脸图像进行边缘检测是很多人脸识别系统在人脸粗定位及人脸主要器官(眼睛、鼻子、嘴巴)定位时采用的预处理方法。边缘检测的方法有很多,主要有:微分算子法、Sobel算子法、拉普拉斯算子法、canny算子法等。每种算子对不同方向边缘的检测能力和抑制噪声的能力都不同。所以,和灰度变换及滤波去噪部分的设计思路相同,在仿真系统中,笔者给出了canny、sobel、log、prewitt四种算子在不同灰度阈值下、不同方向的边缘检测算法,使用者可从检测结果中加以比较、选择合适的算法。图像类型转换、图像二值化、尺寸归一化也是一些人脸识别系统中经常使用的预处理方法。为了在不修改其他算法的基础上,扩大系统处理图像的类型和范围,将输入图像首先转换为统一的类型,是多数人脸图像预处理中的第一步。在本仿真系统中通过调用MATLAB中提供的各种图像类型转换函数来实现TIF、JPG转换为BMP格式及彩色到灰度图像的转换;对图像二值化,采用了graythresh()函数来自动选择阈值的二值化方法[1];尺寸归一化采用的算法是对人脸图像进行剪裁和尺寸缩放,实现去除大部分头发、服饰和背景的干扰并将人脸图像大小统一。

第四章 基于直方图的人脸识别实现

4.1识别理论

用灰度直方图增强图像对比度是基于图像灰度值统计的一种重要方法,它以概率论为基础的,常用的实现算法主要是直方图均衡化和直方图规定化。

直方图均衡化主要用于增强动态范围较小的图像的反差,基本思想是把原始图的直方图变换为均匀分布的形式,这样就增强了像素灰度值的动态范围,从而达到增强图像整体对比度的效果。直方图均衡化的优点是能自动地增强整个图像的对比度,但它的具体的增强效果不好控制,处理的结果总是得到全局均衡化的直方图。实际中有时需要变换直方图使之成为某个需要的形状,从而有选择地增强某个灰度值范围内的对比度或使图像灰度值的分布满足特定的要求,这时可以采用比较灵活的直方图规定化方法。

4.2 人脸识别的matlab实现

实现结果如图4.1和4.2

图4.1 用户界面 图4.2 实现结果

4.3 本章小结

在过去十年中基于直方图方法证其明简单性和有用性。 最初这种想法基于颜色直方图。 此算法提供我们的建议技术名为"直方图处理人脸识别"的第一部分。同时使用灰度图像。 第一,每个灰度级的频率是计算并存储在媒介作进一步处理。 第二,平均从存储载体的连续九个频率的计算,并存储在另一个载体,供以后使用,在测试阶段。 此均值向量用于计算平均值的曾受训练的图像和测试图像绝对差异。 最后确定最小差异的图像与测试图像匹配, 识别的准确性是 99.75%

第五章 结语

基于matlab数字图像处理与识别系统其实是一个范围很大的应用系统,作者在此只是有针对性、有选择地进行了一些开发和实现。

该系统的主要功能模块共有二个:(1)数字图像处理的基本方法;(2)人脸识别。

在"数字图像处理的基本方法"这一部分,用到的一些基本方法和一些最常用的处理方法来实现图像预处理,如格式转换,灰度变化和滤波锐化。仅就这一部分而言,就有很多可以继续完成的工作,可将其它一些数字图像处理方法进一步加以实现,如图像的平滑,图像矩阵的变换(K-L变换、Fourier变换、小波变换等),图像的膨胀腐蚀、图像的几何变换(平移、旋转、缩放等),以及各种编码图像的读写与显示。仅这一部分即可形成一个专用的图像处理平台。

关于"人脸识别",在了解了人脸识别的各种方法后,选择了图像直方图差值比较进行了实现。该方法能较好地实现人脸的分类,但对人脸图像的要求较高,目前仅是采用Orl的标准人脸库中的图像来进行测试,因此能获得较高的识别率。而在现实生活中采集到的人脸图像则会受到很多因素的影响,识别率就未必能达到要求了。若要进一步提高识别率和适用范围,则还需要结合其它算法,如PCA、神经网络等。

参考文献

[1] 祝磊,朱善安.人脸识别的一种新的特征提取方法[J].计算机学报,2022,34(6):122-1251

[2] 何东风,凌捷.人脸识别技术综述[J].计算机学报,2023,13(12)75-78

[3] ,Younus Fazl-e-Basit Javed和Usman Qayyum",采用直方图的人脸识别和处理",第三阶段仅相关新兴技术研报告。

[4] 何国辉,甘俊英.PCA-LDA算法在性别鉴别中的应用[J].中国图像图形学报,2022,32(19):208-211.

[5] 王聃,贾云伟,林福严.人脸识别系统中的特征提取[J].自动化学报,2019,21(7-3).

[6] 张俭鸽,王世卿,盛光磊.基于小波和DFB-PCA的人脸识别算法研究[J].自动化学报,2022,23(2-1).

[7] 曹林,王东峰,刘小军,邹谋炎.基于二维Gabor小波的人脸识别算法[J].电子学报,2006,28(3)490-494

[8] 焦峰,山世光,崔国勤,高文,李锦涛.基于局部特征分析的人脸识别方法[J].自动化学报,2003,15(1):53-58

[9] Wangmeng Zuo,Kuanquan Wang,David Zhang,Hongzhi Zhang. Combination of two novel LDA-based methods for face recognition[C].Proceedings of the IEEE,2007:735-742

[10] 徐倩,邓伟.一种融合两种主成分分析的人脸识别方法[J].计算机学报,2007,43(25):195-197

附录 人脸识别matlab程序

function varargout = FR_Processed_histogram(varargin)

gui_Singleton = 1;

gui_State = struct('gui_Name', mfilename, ...

'gui_Singleton', gui_Singleton, ...

'gui_OpeningFcn', @FR_Processed_histogram_OpeningFcn, ...

'gui_OutputFcn', @FR_Processed_histogram_OutputFcn, ...

'gui_LayoutFcn', [] , ...

'gui_Callback', []);

if nargin && ischar(varargin{1})

gui_State.gui_Callback = str2func(varargin{1});

end

if nargout

[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});

else

gui_mainfcn(gui_State, varargin{:});

end

% End initialization code - DO NOT EDIT

%--------------------------------------------------------------------------

% --- Executes just before FR_Processed_histogram is made visible.

function FR_Processed_histogram_OpeningFcn(hObject, eventdata, handles, varargin)

handles.output = hObject;

% Update handles structure

guidata(hObject, handles);

% UIWAIT makes FR_Processed_histogram wait for user response (see UIRESUME)

% uiwait(handles.figure1);

global total_sub train_img sub_img max_hist_level bin_num form_bin_num;

total_sub = 40;

train_img = 200;

sub_img = 10;

max_hist_level = 256;

bin_num = 9;

form_bin_num = 29;

%--------------------------------------------------------------------------

% --- Outputs from this function are returned to the command line.

function varargout = FR_Processed_histogram_OutputFcn(hObject, eventdata, handles)

varargout{1} = handles.output;

%--------------------------------------------------------------------------

% --- Executes on button press in train_button.

function train_button_Callback(hObject, eventdata, handles)

global train_processed_bin;

global total_sub train_img sub_img max_hist_level bin_num form_bin_num;

train_processed_bin(form_bin_num,train_img) = 0;

K = 1;

train_hist_img = zeros(max_hist_level, train_img);

for Z=1:1:total_sub

for X=1:2:sub_img %%%train on odd number of images of each subject

I = imread( strcat('ORL\S',int2str(Z),'\',int2str(X),'.bmp') );

[rows cols] = size(I);

for i=1:1:rows

for j=1:1:cols

if( I(i,j) == 0 )

train_hist_img(max_hist_level, K) = train_hist_img(max_hist_level, K) + 1;

else

train_hist_img(I(i,j), K) = train_hist_img(I(i,j), K) + 1;

end

end

end

K = K + 1;

end

end

[r c] = size(train_hist_img);

sum = 0;

for i=1:1:c

K = 1;

for j=1:1:r

if( (mod(j,bin_num)) == 0 )

sum = sum + train_hist_img(j,i);

train_processed_bin(K,i) = sum/bin_num;

K = K + 1;

sum = 0;

else

sum = sum + train_hist_img(j,i);

end

end

train_processed_bin(K,i) = sum/bin_num;

end

display ('Training Done')

save 'train' train_processed_bin;

%--------------------------------------------------------------------------

% --- Executes on button press in Testing_button.

function Testing_button_Callback(hObject, eventdata, handles)

global train_img max_hist_level bin_num form_bin_num;

global train_processed_bin;

global filename pathname I

load 'train'

test_hist_img(max_hist_level) = 0;

test_processed_bin(form_bin_num) = 0;

[rows cols] = size(I);

for i=1:1:rows

for j=1:1:cols

if( I(i,j) == 0 )

test_hist_img(max_hist_level) = test_hist_img(max_hist_level) + 1;

else

test_hist_img(I(i,j)) = test_hist_img(I(i,j)) + 1;

end

end

end

[r c] = size(test_hist_img);

sum = 0;

K = 1;

for j=1:1:c

if( (mod(j,bin_num)) == 0 )

sum = sum + test_hist_img(j);

test_processed_bin(K) = sum/bin_num;

K = K + 1;

sum = 0;

else

sum = sum + test_hist_img(j);

end

end

test_processed_bin(K) = sum/bin_num;

sum = 0;

K = 1;

for y=1:1:train_img

for z=1:1:form_bin_num

sum = sum + abs( test_processed_bin(z) - train_processed_bin(z,y) );

end

img_bin_hist_sum(K,1) = sum;

sum = 0;

K = K + 1;

end

[temp M] = min(img_bin_hist_sum);

M = ceil(M/5);

getString_start=strfind(pathname,'S');

getString_start=getString_start(end)+1;

getString_end=strfind(pathname,'\');

getString_end=getString_end(end)-1;

subjectindex=str2num(pathname(getString_start:getString_end));

if (subjectindex == M)

axes (handles.axes3)

%image no: 5 is shown for visualization purpose

imshow(imread(STRCAT('ORL\S',num2str(M),'\5.bmp')))

msgbox ( 'Correctly Recognized');

else

display ([ 'Error==> Testing Image of Subject >>' num2str(subjectindex) ' matches with the image of subject >> ' num2str(M)])

axes (handles.axes3)

%image no: 5 is shown for visualization purpose

imshow(imread(STRCAT('ORL\S',num2str(M),'\5.bmp')))

msgbox ( 'Incorrectly Recognized');

end

display('Testing Done')

%--------------------------------------------------------------------------

function box_Callback(hObject, eventdata, handles)

function box_CreateFcn(hObject, eventdata, handles)

if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))

set(hObject,'BackgroundColor','white');

end

%--------------------------------------------------------------------------

% --- Executes on button press in Input_Image_button.

function Input_Image_button_Callback(hObject, eventdata, handles)

% hObject handle to Input_Image_button (see GCBO)

% eventdata reserved - to be defined in a future version of MATLAB

% handles structure with handles and user data (see GUIDATA)

global filename pathname I

[filename, pathname] = uigetfile('*.bmp', 'Test Image');

axes(handles.axes1)

imgpath=STRCAT(pathname,filename);

I = imread(imgpath);

imshow(I)

%--------------------------------------------------------------------------

% --- Executes during object creation, after setting all properties.

function axes3_CreateFcn(hObject, eventdata, handles)

相关推荐
Theodore_10222 小时前
4 设计模式原则之接口隔离原则
java·开发语言·设计模式·java-ee·接口隔离原则·javaee
----云烟----4 小时前
QT中QString类的各种使用
开发语言·qt
lsx2024064 小时前
SQL SELECT 语句:基础与进阶应用
开发语言
开心工作室_kaic4 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
向宇it4 小时前
【unity小技巧】unity 什么是反射?反射的作用?反射的使用场景?反射的缺点?常用的反射操作?反射常见示例
开发语言·游戏·unity·c#·游戏引擎
武子康4 小时前
Java-06 深入浅出 MyBatis - 一对一模型 SqlMapConfig 与 Mapper 详细讲解测试
java·开发语言·数据仓库·sql·mybatis·springboot·springcloud
转世成为计算机大神5 小时前
易考八股文之Java中的设计模式?
java·开发语言·设计模式
宅小海5 小时前
scala String
大数据·开发语言·scala
qq_327342735 小时前
Java实现离线身份证号码OCR识别
java·开发语言
锅包肉的九珍5 小时前
Scala的Array数组
开发语言·后端·scala