至少平静

学会沉默

  有时候,你被人误解,你不想争辩,所以选择沉默。本来就不是所有的人都得了解你,因此你不必对全世界喊话。却也有时候,你被最爱的人误解,你难过到不想争辩,也只有选择沈默。全世界都可以不懂你,但他应该懂,若他竟然不能懂,还有什么话可说?生命中往往有连舒伯特都无言以对的时刻,毕竟不是所有的是非都能条列清楚,甚至可能根本没有真正的是与非。那么,不想说话,就不说吧,在多说无益的时候也许沉默就是最好的解释。

  至少平静


  在你跌入人生谷底的时候,你身旁所有的人都告诉你:要坚强,而且要快乐。坚强是绝对需要的,但是快乐?在这种情形下,恐怕是太为难你了。毕竟,谁能在跌得头破血流的时候还觉得高兴?但是至少可以做到平静。平静地看待这件事,平静地把其他该处理的事处理好。平静,没有快乐,也没有不快乐。

  学会弯腰 这会有意外的收获

  和别人发生意见上的纷歧,甚造成言语上的冲突,所以你闷闷不乐,因为你觉得都是别人恶意。别再耿耿于怀了,回家去擦地板吧。拎一块抹布,弯下腰,双膝着地,把你面前这张地板的每个角落来回擦拭干净。然后重新省思自己在那场冲突,所说过的每一句话。现在,你发现自己其实也有不对的地方了,是不是?你渐渐心平气和了,是不是?有时候你必须学习弯腰,因为这个动作可以让你谦卑。劳动身体的同时,你也擦亮了自己的心绪。而且,你还拥有了一张光洁的地板呢。这是你的第二个收获。

  不要想 如果 当初

  你说,人生是一条有无限多岔口的长路,永远在不停地做选择。如果只是选择吃炒面或炒饭,影响似乎不大,但选择读什么科系、做什么工作、结婚或不结婚、要不要有孩子,每一个选择都影响深远,而不同的选择也必定造就完全不一样的人生。你又说,生命中不可承受之情,就在于人生没有重来的机会啊。如果当初如何如何,现在就不会怎样怎样...这种充满怅然的喃喃自语,还是别再多说了吧。每一个岔口的选择其实没有真正的好与坏,只要把人生看成是自己。独一无二的创作,就不会频频回首如果当初做了不一样的选择。

  努力吧 不管成功与否 至少曾经美丽

  漫步林间,你看见一株藤蔓附着树干,柔软与坚实相互交缠,你感动于这静美的一幕。让幸福与归属就此驻足吧。你想。不知未来会有怎样一番风雨摧折?也许藤将断、树会倒,也许天会荒,地将老。你又想。那么,请时光停格在此刻吧。停格即是永恒。永恒里若有这静美的一刻,未来可能遭遇的种种劫难,便已得到了安慰与报偿。

  保持单纯

  因为思虑过多,所以你常常把你的人生复杂化了。明明是活在现在,你却总是念念不忘着过去,又忧心忡忡着未来;坚持携带着过去、未来与现在同行,你的人生当然只有一片拖泥带水。而单纯是一种恩宠状态。单纯地以皮肤感受天气的变化,单纯地以鼻腔品尝雨后的青草香,单纯地以眼睛统摄远山近景如一幅画。单纯地活在当下。而当下其实无所谓是非真假。既然没有是非,就不必思虑;没有真假,就无须念念不忘又忧心忡忡。无是非真假,不就像在做梦一样了吗?是呀,就单纯地把你的人生当成梦境去执行吧。

  偶尔"俗气"...

  吃多了健康食品,偶尔你也想啃一啃鸭舌头和盐酥鸡。看多了大师名剧,偶尔你也想瞄一瞄耳光摔不完眼泪掉不完的连续剧。听多了古典音乐,偶尔你也想唱一唱爱他一百年又恨他一他一万年的流行歌曲。你知道健康食品对健胃整肠有意义,大师名剧对培养气质有意义,古典音乐对提升性灵有意义,可是,偶尔你其实并不想让自己时时刻刻活得那么有意。人生不需要把自己绑得那么紧。偶尔的小小放纵,是道德的。灵气充满或许接近大人,但偶尔的俗气会更平易近人。

  控制情绪 别浪费了~

  今天的你,是不开心的你,因为有人在言语间刺伤了你。你不喜欢吵架,所以你离开;可是你只是离开了那,却没有离开被那人伤害的情境,因此你愈想愈生气。愈有气,你就愈没有力气去理会别的事情,许多更该用心去做去想去处理的事件,就在你漫天漫地的心烦意乱之中,被轻忽被漠视被省略了。因为,你只是一心一意地在生气。在情绪上做文章,这是对自己的浪费,而且是很坏的浪费。毕竟,生气也是要花力气的,而且生气一定伤元气。所以,聪明如你,别让情绪控制了你,当你又要生气之前,不妨轻声地提醒自己一句:“别浪费了。”

  抓住最好的时机 绝不错过

  你曾经买了一件很喜欢的衣裳却舍不得穿,郑重地供奉在衣柜里;许久之后,当你再看见它的时候,却发现它已经过时了。所以,你就这样与它错过了。你也曾经买了一块漂亮的蛋糕却舍不得吃,郑重地供奉在冰箱里;许久之后,当你再看见它的时候,却发现它已经过期了。所以,你也这样与它错过了。没有在最喜欢的时候上身的衣裳,没有在最可口的时候品尝的蛋糕,就像没有在最想做的时候去做的事情,都是遗憾。生命也有保存期限,想做的事该趁早去做。如果你只是把你的心愿郑重地供奉在心里,却未曾去实行,那么唯一的结果,就是与它错过,一如那件过时的衣裳,一如那块过期的蛋糕。

  偶尔的出离轨道

  某次你搭火车打算到A地去,中途却忽然临时起意在B地下了车。也许是别致的地名吸引了你,也许是偶然一瞥的风景触动了你,总之,你就这样改变了本来预定的行程,然后经历了一场充满惊奇的意外旅行。A地是你原先的目标,B地却让你体会了小小的冒险。回忆起来,你说,那是一次令你难忘的出轨经验。生命中的许多时候不也如此?心无旁骛地奔赴唯一的目的,不过是履行了原本的行程而已;离开预设的轨道,你才有机会发现其他的风景。

  悄悄 悄悄地 回归平静..

  曾经有一段时间,你心情低落,甚至懒得拉开窗帘,看着窗外的阳光。因此你当然也忘了去看看,窗台上那一盆每天都需要喝水的玛格丽特。如此不知过了多久,总算有一天,你度过了心情的低潮,同时也想起了你的玛格丽特。天啊,可怜的花,她还活着吗?你战战兢兢地拉开窗帘,却见她迎风招摇,花颜可掬。原来在过去的这段日子里,你虽然忘了喂她喝水,老天却没忘了以雨露眷顾她呢。许多事物悄悄地在你的视线之外进行,而且悄悄地安排好了它们自己。天生万物,天养万物,一切其实无须担心......你只要做的就是做好自己,不留任何遗憾...足矣。

classdef EmotionRecognitionSystem < handle % 面部表情识别系统主类 % 支持自定义数据集训练和表情识别 properties fig % 主窗口句柄 net % 表情识别模型 axImg % 图像显示区域 txtResult % 结果显示文本框 cam % 摄像头对象 videoPlayer % 视频播放器 isCapturing = false; % 是否正在捕获视频 end methods function obj = EmotionRecognitionSystem() % 构造函数 - 创建GUI并加载模型 % 创建主窗口 obj.fig = figure('Name', '面部表情识别系统', ... 'Position', [300 200 900 550], ... 'NumberTitle', 'off', ... 'MenuBar', 'none', ... 'CloseRequestFcn', @obj.closeApp); % 尝试加载现有模型 try load('customEmotionNet.mat', 'net'); obj.net = net; disp('自定义模型加载成功'); catch obj.net = []; end % 创建UI控件 uicontrol('Style', 'pushbutton', ... 'Position', [30 480 120 40], ... 'String', '选择图片', ... 'Callback', @obj.loadImage, ... 'FontSize', 11); uicontrol('Style', 'pushbutton', ... 'Position', [170 480 120 40], ... 'String', '摄像头捕获', ... 'Callback', @obj.captureFromCam, ... 'FontSize', 11); uicontrol('Style', 'pushbutton', ... 'Position', [310 480 120 40], ... 'String', '实时识别', ... 'Callback', @obj.realTimeRecognition, ... 'FontSize', 11); uicontrol('Style', 'pushbutton', ... 'Position', [450 480 120 40], ... 'String', '训练模型', ... 'Callback', @obj.trainModel, ... 'FontSize', 11); uicontrol('Style', 'pushbutton', ... 'Position', [590 480 120 40], ... 'String', '帮助', ... 'Callback', @obj.showHelp, ... 'FontSize', 11); % 创建图像显示区域 obj.axImg = axes('Parent', obj.fig, ... 'Position', [0.05 0.1 0.5 0.7], ... 'Box', 'on'); axis(obj.axImg, 'image'); title(obj.axImg, '输入图像'); % 创建结果显示区域 uicontrol('Style', 'text', ... 'Position', [600 400 250 40], ... 'String', '识别结果:', ... 'FontSize', 14, ... 'FontWeight', 'bold', ... 'BackgroundColor', [0.9 0.9 0.9]); obj.txtResult = uicontrol('Style', 'text', ... 'Position', [600 300 250 90], ... 'String', '等待识别...', ... 'FontSize', 16, ... 'FontWeight', 'bold', ... 'ForegroundColor', [0 0.5 0], ... 'BackgroundColor', [0.95 0.95 0.95], ... 'HorizontalAlignment', 'center'); % 置信度指示器 uicontrol('Style', 'text', ... 'Position', [600 200 250 30], ... 'String', '置信度:', ... 'FontSize', 12, ... 'BackgroundColor', [0.9 0.9 0.9]); % 表情标签 emotions = {'平静', '大笑', '微笑', '哭泣', '悲伤'}; for i = 1:length(emotions) uicontrol('Style', 'text', ... 'Position', [600 170-(i-1)*30 100 25], ... 'String', emotions{i}, ... 'FontSize', 11, ... 'HorizontalAlignment', 'left', ... 'BackgroundColor', [0.95 0.95 0.95]); end end function loadImage(obj, ~, ~) % 从文件选择图像 [file, path] = uigetfile({'*.jpg;*.png;*.bmp;*.png', '图像文件'}); if isequal(file, 0) return; end imgPath = fullfile(path, file); obj.processImage(imread(imgPath)); end function captureFromCam(obj, ~, ~) % 从摄像头捕获图像 if isempty(webcamlist) errordlg('未检测到摄像头', '硬件错误'); return; end try obj.cam = webcam; preview(obj.cam); uicontrol('Style', 'text', ... 'Position', [300 10 300 30], ... 'String', '正在捕获...3秒后自动拍照', ... 'FontSize', 12, ... 'ForegroundColor', 'r'); pause(3); img = snapshot(obj.cam); clear obj.cam; obj.processImage(img); delete(findobj(obj.fig, 'Type', 'uicontrol', 'Position', [300 10 300 30])); catch ME errordlg(['摄像头错误: ' ME.message], '硬件错误'); if ~isempty(obj.cam) clear obj.cam; end end end function realTimeRecognition(obj, ~, ~) % 实时表情识别 if obj.isCapturing obj.isCapturing = false; return; end if isempty(webcamlist) errordlg('未检测到摄像头', '硬件错误'); return; end if isempty(obj.net) warndlg('请先训练模型', '模型缺失'); return; end obj.isCapturing = true; obj.cam = webcam; obj.videoPlayer = vision.DeployableVideoPlayer; % 创建停止按钮 stopBtn = uicontrol('Style', 'pushbutton', ... 'Position', [310 480 120 40], ... 'String', '停止识别', ... 'Callback', @obj.stopRealTime, ... 'FontSize', 11, ... 'BackgroundColor', [1 0.6 0.6]); % 实时识别循环 while obj.isCapturing && ishandle(obj.fig) img = snapshot(obj.cam); [emotion, confidence, faceImg] = obj.recognizeEmotion(img); % 在图像上标注结果 if ~isempty(faceImg) bbox = faceImg.bbox; label = sprintf('%s (%.1f%%)', emotion, confidence*100); img = insertObjectAnnotation(img, 'rectangle', bbox, ... label, 'Color', 'green', 'FontSize', 18); end step(obj.videoPlayer, img); end % 清理 release(obj.videoPlayer); clear obj.cam; delete(stopBtn); end function stopRealTime(obj, ~, ~) % 停止实时识别 obj.isCapturing = false; end function processImage(obj, img) % 处理单张图像 if isempty(obj.net) warndlg('请先训练模型', '模型缺失'); return; end axes(obj.axImg); imshow(img); title('输入图像'); % 表情识别 [emotion, confidence, faceImg] = obj.recognizeEmotion(img); % 显示结果 resultStr = sprintf('表情: %s\n置信度: %.2f%%', emotion, confidence*100); set(obj.txtResult, 'String', resultStr); % 绘制检测框 if ~isempty(faceImg) hold on; rectangle('Position', faceImg.bbox, ... 'EdgeColor', 'g', 'LineWidth', 2); text(faceImg.bbox(1), faceImg.bbox(2)-20, ... [emotion ' (' num2str(round(confidence*100)) '%)'], ... 'Color', 'g', 'FontSize', 14, 'FontWeight', 'bold'); hold off; end end function [emotion, confidence, faceImg] = recognizeEmotion(obj, img) % 表情识别函数 faceImg = []; % 人脸检测 faceDetector = vision.CascadeObjectDetector(); bbox = step(faceDetector, img); if isempty(bbox) emotion = '未检测到人脸'; confidence = 0; return; end % 选择最大的人脸区域 [~, idx] = max(bbox(:,3).*bbox(:,4)); mainBbox = bbox(idx,:); % 裁剪人脸区域 faceImg.img = imcrop(img, mainBbox); faceImg.bbox = mainBbox; % 预处理 - 保持RGB三通道 resizedImg = imresize(faceImg.img, [48 48]); % 模型输入尺寸 normalizedImg = im2single(resizedImg); % 归一化 % 表情分类 [pred, scores] = classify(obj.net, normalizedImg); confidence = max(scores); % 映射到表情标签 emotionMap = containers.Map(... {'neutral', 'happy', 'smile', 'cry', 'sad'}, ... {'平静', '大笑', '微笑', '哭泣', '悲伤'}); if isKey(emotionMap, char(pred)) emotion = emotionMap(char(pred)); else emotion = '未知表情'; end end function trainModel(obj, ~, ~) % 训练自定义模型 answer = questdlg('训练模型需要较长时间,是否继续?', ... '模型训练', '是', '否', '是'); if ~strcmp(answer, '是') return; end % 创建训练进度窗口 trainFig = figure('Name', '模型训练', ... 'Position', [400 300 400 200], ... 'NumberTitle', 'off', ... 'MenuBar', 'none'); uicontrol('Style', 'text', ... 'Position', [50 150 300 30], ... 'String', '正在训练模型,请稍候...', ... 'FontSize', 12); progressBar = uicontrol('Style', 'text', ... 'Position', [50 100 300 20], ... 'String', '', ... 'BackgroundColor', [0.8 0.8 1]); % 在单独的函数中训练模型 try obj.net = obj.trainCustomModel(progressBar); save('customEmotionNet.mat', 'net'); msgbox('模型训练完成并已保存!', '训练成功'); catch ME errordlg(['训练错误: ' ME.message], '训练失败'); end close(trainFig); end function net = trainCustomModel(obj, progressBar) % 自定义模型训练函数 datasetPath = uigetdir(pwd, '选择表情数据集目录'); if datasetPath == 0 error('未选择数据集'); end imds = imageDatastore(datasetPath, ... 'IncludeSubfolders', true, ... 'LabelSource', 'foldernames'); % 检查类别数量 classes = categories(imds.Labels); if numel(classes) ~= 5 error('数据集必须包含5个类别: neutral, happy, smile, cry, sad'); end % 数据集分割 [trainImgs, valImgs] = splitEachLabel(imds, 0.7, 'randomized'); % 更新进度 set(progressBar, 'Position', [50 100 100 20], 'String', '数据加载完成'); pause(0.5); % 数据增强 augmenter = imageDataAugmenter(... 'RandXReflection', true, ... 'RandRotation', [-15 15], ... 'RandXScale', [0.8 1.2], ... 'RandYScale', [0.8 1.2]); % 使用RGB图像 (48x48x3) augTrainImgs = augmentedImageDatastore([48 48], trainImgs, ... 'DataAugmentation', augmenter, ... 'OutputSizeMode', 'resize'); augValImgs = augmentedImageDatastore([48 48], valImgs, ... 'OutputSizeMode', 'resize'); % 更新进度 set(progressBar, 'Position', [50 100 150 20], 'String', '数据预处理完成'); pause(0.5); % 构建自定义CNN模型 (支持RGB输入) layers = [ % 修改输入层为48x48x3以支持RGB图像 imageInputLayer([48 48 3], 'Name', 'input') convolution2dLayer(5, 32, 'Padding', 'same', 'Name', 'conv1') batchNormalizationLayer('Name', 'bn1') reluLayer('Name', 'relu1') maxPooling2dLayer(2, 'Stride', 2, 'Name', 'pool1') convolution2dLayer(3, 64, 'Padding', 'same', 'Name', 'conv2') batchNormalizationLayer('Name', 'bn2') reluLayer('Name', 'relu2') maxPooling2dLayer(2, 'Stride', 2, 'Name', 'pool2') convolution2dLayer(3, 128, 'Padding', 'same', 'Name', 'conv3') batchNormalizationLayer('Name', 'bn3') reluLayer('Name', 'relu3') maxPooling2dLayer(2, 'Stride', 2, 'Name', 'pool3') fullyConnectedLayer(256, 'Name', 'fc1') reluLayer('Name', 'relu4') dropoutLayer(0.5, 'Name', 'dropout1') fullyConnectedLayer(5, 'Name', 'fc2') % 5个输出类别 softmaxLayer('Name', 'softmax') classificationLayer('Name', 'classoutput') ]; % 训练选项 options = trainingOptions('adam', ... 'InitialLearnRate', 0.001, ... 'LearnRateSchedule', 'piecewise', ... 'LearnRateDropFactor', 0.5, ... 'LearnRateDropPeriod', 5, ... 'MaxEpochs', 20, ... 'MiniBatchSize', 64, ... 'Shuffle', 'every-epoch', ... 'ValidationData', augValImgs, ... 'ValidationFrequency', 50, ... 'Verbose', true, ... 'Plots', 'none', ... 'OutputFcn', @(info)obj.trainingProgress(info, progressBar)); % 更新进度 set(progressBar, 'Position', [50 100 200 20], 'String', '开始训练模型...'); drawnow; % 训练模型 net = trainNetwork(augTrainImgs, layers, options); end function trainingProgress(obj, info, progressBar) % 训练进度回调函数 if strcmp(info.State, 'iteration') % 计算整个训练过程的进度 progress = (info.Epoch - 1 + info.Iteration/info.NumIterations) / info.NumEpochs; set(progressBar, 'Position', [50 100 round(300*progress) 20], ... 'String', sprintf('训练进度: %.1f%%', progress*100)); drawnow; end end function showHelp(obj, ~, ~) % 显示帮助信息 helpText = { '面部表情识别系统使用指南' '1. 选择图片: 从文件系统加载图像进行识别' '2. 摄像头捕获: 使用摄像头拍摄照片进行识别' '3. 实时识别: 开启摄像头进行实时表情识别' '4. 训练模型: 使用自定义数据集训练新模型' '' '使用说明:' '- 首次使用需点击"训练模型"创建新模型' '- 训练完成后模型将保存为customEmotionNet.mat' '- 支持识别表情: 平静、大笑、微笑、哭泣、悲伤' '' '数据集要求:' '- 创建文件夹结构:' ' dataset/neutral' ' dataset/happy' ' dataset/smile' ' dataset/cry' ' dataset/sad' '- 每个子文件夹包含对应表情的图片' '- 图片格式支持JPG/PNG/BMP' '- 建议每个类别至少100张图片' '- 图像尺寸建议为48x48像素(系统会自动调整)' }; helpdlg(helpText, '系统帮助'); end function closeApp(obj, ~, ~) % 关闭应用程序 if obj.isCapturing obj.isCapturing = false; pause(0.5); end if ~isempty(obj.cam) clear obj.cam; end if ishandle(obj.fig) delete(obj.fig); end end end end保持训练图像与输入层一致matlab完整代码
06-11
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值