-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathImage_Processing_GUI.m
More file actions
3650 lines (3392 loc) · 215 KB
/
Copy pathImage_Processing_GUI.m
File metadata and controls
3650 lines (3392 loc) · 215 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
classdef Image_Processing_GUI < matlab.apps.AppBase
% 与应用程序组件对应的属性
properties (Access = public)
%基本组件
figure matlab.ui.Figure
Label_Name matlab.ui.control.Label %姓名
Label_Number matlab.ui.control.Label %学号
globalVar_LEN
globalVar_THETA
globalVar_PSF
globalVar_NCORR
globalVar_ICORR
globalVar_K
globalGau_VAR
globalGau_MEAN
globalDENSITY
global_SPEVAR
global_idealp_Fre
global_ideahp_Fre
global_ideabp_lFre
global_ideabp_hFre
global_ideabs_Fre
global_ideabs_w
global_butterOrder
global_butterlp_Fre
global_butterhp_Fre
global_butterbp_lFre
global_butterbp_hFre
global_butterbs_Fre
global_butterbs_w
global_gausslp_Fre
global_gausshp_Fre
global_gaussbp_lFre
global_gaussbp_hFre
global_gaussbs_Fre
global_gaussbs_w
global_wtThreshold
global_homeOrder %阶数
global_Fre %截止频率
global_hGain %高频增益
global_lGain %低频增益
global_MeanFilter %均值滤波领域大小
global_MedianFilter %中值滤波领域大小
%总变差滤波
global_lambda % 正则化参数,控制去噪程度
global_numIterations % 迭代次数
global_deltaT % 时间步长
global_nlmeansH %去噪强度
global_patchSize %块大小
global_searchWindowSize %搜索窗口大小
Label_PSNR matlab.ui.control.Label %峰值信噪比
Label_MSE matlab.ui.control.Label %均方误差
Label_SNR matlab.ui.control.Label %信噪比
Label_SSIM matlab.ui.control.Label %结构相似性指数
Label_qualityINFO matlab.ui.control.Label %参数说明
Label_QUALITY
uibuttongroup1 matlab.ui.container.ButtonGroup
%文件操作
reset matlab.ui.control.Button
save matlab.ui.control.Button
exit matlab.ui.control.Button
load matlab.ui.control.Button
uibuttongroup2 matlab.ui.container.ButtonGroup
%原始图像
orgimg matlab.ui.control.UIAxes
uibuttongroup3 matlab.ui.container.ButtonGroup
%效果预览图像
effimg matlab.ui.control.UIAxes
uibuttongroup8 matlab.ui.container.ButtonGroup
%频域滤波
p21 matlab.ui.control.Button %理想低通滤波
Label_idealp_Fre matlab.ui.control.Label % 低通截止频率
EditField_idealp_Fre matlab.ui.control.NumericEditField %低通截止频率
p22 matlab.ui.control.Button %理想高通滤波
Label_ideahp_Fre matlab.ui.control.Label % 高通截止频率
EditField_ideahp_Fre matlab.ui.control.NumericEditField %高通截止频率
p23 matlab.ui.control.Button %理想带通滤波
Label_ideabp_lFre matlab.ui.control.Label % 带通低频截止频率
EditField_ideabp_lFre matlab.ui.control.NumericEditField %带通低频截止频率
Label_ideabp_hFre matlab.ui.control.Label % 带通高频截止频率
EditField_ideabp_hFre matlab.ui.control.NumericEditField %带通高频截止频率
p24 matlab.ui.control.Button %理想带阻滤波
Label_ideabs_Fre matlab.ui.control.Label % 带通低频截止频率
EditField_ideabs_Fre matlab.ui.control.NumericEditField %带通低频截止频率
Label_ideabs_w matlab.ui.control.Label % 带通高频截止频率
EditField_ideabs_w matlab.ui.control.NumericEditField %带通高频截止频率
%巴特沃斯滤波器
Label_butterOrder matlab.ui.control.Label % 巴特沃斯滤波器阶数
EditField_butterOrder matlab.ui.control.NumericEditField %巴特沃斯滤波器阶数
p31 matlab.ui.control.Button %巴特沃斯低通
Label_butterlp_Fre matlab.ui.control.Label % 低通截止频率
EditField_butterlp_Fre matlab.ui.control.NumericEditField %低通截止频率
p32 matlab.ui.control.Button %巴特沃斯高通
Label_butterhp_Fre matlab.ui.control.Label % 高通截止频率
EditField_butterhp_Fre matlab.ui.control.NumericEditField %高通截止频率
p33 matlab.ui.control.Button %巴特沃斯带通
Label_butterbp_lFre matlab.ui.control.Label % 带通低频截止频率
EditField_butterbp_lFre matlab.ui.control.NumericEditField %带通低频截止频率
Label_butterbp_hFre matlab.ui.control.Label % 带通高频截止频率
EditField_butterbp_hFre matlab.ui.control.NumericEditField %带通高频截止频率
p34 matlab.ui.control.Button %巴特沃斯带通
Label_butterbs_Fre matlab.ui.control.Label % 带通低频截止频率
EditField_butterbs_Fre matlab.ui.control.NumericEditField %带通低频截止频率
Label_butterbs_w matlab.ui.control.Label % 带通高频截止频率
EditField_butterbs_w matlab.ui.control.NumericEditField %带通高频截止频率
f21 matlab.ui.control.Button %高斯低通滤波
Label_gausslp_Fre matlab.ui.control.Label % 低通截止频率
EditField_gausslp_Fre matlab.ui.control.NumericEditField %低通截止频率
f22 matlab.ui.control.Button %高斯高通滤波
Label_gausshp_Fre matlab.ui.control.Label % 高通截止频率
EditField_gausshp_Fre matlab.ui.control.NumericEditField %高通截止频率
f23 matlab.ui.control.Button %高斯带通滤波
Label_gaussbp_lFre matlab.ui.control.Label % 带通低频截止频率
EditField_gaussbp_lFre matlab.ui.control.NumericEditField %带通低频截止频率
Label_gaussbp_hFre matlab.ui.control.Label % 带通高频截止频率
EditField_gaussbp_hFre matlab.ui.control.NumericEditField %带通高频截止频率
f24 matlab.ui.control.Button %高斯带阻滤波
Label_gaussbs_Fre matlab.ui.control.Label % 带通截止频率
EditField_gaussbs_Fre matlab.ui.control.NumericEditField %带通截止频率
Label_gaussbs_w matlab.ui.control.Label % 阻带带宽
EditField_gaussbs_w matlab.ui.control.NumericEditField % 阻带带宽
p4 matlab.ui.control.Button %小波去噪
Label_wtThreshold matlab.ui.control.Label % 小波去噪阈值
EditField_wtThreshold matlab.ui.control.NumericEditField %小波去噪阈值
homefilter matlab.ui.container.ButtonGroup %同态滤波
p5 matlab.ui.control.Button %同态滤波
Label_homeOrder matlab.ui.control.Label % 同态滤波阶数
EditField_homeOrder matlab.ui.control.NumericEditField %同态滤波阶数
Label_Fre matlab.ui.control.Label % 同态滤波截止频率
EditField_Fre matlab.ui.control.NumericEditField %同态滤波截止频率
Label_hGain matlab.ui.control.Label %同态滤波高频增益
EditField_hGain matlab.ui.control.NumericEditField %同态滤波高频增益
Label_lGain matlab.ui.control.Label % 同态滤波低频增益
EditField_lGain matlab.ui.control.NumericEditField %同态滤波低频增益
uibuttongroup9 matlab.ui.container.ButtonGroup
%空间滤波器/去噪
p1 matlab.ui.control.Button %维纳滤波
Label_Avg matlab.ui.control.Label %均值滤波
Label_MeanFilter matlab.ui.control.Label % 均值滤波领域大小
EditField_MeanFilter matlab.ui.control.NumericEditField % 均值滤波领域大小
f1_1 matlab.ui.control.Button %均值滤波 replicate
f1_2 matlab.ui.control.Button %均值滤波 symmetric
f1_3 matlab.ui.control.Button %均值滤波 circular
f3 matlab.ui.control.Button %中值滤波
Label_MedianFilter matlab.ui.control.Label % 中值滤波领域大小
EditField_MedianFilter matlab.ui.control.NumericEditField % 中值滤波领域大小
f4 matlab.ui.control.Button %非局部均值去噪
Label_nlmeansH matlab.ui.control.Label%去噪强度
EditField_nlmeansH matlab.ui.control.NumericEditField
Label_patchSize matlab.ui.control.Label %块大小
EditField_patchSize matlab.ui.control.NumericEditField
Label_searchWindowSize matlab.ui.control.Label %搜索窗口大小
EditField_searchWindowSize matlab.ui.control.NumericEditField
f5 matlab.ui.control.Button %总变差去噪
Label_lambda matlab.ui.control.Label%去噪强度
EditField_lambda matlab.ui.control.NumericEditField
Label_numIterations matlab.ui.control.Label %块大小
EditField_numIterations matlab.ui.control.NumericEditField
Label_deltaT matlab.ui.control.Label %搜索窗口大小
EditField_deltaT matlab.ui.control.NumericEditField
Label_Wn matlab.ui.control.Label %维纳滤波提示
%添加噪波
uibuttongroup10 matlab.ui.container.ButtonGroup
n1 matlab.ui.control.Button %高斯噪声
Label_MEAN matlab.ui.control.Label %均值
Label_VAR matlab.ui.control.Label %方差
EditField_MEAN matlab.ui.control.NumericEditField %运动长度输入
EditField_VAR matlab.ui.control.NumericEditField %运动方向角输入
n2 matlab.ui.control.Button %泊松噪波
n3 matlab.ui.control.Button %椒盐噪声
Label_DENSITY matlab.ui.control.Label %噪声密度
EditField_DENSITY matlab.ui.control.NumericEditField %噪声密度
n4 matlab.ui.control.Button %斑点噪声
Label_SPEVAR matlab.ui.control.Label %斑点噪声方差
EditField_SPEVAR matlab.ui.control.NumericEditField %噪声密度
n5 matlab.ui.control.Button %运动噪波
Label_LEN matlab.ui.control.Label %运动长度
Label_THETA matlab.ui.control.Label %运动方向角
EditField_LEN matlab.ui.control.NumericEditField %运动长度输入
EditField_THETA matlab.ui.control.NumericEditField %运动方向角输入
uibuttongroup11 matlab.ui.container.ButtonGroup
%变换波形显示
g1 matlab.ui.control.UIAxes %图像RGB颜色分解
g2 matlab.ui.control.UIAxes %傅里叶变换
g3 matlab.ui.control.UIAxes %DCT变换
g4 matlab.ui.control.UIAxes %小波变换1
g5 matlab.ui.control.UIAxes %小波变换2
g6 matlab.ui.control.UIAxes %小波变换3
g7 matlab.ui.control.UIAxes %小波变换4
uibuttongroup12_1 matlab.ui.container.ButtonGroup %小波选择
Label matlab.ui.control.Label
Button1 matlab.ui.control.Button
Button2 matlab.ui.control.Button
Button3 matlab.ui.control.Button
Button4 matlab.ui.control.Button
Button5 matlab.ui.control.Button
Button6 matlab.ui.control.Button
Button7 matlab.ui.control.Button
end
%根据对图片施加的效果更新变换图像
methods (Access = private)
function update(app, handles) %更新图表
% 显示等待条
h = waitbar(0, '更新图像中 等待...');
steps = 30;
for step = 1:steps
waitbar(step / steps)
end
close(h)
mysize=size(handles.img); % 获取处理后的图像大小
if numel(mysize)>2
% 如果图像大小大于二维,则执行 updateColr 函数进行处理
updateColr(app, handles)
updateColr_FT(app, handles)
updateColr_DCT(app, handles)
else
% 否则执行 updateGray 函数进行处理
updateGray(app, handles)
updateGray_FT(app, handles)
updateGary_DCT(app, handles) %更新彩色图像彩色直方图
end
updateDWT(app, handles)
[quality_MSE,quality_SNR,quality_PSNR,quality_SSIM] = calculateQualityMetrics(app,handles.i,handles.img);
app.Label_SSIM.Text = ['SSIM: ', num2str(round(quality_SSIM, 3)), ' dB'];
app.Label_PSNR.Text = ['PSNR: ', num2str(round(quality_PSNR, 3)), ' dB'];
app.Label_SNR.Text = ['SNR: ', num2str(round(quality_SNR, 3)), ' dB'];
app.Label_MSE.Text = ['MSE: ', num2str(round(quality_MSE, 3)), ''];
end
function updateColr(app, handles) %更新彩色图像彩色直方图
set(handles.g1, 'Visible', 'on');
% 将图像数据重塑为一维数组
ImageData1 = mat2gray( handles.img(:,:,1) );
ImageData1 = reshape(ImageData1, [numel(ImageData1), 1]) * 255;
ImageData2 = mat2gray( handles.img(:,:,2) );
ImageData2 = reshape(ImageData2, [numel(ImageData2), 1]) * 255;
ImageData3 = mat2gray( handles.img(:,:,3) );
ImageData3 = reshape(ImageData3, [numel(ImageData3), 1]) * 255;
% 计算直方图
[H1, X1] = imhist(uint8(ImageData1), 256); % 指定横坐标范围为0~255
[H2, X2] = imhist(uint8(ImageData2), 256); % 指定横坐标范围为0~255
[H3, X3] = imhist(uint8(ImageData3), 256); % 指定横坐标范围为0~255
% 在g1示波器中绘制彩色直方图
axes(handles.g1);
cla;
hold on; % 保持绘图区域,以便绘制其他曲线
plot(X1, H1, 'R'); % 绘制红色通道直方图,颜色为红色
plot(X2, H2, 'G'); % 绘制绿色通道直方图,颜色为绿色
plot(X3, H3, 'B'); % 绘制蓝色通道直方图,颜色为蓝色
legend('R','G','B');
title('图像颜色直方图');
maxY = max([H1 H2 H3]);
maxY = max(maxY);
disp(maxY);
axis([0 255 0 maxY-1]); % 设置坐标轴范围,x轴范围为0到256,y轴范围根据直方图的最大值确定
hold off; % 结束绘图区域的保持状态
end
function updateGray(app, handles) %更新灰度直方图
set(handles.g1, 'Visible', 'on');
% 将滤波后的图像数据重塑为一维数组,并将像素值从[0, 1]映射到[0, 255]
ImageData = mat2gray(handles.img);
ImageData = reshape(ImageData, [numel(ImageData), 1]) * 255;
% 计算直方图
[H, X] = imhist(uint8(ImageData), 256); % 指定横坐标范围为0~255
% 在 g1 示波器中绘制灰色直方图
axes(handles.g1);
cla;
hold on;
bar(X, H, 'k');
legend('灰度');
title('图像灰度直方图');
axis([0 255 0 max(H)]);
hold off;
end
function updateColr_FT(app, handles) %更新彩色图像彩色直方图
set(handles.g2, 'Visible', 'on');
% 计算傅里叶变换
imgft = zeros(size(handles.img));
for i = 1:3 % 遍历每个颜色通道
channel = handles.img(:,:,i);
channel_ft = fft2(channel); % 傅里叶变换
imgft(:,:,i) = abs(fftshift(channel_ft)); % 将傅里叶变换的模进行象限转换并保存
end
% 将三个颜色通道的傅里叶变换结果合并或做其他处理
final_imgft = sum(imgft, 3); % 简单地将三个通道的结果相加
% 可视化傅里叶变换结果
imgftam = log(final_imgft + 1); % 将傅里叶变换结果的幅值映射到小的正数
axes(handles.g2);
cla;
imshow(imgftam, []); % 显示傅里叶变换结果图像,映射到[0,1]
title('彩色图像的傅里叶谱');
hold off;
end
function updateGray_FT(app, handles) %更新彩色图像彩色直方图
set(handles.g2, 'Visible', 'on');
% 计算灰度傅里叶变换
grayImg = handles.img;
% 计算傅里叶变换
imgft = fft2(grayImg); % 对灰度图像执行傅里叶变换
imgft = abs(fftshift(imgft)); % 将傅里叶变换的模进行象限转换并保存
% 可视化傅里叶变换结果
imgftam = log(imgft + 1); % 将傅里叶变换结果的幅值映射到小的正数
axes(handles.g2);
cla;
imshow(imgftam, []); % 显示傅里叶变换结果图像,映射到[0,1]
title('灰度图像的傅里叶谱');
hold off;
end
function updateColr_DCT(app, handles) %更新彩色图像彩色直方图
set(handles.g3, 'Visible', 'on');
% 对彩色图像进行DCT变换
dct_img = zeros(size(handles.img));
for i = 1:3 % 遍历每个颜色通道
channel = handles.img(:,:,i);
dct_channel = dct2(channel);
dct_img(:,:,i) = dct_channel;
end
dct_img = log(abs(dct_img));
axes(handles.g3);
cla;
imshow(dct_img, []);
title('彩色图像的DCT频谱');
hold off;
end
function updateGary_DCT(app, handles) %更新彩色图像彩色直方图
set(handles.g3, 'Visible', 'on');
% 对灰色图像进行DCT变换
grayImg = handles.img;
% 计算DCT变换
dctImg = dct2(grayImg);
% 可视化DCT变换结果
axes(handles.g3);
cla;
imshow(log(abs(dctImg) + 1), []); % 显示DCT变换结果的幅值,映射到[0,1]
title('灰度图像的DCT变换');
hold off;
end
function updateDWT(app, handles) %更新小波变换
set(handles.g4, 'Visible', 'on');
set(handles.g5, 'Visible', 'on');
set(handles.g6, 'Visible', 'on');
set(handles.g7, 'Visible', 'on');
% 计算小波变换
mysize=size(handles.img); % 获取处理后的图像大小
if numel(mysize)>2
grayimg = rgb2gray(handles.img);
else
grayimg = handles.img;
end
[grap_LLY, HL, LH, HH] = dwt2(grayimg, 'haar');
[LLY, HL, LH, HH] = dwt2(handles.img, 'haar');
%显示小波变换
set(handles.g4, 'Visible', 'on');
axes(handles.g4);
cla;
imshow(grap_LLY, []);
hold off;
title('小波变换(1.灰度低频近似值)');
set(handles.g5, 'Visible', 'on');
axes(handles.g5);
cla;
imshow(HL, []);
title('2.水平方向细节');
hold off;
set(handles.g6, 'Visible', 'on');
axes(handles.g6);
cla;
imshow(LH, []);
title('3.垂直方向细节');
hold off;
set(handles.g7, 'Visible', 'on');
axes(handles.g7);
cla;
imshow(HH, []);
title('4.对角线方向细节');
hold off;
end
% 定义计算图像质量评价指标的函数
function [quality_MSE,quality_SNR,quality_PSNR,quality_SSIM] = calculateQualityMetrics(app,originalImage, processedImage, metric)
% 将图像转为双精度类型
originalImage = double(originalImage);
processedImage = double(processedImage);
quality_PSNR = calculatePSNR(app,originalImage, processedImage);
quality_SSIM = calculateSSIM(app,originalImage, processedImage);
quality_MSE = calculateMSE(app,originalImage, processedImage);
quality_SNR = calculateSNR(app,originalImage, processedImage);
end
% 定义计算PSNR的函数
function quality_PSNR = calculatePSNR(app,originalImage, processedImage)
% 获取图像大小
[M, N, ~] = size(originalImage);
% 计算均方误差(MSE)
mse = sum(sum((originalImage - processedImage).^2)) / (M * N);
% 计算PSNR
A = 255; % 8比特精度图像的最大像素值
quality_PSNR = 10 * log10(A^2 / mse);
end
% 定义计算SSIM的函数
function quality_SSIM = calculateSSIM(app,originalImage, processedImage)
% 使用 MATLAB 内置的 ssim 函数计算 SSIM
quality_SSIM = ssim(processedImage,originalImage);
end
% 定义计算MSE的函数
function quality_MSE = calculateMSE(app,originalImage, processedImage)
% 获取图像大小
[M, N, ~] = size(originalImage);
% 计算均方误差(MSE)
quality_MSE = sum(sum((originalImage - processedImage).^2)) / (M * N);
end
% 定义计算 SNR 的函数
function quality_SNR = calculateSNR(app,originalImage, processedImage)
% 计算信号强度
signal = sum(sum(originalImage.^2));
% 计算噪声强度
noise = sum(sum((originalImage - processedImage).^2));
% 计算 SNR
quality_SNR = 10 * log10(signal / noise);
end
end
% 句柄控件控制的回调函数
methods (Access = private)
% 组件创建后执行的代码
function Image_processing_GUI_OpeningFcn(app, varargin)
% Create GUIDE-style callback args - Added by Migration Tool
[hObject, eventdata, handles] = convertToGUIDECallbackArguments(app); %#ok<ASGLU>
% 选择 Image_processing_GUI 的默认命令行输出
handles.output = hObject;
% 禁用一些按钮和控件
set(handles.load,'Enable','on');
set(handles.save,'Enable','off');
set(handles.exit,'Enable','off');
set(handles.reset,'Enable','off');
set(handles.effimg,'Visible','off');
set(handles.orgimg,'Visible','off');
set(handles.g1,'Visible','off');
set(handles.g2,'Visible','off');
set(handles.g3,'Visible','off');
set(handles.g4,'Visible','off');
set(handles.g5,'Visible','off');
set(handles.g6,'Visible','off');
set(handles.g7,'Visible','off');
set(handles.n1,'Enable','off');
set(handles.n2,'Enable','off');
set(handles.n3,'Enable','off');
set(handles.n4,'Enable','off');
set(handles.f1_1,'Enable','off');
set(handles.f1_2,'Enable','off');
set(handles.f1_3,'Enable','off');
set(handles.f21,'Enable','off');
set(handles.f22,'Enable','off');
set(handles.f23,'Enable','off');
set(handles.f24,'Enable','off');
set(handles.f3,'Enable','off');
set(handles.f4,'Enable','off');
set(handles.f5,'Enable','off');
set(handles.p1,'Enable','off');
set(handles.p21,'Enable','off');
set(handles.p22,'Enable','off');
set(handles.p23,'Enable','off');
set(handles.p24,'Enable','off');
set(handles.p31,'Enable','off');
set(handles.p32,'Enable','off');
set(handles.p33,'Enable','off');
set(handles.p34,'Enable','off');
set(handles.p4,'Enable','off');
set(handles.p5,'Enable','off');
set(handles.uibuttongroup12_1,'visible','off');
set(handles.Button1,'Enable','off');
set(handles.Button2,'Enable','off');
set(handles.Button3,'Enable','off');
set(handles.Button4,'Enable','off');
set(handles.Button5,'Enable','off');
set(handles.Button6,'Enable','off');
set(handles.Button7,'Enable','off');
set(handles.n5,'Enable','off');
% 更新 handles 结构
guidata(hObject, handles);
end
% 加载
function load_Callback(app, event)
% Create GUIDE-style callback args - Added by Migration Tool
[hObject, eventdata, handles] = convertToGUIDECallbackArguments(app, event); %#ok<ASGLU>
% 打开文件选择对话框
[file, path] = uigetfile({'*.jpg;*.bmp;*.jpeg;*.png', '图片文件 (*.jpg,*.bmp,*.jpeg,*.png)'}, '打开文件');
image = [path file];
handles.file = image;
% 如果用户取消选择文件,弹出警告对话框
if (file == 0)
warndlg('您没有选择图片。') ;
return;
end
% 获取文件扩展名
[fpath, fname, fext] = fileparts(file);
validex = {'.bmp', '.jpg', '.jpeg', '.png'};
found = 0;
% 检查文件扩展名是否合法
for x = 1:length(validex)
if (strcmpi(fext, validex{x}))
found = 1;
% 启用一些按钮和控件
set(handles.save, 'Enable', 'on');
set(handles.exit, 'Enable', 'on');
set(handles.reset, 'Enable', 'on');
set(handles.effimg, 'Visible', 'on');
set(handles.orgimg, 'Visible', 'on');
set(handles.n1, 'Enable', 'on');
set(handles.n2, 'Enable', 'on');
set(handles.n3, 'Enable', 'on');
set(handles.n4, 'Enable', 'on');
set(handles.f1_1,'Enable','on');
set(handles.f1_2,'Enable','on');
set(handles.f1_3,'Enable','on');
set(handles.f21, 'Enable', 'on');
set(handles.f22, 'Enable', 'on');
set(handles.f23, 'Enable', 'on');
set(handles.f24, 'Enable', 'on');
set(handles.f3, 'Enable', 'on');
set(handles.f4, 'Enable', 'on');
set(handles.f5, 'Enable', 'on');
set(handles.p21,'Enable','on');
set(handles.p22,'Enable','on');
set(handles.p23,'Enable','on');
set(handles.p24,'Enable','on');
set(handles.p31,'Enable','on');
set(handles.p32,'Enable','on');
set(handles.p33,'Enable','on');
set(handles.p34,'Enable','on');
set(handles.p4, 'Enable', 'on');
set(handles.p5, 'Enable', 'on');
set(handles.Button1,'Enable','on');
set(handles.Button2,'Enable','on');
set(handles.Button3,'Enable','on');
set(handles.Button4,'Enable','on');
set(handles.Button5,'Enable','on');
set(handles.Button6,'Enable','on');
set(handles.Button7,'Enable','on');
set(handles.n5,'Enable','on');
% 读取图像数据
handles.img = imread(image); %handles.img载入图像数据
handles.i = imread(image); %原图数据
% assignin('base', 'myVariable2', handles.img);
% 显示图像在effimg和orgimg中
axes(handles.orgimg); % 设置orgimg为当前绘图区域
cla; % 清空当前绘图区域
imshow(handles.img); % 在orgimg绘图区域显示图像数据
axes(handles.effimg); % 设置effimg为当前绘图区域
cla; % 清空当前绘图区域
imshow(handles.img); % 在effimg绘图区域显示图像数据
% 更新 handles 结构
guidata(hObject, handles);
% 关闭等待条
hWaitbar = waitbar(0, '等待......', 'CreateCancelBtn', 'delete(gcbf)');
set(hWaitbar, 'Color', [0.9, 0.9, 0.9]);
steps = 3;
waitbar(1 / steps);
waitbar(2 / steps);
waitbar(3 / steps);
%关闭进度条
close(hWaitbar);
update(app, handles);
hWaitbar = waitbar(0, '等待......', 'CreateCancelBtn', 'delete(gcbf)');
set(hWaitbar, 'Color', [0.9, 0.9, 0.9]);
steps = 10;
for waiting = 1 : 10
waitbar(waiting / steps);
end
close(hWaitbar);
set(handles.uibuttongroup12_1,'visible','on');
app.globalVar_LEN = 10;
app.globalVar_THETA = 20;
app.globalGau_MEAN = 0;
app.globalGau_VAR = 0.05;
app.globalDENSITY = 0.1;
app.global_SPEVAR = 0.04;
%理想滤波器
app.global_idealp_Fre = 60;
app.global_ideahp_Fre = 30;
app.global_ideabp_lFre = 20;
app.global_ideabp_hFre = 80;
app.global_ideabs_Fre = 50;
app.global_ideabs_w = 30;
%巴特沃斯滤波器
app.global_butterOrder = 6;
app.global_butterlp_Fre = 60;
app.global_butterhp_Fre = 30;
app.global_butterbp_lFre = 20;
app.global_butterbp_hFre = 80;
app.global_butterbs_Fre = 50;
app.global_butterbs_w = 30;
%高斯滤波器
app.global_gausslp_Fre = 60;
app.global_gausshp_Fre = 30;
app.global_gaussbp_lFre = 20;
app.global_gaussbp_hFre = 80;
app.global_gaussbs_Fre = 50;
app.global_gaussbs_w = 30;
%小波去噪
app.global_wtThreshold = 0.5;
%同态滤波
app.global_homeOrder = 1;
app.global_Fre = 5;
app.global_hGain = 1.1;
app.global_lGain = 0.1;
%均值滤波领域大小
app.global_MeanFilter = 6;
%中值滤波领域大小
app.global_MedianFilter = 3;
%总变差滤波
app.global_lambda = 0.1; % 正则化参数,控制去噪程度
app.global_numIterations = 30; % 迭代次数
app.global_deltaT = 0.1; % 时间步长
app.global_nlmeansH = 2; %去噪强度
app.global_patchSize = 5; %块大小
app.global_searchWindowSize = 10; %搜索窗口大小
% 更新 handles 结构
guidata(hObject, handles);
break;
end
end
% 如果文件扩展名不合法,弹出错误对话框
if (found == 0)
errordlg('文件扩展名不正确,请从可用扩展名[.jpg、.jpeg、.bmp、.png]中选择文件','Image Format Error');
end
end
% 退出
function exit_Callback(app, event)
% Create GUIDE-style callback args - Added by Migration Tool
[hObject, eventdata, handles] = convertToGUIDECallbackArguments(app, event); %#ok<ASGLU>
% 关闭所有图形窗口
close all;
end
% 恢复原图
function reset_Callback(app, event)
% Create GUIDE-style callback args - Added by Migration Tool
[hObject, eventdata, handles] = convertToGUIDECallbackArguments(app, event); %#ok<ASGLU>
% 将图像恢复为初始状态
handles.img = handles.i;
% 在effimg中显示图像
axes(handles.effimg);
cla;
imshow(handles.img);
% 更新
update(app, handles);
% 更新 handles 结构
guidata(hObject,handles);
end
% 保存图像
function save_Callback(app, event)
% Create GUIDE-style callback args - Added by Migration Tool
[hObject, eventdata, handles] = convertToGUIDECallbackArguments(app, event); %#ok<ASGLU>
% 弹出文件保存对话框
[file, path] = uiputfile('*.jpg', 'Save Image as');
% 拼接保存路径和文件名
save = [path file];
try
% 将图像保存为 JPG 格式
imwrite(handles.img, save, 'jpg');
catch
warndlg('您没有填写保存图片名称。') ;
return;
end
end
% f1_1 : 均值滤波 replicate
function f1_1_Callback(app, event)
% 定义一个名为 f1_1_Callback 的函数,其输入参数为 app、event 和 neighborhood_size
% 创建 GUIDE 风格的回调函数参数(由迁移工具添加)
[hObject, eventdata, handles] = convertToGUIDECallbackArguments(app, event); %#ok<ASGLU>
% 显示等待条
h = waitbar(0, '等待...');
steps = 200;
for step = 1:steps
waitbar(step / steps)
end
close(h)
mean_size = [app.global_MeanFilter, app.global_MeanFilter];
% 使用 convertToGUIDECallbackArguments 函数将 app 和 event 转换为 GUIDE 回调函数所需的参数,并将其存储在 hObject、eventdata 和 handles 变量中
h = fspecial('average', mean_size);
% 创建一个指定大小的平均滤波器模板
handles.img = imfilter(handles.img, h, 'replicate');
% 使用平均滤波器对图像进行滤波处理
axes(handles.effimg);
cla;
imshow(handles.img)
% 将当前坐标轴更改为 handles.effimg 所代表的坐标轴,清空坐标轴并显示处理后的图像
% 更新 handles 结构
guidata(hObject, handles);
% 显示等待条
h = waitbar(0, '更新图像中 等待...');
steps = 200;
for step = 1:steps
waitbar(step / steps)
end
close(h)
% 更新函数
update(app, handles);
end
% f1_2 : 均值滤波 symmetric
function f1_2_Callback(app, event)
% 创建 GUIDE 风格的回调函数参数(由迁移工具添加)
[hObject, eventdata, handles] = convertToGUIDECallbackArguments(app, event); %#ok<ASGLU>
% 显示等待条
h = waitbar(0, '等待...');
steps = 200;
for step = 1:steps
waitbar(step / steps)
end
close(h)
mean_size = [app.global_MeanFilter, app.global_MeanFilter];
% 使用 convertToGUIDECallbackArguments 函数将 app 和 event 转换为 GUIDE 回调函数所需的参数,并将其存储在 hObject、eventdata 和 handles 变量中
h = fspecial('average', mean_size);
% 创建一个平均滤波器模板
handles.img=imfilter(handles.img,h,'symmetric');
% 使用平均滤波器对图像进行滤波处理
axes(handles.effimg);
cla;
imshow(handles.img)
% 将当前坐标轴更改为 handles.effimg 所代表的坐标轴,清空坐标轴并显示处理后的图像
% 更新 handles 结构
guidata(hObject, handles);
% 显示等待条
h = waitbar(0, '更新图像中 等待...');
steps = 200;
for step = 1:steps
waitbar(step / steps)
end
close(h)
% 更新函数
update(app,handles);
end
% f1_3 : 均值滤波 circular
function f1_3_Callback(app, event)
% 创建 GUIDE 风格的回调函数参数(由迁移工具添加)
[hObject, eventdata, handles] = convertToGUIDECallbackArguments(app, event); %#ok<ASGLU>
% 显示等待条
h = waitbar(0, '等待...');
steps = 200;
for step = 1:steps
waitbar(step / steps)
end
close(h)
mean_size = [app.global_MeanFilter, app.global_MeanFilter];
% 使用 convertToGUIDECallbackArguments 函数将 app 和 event 转换为 GUIDE 回调函数所需的参数,并将其存储在 hObject、eventdata 和 handles 变量中
h = fspecial('average', mean_size);
% 创建一个平均滤波器模板
handles.img=imfilter(handles.img,h,'circular');
% 使用平均滤波器对图像进行滤波处理
axes(handles.effimg);
cla;
imshow(handles.img)
% 将当前坐标轴更改为 handles.effimg 所代表的坐标轴,清空坐标轴并显示处理后的图像
% 更新 handles 结构
guidata(hObject, handles);
% 显示等待条
h = waitbar(0, '更新图像中 等待...');
steps = 200;
for step = 1:steps
waitbar(step / steps)
end
close(h)
% 更新函数
update(app,handles);
end
% Value changed function: EditField_MeanFilterChanged
function EditField_MeanFilterChanged(app, event)
app.global_MeanFilter = app.EditField_MeanFilter.Value;
end
% f3 中值滤波
function f3_Callback(app, event)
% 定义一个名为 f3_Callback 的函数,其输入参数为 app 和 event
% 创建 GUIDE 风格的回调函数参数(由迁移工具添加)
[hObject, eventdata, handles] = convertToGUIDECallbackArguments(app, event); %#ok<ASGLU>
% 显示等待条
h = waitbar(0, '等待...');
steps = 200;
for step = 1:steps
waitbar(step / steps)
end
close(h)
median_size = [app.global_MedianFilter, app.global_MedianFilter];
% 使用 convertToGUIDECallbackArguments 函数将 app 和 event 转换为 GUIDE 回调函数所需的参数,并将其存储在 hObject、eventdata 和 handles 变量中
mysize=size(handles.img); % 获取处理后的图像大小
if numel(mysize)>2
r=medfilt2(handles.img(:,:,1), median_size);
% 对图像的红色通道进行中值滤波处理
g=medfilt2(handles.img(:,:,2), median_size);
% 对图像的绿色通道进行中值滤波处理
b=medfilt2(handles.img(:,:,3), median_size);
% 对图像的蓝色通道进行中值滤波处理
handles.img=cat(3,r,g,b);
else
gray=medfilt2(handles.img(:,:,1), median_size);
handles.img=cat(1, gray);
end
% 将三个滤波处理后的通道重新组合成图像
axes(handles.effimg);
% 将当前坐标轴更改为 handles.effimg 所代表的坐标轴
cla; imshow(handles.img);
% 清空坐标轴并显示处理后的图像
guidata(hObject,handles);
% 更新应用程序数据,将 handles 变量保存到 app 中
% 更新 handles 结构
guidata(hObject, handles);
% 显示等待条
h = waitbar(0, '更新图像中 等待...');
steps = 200;
for step = 1:steps
waitbar(step / steps)
end
close(h)
% 更新函数
update(app,handles);
end
% Value changed function: EditField_MedianFilterChanged
function EditField_MedianFilterChanged(app, event)
app.global_MedianFilter = app.EditField_MedianFilter.Value;
end
%非局部均值去噪
function f4_Callback(app, event)
% 从输入参数中获取对象句柄和其他信息
[hObject, eventdata, handles] = convertToGUIDECallbackArguments(app, event); %#ok<ASGLU>
% 显示等待条
h_waitbar = waitbar(0, '等待... 正在计算,非局部均值去噪计算时间较长,请耐心等待。');
steps = 200;
for step = 0:100
waitbar(step / steps)
end
% 获取图像及相关参数
img = handles.img; % 获取图像
%I:含噪声图像
%ds:邻域窗口半径
%Ds:搜索窗口半径
%h:高斯函数平滑参数
%DenoisedImg:去噪图像
h = app.global_nlmeansH; % 获取非局部均值去噪参数h
ds = app.global_patchSize; % 获取像素块大小参数
Ds = app.global_searchWindowSize; % 获取搜索窗口大小参数
I=double(img);
[m,n]=size(I);
DenoisedImg=zeros(m,n);
PaddedImg = padarray(I,[ds,ds],'symmetric','both');
kernel=ones(2*ds+1,2*ds+1);
kernel=kernel./((2*ds+1)*(2*ds+1));
h2=h*h;
for i=1:m
for j=1:n
i1=i+ds;
j1=j+ds;
W1=PaddedImg(i1-ds:i1+ds,j1-ds:j1+ds);%邻域窗口1
wmax=0;
average=0;
sweight=0;
%%搜索窗口
rmin = max(i1-Ds,ds+1);
rmax = min(i1+Ds,m+ds);
smin = max(j1-Ds,ds+1);
smax = min(j1+Ds,n+ds);
for r=rmin:rmax
for s=smin:smax
if(r==i1&&s==j1)
continue;
end
W2=PaddedImg(r-ds:r+ds,s-ds:s+ds);%邻域窗口2
Dist2=sum(sum(kernel.*(W1-W2).*(W1-W2)));%邻域间距离
w=exp(-Dist2/h2);
if(w>wmax)
wmax=w;
end
sweight=sweight+w;
average=average+w*PaddedImg(r,s);
end
end
average=average+wmax*PaddedImg(i1,j1);%自身取最大权值
sweight=sweight+wmax;
DenoisedImg(i,j)=average/sweight;
end
end
for step = 100:200
waitbar(step / steps)
end
close(h_waitbar)
% 更新图像句柄中的图像数据
handles.img = DenoisedImg;
assignin('base', 'myVariable2', handles.img);
% 在图像窗口中显示处理后的图像
axes(handles.effimg);
cla;
imshow(handles.img,[]);
% 更新图像句柄
guidata(hObject, handles);
% 更新应用程序
update(app,handles);
end
% Value changed function: EditField_lambdaChanged
function EditField_nlmeansHChanged(app, event)
app.global_nlmeansH = app.EditField_nlmeansH.Value;
end
% Value changed function: EditField_numIterationsChanged
function EditField_patchSizeChanged(app, event)
app.global_patchSize = app.EditField_patchSize.Value;
end
% Value changed function: EditField_deltaTChanged
function EditField_searchWindowSizeChanged(app, event)
app.global_searchWindowSize = app.EditField_searchWindowSize.Value;
end
%总变差去噪
function f5_Callback(app, event)
% 创建 GUIDE 风格的回调函数参数
[hObject, eventdata, handles] = convertToGUIDECallbackArguments(app, event); %#ok<ASGLU>
% 显示等待条
h = waitbar(0, '等待...');
steps = 200;
for step = 1:steps
waitbar(step / steps)
end
close(h)
% 获取处理后的图像大小
mysize = size(handles.img);
if numel(mysize) > 2
% 对图像的三个通道分别进行总变差去噪处理
r = total_variation_denoising(app, handles.img(:,:,1)); % 对红色通道进行总变差去噪处理
g = total_variation_denoising(app, handles.img(:,:,2)); % 对绿色通道进行总变差去噪处理
b = total_variation_denoising(app, handles.img(:,:,3)); % 对蓝色通道进行总变差去噪处理
handles.img = cat(3, r, g, b);
else
% 对灰度图像进行总变差去噪处理
gray = total_variation_denoising(app, handles.img(:,:,1));
handles.img = cat(1, gray);
end
% 将处理后的图像显示在坐标轴上