-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.xml
1554 lines (746 loc) · 524 KB
/
search.xml
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
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>暑期的归家惊喜</title>
<link href="/2024/08/26/surprise-go-home/"/>
<url>/2024/08/26/surprise-go-home/</url>
<content type="html"><![CDATA[<p> 一时的心血来潮,萌生了回家一趟的想法。四个月没回家了,还挺想回家看看的。<br> 火车硬卧十几个小时,虽然包括了一个可以闭着眼睛度过的夜晚,但却比我想象中难熬,因为我在喧闹的环境下根本睡不踏实。车厢连接处不间断的叮叮当当,到站下车的旅客拖着行李从昏暗的走廊穿行,窗外时不时传来狂风暴雨般的巨响,但神奇的是火车停站时周遭又会突然变得很安静。走廊熄灯后还好些,否则还要忍受不知从何处传来的二手烟🚬,烟味混杂在空气里,强行混入我的呼吸。耳边偶尔传来列车员播报的“列车内禁止吸烟”,属实有些讽刺。<br> 半夜一点多醒来以后我便不困了,躺在床上有点热也有点渴,索性坐起来。意识清醒一些以后,我才发现外面根本没有狂风暴雨,聒噪的呼呼声来自头顶的中央空调。我无事可干,打开电脑填了会社会实践的表,又找插座给手机充了会电。凌晨三点困意袭来,再去睡会儿。<br> 说起来这车厢的温度,也是起伏不定,入睡前冷,半夜又热,清晨又开始冷,冷得我恨不得没有一寸皮肤露在外面。早上六点多车厢内陆陆续续有人开始活动了,察觉到旁边有人想拉开窗帘,我就起床了。说是起床,也只是坐起身来,从昨天上车到现在还没有洗漱,有些难受。回家以后一定要马上洗个澡!<br> 这是我第一次瞒着家人悄悄回家,直到坐上绿皮火车后,我都无法想象他们发现我突然回家时会是什么样的场景。之前总是顾及这顾及那,不是路途遥远,就是工作繁忙,这次终于勇敢了一次,我想向那个总是畏畏缩缩的自己证明,杭州到聊城的距离并没有那么远。<br> 随着火车逐渐靠近聊城,我脑海中与家人在一起的回忆愈发鲜活,想象中相见时的画面愈发清晰。我望向窗外的大片玉米地,不禁弯了嘴角。师弟说的对,人只会为自己没能去做的事情后悔。回家,我永远不会后悔。<br> 我原本计划下火车后坐公交回家,但把一个秘密瞒了那么久,我愈发渴望和别人倾诉,我思来想去,觉得我弟弟是个不错的人选。<br> 我问他,你认不认识聊城火车站。<br> 他发我一张百度地图的导航截图,说认识。<br> 我说,我十点二十到火车站,你给电车充上电,到时候来接我,不要告诉其他人。<br> 他说好,出发前还问我穿的厚不,聊城的天气有点冷。<br> 我出站后在路边等他时,看着路边来往的出租车和公交车,我一点也不心动,因为我在等我的家人。我弟弟果然如我妈所说,大夏天练体育晒得全身黝黑,不过依旧很帅气。<br> 从火车站骑电动车到我家需要四十多分钟的车程,我们边走边聊,十一点半电车电量告急时我们正好到家门口。我试了几次指纹解锁都失败了,索性用人脸识别。“用户08欢迎回家”,虽然这个编号不常出现,但我猜爷爷奶奶肯定还意识不到是我回来了。<br> 我打开门,奶奶正拿着手机准备给我爸爸打电话,询问我弟弟去哪里了,怎么还不回家吃饭。看到是我回来了,奶奶的表情又是震惊又是开心,说做梦也想不到是我回家了。奶奶说她上午打了几个喷嚏,心想是谁想她了,没想到中午我就回家了。我说,当然是我想你啦。<br> 爷爷从厨房闻声出来,刚把炒好的丝瓜端出来,就招呼奶奶再去给我煮一碗面条。我连忙说不用那么麻烦,可爷爷奶奶坚持“起脚扁食落脚面”。<br> 奶奶煮面条时还问我,怎么昨天下午不在电话里说。<br> 我说,这不是给你个惊喜嘛。<br> 奶奶回想了一下我们昨天的通话,说怪不得你问家里有什么菜,还跟我说想吃我包的韭菜包子。<br> 我本来想等爸爸妈妈下班回家以后给他们一个惊喜,没想到我家监控检测到有人经过就会“滴”一声,然后给手机发通知,而我妈白天又习惯性看家里的监控,自然发现了一些猫腻。<br> 我妈给我弟弟打电话,你带回家的那个女孩是谁?<br> 我弟,你自己看监控没看到是谁吗?<br> 我妈,我在监控里看不清。<br> 我弟,你妮儿。<br> 就这样,我妈受到了我回家的消息的第一次冲击,我弟弟说是我,她从监控里看着沙发上的书包也像是我的,但她还是不敢相信。在午饭后我奶奶带着我和我弟弟去菜园里割韭菜时,我妈又向我爷爷打电话确认了一遍,我妈才相信我回家了。她给我打了几个视频,我没接到,我随手拍了一张我们在菜地的照片发了过去。晚上我才知道,我爸也受到了我妈妈的电话轰炸,一看手机,四个未接电话。<br> 下午洗完澡一觉睡到五点,家里的床真舒服。<br> 虽然没有当面看见爸爸妈妈的表情,但我想应该是很开心的吧。爸爸妈妈还小小担心了一下是不是我像大学那样在学校受欺负了,但晚上回家看到我好好的就打消了这个疑虑。爸爸妈妈提前知道我回家的好处就是,晚上下班后会给我买很多好吃的!妈妈买了猪蹄和焖子,爸爸买了烤鸭,爷爷奶奶烙了韭菜盒子,又是“简简单单”的一餐。<br> 晚上和妈妈一起去姥娘家玩,在路上的时候妈妈提前打了个电话,问我姥娘睡觉了没有,她快走到楼下了。<br> 我问妈妈,你怎么不跟我姥娘说我也来。<br> 妈妈说,给你姥娘一个惊喜。<br> 我心想,我妈学的还挺快。<br> 第二天妈妈请了一天假在家陪我,上午带我去换断掉的手链,添了些钱买了个新的(此处感谢爸爸的红包助力!)。<br> 中午回到家发现大娘、嫂子还有小朋友们都在爷爷奶奶家,在一起包韭菜包子,嘿嘿˙ᗜ˙,我小侄子知道我是他姑姑了!<br> 下午我和弟弟去看了电影,沈腾不演喜剧确实有点看不习惯。<br> 晚上一大家人去饭店聚餐,之前爷爷奶奶过生日总是去饭店吃好吃的,我总是在学校都赶不上,这次我爸也带我奢侈了一次,开心开心!吃饭的时候不禁感叹,山东人的酒桌文化是耳濡目染的,倒酒、敬酒碰杯,要从娃娃抓起。<br> 没想到流水账式的记录竟然写了两千多字,在家一天半时间虽短却非常充实。不同于在学校,两眼一睁就是赶校车,在实验室每天就是训鼠、收集数据和分析数据,有时觉得自己跟人机一样,快进化为没有感情的工作机器了。<br> 偶尔回家放松放松,和家人在一起,总是幸福的🥰。 </p>]]></content>
<categories>
<category> 生活随笔 </category>
</categories>
</entry>
<entry>
<title>Matlab调用Pytorch模型</title>
<link href="/2024/07/24/matlab-run-pytorch-model/"/>
<url>/2024/07/24/matlab-run-pytorch-model/</url>
<content type="html"><![CDATA[<h1 id="环境配置"><a href="#环境配置" class="headerlink" title="环境配置"></a>环境配置</h1><ol><li>查看matlab与python的版本对应关系 <a href="https://ww2.mathworks.cn/support/requirements/python-compatibility.html">Versions of Python Compatible with MATLAB Products by Release</a><br>我用的是matlab_r2021a,支持python3.8。</li><li>找到python解释器的位置<br>我之前把pytorch装在了虚拟环境dl中,所以要找到这个虚拟环境下python解释器的位置。<figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">conda activate dl</span><br><span class="line">where python</span><br><span class="line">/Users/wenxin/opt/anaconda3/envs/dl/bin/python</span><br></pre></td></tr></table></figure></li><li>将matlab中的python版本设置为指定路径的python解释器<figure class="highlight matlab"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">>> pyenv(<span class="string">'Version'</span>, <span class="string">'/Users/wenxin/opt/anaconda3/envs/dl/bin/python'</span>)</span><br><span class="line">>> pyversion</span><br><span class="line"></span><br><span class="line"> version: <span class="string">'3.8'</span></span><br><span class="line"> executable: <span class="string">'/Users/wenxin/opt/anaconda3/envs/dl/bin/python'</span></span><br><span class="line"> library: <span class="string">'/Users/wenxin/opt/anaconda3/envs/dl/lib/libpython3.8.dylib'</span></span><br><span class="line"> home: <span class="string">'/Users/wenxin/opt/anaconda3/envs/dl'</span></span><br><span class="line"> isloaded: <span class="number">0</span></span><br></pre></td></tr></table></figure></li></ol><h1 id="Python端"><a href="#Python端" class="headerlink" title="Python端"></a>Python端</h1><h2 id="simple-model-py"><a href="#simple-model-py" class="headerlink" title="simple_model.py"></a>simple_model.py</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 神经网络模型</span></span><br><span class="line"><span class="keyword">import</span> torch</span><br><span class="line"><span class="keyword">from</span> torch <span class="keyword">import</span> nn</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">SimpleModel</span>(nn.Module):</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line"> <span class="built_in">super</span>(SimpleModel, self).__init__()</span><br><span class="line"> self.linear = nn.Linear(<span class="number">10</span>, <span class="number">1</span>)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">forward</span>(<span class="params">self, x</span>):</span><br><span class="line"> <span class="keyword">return</span> self.linear(x)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 将状态字典保存为.pth文件(只保存模型的权重和偏置,而不保存模型结构)</span></span><br><span class="line"><span class="comment"># model = SimpleModel()</span></span><br><span class="line"><span class="comment"># torch.save(model.state_dict(), 'Code/simple_model.pth')</span></span><br></pre></td></tr></table></figure><h2 id="inference-py"><a href="#inference-py" class="headerlink" title="inference.py"></a>inference.py</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 网络预测部分</span></span><br><span class="line"><span class="keyword">import</span> torch</span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">from</span> simple_model <span class="keyword">import</span> SimpleModel</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">prediction</span>(<span class="params">params_path, data</span>):</span><br><span class="line"> model = SimpleModel()</span><br><span class="line"> model.load_state_dict(torch.load(params_path, map_location=torch.device(<span class="string">'cpu'</span>)))</span><br><span class="line"> model.<span class="built_in">eval</span>() <span class="comment"># 将模型设置为评估模式</span></span><br><span class="line"> data = torch.tensor(data, dtype=torch.float32)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">with</span> torch.no_grad():</span><br><span class="line"> pred = model(data)</span><br><span class="line"> <span class="keyword">return</span> pred.numpy()</span><br></pre></td></tr></table></figure><h1 id="Matlab端"><a href="#Matlab端" class="headerlink" title="Matlab端"></a>Matlab端</h1><h2 id="test-simple-model-m"><a href="#test-simple-model-m" class="headerlink" title="test_simple_model.m"></a>test_simple_model.m</h2><figure class="highlight matlab"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">in_data = <span class="built_in">ones</span>(<span class="number">1</span>, <span class="number">10</span>) * <span class="number">0.6</span>;</span><br><span class="line">pred = matpy(<span class="string">'simple_model.pth'</span>, in_data);</span><br><span class="line"><span class="built_in">disp</span>(pred);</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">pred</span> = <span class="title">matpy</span><span class="params">(params_path, data)</span></span></span><br><span class="line"> model = py.importlib.import_module(<span class="string">'inference'</span>);</span><br><span class="line"> pred = model.prediction(pyargs(<span class="string">'params_path'</span>, params_path, <span class="string">'data'</span>, data));</span><br><span class="line"> pred = double(pred);</span><br><span class="line"><span class="keyword">end</span></span><br></pre></td></tr></table></figure><h1 id="参考文章"><a href="#参考文章" class="headerlink" title="参考文章"></a>参考文章</h1><ul><li><a href="https://zhuanlan.zhihu.com/p/536858806">MATLAB调用Pytorch神经网络模型进行预测</a></li><li><a href="https://ww2.mathworks.cn/help/matlab/matlab_external/create-object-from-python-class.html">从MATLAB访问Python模块-快速入门</a></li><li><a href="https://blog.csdn.net/chlet/article/details/130422820">深入理解Pytorch中模型保存文件pth</a></li></ul>]]></content>
<categories>
<category> 项目实战 </category>
</categories>
<tags>
<tag> Python </tag>
<tag> Matlab </tag>
</tags>
</entry>
<entry>
<title>解决键盘Win+L无法锁屏</title>
<link href="/2024/01/25/win-l-invalid/"/>
<url>/2024/01/25/win-l-invalid/</url>
<content type="html"><![CDATA[<p>这两天按键盘上的Win+L键突然不能锁屏了,隐约记得之前也遇到过类似的问题,但之前没有记录下来。这次又遇到了,找到解决方案后马上记录!</p><h2 id="解决方法"><a href="#解决方法" class="headerlink" title="解决方法"></a>解决方法</h2><p>第一步:按下Ctrl+Esc键(Win键的组合键),看看是否好用,如果是好的情况,那么大概率是Win键被锁住了。</p><p>第二步:按下Fn+Win键,解开Win键,此时Win+L已经可以使用了。</p><h2 id="参考文章"><a href="#参考文章" class="headerlink" title="参考文章"></a>参考文章</h2><ul><li><a href="https://blog.csdn.net/weixin_43947456/article/details/107952943">解决Windows键+L不能锁屏的问题</a></li></ul>]]></content>
<categories>
<category> 方法教程 </category>
</categories>
</entry>
<entry>
<title>小鼠脑图谱——脑区定位</title>
<link href="/2024/01/17/mice-brain-atlas/"/>
<url>/2024/01/17/mice-brain-atlas/</url>
<content type="html"><![CDATA[<h1 id="小鼠脑立体定位图谱"><a href="#小鼠脑立体定位图谱" class="headerlink" title="小鼠脑立体定位图谱"></a>小鼠脑立体定位图谱</h1><div class="row"> <embed src="https://img.cwxhmk.top/pdf/mice_brain_atlas_v4.pdf" width="100%" height="550" type="application/pdf"></div><h1 id="小鼠脑立体定位图谱网页版"><a href="#小鼠脑立体定位图谱网页版" class="headerlink" title="小鼠脑立体定位图谱网页版"></a>小鼠脑立体定位图谱网页版</h1><p>之前就听说有一个网站,输入脑立体定位坐标(ML、AP、DV)后就可以看位点在图谱中的位置,今天偶然在丁香园社区中看到了一个帖子,分享的正是我想找的网站。不过需要注意实验小鼠的体重尽量与图谱保持一致(26~30g)。</p><ul><li><a href="http://labs.gaidi.ca/mouse-brain-atlas/">小鼠脑图谱</a></li><li><a href="http://labs.gaidi.ca/rat-brain-atlas/">大鼠脑图谱</a></li></ul><p>网页中会用红点🔴标识位点在冠状面和矢状面的位置。以lOFC为例,输入(2.6, 1.3, -2.2),即可得到位点所在冠状面和矢状面(此处我没有保存带位点的图片)。注意日常习惯的坐标顺序是(AP, ML, DV),但是网站中坐标顺序是ML在前,输入时务必注意。<br><img src="http://labs.gaidi.ca/mouse-brain-atlas/images/Mouse_Brain_Atlas_8.jpg"><br><img src="http://labs.gaidi.ca/mouse-brain-atlas/images/Mouse_Brain_Atlas_111.jpg"></p><h1 id="参考文章"><a href="#参考文章" class="headerlink" title="参考文章"></a>参考文章</h1><ul><li><a href="https://www.dxy.cn/bbs/newweb/pc/post/43382059">小鼠和大鼠的大脑立体定位图谱</a></li></ul>]]></content>
<categories>
<category> 方法教程 </category>
</categories>
<tags>
<tag> 脑图谱 </tag>
</tags>
</entry>
<entry>
<title>使用matlab向串口收发数据</title>
<link href="/2024/01/12/matlab-serialport/"/>
<url>/2024/01/12/matlab-serialport/</url>
<content type="html"><![CDATA[<p>我想获取到行为端的数据,以及控制TFT屏幕显示不同的内容。之前只是简单地使用过arduino ide的串口调试器,将刺激呈现的时间戳发送给串口。昨天看到一篇<a href="https://zhuanlan.zhihu.com/p/379766979">教程</a>,提及matlab可以接收串口数据,经查阅,也可以向串口发送数据,这样一来就可以在matlab中直接获取串口内的时间戳,也可以通过串口给arduino发送控制信息。</p><h1 id="matlab端"><a href="#matlab端" class="headerlink" title="matlab端"></a>matlab端</h1><figure class="highlight matlab"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">s = serialport(<span class="string">'COM7'</span>, <span class="number">9600</span>);</span><br><span class="line"><span class="keyword">while</span> <span class="number">1</span></span><br><span class="line"> write(s, trial_types(randi(<span class="built_in">size</span>(trial_types,<span class="number">2</span>))), <span class="string">"string"</span>); <span class="comment">% 向串口写数据</span></span><br><span class="line"> str = readline(s); <span class="comment">% 从串口读数据</span></span><br><span class="line"> <span class="built_in">disp</span>(strtrim(str));</span><br><span class="line"><span class="keyword">end</span></span><br></pre></td></tr></table></figure><h1 id="arduino端"><a href="#arduino端" class="headerlink" title="arduino端"></a>arduino端</h1><figure class="highlight arduino"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">setup</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="built_in">Serial</span>.<span class="built_in">begin</span>(<span class="number">9600</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">String</span> <span class="title">readLine</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="type">String</span> str = <span class="string">""</span>;</span><br><span class="line"> <span class="keyword">while</span>(<span class="built_in">Serial</span>.<span class="built_in">available</span>()){</span><br><span class="line"> str += <span class="built_in">char</span>(<span class="built_in">Serial</span>.<span class="built_in">read</span>());</span><br><span class="line"> <span class="built_in">delay</span>(<span class="number">2</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> str;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">loop</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="type">String</span> str = <span class="built_in">readLine</span>();</span><br><span class="line"> <span class="keyword">if</span> (str.<span class="built_in">length</span>() != <span class="number">0</span>){</span><br><span class="line"> <span class="built_in">Serial</span>.<span class="built_in">println</span>(<span class="string">"Arduino: "</span> + str);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h1 id="补充"><a href="#补充" class="headerlink" title="补充"></a>补充</h1><ol><li>端口号可以在设备管理器的端口中查看</li><li>使用matlab向串口发送数据有一定的延时,最好的解决方案是放在while循环中</li></ol><h1 id="参考文章"><a href="#参考文章" class="headerlink" title="参考文章"></a>参考文章</h1><ul><li><a href="http://www.zlmcu.com/document/com_debug_tools.html">串口调试助手</a></li><li><a href="https://zhuanlan.zhihu.com/p/379766979">9天学会Arduino系列- 3 串口的数据传送</a></li><li><a href="https://www.bilibili.com/video/BV1at4y187yf">python与arduino通信教程</a></li></ul>]]></content>
<categories>
<category> 方法教程 </category>
</categories>
<tags>
<tag> arduino </tag>
</tags>
</entry>
<entry>
<title>【arduino探索】点亮ST7789 1.3寸TFT屏幕</title>
<link href="/2024/01/09/arduino-tft/"/>
<url>/2024/01/09/arduino-tft/</url>
<content type="html"><![CDATA[<h1 id="Adafruit-GFX-Library"><a href="#Adafruit-GFX-Library" class="headerlink" title="Adafruit-GFX-Library"></a>Adafruit-GFX-Library</h1><p>该类库为所有彩色屏幕的基础类库,安装方式:在Arduino的项目-加载库-库管理器中搜索Adafruit GFX Library,选择最新版本进行安装。<a href="https://github.com/adafruit/Adafruit-GFX-Library">Github下载地址</a><br>Arduino中的第三方库的存放地址可以在首选项-项目文件夹位置处查看,该路径下的libraries文件夹下即为第三方库的存放地址。</p><h1 id="Arduino-ST7789-Library"><a href="#Arduino-ST7789-Library" class="headerlink" title="Arduino-ST7789-Library"></a>Arduino-ST7789-Library</h1><p>该类库为ST7789的专用驱动库。<a href="https://github.com/lspoplove/Arduino-ST7789-Library">Github下载地址</a><br>运行画直线的程序,用时约32.6s,太慢了,每次黑屏都要等半天!</p><figure class="highlight arduino"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><Adafruit_GFX.h></span> <span class="comment">// Core graphics library by Adafruit</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><Arduino_ST7789.h></span> <span class="comment">// Hardware-specific library for ST7789 (with or without CS pin)</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><SPI.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> TFT_DC 8</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> TFT_RST 7 <span class="comment">//9 </span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> TFT_CS 9 <span class="comment">//10 // only for displays with CS pin</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> TFT_MOSI 11 <span class="comment">// for hardware SPI data pin (all of available pins)</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> TFT_SCLK 13 <span class="comment">// for hardware SPI sclk pin (all of available pins)</span></span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> w 240</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> h 240</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">Arduino_ST7789 tft = <span class="built_in">Arduino_ST7789</span>(TFT_DC, TFT_RST, TFT_MOSI, TFT_SCLK, TFT_CS); <span class="comment">//for display with CS pin</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">static</span> <span class="keyword">inline</span> <span class="type">uint32_t</span> <span class="title">micros_start</span><span class="params">()</span> __<span class="title">attribute__</span><span class="params">((always_inline))</span></span>;</span><br><span class="line"><span class="function"><span class="type">static</span> <span class="keyword">inline</span> <span class="type">uint32_t</span> <span class="title">micros_start</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="type">uint8_t</span> oms = <span class="built_in">millis</span>();</span><br><span class="line"> <span class="keyword">while</span> ((<span class="type">uint8_t</span>)<span class="built_in">millis</span>() == oms)</span><br><span class="line"> ;</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">micros</span>();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">setup</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="built_in">Serial</span>.<span class="built_in">begin</span>(<span class="number">9600</span>);</span><br><span class="line"> tft.<span class="built_in">init</span>(w, h);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">loop</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="type">uint32_t</span> start = <span class="built_in">micros_start</span>();</span><br><span class="line"></span><br><span class="line"> tft.<span class="built_in">fillScreen</span>(BLACK);</span><br><span class="line"> <span class="built_in">testLines</span>();</span><br><span class="line"> </span><br><span class="line"> <span class="type">uint32_t</span> usecLines = <span class="built_in">micros</span>() - start;</span><br><span class="line"> tft.<span class="built_in">setCursor</span>(<span class="number">0</span>, <span class="number">20</span>);</span><br><span class="line"> tft.<span class="built_in">setTextSize</span>(<span class="number">3</span>);</span><br><span class="line"> tft.<span class="built_in">setTextColor</span>(RED);</span><br><span class="line"> tft.<span class="built_in">println</span>(<span class="string">"Cost Time:"</span>);</span><br><span class="line"></span><br><span class="line"> tft.<span class="built_in">setCursor</span>(<span class="number">0</span>, <span class="number">50</span>);</span><br><span class="line"> tft.<span class="built_in">setTextSize</span>(<span class="number">4</span>);</span><br><span class="line"> tft.<span class="built_in">setTextColor</span>(RED);</span><br><span class="line"> tft.<span class="built_in">println</span>(usecLines);</span><br><span class="line"></span><br><span class="line"> <span class="built_in">delay</span>(<span class="number">60</span> * <span class="number">1000L</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int32_t</span> <span class="title">testLines</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="type">uint32_t</span> start;</span><br><span class="line"> <span class="type">int32_t</span> x1, y1, x2, y2;</span><br><span class="line"></span><br><span class="line"> start = <span class="built_in">micros_start</span>();</span><br><span class="line"></span><br><span class="line"> x1 = y1 = <span class="number">0</span>;</span><br><span class="line"> y2 = h - <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span> (x2 = <span class="number">0</span>; x2 < w; x2 += <span class="number">6</span>)</span><br><span class="line"> {</span><br><span class="line"> tft.<span class="built_in">drawLine</span>(x1, y1, x2, y2, BLUE);</span><br><span class="line"> }</span><br><span class="line"><span class="meta">#<span class="keyword">ifdef</span> ESP8266</span></span><br><span class="line"> <span class="built_in">yield</span>(); <span class="comment">// avoid long run triggered ESP8266 WDT restart</span></span><br><span class="line"><span class="meta">#<span class="keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"> x2 = w - <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span> (y2 = <span class="number">0</span>; y2 < h; y2 += <span class="number">6</span>)</span><br><span class="line"> {</span><br><span class="line"> tft.<span class="built_in">drawLine</span>(x1, y1, x2, y2, BLUE);</span><br><span class="line"> }</span><br><span class="line"><span class="meta">#<span class="keyword">ifdef</span> ESP8266</span></span><br><span class="line"> <span class="built_in">yield</span>(); <span class="comment">// avoid long run triggered ESP8266 WDT restart</span></span><br><span class="line"><span class="meta">#<span class="keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"> x1 = w - <span class="number">1</span>;</span><br><span class="line"> y1 = <span class="number">0</span>;</span><br><span class="line"> y2 = h - <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span> (x2 = <span class="number">0</span>; x2 < w; x2 += <span class="number">6</span>)</span><br><span class="line"> {</span><br><span class="line"> tft.<span class="built_in">drawLine</span>(x1, y1, x2, y2, BLUE);</span><br><span class="line"> }</span><br><span class="line"><span class="meta">#<span class="keyword">ifdef</span> ESP8266</span></span><br><span class="line"> <span class="built_in">yield</span>(); <span class="comment">// avoid long run triggered ESP8266 WDT restart</span></span><br><span class="line"><span class="meta">#<span class="keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"> x2 = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (y2 = <span class="number">0</span>; y2 < h; y2 += <span class="number">6</span>)</span><br><span class="line"> {</span><br><span class="line"> tft.<span class="built_in">drawLine</span>(x1, y1, x2, y2, BLUE);</span><br><span class="line"> }</span><br><span class="line"><span class="meta">#<span class="keyword">ifdef</span> ESP8266</span></span><br><span class="line"> <span class="built_in">yield</span>(); <span class="comment">// avoid long run triggered ESP8266 WDT restart</span></span><br><span class="line"><span class="meta">#<span class="keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"> x1 = <span class="number">0</span>;</span><br><span class="line"> y1 = h - <span class="number">1</span>;</span><br><span class="line"> y2 = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (x2 = <span class="number">0</span>; x2 < w; x2 += <span class="number">6</span>)</span><br><span class="line"> {</span><br><span class="line"> tft.<span class="built_in">drawLine</span>(x1, y1, x2, y2, BLUE);</span><br><span class="line"> }</span><br><span class="line"><span class="meta">#<span class="keyword">ifdef</span> ESP8266</span></span><br><span class="line"> <span class="built_in">yield</span>(); <span class="comment">// avoid long run triggered ESP8266 WDT restart</span></span><br><span class="line"><span class="meta">#<span class="keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"> x2 = w - <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span> (y2 = <span class="number">0</span>; y2 < h; y2 += <span class="number">6</span>)</span><br><span class="line"> {</span><br><span class="line"> tft.<span class="built_in">drawLine</span>(x1, y1, x2, y2, BLUE);</span><br><span class="line"> }</span><br><span class="line"><span class="meta">#<span class="keyword">ifdef</span> ESP8266</span></span><br><span class="line"> <span class="built_in">yield</span>(); <span class="comment">// avoid long run triggered ESP8266 WDT restart</span></span><br><span class="line"><span class="meta">#<span class="keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"> x1 = w - <span class="number">1</span>;</span><br><span class="line"> y1 = h - <span class="number">1</span>;</span><br><span class="line"> y2 = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (x2 = <span class="number">0</span>; x2 < w; x2 += <span class="number">6</span>)</span><br><span class="line"> {</span><br><span class="line"> tft.<span class="built_in">drawLine</span>(x1, y1, x2, y2, BLUE);</span><br><span class="line"> }</span><br><span class="line"><span class="meta">#<span class="keyword">ifdef</span> ESP8266</span></span><br><span class="line"> <span class="built_in">yield</span>(); <span class="comment">// avoid long run triggered ESP8266 WDT restart</span></span><br><span class="line"><span class="meta">#<span class="keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"> x2 = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (y2 = <span class="number">0</span>; y2 < h; y2 += <span class="number">6</span>)</span><br><span class="line"> {</span><br><span class="line"> tft.<span class="built_in">drawLine</span>(x1, y1, x2, y2, BLUE);</span><br><span class="line"> }</span><br><span class="line"><span class="meta">#<span class="keyword">ifdef</span> ESP8266</span></span><br><span class="line"> <span class="built_in">yield</span>(); <span class="comment">// avoid long run triggered ESP8266 WDT restart</span></span><br><span class="line"><span class="meta">#<span class="keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">micros</span>() - start;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h1 id="Arduino-GFX"><a href="#Arduino-GFX" class="headerlink" title="Arduino_GFX"></a>Arduino_GFX</h1><p>安装方式:在Arduino的项目-加载库-库管理器中搜索GFX Library For Arduino,选择最新版本进行安装。<a href="https://github.com/moononournation/Arduino_GFX">Github下载地址</a><br>运行画直线的程序,用时约5.7s,速度超级快!在测试Arduino_GFX的时候还发生了一个小插曲,我连线明明是正确的,但屏幕没有任何反应,排了很久的bug,最后发现是我的arduino开发板有问题,果然太便宜了容易出问题,以后还是用正版的arduino开发板吧!</p><figure class="highlight arduino"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><Arduino_GFX_Library.h></span></span></span><br><span class="line"><span class="type">int32_t</span> w, h;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* More dev device declaration: https://github.com/moononournation/Arduino_GFX/wiki/Dev-Device-Declaration */</span></span><br><span class="line"><span class="meta">#<span class="keyword">if</span> defined(DISPLAY_DEV_KIT)</span></span><br><span class="line">Arduino_GFX *gfx = <span class="built_in">create_default_Arduino_GFX</span>();</span><br><span class="line"><span class="meta">#<span class="keyword">else</span> <span class="comment">/* !defined(DISPLAY_DEV_KIT) */</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* More data bus class: https://github.com/moononournation/Arduino_GFX/wiki/Data-Bus-Class */</span></span><br><span class="line">Arduino_DataBus *bus = <span class="built_in">create_default_Arduino_DataBus</span>();</span><br><span class="line"></span><br><span class="line"><span class="comment">/* More display class: https://github.com/moononournation/Arduino_GFX/wiki/Display-Class */</span></span><br><span class="line">Arduino_GFX *gfx = <span class="keyword">new</span> <span class="built_in">Arduino_ST7789</span>(bus, DF_GFX_RST, <span class="number">0</span> <span class="comment">/* rotation */</span>, <span class="literal">true</span> <span class="comment">/* IPS */</span>);</span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">endif</span> <span class="comment">/* !defined(DISPLAY_DEV_KIT) */</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">static</span> <span class="keyword">inline</span> <span class="type">uint32_t</span> <span class="title">micros_start</span><span class="params">()</span> __<span class="title">attribute__</span><span class="params">((always_inline))</span></span>;</span><br><span class="line"><span class="function"><span class="type">static</span> <span class="keyword">inline</span> <span class="type">uint32_t</span> <span class="title">micros_start</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="type">uint8_t</span> oms = <span class="built_in">millis</span>();</span><br><span class="line"> <span class="keyword">while</span> ((<span class="type">uint8_t</span>)<span class="built_in">millis</span>() == oms)</span><br><span class="line"> ;</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">micros</span>();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">setup</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="built_in">Serial</span>.<span class="built_in">begin</span>(<span class="number">9600</span>);</span><br><span class="line"> gfx-><span class="built_in">begin</span>();</span><br><span class="line"> w = gfx-><span class="built_in">width</span>();</span><br><span class="line"> h = gfx-><span class="built_in">height</span>();</span><br><span class="line"></span><br><span class="line"> <span class="meta">#<span class="keyword">ifdef</span> DF_GFX_BL</span></span><br><span class="line"> <span class="built_in">pinMode</span>(DF_GFX_BL, <span class="literal">OUTPUT</span>);</span><br><span class="line"> <span class="built_in">digitalWrite</span>(DF_GFX_BL, <span class="literal">HIGH</span>);</span><br><span class="line"> <span class="meta">#<span class="keyword">endif</span></span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">loop</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="type">uint32_t</span> start = <span class="built_in">micros_start</span>();</span><br><span class="line"></span><br><span class="line"> gfx-><span class="built_in">fillScreen</span>(BLACK);</span><br><span class="line"> <span class="built_in">testLines</span>();</span><br><span class="line"> </span><br><span class="line"> <span class="type">uint32_t</span> usecLines = <span class="built_in">micros</span>() - start;</span><br><span class="line"></span><br><span class="line"> gfx-><span class="built_in">setCursor</span>(<span class="number">0</span>, <span class="number">20</span>);</span><br><span class="line"> gfx-><span class="built_in">setTextSize</span>(<span class="number">3</span>);</span><br><span class="line"> gfx-><span class="built_in">setTextColor</span>(RED);</span><br><span class="line"> gfx-><span class="built_in">println</span>(<span class="built_in">F</span>(<span class="string">"Cost Time:"</span>));</span><br><span class="line"></span><br><span class="line"> gfx-><span class="built_in">setCursor</span>(<span class="number">0</span>, <span class="number">50</span>);</span><br><span class="line"> gfx-><span class="built_in">setTextSize</span>(<span class="number">4</span>);</span><br><span class="line"> gfx-><span class="built_in">setTextColor</span>(RED);</span><br><span class="line"> gfx-><span class="built_in">println</span>(usecLines);</span><br><span class="line"></span><br><span class="line"> <span class="built_in">delay</span>(<span class="number">60</span> * <span class="number">1000L</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int32_t</span> <span class="title">testLines</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="type">uint32_t</span> start;</span><br><span class="line"> <span class="type">int32_t</span> x1, y1, x2, y2;</span><br><span class="line"></span><br><span class="line"> start = <span class="built_in">micros_start</span>();</span><br><span class="line"></span><br><span class="line"> x1 = y1 = <span class="number">0</span>;</span><br><span class="line"> y2 = h - <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span> (x2 = <span class="number">0</span>; x2 < w; x2 += <span class="number">6</span>)</span><br><span class="line"> {</span><br><span class="line"> gfx-><span class="built_in">drawLine</span>(x1, y1, x2, y2, BLUE);</span><br><span class="line"> }</span><br><span class="line"><span class="meta">#<span class="keyword">ifdef</span> ESP8266</span></span><br><span class="line"> <span class="built_in">yield</span>(); <span class="comment">// avoid long run triggered ESP8266 WDT restart</span></span><br><span class="line"><span class="meta">#<span class="keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"> x2 = w - <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span> (y2 = <span class="number">0</span>; y2 < h; y2 += <span class="number">6</span>)</span><br><span class="line"> {</span><br><span class="line"> gfx-><span class="built_in">drawLine</span>(x1, y1, x2, y2, BLUE);</span><br><span class="line"> }</span><br><span class="line"><span class="meta">#<span class="keyword">ifdef</span> ESP8266</span></span><br><span class="line"> <span class="built_in">yield</span>(); <span class="comment">// avoid long run triggered ESP8266 WDT restart</span></span><br><span class="line"><span class="meta">#<span class="keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"> x1 = w - <span class="number">1</span>;</span><br><span class="line"> y1 = <span class="number">0</span>;</span><br><span class="line"> y2 = h - <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span> (x2 = <span class="number">0</span>; x2 < w; x2 += <span class="number">6</span>)</span><br><span class="line"> {</span><br><span class="line"> gfx-><span class="built_in">drawLine</span>(x1, y1, x2, y2, BLUE);</span><br><span class="line"> }</span><br><span class="line"><span class="meta">#<span class="keyword">ifdef</span> ESP8266</span></span><br><span class="line"> <span class="built_in">yield</span>(); <span class="comment">// avoid long run triggered ESP8266 WDT restart</span></span><br><span class="line"><span class="meta">#<span class="keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"> x2 = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (y2 = <span class="number">0</span>; y2 < h; y2 += <span class="number">6</span>)</span><br><span class="line"> {</span><br><span class="line"> gfx-><span class="built_in">drawLine</span>(x1, y1, x2, y2, BLUE);</span><br><span class="line"> }</span><br><span class="line"><span class="meta">#<span class="keyword">ifdef</span> ESP8266</span></span><br><span class="line"> <span class="built_in">yield</span>(); <span class="comment">// avoid long run triggered ESP8266 WDT restart</span></span><br><span class="line"><span class="meta">#<span class="keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"> x1 = <span class="number">0</span>;</span><br><span class="line"> y1 = h - <span class="number">1</span>;</span><br><span class="line"> y2 = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (x2 = <span class="number">0</span>; x2 < w; x2 += <span class="number">6</span>)</span><br><span class="line"> {</span><br><span class="line"> gfx-><span class="built_in">drawLine</span>(x1, y1, x2, y2, BLUE);</span><br><span class="line"> }</span><br><span class="line"><span class="meta">#<span class="keyword">ifdef</span> ESP8266</span></span><br><span class="line"> <span class="built_in">yield</span>(); <span class="comment">// avoid long run triggered ESP8266 WDT restart</span></span><br><span class="line"><span class="meta">#<span class="keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"> x2 = w - <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span> (y2 = <span class="number">0</span>; y2 < h; y2 += <span class="number">6</span>)</span><br><span class="line"> {</span><br><span class="line"> gfx-><span class="built_in">drawLine</span>(x1, y1, x2, y2, BLUE);</span><br><span class="line"> }</span><br><span class="line"><span class="meta">#<span class="keyword">ifdef</span> ESP8266</span></span><br><span class="line"> <span class="built_in">yield</span>(); <span class="comment">// avoid long run triggered ESP8266 WDT restart</span></span><br><span class="line"><span class="meta">#<span class="keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"> x1 = w - <span class="number">1</span>;</span><br><span class="line"> y1 = h - <span class="number">1</span>;</span><br><span class="line"> y2 = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (x2 = <span class="number">0</span>; x2 < w; x2 += <span class="number">6</span>)</span><br><span class="line"> {</span><br><span class="line"> gfx-><span class="built_in">drawLine</span>(x1, y1, x2, y2, BLUE);</span><br><span class="line"> }</span><br><span class="line"><span class="meta">#<span class="keyword">ifdef</span> ESP8266</span></span><br><span class="line"> <span class="built_in">yield</span>(); <span class="comment">// avoid long run triggered ESP8266 WDT restart</span></span><br><span class="line"><span class="meta">#<span class="keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"> x2 = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (y2 = <span class="number">0</span>; y2 < h; y2 += <span class="number">6</span>)</span><br><span class="line"> {</span><br><span class="line"> gfx-><span class="built_in">drawLine</span>(x1, y1, x2, y2, BLUE);</span><br><span class="line"> }</span><br><span class="line"><span class="meta">#<span class="keyword">ifdef</span> ESP8266</span></span><br><span class="line"> <span class="built_in">yield</span>(); <span class="comment">// avoid long run triggered ESP8266 WDT restart</span></span><br><span class="line"><span class="meta">#<span class="keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">micros</span>() - start;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h1 id="TFT-eSPI"><a href="#TFT-eSPI" class="headerlink" title="TFT_eSPI"></a>TFT_eSPI</h1><p>在Arduino的库管理器中搜索TFT_eSPI,安装最新版本。<a href="https://github.com/Bodmer/TFT_eSPI">Github下载地址</a>经测试,这个库太大了,arduino uno开发板无法成功上传。</p><h1 id="参考内容"><a href="#参考内容" class="headerlink" title="参考内容"></a>参考内容</h1><ul><li><a href="https://blog.csdn.net/yulusilian1/article/details/118422711">Arduino ST7789 240*240 1.3寸 TFT —— 新屏点亮篇</a></li><li><a href="https://simple-circuit.com/arduino-st7789-ips-tft-display-example/">Interfacing Arduino with ST7789 TFT Display – Graphics Test Example</a></li><li><a href="https://blog.csdn.net/yulusilian1/article/details/118444105">Arduino ST7789 240*240 1.3寸 TFT —— 飞升之高效率显示驱动篇</a></li><li><a href="https://zhuanlan.zhihu.com/p/141616278">ESP32彩屏显示入门:我要五彩斑斓的黑 | ESP32学习之旅-Arduino版</a></li></ul>]]></content>
<categories>
<category> 方法教程 </category>
</categories>
<tags>
<tag> arduino </tag>
</tags>
</entry>
<entry>
<title>Github Desktop同步代码</title>
<link href="/2024/01/05/github-desktop/"/>
<url>/2024/01/05/github-desktop/</url>
<content type="html"><![CDATA[<p>Github Desktop主要有三个添加仓库的选项:</p><ol><li>Clone a Repository</li><li>Create a new Repository</li><li>Add Existing/Local Repository</li></ol><p>如果想把github远程仓库的代码克隆到本地,选择<code>Clone a Repository</code>,即可把远程仓库下载到指定的本地路径。</p><p>如果想创建新的仓库,选择<code>Create a new Repository</code>。</p><p>如果想把本地文件夹作为新的仓库上传到github,选择<code>Add Local Repository</code>。</p><p>如果本地改动了仓库中的代码,点击<code>Commit to main</code>,然后<code>Push origin</code>,即将新的代码推送到github上。<code>Fetching origin</code>是把github上的代码拉到本地。</p><div class="note warning flat"><ul><li>不要轻易同意删除本地仓库!!!警惕带<code>local</code>的选项!如果不小心删除了,尝试去回收站找回。</li><li>大部分情况下,创建仓库时选择<code>Keep this code private</code>。</li><li>不要一次性上传很多文件,也不要反复<code>push</code>代码,撤销<code>push</code>操作可能会误删本地代码!</li><li>同步重要数据时提前把数据复制到别的地方,做好备份,给自己留个后路!</li></ul></div>]]></content>
<categories>
<category> 方法教程 </category>
</categories>
<tags>
<tag> Github Desktop </tag>
</tags>
</entry>
<entry>
<title>下载教育版origin</title>
<link href="/2024/01/04/install-origin/"/>
<url>/2024/01/04/install-origin/</url>
<content type="html"><![CDATA[<p>之前在联想电脑上安装过origin,今天想在mac的虚拟机上也安一个origin,结果发现我不记得怎么下载了,也不记得之前是从哪里找到的正版安装途径,今天在搜索过程中竟然连官网都找错了,索性记录一下安装过程。</p><p>进入<a href="https://www.originlab.com/">origin官网</a>,点击顶部的<code>Try Origin for Free</code>,选择<code>I have NEVER used Origin</code>和<code>Student</code>,点击继续,即可看到如下的界面。<br><img src="https://img.cwxhmk.top/post/origin_install_1.jpg"></p><p>选择<code>Learning Edition</code>,填写姓名、学校、邮箱等信息。填写完提交后去教育邮箱中验证,即可收到软件的下载链接、序列号和密钥。<br><img src="https://img.cwxhmk.top/post/origin_install_2.jpg"></p><div class="note warning flat"><p>用同一个教育邮箱申请账号的话,得到的密钥是同一个,如果已经激活过origin软件,就不能在别的电脑上安装origin时使用了。┭┮﹏┭┮</p></div>]]></content>
<categories>
<category> 方法教程 </category>
</categories>
<tags>
<tag> 软件安装 </tag>
</tags>
</entry>
<entry>
<title>在网页中实时显示当前时间</title>
<link href="/2024/01/01/html-show-current-time/"/>
<url>/2024/01/01/html-show-current-time/</url>
<content type="html"><![CDATA[<p>早上吃完早饭去浙大图书馆主馆逛了一圈,终于见识到了传说中的自习区域墨水屏幕,确实很高级,如果这个座位被人预约了,屏幕上会显示预约人的姓名和预约时间!之前的基础图书馆里面很少有计算机相关的书籍,没想到新开的主馆里弥补了这个缺憾。</p><p>我上午看了一本arduino编程相关的书籍,对蓝牙和wifi模块很感兴趣,书中对这两个模块的使用只是举了一个很简单的例子,连接的都是arduino开发板的串口收发口,可以实现手机与arduino串口监视器的通信。</p><p>书中最后举了一个智能温室大棚的例子,我一直不太理解怎么实现手机远程控制arduino端的传感器。中午请教了一下康康,梳理了一下大致流程:arduino板连接wifi模块,接入校园网,向服务器发送传感器数据,可以存入txt文件或数据库中,手机或网页端通过服务器获取到传感器的数据,可以每隔1s请求一次数据。</p><div class="note info flat"><p>上位机:指可以<code>直接发送操作指令</code>的计算机或单片机,一般提供用户操作交互界面并向用户展示反馈数据。</p><p>下位机:指直接与机器相连接的计算机或单片机,一般用于<code>接收和反馈上位机的指令</code>,并且<code>根据指令控制机器执行动作</code>以及<code>从机器传感器读取数据</code>。</p><p>上位机给下位机发送控制命令,下位机收到此命令并执行相应的动作。<br>上位机给下位机发送状态获取命令,下位机收到此命令后调用传感器测量,然后转为数字信息反馈给上位机。<br>下位机主动发送状态信息或报警信息给上位机。</p></div><p>我一直困惑间隔1s请求一次数据,是否会在网页上看到数据刷新时的闪烁,为了解决这个困惑,康康建议我写个简单的网页测试一下,每个1s获取一下当前的时间。经实践测试,人眼并不会看到数据刷新时的闪烁。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><!DOCTYPE html></span><br><span class="line"><html lang="en"></span><br><span class="line"><head></span><br><span class="line"> <meta charset="UTF-8"></span><br><span class="line"> <meta name="viewport" content="width=device-width, initial-scale=1.0"></span><br><span class="line"> <title>Document</title></span><br><span class="line"> <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script></span><br><span class="line"></span><br><span class="line"></head></span><br><span class="line"><body></span><br><span class="line"> <div id="time-now"></span><br><span class="line"></span><br><span class="line"> </div></span><br><span class="line"> <script></span><br><span class="line"> setInterval(function (){</span><br><span class="line"> $('#time-now').text(new Date())</span><br><span class="line"> }, 1000)</span><br><span class="line"> </script></span><br><span class="line"></body></span><br><span class="line"></html></span><br></pre></td></tr></table></figure><h1 id="参考文章"><a href="#参考文章" class="headerlink" title="参考文章"></a>参考文章</h1><ul><li><a href="https://blog.csdn.net/qq_35394434/article/details/83747008">在html页面实时显示系统时间</a></li><li><a href="https://blog.csdn.net/baidu_38607919/article/details/102506792">一个好用的VScode预览html插件——Live Server Preview</a></li><li><a href="https://blog.csdn.net/BlizzardWu/article/details/124143767">JS定时器的4种写法及介绍</a></li><li><a href="https://zhuanlan.zhihu.com/p/269714623">【基础篇】做了这么久,才知道什么是上位机</a></li></ul>]]></content>
<categories>
<category> 方法教程 </category>
</categories>
<tags>
<tag> 物联网 </tag>
<tag> HTML </tag>
</tags>
</entry>
<entry>
<title>2023年度总结</title>
<link href="/2023/12/29/experience-2023/"/>
<url>/2023/12/29/experience-2023/</url>
<content type="html"><![CDATA[<h1 id="小确幸"><a href="#小确幸" class="headerlink" title="小确幸"></a>小确幸</h1><h2 id="科研"><a href="#科研" class="headerlink" title="科研"></a>科研</h2><p>和去年的我相比,我最大的感触就是我开始去做一些事情了,我能渐渐抛开过去的成绩,正视自己存在的不足,耐心去学习、去积累。从一开始辅助课题组同事做数据分析,到后来争取到合作课题,再到现在慢慢有了自己的课题,很多事情在一开始我并不能看清未来的走向,但我还是选择坚定的走下去,我相信只有这样才能把路走远走宽。</p><p>我原本以为这五年我都不会碰生物实验,我相信或许我跨专业就不该碰生物实验,但我常常内心动摇,一方面是对我已有的能力能否支撑我顺利毕业信心不足,另一方面是希望可以自己做实验收集数据,不想一直依附于其他人。</p><p>我经常感觉很多事情困难,其实是因为它们一直停留在我的想象中,从未付诸实践。今年下半年我的做事态度转变很大,我开始敢于提出自己的数据分析思路,开始尝试稍微复杂一些的算法,开始学做生物实验,开始自己焊接线路搭建行为装置。我才发现我有能力做到这么多事情,我可以用数据分析结果影响课题的走向,我可以一个人完成小鼠脑立体定位手术,我可以搭建好硬件电路!</p><p>希望新的一年我可以进一步提升专业技能,努力做一个有价值的、值得信赖的人,也希望科研方面可以有新的突破,加油加油!我的2024一定很哇塞!🥳</p><h2 id="电影🎬"><a href="#电影🎬" class="headerlink" title="电影🎬"></a>电影🎬</h2><ul><li>航海王:红发歌姬</li><li>满江红</li><li>人生路不熟</li><li>变形金刚:超能勇士崛起</li><li>消失的她</li><li>八角笼中</li><li>长安三万里</li><li>流浪地球2</li><li>孤注一掷</li><li>无价之宝</li><li>刀尖</li><li>指环王</li><li>三大队</li></ul><h2 id="旅行"><a href="#旅行" class="headerlink" title="旅行"></a>旅行</h2><ul><li>聊城</li></ul><div class="fj-gallery"><p><img src="https://img.cwxhmk.top/gallary/2023-1-1.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-1-2.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-1-3.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-1-4.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-1-5.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-1-6.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-10-4.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-10-5.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-10-6.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-10-7.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-10-8.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-10-9.jpg"></p> </div><ul><li>杭州</li><li><ul><li>浙大紫金港</li></ul></li></ul><div class="fj-gallery"><p><img src="https://img.cwxhmk.top/gallary/2023-3-1.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-3-3.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-3-4.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-3-5.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-3-6.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-4-4.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-4-5.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-4-6.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-4-7.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-5-4.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-6-7.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-7-1.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-9-4.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-11-1.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-11-2.jpg"></p> </div><ul><li><ul><li>动物园和植物园</li></ul></li></ul><div class="fj-gallery"><p><img src="https://img.cwxhmk.top/gallary/2023-2-1.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-2-2.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-2-3.jpg"></p> </div><ul><li><ul><li>湘湖</li></ul></li></ul><div class="fj-gallery"><p><img src="https://img.cwxhmk.top/gallary/2023-4-1.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-4-2.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-4-3.jpg"></p> </div><ul><li><ul><li>西湖</li></ul></li></ul><div class="fj-gallery"><p><img src="https://img.cwxhmk.top/gallary/2023-9-1.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-9-2.jpg"></p> </div><ul><li><ul><li>灵隐寺</li></ul></li></ul><div class="fj-gallery"><p><img src="https://img.cwxhmk.top/gallary/2023-10-10.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-10-11.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-10-12.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-10-13.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-10-14.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-10-15.jpg"></p> </div><ul><li><ul><li>浙江升非物质文化遗产馆</li></ul></li></ul><div class="fj-gallery"><p><img src="https://img.cwxhmk.top/gallary/2023-11-6.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-11-7.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-11-8.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-11-9.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-11-10.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-11-11.jpg"></p> </div><ul><li><ul><li>塘栖古镇</li></ul></li></ul><div class="fj-gallery"><p><img src="https://img.cwxhmk.top/gallary/2023-12-4.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-12-5.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-12-6.jpg"></p> </div><ul><li><ul><li>闲逛</li></ul></li></ul><div class="fj-gallery"><p><img src="https://img.cwxhmk.top/gallary/2023-9-3.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-9-5.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-9-6.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-11-3.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-11-4.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-11-5.jpg"></p> </div><ul><li>北京</li></ul><div class="fj-gallery"><p><img src="https://img.cwxhmk.top/gallary/2023-2-4.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-2-5.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-2-6.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-2-7.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-2-8.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-2-9.jpg"></p> </div><ul><li>南京</li></ul><div class="fj-gallery"><p><img src="https://img.cwxhmk.top/gallary/2023-4-8.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-4-9.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-4-10.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-5-1.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-5-2.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-5-3.jpg"></p> </div><ul><li>绍兴</li></ul><div class="fj-gallery"><p><img src="https://img.cwxhmk.top/gallary/2023-6-1.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-6-2.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-6-3.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-6-4.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-6-5.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-6-6.jpg"></p> </div><ul><li>邢台</li></ul><div class="fj-gallery"><p><img src="https://img.cwxhmk.top/gallary/2023-8-8.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-8-1.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-8-2.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-8-3.jpg"></p> </div><ul><li>西安</li></ul><div class="fj-gallery"><p><img src="https://img.cwxhmk.top/gallary/2023-10-1.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-10-2.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-10-3.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-10-16.jpg"></p> </div><h2 id="鸟🐦"><a href="#鸟🐦" class="headerlink" title="鸟🐦"></a>鸟🐦</h2><div class="fj-gallery"><p><img src="https://img.cwxhmk.top/gallary/2023-bird-1.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-bird-2.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-bird-3.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-bird-4.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-bird-5.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-bird-6.jpg"></p> </div><h2 id="喜事"><a href="#喜事" class="headerlink" title="喜事"></a>喜事</h2><ul><li>我的小侄子出生啦~</li><li>实验室三位同门都在今年结婚了,喜糖不断!🍬</li><li>康康要来杭州工作啦!</li></ul><h2 id="小技能"><a href="#小技能" class="headerlink" title="小技能"></a>小技能</h2><ul><li>催眠课上学到了一个小魔术🥰</li><li>做饭!</li></ul><div class="fj-gallery"><p><img src="https://img.cwxhmk.top/gallary/2023-5-6.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-8-4.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-8-5.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-8-6.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-12-2.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-12-3.jpg"></p> </div><h2 id="讲座"><a href="#讲座" class="headerlink" title="讲座"></a>讲座</h2><div class="fj-gallery"><p><img src="https://img.cwxhmk.top/gallary/2023-5-5.jpg"><br><img src="https://img.cwxhmk.top/gallary/2023-12-1.jpg"></p> </div><h1 id="经验"><a href="#经验" class="headerlink" title="经验"></a>经验</h1><ol><li>生活不是一成不变的,路是越走越宽的</li><li>不要一味地获取资源,对已有资源的消化和吸收更重要</li><li>在做重大决定之前要给自己想好后路,不要心血来潮</li><li>想学的东西很多不要怕,每次学多少也不用太过死板,重要的是持续去学习</li><li>从论文中摘录的观点或数据图,要注明文献出处,以免后续找不到哪一篇文献</li><li>代码要规范命名,写好注释及文档说明,及时同步到github</li><li>做事情要有逻辑,数据分析要紧紧围绕科研问题</li><li>我们并不仅仅是被动处于一个环境之中,我们也可以通过努力去影响和改变周围的环境</li><li>做事要善始善终,别人交代的事情要及时反馈</li><li>笔记中注明当天时间,便于复盘</li><li>对自己的能力有合理的评估,既要量力而行,又要适当突破舒适圈</li><li>要相信每次讨论都是有价值的,及时记录</li><li>文件多平台同步会极大提高工作效率</li><li>学到的知识及时整理,尽量可以用自己的话写出来,有机会的话还可以讲给别人,这样对知识的理解更深刻</li><li>要警惕一直做别人安排的事情,要有自己的思想,对自己做的事情有清晰的认知和规划,明确任务的优先级</li><li>事情并不会总按预期进行,要考虑全面,接受有可能发生的不好的结果</li><li>实践是最快速的学习方式</li><li>成绩不等于个人能力,要想证明自己就要拿出成果</li><li>过去偷懒绕开的困难也许在不久的将来又会变成拦路石,总是要面对的</li></ol>]]></content>
<categories>
<category> 生活随笔 </category>
</categories>
<tags>
<tag> 年度总结 </tag>
</tags>
</entry>
<entry>
<title>【MATLAB App Designer使用教程】可拖拽的线</title>
<link href="/2023/12/29/matlab-app-designer-1/"/>
<url>/2023/12/29/matlab-app-designer-1/</url>
<content type="html"><![CDATA[<h2 id="核心代码"><a href="#核心代码" class="headerlink" title="核心代码"></a>核心代码</h2><figure class="highlight matlab"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">drag_line</span><span class="params">(app, fig, sel_line)</span></span></span><br><span class="line"> sel_line.ButtonDownFcn = @bdfcn;</span><br><span class="line"> opx = <span class="number">0</span>;</span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">bdfcn</span><span class="params">(~, edata)</span></span></span><br><span class="line"> opx = edata.IntersectionPoint(<span class="number">1</span>); <span class="comment">% 鼠标点击位置在坐标轴中的x坐标</span></span><br><span class="line"> sel_line.Selected = <span class="string">'on'</span>; <span class="comment">% 将拖动的线条设置为选中状态</span></span><br><span class="line"> app.UIFigure.WindowButtonMotionFcn = @wbmfcn; <span class="comment">% 鼠标在窗口内移动时</span></span><br><span class="line"> app.UIFigure.WindowButtonUpFcn = @wbufcn; <span class="comment">% 鼠标在窗口内弹起时</span></span><br><span class="line"> <span class="keyword">end</span></span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">wbmfcn</span><span class="params">(~,~)</span></span></span><br><span class="line"> cp = fig.CurrentPoint; <span class="comment">% 当下鼠标所在的位置</span></span><br><span class="line"> dx = cp(<span class="number">1</span>,<span class="number">1</span>) - opx; <span class="comment">% 鼠标移动的差值</span></span><br><span class="line"> newXData = sel_line.XData + dx;</span><br><span class="line"> xLimits = fig.XLim;</span><br><span class="line"> <span class="comment">% 检查新的 XData 是否在范围内</span></span><br><span class="line"> <span class="keyword">if</span> all(newXData >= xLimits(<span class="number">1</span>)) && all(newXData <= xLimits(<span class="number">2</span>))</span><br><span class="line"> sel_line.XData = newXData;</span><br><span class="line"> opx = cp(<span class="number">1</span>,<span class="number">1</span>); <span class="comment">% 更新 opx</span></span><br><span class="line"> <span class="keyword">end</span></span><br><span class="line"> app.LocationEditField.Value = sel_line.XData(<span class="number">1</span>);</span><br><span class="line"> <span class="keyword">end</span></span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">wbufcn</span><span class="params">(~,~)</span></span></span><br><span class="line"> app.UIFigure.WindowButtonMotionFcn = <span class="string">''</span>; <span class="comment">% 窗口内按键移动回调</span></span><br><span class="line"> app.UIFigure.WindowButtonUpFcn = <span class="string">''</span>; <span class="comment">% 窗口内按键弹起回调</span></span><br><span class="line"> sel_line.Selected = <span class="string">'off'</span>;</span><br><span class="line"> <span class="keyword">end</span></span><br><span class="line"><span class="keyword">end</span></span><br><span class="line"><span class="comment">% startupFcn</span></span><br><span class="line">arrayfun(@(ax) disableDefaultInteractivity(ax),[app.UIAxes]);</span><br><span class="line">xlim(app.UIAxes, [<span class="number">-10</span> <span class="number">10</span>]);</span><br><span class="line">drag_line(app, app.UIAxes, <span class="built_in">plot</span>(app.UIAxes, [<span class="number">0</span> <span class="number">0</span>], [<span class="number">0</span> <span class="number">1</span>], <span class="string">'LineWidth'</span>, <span class="number">2</span>));</span><br></pre></td></tr></table></figure><h2 id="运行效果"><a href="#运行效果" class="headerlink" title="运行效果"></a>运行效果</h2><p><img src="https://img.cwxhmk.top/gif/drag_line.gif" alt="文字"> </p>]]></content>
<categories>
<category> 方法教程 </category>
</categories>
<tags>
<tag> Matlab </tag>
</tags>
</entry>
<entry>
<title>【arduino探索】搭建触摸给水装置</title>
<link href="/2023/12/29/arduino-touch-pump/"/>
<url>/2023/12/29/arduino-touch-pump/</url>
<content type="html"><![CDATA[<h1 id="实验材料准备"><a href="#实验材料准备" class="headerlink" title="实验材料准备"></a>实验材料准备</h1><ul><li><p>电容触摸传感器*1</p><img src="https://img.cwxhmk.top/post/touch-sensor.jpg" alt="触摸传感器" width="30%" height="30%" /> </li><li><p>蠕动泵*1</p></li><li><p>可孚一次性无菌加药器 50ml(粗针管)</p></li><li><p>杜邦线公对公</p></li><li><p>Arduino Uno R3*1</p></li><li><p>粗针头*2</p></li><li><p>绝缘胶带</p></li></ul><blockquote><p>电容触摸传感器和蠕动泵需要焊接杜邦线,用剪刀减去杜邦线一端的公头,用剥线钳暴露铜丝,短暂加热焊锡覆盖暴露的铜丝。</p></blockquote><h1 id="配件功能测试"><a href="#配件功能测试" class="headerlink" title="配件功能测试"></a>配件功能测试</h1><p>首先测试给水装置核心配件的功能是否正常。</p><h2 id="电容触摸传感器"><a href="#电容触摸传感器" class="headerlink" title="电容触摸传感器"></a>电容触摸传感器</h2><p>电容触摸传感器上标有VCC、GND和DAT引脚,VCC是电源引脚,用于给传感器供电;GND是接地引脚;DAT是数据引脚,用于传输触摸信号。经过Arduino程序测试,发现电容触摸传感器默认为高电平,触摸时为低电平。</p><figure class="highlight arduino"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">setup</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="built_in">pinMode</span>(A0, <span class="literal">INPUT</span>); <span class="comment">// 电容触摸传感器</span></span><br><span class="line"> <span class="built_in">pinMode</span>(<span class="number">2</span>, <span class="literal">OUTPUT</span>); <span class="comment">// LED</span></span><br><span class="line"> <span class="built_in">Serial</span>.<span class="built_in">begin</span>(<span class="number">9600</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">loop</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="built_in">Serial</span>.<span class="built_in">println</span>(<span class="built_in">digitalRead</span>(A0));</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>用绝缘胶带缠绕触摸传感器引脚的杜邦线(起到保护和固定的作用),将粗针头固定到传感器较平整的一面,该装置即可作为小鼠的舔水口,小鼠通过针头舔水时,针头另一端会按压触摸传感器,因此可以根据触摸传感器电平的变化检测舔水事件。</p><p>为了更好地观察小鼠的舔水事件,我选用LED灯反映触摸传感器的状态,LED的正极连接arduino开发板的2号引脚。实现的效果为,小鼠舔水时(即按压触摸传感器)时,LED灯亮。</p><figure class="highlight arduino"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">loop</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (<span class="built_in">digitalRead</span>(A0) == <span class="literal">LOW</span>){</span><br><span class="line"> <span class="built_in">digitalWrite</span>(<span class="number">2</span>, <span class="literal">HIGH</span>);</span><br><span class="line"> }<span class="keyword">else</span>{</span><br><span class="line"> <span class="built_in">digitalWrite</span>(<span class="number">2</span>, <span class="literal">LOW</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="蠕动泵"><a href="#蠕动泵" class="headerlink" title="蠕动泵"></a>蠕动泵</h2><p>上次买的蠕动泵有一个小配件被我弄坏了,这次测试新买的蠕动泵,通过转接头连接硅胶管,进水口放入粗针管内。给蠕动泵提供5V的电压,经测试,可以正常工作,出水口正常出水。<br>由于要控制训练过程中每个试次的给水量,因此对蠕动泵的出水量进行测试。经询问师弟,可以采用给水0.1s,间隔0.1s,并重复40次的方式测量,测量前称纸巾的重量,测量后再对纸巾称重,即可计算出每次给水的体积。连续两天测量蠕动泵的出水量,如果保持不变,即认为可正常工作。<br>$$m=\rho V$$</p><p>$$\rho_{水} =1g/cm^3 $$</p><p>$$1cm^3=1000\mu L$$</p><ul><li>12.29 测试结果:40次 给水0.1s 间隔0.1s 称重:0.05g</li></ul><figure class="highlight arduino"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">setup</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="built_in">pinMode</span>(A0, <span class="literal">INPUT</span>); <span class="comment">// 电容触摸传感器</span></span><br><span class="line"> <span class="built_in">pinMode</span>(<span class="number">2</span>, <span class="literal">OUTPUT</span>); <span class="comment">// 蠕动泵</span></span><br><span class="line"> <span class="built_in">Serial</span>.<span class="built_in">begin</span>(<span class="number">9600</span>);</span><br><span class="line"> <span class="built_in">delay</span>(<span class="number">1000</span>); </span><br><span class="line"> <span class="type">int</span> i = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(i = <span class="number">1</span>; i <= <span class="number">40</span>; i ++){ <span class="comment">// 测出水量</span></span><br><span class="line"> <span class="built_in">digitalWrite</span>(<span class="number">2</span>, <span class="literal">HIGH</span>);</span><br><span class="line"> <span class="built_in">delay</span>(<span class="number">100</span>); <span class="comment">// ms</span></span><br><span class="line"> <span class="built_in">digitalWrite</span>(<span class="number">2</span>, <span class="literal">LOW</span>);</span><br><span class="line"> <span class="built_in">delay</span>(<span class="number">100</span>); <span class="comment">// ms</span></span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">loop</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="built_in">Serial</span>.<span class="built_in">println</span>(<span class="built_in">digitalRead</span>(A0));</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h1 id="实验装置"><a href="#实验装置" class="headerlink" title="实验装置"></a>实验装置</h1><p><img src="https://img.cwxhmk.top/post/%E8%A7%A6%E6%91%B8%E7%BB%99%E6%B0%B4%E8%A3%85%E7%BD%AE%E5%AE%9E%E7%89%A9%E8%BF%9E%E7%BA%BF.jpg" alt="触摸给水装置实物连线"></p><h1 id="触摸给水"><a href="#触摸给水" class="headerlink" title="触摸给水"></a>触摸给水</h1><p>接下来测试触摸传感器控制蠕动泵给水的功能,经测试,功能正常。</p><figure class="highlight arduino"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">setup</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="built_in">pinMode</span>(A0, <span class="literal">INPUT</span>); <span class="comment">// 电容触摸传感器</span></span><br><span class="line"> <span class="built_in">pinMode</span>(<span class="number">2</span>, <span class="literal">OUTPUT</span>); <span class="comment">// 蠕动泵</span></span><br><span class="line"> <span class="built_in">Serial</span>.<span class="built_in">begin</span>(<span class="number">9600</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">loop</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="built_in">Serial</span>.<span class="built_in">println</span>(<span class="built_in">digitalRead</span>(A0));</span><br><span class="line"> <span class="keyword">if</span> (<span class="built_in">digitalRead</span>(A0) == <span class="literal">LOW</span>){ <span class="comment">// 测试触摸给水</span></span><br><span class="line"> <span class="built_in">digitalWrite</span>(<span class="number">2</span>, <span class="literal">HIGH</span>);</span><br><span class="line"> <span class="built_in">delay</span>(<span class="number">100</span>); <span class="comment">// ms</span></span><br><span class="line"> <span class="built_in">digitalWrite</span>(<span class="number">2</span>, <span class="literal">LOW</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h1 id="经验"><a href="#经验" class="headerlink" title="经验"></a>经验</h1><ol><li>小鼠训练过程中每天摄入水量为1ml~1.2ml</li><li>测试时针管内的气泡一定要排干净,且传感器的放置方式与实际任务期间保持一致</li></ol>]]></content>
<categories>
<category> 方法教程 </category>
</categories>
<tags>
<tag> arduino </tag>
</tags>
</entry>
<entry>
<title>【arduino探索】使用ArControl编写“炸弹💣游戏”</title>
<link href="/2023/12/26/arcontrol-boom-game/"/>
<url>/2023/12/26/arcontrol-boom-game/</url>
<content type="html"><![CDATA[<div class="note info flat"><p>游戏规则:<br>简易版:游戏有一个5秒倒计时炸弹,时间到了就会爆炸,马里奥玩家就会死亡。如果玩家可以在这5s内按下停止开关,炸弹不会爆炸,玩家马里奥任务成功。</p><p>实验材料:<br>Arduino UNO R3 * 1<br>面包板 * 1<br>发光二极管 * 1(模拟炸弹)<br>按钮 * 1(模拟开关)</p></div><h1 id="Arduino引脚映射"><a href="#Arduino引脚映射" class="headerlink" title="Arduino引脚映射"></a>Arduino引脚映射</h1><p>ArControl对Arduino UNO开发板做了端口映射,定义好了6个输入端口和8个输出端口,示意图如下。IN和OUT都是相对于Arduino开发板来说的。在这个小游戏中,我们使用<code>pinA0</code>即<code>IN1</code>接收按钮的状态,<code>pin2</code>即<code>OUT1</code>控制LED灯的状态。</p><p><img src="https://img.cwxhmk.top/post/Arduino_UNO_Pin.png" alt="Arduino引脚映射"></p><h1 id="Arduino测试程序"><a href="#Arduino测试程序" class="headerlink" title="Arduino测试程序"></a>Arduino测试程序</h1><figure class="highlight arduino"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//测试按钮控制led灯是否正常</span></span><br><span class="line"><span class="type">int</span> ledPin = <span class="number">2</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">setup</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="built_in">pinMode</span>(A0, <span class="literal">INPUT</span>);</span><br><span class="line"> <span class="built_in">pinMode</span>(ledPin, <span class="literal">OUTPUT</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">loop</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (<span class="built_in">digitalRead</span>(A0) == <span class="literal">HIGH</span>){</span><br><span class="line"> <span class="built_in">digitalWrite</span>(ledPin, <span class="literal">HIGH</span>);</span><br><span class="line"> } <span class="keyword">else</span>{</span><br><span class="line"> <span class="built_in">digitalWrite</span>(ledPin, <span class="literal">LOW</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h1 id="Arduino实物连接图"><a href="#Arduino实物连接图" class="headerlink" title="Arduino实物连接图"></a>Arduino实物连接图</h1><div class="note warning flat"><p>关于接线我还闹了个笑话,我在ArControl上进行测试,发现按下按钮之后,<code>IN1</code>端口会持续很久的高电平,而且不按按钮时也会有通道闪烁的情况。我在arduino IDE中测试按钮控制LED灯的情况,发现了类似的问题,当我不按按钮时,LED灯也是亮的,按下按钮之后,LED灯只是变得更亮了。我检查线路并没发现什么问题,去请教师兄,才发现我接线时按钮旁边的下拉电阻没接上!!!😅按我那样的接法,电阻纯属摆设,跟按钮的电路半毛钱关系都没有。重新接好电阻之后,再测试就正常了。(^-^)V</p></div><p><img src="https://img.cwxhmk.top/post/arduino-boom%E5%AE%9E%E7%89%A9%E6%8E%A5%E7%BA%BF%E5%9B%BE.jpg" alt="实物连接图"></p><h1 id="ArControl使用流程"><a href="#ArControl使用流程" class="headerlink" title="ArControl使用流程"></a>ArControl使用流程</h1><p>ArControl的软件部分主要包括两个应用程序,其中ArControl Designer用于编写行为范式的protocol,ArControl Recorder用于监控端口的运行状态并采集实验数据。</p><h2 id="ArControl-Designer"><a href="#ArControl-Designer" class="headerlink" title="ArControl Designer"></a>ArControl Designer</h2><p>ArControl Designer借鉴了状态机的原理,把行为实验流程等效分解为一系列时序上相互衔接的子任务(State),可以根据实验逻辑在状态之间进行跳转。</p><p>每一个State可以对6种功能进行配置,包括改变任务变量(do-var)、控制输出通道(do-pin)、 检测任务变量(when-var)、检测实验计数(when-count)、检测等待时间 (when-time)以及检测输入端口(when-pin)。其中每个功能的详细配置是在子窗体中进行的。</p><p>在这个小游戏中,逻辑比较简单,可以分为倒计时、炸弹爆炸和炸弹不爆炸三个状态,分别记为<code>S1</code>、<code>S2</code>和<code>S3</code>。如果在没有在5s内按下停止开关,则跳转到<code>S2</code>;如果在5s内按下停止开关,则跳转到<code>S3</code>。编写完实验流程之后,保存。</p><p><img src="https://img.cwxhmk.top/post/arcontrol-designer.jpg" alt="ArControl Designer"><br>如果想查看实验流程图,也可以点击File→Export pdf,这个功能真的很方便检查实验逻辑!<br><img src="https://img.cwxhmk.top/post/arduino-boom-procedure.jpg" alt="流程图"></p><h2 id="ArControl-Recorder"><a href="#ArControl-Recorder" class="headerlink" title="ArControl Recorder"></a>ArControl Recorder</h2><p>选择Arduino开发板对应的端口,载入实验流程并烧录进开发板。点击<code>Start</code>按钮即可运行,点击<code>Stop</code>按钮即可手动终止程序,也可以等程序运行完自动结束。中间的板块可以实时观察输入/输出端口的电平变化,如果为绿色,则表示当前端口是高电平。下图分别为炸弹💣爆炸💥和成功按下停止开关时的端口状态。</p><p><img src="https://img.cwxhmk.top/post/arcontrol-boom-1.jpg" alt="Boom"><br><img src="https://img.cwxhmk.top/post/arcontrol-boom-2.jpg" alt="No boom"></p><h1 id="参考内容"><a href="#参考内容" class="headerlink" title="参考内容"></a>参考内容</h1><ul><li><a href="https://www.bilibili.com/video/BV13v411v7TN/">[Arduino] 2_状态机可视化编程_ArControl工具_实例”炸弹游戏”</a></li><li><a href="https://github.com/chenxinfeng4/ArControl">Github ArControl</a></li></ul>]]></content>
<categories>
<category> 方法教程 </category>
</categories>
<tags>
<tag> arduino </tag>
<tag> ArControl </tag>
</tags>
</entry>
<entry>
<title>【arduino探索】控制蠕动泵出水</title>
<link href="/2023/12/26/arduino-pump/"/>
<url>/2023/12/26/arduino-pump/</url>
<content type="html"><![CDATA[<p>前几天在淘宝上买的蠕动泵终于到货了,早上拆开快递一脸懵,摆在我面前两个难题:第一,我该怎么给这个蠕动泵供电呢?虽然顶部标有正负极,但我还是不知道该怎么办;第二,蠕动泵自带了管子,比较短,我怎么换成我们实验室自己的硅胶管呢?</p><p>对于第一个问题,我请教了师弟。拿剪刀将杜邦线剪去一头,然后用剥线钳暴露电线,将电线穿过蠕动泵顶部的孔,折叠后焊锡,另一个孔也同样操作即可。接好线后我在arduino板上测试了一下,一端接入5V电压,另一端接地,测试发现可以正常工作!</p><p>对于第二个问题,我的第一反应是把自带的管抽出来,换成我们实验室自己的硅胶管。但我抽出来才发现,泵头的孔太小,硅胶管穿不进去。后来尝试把管口剪尖,终于穿进去了,结果泵头的一个小组件崩飞了,┭┮﹏┭┮。后来师弟和师姐意外发现快递里面的转接头(我早就看到了,但不知道是干啥用的),告诉我说这个可以直接接到自带的管上,然后另一端连自己的硅胶管,我才恍然大悟!</p><img src="https://img.cwxhmk.top/post/%E8%BD%AC%E6%8E%A5%E5%A4%B4.jpg" alt="图片说明" width="50%" height="50%" /> <p>虽然小零件崩飞了,但我还是完整地测试了一下蠕动泵的功能(用led blink的程序测试的),一端接<code>pin12</code>,一端接地,arduino写入程序后蠕动泵可以实现间隔1s给水。静待我买的新蠕动泵!<br><img src="https://img.cwxhmk.top/post/%E8%A0%95%E5%8A%A8%E6%B3%B5%E6%8E%A5%E7%BA%BF%E5%AE%9E%E7%89%A9.jpg" alt="蠕动泵实物连线"></p>]]></content>
<categories>
<category> 方法教程 </category>
</categories>
<tags>
<tag> arduino </tag>
</tags>
</entry>
<entry>
<title>【arduino探索】按键控制LED灯</title>
<link href="/2023/12/25/arduino-button-led-demo/"/>
<url>/2023/12/25/arduino-button-led-demo/</url>
<content type="html"><![CDATA[<h1 id="Arudino-Uno-R3开发板简介"><a href="#Arudino-Uno-R3开发板简介" class="headerlink" title="Arudino Uno R3开发板简介"></a>Arudino Uno R3开发板简介</h1><p><img src="https://img.cwxhmk.top/post/arduino-uno-description.jpg" alt="Arudino Uno R3开发板引脚说明"> </p><h1 id="电路图"><a href="#电路图" class="headerlink" title="电路图"></a>电路图</h1><div class="note info flat"><p>目标:使用四角按键开关控制LED灯,当按钮按下时灯亮,松开时灯灭。</p><p>实现思路:将引脚2改为<code>input mode</code>,反映按键的状态。引脚12为<code>output mode</code>,控制led灯的亮灭。当按键按下时,引脚2为高电平,此时led灯亮;当按钮松开时,引脚2为低电平,此时led灯灭。(对应仿真图连线)</p><p>如果引脚2的状态为<code>input pullup mode</code>(如果外部组件未启用,上拉电阻将输入端口处的电压拉到高电平),当按键按下时,引脚2为低电平,此时led灯亮;当按钮松开时,引脚2为高电平,此时led灯灭。(对应实物连线)</p><p>注意事项:四角按键同侧不相连,相连不同侧。</p></div><p><img src="https://img.cwxhmk.top/post/button-led%E4%BB%BF%E7%9C%9F%E5%9B%BE.jpg" alt="仿真"><br><img src="https://img.cwxhmk.top/post/button-led%E5%AE%9E%E7%89%A9%E5%9B%BE.jpg" alt="实物"> </p><h1 id="Arduino程序"><a href="#Arduino程序" class="headerlink" title="Arduino程序"></a>Arduino程序</h1><figure class="highlight arduino"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> buttonPin = <span class="number">2</span>;</span><br><span class="line"><span class="type">int</span> ledPin = <span class="number">12</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">setup</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="comment">// put your setup code here, to run once:</span></span><br><span class="line"> <span class="built_in">pinMode</span>(buttonPin, <span class="literal">INPUT_PULLUP</span>);</span><br><span class="line"> <span class="built_in">pinMode</span>(ledPin, <span class="literal">OUTPUT</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">loop</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="comment">// put your main code here, to run repeatedly:</span></span><br><span class="line"> <span class="keyword">if</span> (<span class="built_in">digitalRead</span>(buttonPin) == <span class="literal">LOW</span>){</span><br><span class="line"> <span class="built_in">digitalWrite</span>(ledPin, <span class="literal">HIGH</span>);</span><br><span class="line"> } <span class="keyword">else</span>{</span><br><span class="line"> <span class="built_in">digitalWrite</span>(ledPin, <span class="literal">LOW</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure><h1 id="参考文章"><a href="#参考文章" class="headerlink" title="参考文章"></a>参考文章</h1><ul><li><a href="https://blog.csdn.net/TonyIOT/article/details/81414118">Arduino基础入门篇07—按键控制LED灯</a></li><li><a href="https://www.tinkercad.com/">Arduino在线仿真平台</a></li><li><a href="https://www.bilibili.com/video/BV164411J7GE/">【太极创客】零基础入门学用Arduino 第一部分 合辑</a></li></ul>]]></content>
<categories>
<category> 方法教程 </category>
</categories>
<tags>
<tag> arduino </tag>
</tags>
</entry>
<entry>
<title>在Mac电脑上安装VMware Fusion</title>
<link href="/2023/12/23/mac-vmware-fusion/"/>
<url>/2023/12/23/mac-vmware-fusion/</url>
<content type="html"><![CDATA[<p>大学毕业以后买了一台新的联想电脑,当时还因为终于可以用GPU而兴奋了很久,后来去北京出差背着电脑来回走了很久,不插着电源很快就会没电。从北京回来我就斥巨资买了一台苹果电脑,续航能力没得说,平时用的大部分软件也都是有mac版的。因为工位空间有限,我就把苹果电脑放在了工位,联想电脑留在了宿舍,平时偶尔会远程控制一下宿舍的电脑,但有时会很卡,操作也不太方便。</p><p>之前有想过安装mac双系统,但又怕对电脑不好,就一直将就着使用了。最近有一些软件只能在windows系统上运行,狠了狠心,在mac上安了个虚拟机(<a href="https://www.vmware.com/products/fusion/fusion-evaluation.html">VMware Fusion 13</a>),可以比较方便地使用windows系统。(存储空间一下子少了很多,┻┳|・ω・|)</p><p>VMware Fusion有个人免费版,但我实在是注册不上这个网站,曲线救国选择下载Fusion 13 Pro,然后输入网上找到的序列号(<mark class="hl-label green">5N400-4AH82-M88Q3-0LC0P-0TRL0</mark> ),就可以正常使用了。</p><h1 id="注意事项"><a href="#注意事项" class="headerlink" title="注意事项"></a>注意事项</h1><ol><li>可以直接通过Microsoft安装win11</li><li>新建虚拟磁盘</li><li>记住密码并存储在mac钥匙串中</li><li>安装VMware Tools之后全屏可以铺满且有原始mac电脑的分辨率(以管理员身份运行windows powershell→输入Set-ExecutionPolicy RemoteSigned→A→菜单栏选择虚拟机→安装VMware Tools)</li><li>我安装的时候没有遇到网上教程所说的网络问题</li></ol><h1 id="参考文章"><a href="#参考文章" class="headerlink" title="参考文章"></a>参考文章</h1><ul><li><a href="https://blog.csdn.net/weixin_52799373/article/details/129658881">M1/M2 Pro VMware Fusion虚拟机安装Win11教程(超详细)</a></li><li><a href="https://www.bilibili.com/read/cv19980721/">支持M芯片的免费虚拟机软件来了!VMware Fusion 13安装教程</a></li><li><a href="https://zhuanlan.zhihu.com/p/452412091">在Apple芯片的Mac上通过VMware Fusion 13使用Windows 11</a></li></ul>]]></content>
<categories>
<category> 方法教程 </category>
</categories>
<tags>
<tag> 虚拟机 </tag>
</tags>
</entry>
<entry>
<title>VSCode无法正常打开.ipynb文件</title>
<link href="/2023/12/23/vscode-ipynb-error/"/>
<url>/2023/12/23/vscode-ipynb-error/</url>
<content type="html"><![CDATA[<p>上午原本想写程序,打开VSCode之后发现不能打开.ipynb文件了,报错信息如下:</p><div class="note danger flat"><p>Error loading webview: Error: Could not register service worker: InvalidStateError: Failed to register a ServiceWorker: The document is in an invalid state..</p><p>The editor could not be opened due to an unexpected error: Could not initialize webview: Error: Could not register service worker: InvalidStateError: Failed to register a ServiceWorker: The document is in an invalid state..</p></div><p>在网上查了一些解决方法,尝试过删除vscode缓存(~/Library/Application Support/Code/)、重新安装插件和重启VSCode,但都不起作用。经过不懈努力,终于在<a href="https://stackoverflow.com/questions/67698176/error-loading-webview-error-could-not-register-service-workers-typeerror-fai">stack overflow</a>上找到了适合我的解决方案,删除Service Worker文件夹之后重启VSCode,.ipynb文件就可以正常显示了!</p><div class="note success flat"><p>There is another possible reason for OSX, that the files in the following paths are restricted by user permissions.</p><p>MAC: ~/Library/Application Support/Code/Service Worker</p><p>You can directly delete folders with restricted permissions.</p><p>After restarting VScode, he will generate it again.</p></div>]]></content>
<categories>
<category> 方法教程 </category>
</categories>
<tags>
<tag> Jupyter Notebook </tag>
<tag> VSCode </tag>
</tags>
</entry>
<entry>
<title>ImageJ插件开发</title>
<link href="/2023/07/21/imagej-plugin-9/"/>
<url>/2023/07/21/imagej-plugin-9/</url>
<content type="html"><![CDATA[<h1 id="开发流程"><a href="#开发流程" class="headerlink" title="开发流程"></a>开发流程</h1><ol><li>安装Java8 JDK (Windows x86 64-bit) <a href="https://docs.azul.com/core/zulu-openjdk/install/windows">https://docs.azul.com/core/zulu-openjdk/install/windows</a></li><li>安装Eclipse IDE for Java Developers <a href="https://www.eclipse.org/downloads/">https://www.eclipse.org/downloads/</a></li><li>在github下载示例插件并修改 GitHub - imagej/example-imagej2-command: Simple Maven project for an ImageJ2 command</li></ol><ul><li>修改pom.xml:重点修改groupId、artifactId、version、name、<properties>的内容</li><li>Eclipse-Import-Maven-Existing Maven Projects</li><li>重命名:项目名、包名、java文件中类名和菜单路径</li></ul><ol start="4"><li>Run as Java application 确保程序可以正常运行</li><li>Run as Maven build 控制台输出<mark class="hl-label green">BUILD</mark> <mark class="hl-label green">SUCCESS</mark> 则表示程序成功打包为jar包(保存在target目录下)</li><li>将jar包粘贴至Fiji的plugin目录,运行软件测试插件效果</li></ol><h1 id="问题记录"><a href="#问题记录" class="headerlink" title="问题记录"></a>问题记录</h1><ol><li>如果pom.xml中<parent>报错,则尝试修改<version>,并等待右下角更新完成</li><li>打包好的插件在ImageJ中无法正常运行,报错<code>java.lang.ClassCastException: com.chen.brain.pluginMain cannot be cast to org.scijava.plugin.SciJavaPlugin</code><br><strong>报错原因:</strong>pluginMain类没有实现org.scijava.command.Command接口,而这是必须的,才能将其识别为有效的SciJava插件。@Plugin注解用于指定该类应注册为一个命令插件,但由于它没有实现所需的接口,因此会导致ClassCastException异常。<br><strong>解决方案:</strong><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> org.scijava.command.Command;</span><br><span class="line"><span class="keyword">import</span> org.scijava.plugin.Plugin;</span><br><span class="line"></span><br><span class="line"><span class="meta">@Plugin(type = Command.class, menuPath = "Plugins>brainRegistration")</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">pluginMain</span> <span class="keyword">implements</span> <span class="title class_">Command</span> {</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 省略其他部分</span></span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">run</span><span class="params">()</span> {</span><br><span class="line"> <span class="comment">// 在这里实现插件的逻辑</span></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> {</span><br><span class="line"> <span class="keyword">new</span> <span class="title class_">pluginMain</span>().location();</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li>在Eclipse中初次导入项目时,要等待build(可能需要等待几分钟)</li><li>最好在官方提供的模板基础上写自己的代码,而不是用自己新建的maven项目</li></ol><h1 id="参考内容"><a href="#参考内容" class="headerlink" title="参考内容"></a>参考内容</h1><ul><li><a href="https://imagej.net/develop/eclipse">参考文档</a></li><li><a href="%E2%80%8Bhttps://www.youtube.com/watch?v=YIWpoBnnLio">参考视频</a></li></ul>]]></content>
<categories>
<category> 项目实战 </category>
</categories>
<tags>
<tag> ImageJ </tag>
<tag> Java </tag>
<tag> Eclipse </tag>
</tags>
</entry>
<entry>
<title>neurogym学习笔记【01】</title>
<link href="/2023/07/17/neurogym/"/>
<url>/2023/07/17/neurogym/</url>
<content type="html"><![CDATA[<div class="note info flat"><p>NeuroGym是一个经过仔细挑选的神经科学任务集合,具有公共接口。其目标是促进在神经科学任务上神经网络模型的训练。</p><p>NeuroGym是一个工具包,可以让您在许多已建立的神经科学任务技术上训练任何神经网络模型,如标准的监督学习或强化学习。</p><p>该教程用于理解Neurogym的任务结构,程序运行环境为Google Colab。本文翻译自Neurogym官方文档,对应的代码 <a href="https://colab.research.google.com/drive/1ays7_LTBsLAM9O29Z0z0ozCZdvDWy3-R?usp=sharing">[Open in Colab]</a></p><p>neurogym是基于gym开发的,很多参数的设置用起来不是很顺手,不清楚源代码怎么写的,有些代码不太好理解。但本质上就是继承了gym的一些方法,生成行为任务的数据。后面可能不会直接用neurogym,而是仿写并实现课题组内已有的范式。</p></div><h1 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h1><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">! pip install gym</span><br><span class="line">! git clone https://github.com/gyyang/neurogym.git</span><br><span class="line">%cd neurogym</span><br><span class="line">! pip install -e .</span><br></pre></td></tr></table></figure><h1 id="OpenAI-gym-任务"><a href="#OpenAI-gym-任务" class="headerlink" title="OpenAI gym 任务"></a>OpenAI gym 任务</h1><p>Neurogym任务遵循基本的OpenAI gym任务形式。每个任务定义为一个Python类,继承自<code>gym.Env</code>类。</p><p>在这一节中,我们描述一个OpenAI gym任务的基本结构。</p><p>在<code>__init__</code>方法中,必须定义两个属性,<code>self.observation_space</code>和<code>self.action_space</code>,它们描述了观测(网络输入)和动作(网络输出)的空间类型。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> warnings</span><br><span class="line">warnings.filterwarnings(<span class="string">"ignore"</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">import</span> gym</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">MyEnv</span>(gym.Env):</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line"> <span class="built_in">super</span>().__init__()</span><br><span class="line"> self.observation_space = gym.spaces.Box(low=<span class="number">0.</span>, high=<span class="number">1.</span>, shape=(<span class="number">2</span>,))</span><br><span class="line"> self.action_space = gym.spaces.Discrete(<span class="number">3</span>)</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">step</span>(<span class="params">self, action</span>):</span><br><span class="line"> ob = self.observation_space.sample()</span><br><span class="line"> reward = <span class="number">1.</span></span><br><span class="line"> done = <span class="literal">False</span></span><br><span class="line"> info = {}</span><br><span class="line"> <span class="keyword">return</span> ob, reward, done, info</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">reset</span>(<span class="params">self</span>):</span><br><span class="line"> ob = self.observation_space.sample()</span><br><span class="line"> <span class="keyword">return</span> ob </span><br><span class="line">env = MyEnv()</span><br><span class="line"><span class="built_in">print</span>(<span class="string">'sample random observation value'</span>)</span><br><span class="line"><span class="built_in">print</span>(env.observation_space.sample())</span><br><span class="line"><span class="built_in">print</span>(<span class="string">'sample random action value'</span>)</span><br><span class="line"><span class="built_in">print</span>(env.action_space.sample())</span><br><span class="line"><span class="comment"># 输出:</span></span><br><span class="line"><span class="comment"># sample random observation value</span></span><br><span class="line"><span class="comment"># [0.23197113 0.8055692 ]</span></span><br><span class="line"><span class="comment"># sample random action value</span></span><br><span class="line"><span class="comment"># 0</span></span><br></pre></td></tr></table></figure><p>另一个需要定义的关键方法是<code>step</code>方法,用于接收智能体的动作后更新环境、输出观测和奖励。</p><p><code>step</code>方法将<code>action</code>作为输入,并输出智能体的下一个观测<code>observation</code>,智能体获得的标量奖励<code>reward</code>,用于描述环境是否需要重置的布尔值<code>done</code>,以及包含任何额外信息的字典<code>info</code>。</p><p>如果环境通过内部状态描述,<code>reset</code>方法需要重置这些内部状态。该方法返回一个初始观测<code>observation</code>。</p><p>下面我们定义一个简单的任务,智能体沿着一维直线采取动作。奖励由智能体在直线上的位置决定。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">get_reward</span>(<span class="params">x</span>):</span><br><span class="line"> <span class="keyword">return</span> np.sin(x) * np.exp(-np.<span class="built_in">abs</span>(x)/<span class="number">3</span>)</span><br><span class="line"></span><br><span class="line">xs = np.linspace(-<span class="number">10</span>, <span class="number">10</span>, <span class="number">100</span>)</span><br><span class="line">plt.plot(xs, get_reward(xs))</span><br><span class="line">plt.xlabel(<span class="string">'State value(observation)'</span>)</span><br><span class="line">plt.ylabel(<span class="string">'Reward'</span>)</span><br></pre></td></tr></table></figure><p><img src="https://img.cwxhmk.top/post/20230719-1.png" alt="运行结果"><br>智能体可以与环节迭代地互动,红色星星表示智能体的初始状态。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">MyEnv</span>(gym.Env):</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line"> <span class="built_in">super</span>().__init__()</span><br><span class="line"> self.observation_space = gym.spaces.Box(-<span class="number">10</span>,<span class="number">10</span>,(<span class="number">1</span>,))</span><br><span class="line"> self.action_space = gym.spaces.Discrete(<span class="number">3</span>) <span class="comment"># 0,1,2</span></span><br><span class="line"> self.state = <span class="number">0.</span></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">step</span>(<span class="params">self,action</span>):</span><br><span class="line"> self.state += (action - <span class="number">1.</span>) * <span class="number">0.1</span> <span class="comment"># action 0 1 2 对应状态 -0.1 0 0.1</span></span><br><span class="line"> self.state = np.clip(self.state, -<span class="number">10</span>, <span class="number">10</span>) <span class="comment"># 限制取值范围</span></span><br><span class="line"> ob = self.state</span><br><span class="line"> reward = get_reward(self.state)</span><br><span class="line"> done = <span class="literal">False</span></span><br><span class="line"> info = {}</span><br><span class="line"> <span class="keyword">return</span> ob, reward, done, info</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">reset</span>(<span class="params">self</span>):</span><br><span class="line"> <span class="comment"># 重新初始化状态</span></span><br><span class="line"> self.state = self.observation_space.sample()</span><br><span class="line"> <span class="keyword">return</span> self.state</span><br><span class="line">env = MyEnv()</span><br><span class="line">ob = env.reset() </span><br><span class="line">ob_log = <span class="built_in">list</span>() </span><br><span class="line">reward_log = <span class="built_in">list</span>()</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1000</span>):</span><br><span class="line"> action = env.action_space.sample()</span><br><span class="line"> ob, reward, done, info = env.step(action)</span><br><span class="line"> ob_log.append(ob)</span><br><span class="line"> reward_log.append(reward)</span><br><span class="line">plt.plot(ob_log, reward_log)</span><br><span class="line">plt.xlabel(<span class="string">'State value(observation)'</span>)</span><br><span class="line">plt.ylabel(<span class="string">'Reward'</span>)</span><br></pre></td></tr></table></figure><p><img src="https://img.cwxhmk.top/post/20230719-2.png" alt="运行结果"></p><h1 id="基于试次(trial)的Neurogym任务"><a href="#基于试次(trial)的Neurogym任务" class="headerlink" title="基于试次(trial)的Neurogym任务"></a>基于试次(trial)的Neurogym任务</h1><p>许多神经科学和认知科学的任务有试次结构。<code>neurogym.TrialEnv</code>为常见的基于试次任务提供了类。它与<code>gym.Env</code>的主要不同在于<code>_new_trial()</code>方法,该方法可以生成新试次的摘要信息,并且可选择地,生成观测和真实值输出。除此之外,用户提供了<code>_step()</code>方法而不是<code>step()</code>方法。</p><p><code>_new_trial()</code>方法接收任意键-值参数<code>**kwargs</code>,输出一个包含该试次相关信息的字典<code>trial</code>。这个字典在<code>_step</code>中可以作为<code>self.trial</code>访问。</p><p>这里我们定义一个简单的任务,智能体在每个试次需要基于它的观测做出一个二元决策。每个试次只有一个时间步。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> neurogym <span class="keyword">as</span> ngym</span><br><span class="line"><span class="keyword">from</span> neurogym <span class="keyword">import</span> TrialEnv</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">MyTrialEnv</span>(<span class="title class_ inherited__">TrialEnv</span>):</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self</span>):</span><br><span class="line"> <span class="built_in">super</span>().__init__()</span><br><span class="line"> self.observation_space = gym.spaces.Box(-<span class="number">1.</span>, <span class="number">1.</span>, (<span class="number">1</span>,))</span><br><span class="line"> self.action_space = gym.spaces.Discrete(<span class="number">2</span>) <span class="comment"># 0 1</span></span><br><span class="line"> self.next_ob = np.random.uniform(-<span class="number">1</span>, <span class="number">1</span>, size=(<span class="number">1</span>,)) <span class="comment"># 用于生成[-1,1)范围内均分分布的随机数</span></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">_new_trial</span>(<span class="params">self</span>): <span class="comment"># 实现父类TrialEnv中的_new_trial和_step方法</span></span><br><span class="line"> ob = self.next_ob</span><br><span class="line"> self.next_ob = np.random.uniform(-<span class="number">1</span>, <span class="number">1</span>, size=(<span class="number">1</span>,))</span><br><span class="line"> trial = <span class="built_in">dict</span>()</span><br><span class="line"> trial[<span class="string">'ground_truth'</span>] = (ob > <span class="number">0</span>) * <span class="number">1.0</span></span><br><span class="line"> <span class="keyword">return</span> trial</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">_step</span>(<span class="params">self, action</span>):</span><br><span class="line"> ob = self.next_ob</span><br><span class="line"> reward = (action == self.trial[<span class="string">'ground_truth'</span>]) * <span class="number">1.0</span></span><br><span class="line"> </span><br><span class="line"> done = <span class="literal">False</span></span><br><span class="line"> info = {<span class="string">'new_trial'</span>: <span class="literal">True</span>}</span><br><span class="line"> <span class="keyword">return</span> ob, reward, done, info</span><br><span class="line"></span><br><span class="line">env = MyTrialEnv()</span><br><span class="line">ob = env.reset()</span><br><span class="line"><span class="built_in">print</span>(<span class="string">'Trial'</span>, <span class="number">0</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">'Observation'</span>, ob)</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">5</span>):</span><br><span class="line"> action = env.action_space.sample()</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'Action'</span>, action)</span><br><span class="line"> ob, reward, done, info = env.step(action)</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'Reward'</span>, reward)</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'Trial'</span>, i+<span class="number">1</span>)</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'Observation'</span>, ob)</span><br><span class="line"> Trial <span class="number">0</span></span><br><span class="line"><span class="comment"># 输出:</span></span><br><span class="line"><span class="comment"># Observation [0.37521716]</span></span><br><span class="line"><span class="comment"># Action 1</span></span><br><span class="line"><span class="comment"># Reward [1.]</span></span><br><span class="line"><span class="comment"># Trial 1</span></span><br><span class="line"><span class="comment"># Observation [0.88569181]</span></span><br><span class="line"><span class="comment"># Action 1</span></span><br><span class="line"><span class="comment"># Reward [1.] ···</span></span><br></pre></td></tr></table></figure><p><code>TrialEnv</code>类定义了两个抽象方法:<code>_new_trial()</code>和<code>_step()</code>。这两个方法没有具体的实现,只有方法的声明和文档字符串。这样做的目的是强制任何继承<code>TrialEnv</code>的子类必须实现这两个方法,以便成为一个完整的环境。</p><p>环境<code>reset</code>时会调用<code>new_trial()</code>方法,<code>step</code>之后也会调用<code>new_trial()</code>方法,只不过这些是在父类中实现的,我们创建环境时只需要把<code>_new_trial()</code>方法实现即可。</p><p>具体可见neurogym目录下的<code>core.py</code>文件。</p><h1 id="在基于试次的任务中包含时间,阶段和观测"><a href="#在基于试次的任务中包含时间,阶段和观测" class="headerlink" title="在基于试次的任务中包含时间,阶段和观测"></a>在基于试次的任务中包含时间,阶段和观测</h1><p>许多神经科学和认知科学任务遵循额外的时间结构,这些结构被包含进<code>neurogym.TrialEnv</code>。这些任务通常</p><ol><li>描述为实际时间而不是离散时间步。例如,任务可以持续3s</li><li>每个试次包含许多时间阶段,比如刺激阶段和响应阶段。</li></ol><p>为了包含这些特征,neurogym任务通常支持设置每一步的时间长度<code>dt</code>(单位为ms),以及每个时间阶段的时间长度<code>timing</code>。</p><p>例如,考虑下面的二元决策任务,有500ms的刺激阶段,跟着500ms的决策阶段。可以通过<code>self._new_trial()</code>中的<code>self.add_period()</code>在每个试次中添加阶段。在<code>_step()</code>中,你可以通过<code>self.in_period(period_name)</code>检查任务当前所处的阶段。</p><div class="note warning flat"><p>关于这段代码,我真的向多说几句:官方文档给的这段示例代码有点问题,按它原本的写法,stimulus阶段不应该获得奖励,但是奖励却为1。我调试了很久,总觉得observation、action和reward之间错位了,但看代码又找不出具体问题。今天上午终于发现了,在<code>env.reset()</code>时stimulus阶段就开始了,等进入循环时时间步已经走了一步了,但是此时仍用初始的观测执行<code>env.step(action)</code>,就会造成reward不匹配。所以采取的修改方式是删掉循环外存储的<code>ob</code>,直接从第二个时间步开始,这样就不会错位了。</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">import</span> neurogym <span class="keyword">as</span> ngym</span><br><span class="line"><span class="keyword">import</span> gym</span><br><span class="line"><span class="keyword">from</span> neurogym <span class="keyword">import</span> TrialEnv</span><br><span class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</span><br><span class="line">plt.rcParams[<span class="string">'font.family'</span>] = <span class="string">'DejaVu Sans'</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">MyDecisionEnv</span>(<span class="title class_ inherited__">TrialEnv</span>):</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, dt=<span class="number">100</span>, timing=<span class="literal">None</span></span>):</span><br><span class="line"> <span class="built_in">super</span>().__init__(dt=dt)</span><br><span class="line"> self.timing = {<span class="string">'stimulus'</span>:<span class="number">500</span>, <span class="string">'decision'</span>:<span class="number">500</span>}</span><br><span class="line"> <span class="keyword">if</span> timing:</span><br><span class="line"> self.timing.update(timing)</span><br><span class="line"> self.observation_space = gym.spaces.Box(-<span class="number">1.</span>, <span class="number">1.</span>, (<span class="number">1</span>,))</span><br><span class="line"> self.action_space = gym.spaces.Discrete(<span class="number">2</span>)</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">_new_trial</span>(<span class="params">self</span>):</span><br><span class="line"> periods = [<span class="string">'stimulus'</span>, <span class="string">'decision'</span>]</span><br><span class="line"> self.add_period(periods)</span><br><span class="line"></span><br><span class="line"> stimulus = np.random.uniform(-<span class="number">1</span>, <span class="number">1</span>, (<span class="number">1</span>,))</span><br><span class="line"> trial = <span class="built_in">dict</span>()</span><br><span class="line"> trial[<span class="string">'stimulus'</span>] = stimulus</span><br><span class="line"> trial[<span class="string">'ground_truth'</span>] = (stimulus > <span class="number">0</span>) * <span class="number">1.0</span></span><br><span class="line"> trial[<span class="string">'new_trial'</span>] = <span class="literal">True</span></span><br><span class="line"> <span class="keyword">return</span> trial</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">_step</span>(<span class="params">self, action</span>):</span><br><span class="line"> <span class="keyword">if</span> self.in_period(<span class="string">'stimulus'</span>):</span><br><span class="line"> ob = np.array([self.trial[<span class="string">'stimulus'</span>]])</span><br><span class="line"> reward = <span class="number">0.</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> ob = np.array([<span class="number">0.</span>])</span><br><span class="line"> reward = (action==self.trial[<span class="string">'ground_truth'</span>])*<span class="number">1.0</span></span><br><span class="line"> </span><br><span class="line"> done = <span class="literal">False</span></span><br><span class="line"> info = {<span class="string">'new_trial'</span>: <span class="literal">False</span>}</span><br><span class="line"> <span class="keyword">return</span> ob, reward, done, info</span><br><span class="line"></span><br><span class="line">log = {<span class="string">'ob'</span>:[], <span class="string">'action'</span>:[], <span class="string">'reward'</span>:[]}</span><br><span class="line">env = MyDecisionEnv(dt=<span class="number">100</span>)</span><br><span class="line">ob = env.reset()</span><br><span class="line"></span><br><span class="line"><span class="comment"># log['ob'].append(ob)</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">20</span>):</span><br><span class="line"> action = env.action_space.sample()</span><br><span class="line"> log[<span class="string">'action'</span>].append(action)</span><br><span class="line"> ob, reward, done, info = env.step(action)</span><br><span class="line"> log[<span class="string">'reward'</span>].append(reward)</span><br><span class="line"> log[<span class="string">'ob'</span>].append(ob)</span><br><span class="line"></span><br><span class="line">log[<span class="string">'ob'</span>] = log[<span class="string">'ob'</span>][:-<span class="number">1</span>]</span><br><span class="line">f, axes = plt.subplots(<span class="number">3</span>, <span class="number">1</span>, sharex=<span class="literal">True</span>)</span><br><span class="line"><span class="keyword">for</span> ax, key <span class="keyword">in</span> <span class="built_in">zip</span>(axes, [<span class="string">'ob'</span>, <span class="string">'action'</span>, <span class="string">'reward'</span>]):</span><br><span class="line"> ax.plot(log[key], <span class="string">'o-'</span>)</span><br><span class="line"> ax.set_ylabel(key)</span><br></pre></td></tr></table></figure><p><img src="https://img.cwxhmk.top/post/20230721-1.png" alt="运行结果"></p><h1 id="在每个试次的开始设置观测和真实值"><a href="#在每个试次的开始设置观测和真实值" class="headerlink" title="在每个试次的开始设置观测和真实值"></a>在每个试次的开始设置观测和真实值</h1><p>在许多任务中,每个试次的观测和真实值是提前确定的,可以在<code>self._new_trial()</code>中设置。生成的观测和真实值可以用作监督学习的输入和目标。</p><p>观测和真实值可以在<code>self._new_trial()</code>中通过<code>self.add_ob()</code>和<code>self.set_groundtruth()</code>方法设置。用户可以用它们的名字指明观测的阶段和位置。比如,<code>self.add_ob(1, period='stimulus', where='fixation')</code>。</p><p>允许用户通过<code>self.ob</code>和<code>self.gt</code>访问整个试次的观测和真实值,并通过<code>self.ob_now</code>和<code>self.gt_now</code>访问它们的值。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">import</span> neurogym <span class="keyword">as</span> ngym</span><br><span class="line"><span class="keyword">import</span> gym</span><br><span class="line"><span class="keyword">from</span> neurogym <span class="keyword">import</span> TrialEnv</span><br><span class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</span><br><span class="line">plt.rcParams[<span class="string">'font.family'</span>] = <span class="string">'DejaVu Sans'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">MyDecisionEnv</span>(<span class="title class_ inherited__">TrialEnv</span>):</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, dt=<span class="number">100</span>, timing=<span class="literal">None</span></span>): </span><br><span class="line"> <span class="comment"># 初始化,关键是设置观测空间和动作空间</span></span><br><span class="line"> <span class="built_in">super</span>().__init__(dt=dt)</span><br><span class="line"> self.timing = {<span class="string">'stimulus'</span>:<span class="number">500</span>, <span class="string">'decision'</span>:<span class="number">500</span>}</span><br><span class="line"> <span class="keyword">if</span> timing:</span><br><span class="line"> self.timing.update(timing)</span><br><span class="line"> </span><br><span class="line"> name = {<span class="string">'fixation'</span>: <span class="number">0</span>, <span class="string">'stimulus'</span>: <span class="number">1</span>}</span><br><span class="line"> self.observation_space = ngym.spaces.Box(low=-<span class="number">1</span>, high=<span class="number">1</span>, shape=(<span class="number">2</span>,), name=name) <span class="comment"># 可以给每个维度命名</span></span><br><span class="line"> name = {<span class="string">'fixation'</span>:<span class="number">0</span>, <span class="string">'choice'</span>:[<span class="number">1</span>,<span class="number">2</span>]}</span><br><span class="line"> self.action_space = ngym.spaces.Discrete(<span class="number">3</span>, name=name)</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">_new_trial</span>(<span class="params">self</span>):</span><br><span class="line"> <span class="comment"># 返回试次相关信息:阶段,刺激,真实值等</span></span><br><span class="line"> periods = [<span class="string">'stimulus'</span>, <span class="string">'decision'</span>]</span><br><span class="line"> self.add_period(periods)</span><br><span class="line"> stimulus = np.random.uniform(-<span class="number">1</span>, <span class="number">1</span>, (<span class="number">1</span>,))</span><br><span class="line"> self.add_ob(<span class="number">1</span>, period=<span class="string">"stimulus"</span>, where=<span class="string">"fixation"</span>)</span><br><span class="line"> self.add_ob(stimulus, period=<span class="string">"stimulus"</span>, where=<span class="string">"stimulus"</span>)</span><br><span class="line"> <span class="comment"># where对应的是维度名</span></span><br><span class="line"> ground_truth = <span class="built_in">int</span>(stimulus > <span class="number">0</span>)</span><br><span class="line"> self.set_groundtruth(ground_truth, period=<span class="string">"decision"</span>, where=<span class="string">"choice"</span>)</span><br><span class="line"></span><br><span class="line"> trial = <span class="built_in">dict</span>()</span><br><span class="line"> trial[<span class="string">'stimulus'</span>] = stimulus</span><br><span class="line"> trial[<span class="string">'ground_truth'</span>] = ground_truth</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> trial</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">_step</span>(<span class="params">self, action</span>):</span><br><span class="line"> <span class="comment"># 执行动作,返回观测,奖励等信息</span></span><br><span class="line"> reward = (action==self.gt_now) * <span class="number">1.0</span></span><br><span class="line"> done = <span class="literal">False</span> <span class="comment"># 环境是否需要重置</span></span><br><span class="line"> info = {<span class="string">'new_trial'</span>: <span class="literal">False</span>}</span><br><span class="line"> <span class="keyword">return</span> self.ob_now, reward, done, info</span><br><span class="line">env = MyDecisionEnv()</span><br><span class="line">_ = env.reset()</span><br><span class="line"></span><br><span class="line">trial = env.new_trial()</span><br><span class="line">ob, gt = env.ob, env.gt</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(trial)</span><br><span class="line"><span class="built_in">print</span>(ob)</span><br><span class="line"><span class="built_in">print</span>(gt)</span><br><span class="line">fig = ngym.utils.plot_env(env, num_trials=<span class="number">2</span>)</span><br></pre></td></tr></table></figure><h1 id="补充知识"><a href="#补充知识" class="headerlink" title="补充知识"></a>补充知识</h1><ol><li><strong>self:</strong> 在Python中,当定义一个类方法时,第一个参数通常被称为<code>self</code>,它代表类的实例对象,允许在类的方法中访问对象的属性和其他方法。</li><li><strong>super().<strong>init</strong>():</strong> 在面向对象编程中,当创建一个子类时,通常需要继承父类的属性和方法,可以使用<code>super().__init__()</code>来调用父类的构造方法,确保父类的初始化代码得以执行。当<code>super().__init__()</code>不带参数时,它会调用父类的构造方法,并将子类的实例作为第一个参数传递给父类的构造方法。</li><li><strong>继承:</strong> 在面向对象编程中,继承是一种重要的概念,它允许你创建一个新的类(子类),从一个现有的类(父类)继承属性和方法。子类可以访问父类的属性和方法,并且还可以添加自己的属性和方法。如<code>class Child(Parent):</code> 这样的语法表示子类 Child 继承了父类 Parent。</li><li><strong>时间步(time step):</strong> 在计算机科学和数学中,时间步长通常用于描述在离散时间模型中的时间间隔。理解时间步长的关键是认识到许多模型和系统在仿真或模拟时需要将时间划分成离散的部分,而时间步长就是这个离散化的单位。在每个时间步长内,系统的状态会被更新,从而使得系统在连续时间范围内的变化可以通过离散时间步长来近似。</li><li><strong>抽象方法:</strong> 抽象方法是指在父类中声明但没有具体实现的方法,它只有方法名、参数列表和文档字符串,没有具体的代码实现。子类继承这个父类时,必须实现这些抽象方法,否则子类也会被视为抽象类,无法实例化。</li></ol><h1 id="参考内容"><a href="#参考内容" class="headerlink" title="参考内容"></a>参考内容</h1><ul><li><a href="https://neurogym.github.io/index.html">neurogym’s documentation!</a></li><li><a href="https://www.gymlibrary.dev/content/basic_usage/">Gym Documentation</a></li><li><a href="https://gymnasium.farama.org/content/basic_usage/">Gymnasium Documentation</a></li><li><a href="https://zhuanlan.zhihu.com/p/89549054">接口与抽象基类</a></li></ul>]]></content>
<categories>
<category> 学习笔记 </category>
</categories>
</entry>
<entry>
<title>二维脑片配准插件开发</title>
<link href="/2023/07/16/imagej-plugin-8/"/>
<url>/2023/07/16/imagej-plugin-8/</url>
<content type="html"><![CDATA[<h1 id="具体步骤"><a href="#具体步骤" class="headerlink" title="具体步骤"></a>具体步骤</h1><ol><li><p>在Eclipse中配置Maven环境 Window → Preferences → Maven → Installations → Add → 找到Maven安装路径</p></li><li><p>创建Maven项目 File → New → Other → Maven Project → Create a simple project</p></li><li><p>编写组件并合理布局(FlowLayout和BoxLayout结合)</p><img src="https://img.cwxhmk.top/post/20230717-1.png" alt="界面展示" width="50%" height="50%" /> </li><li><p>编写<mark class="hl-label pink">选择按钮</mark> 和<mark class="hl-label pink">确认按钮</mark> 的触发事件</p></li><li><p>编写<mark class="hl-label pink">降采样按钮</mark> 、<mark class="hl-label pink">配准</mark> 、<mark class="hl-label pink">合并通道</mark> 和<mark class="hl-label pink">保存</mark> 的触发事件</p></li><li><p>整理目录结构:<code>input</code>文件夹存放原始脑片,<code>output</code>文件夹存放配准合并完成的图片,<code>params</code>文件夹存放配准参数,<code>registration</code>文件夹存放中间处理过程得到的图片以及配准文件<br><img src="https://img.cwxhmk.top/post/20230719-3.png" alt="目录结构"></p></li><li><p><code>Run as Maven build</code>生成jar包</p></li></ol><h1 id="效果展示"><a href="#效果展示" class="headerlink" title="效果展示"></a>效果展示</h1><p><img src="https://img.cwxhmk.top/gif/7caa0525-2d17-4fd1-b3a8-c63d54d0b051.gif" alt="效果展示"></p><h1 id="问题记录"><a href="#问题记录" class="headerlink" title="问题记录"></a>问题记录</h1><ol><li>为什么编写了按钮的触发事件后,运行程序时点击按钮没有反应?<br><strong>答:</strong>需要调用event()函数!</li><li>想获取tempImage.tif中某一张图片,但是总报错说out of range<br><strong>答:</strong>不能在使用<code>tempStack.getProcessor(tempIndex)</code>之前使用<code>tempImage.close()</code>,但手动关闭是不影响的。</li><li>Java中string转int<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> <span class="variable">tempIndex</span> <span class="operator">=</span> Integer.valueOf(tempNum.getText());</span><br></pre></td></tr></table></figure></li><li>运行命令行输出的内容如何动态打印到JTextArea<div class="note info flat"><ol start="5"><li>如何获取<code>resources</code>下的文件?<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">this</span>.getClass().getClassLoader().getResource(<span class="string">"tempImage.tif"</span>).getPath()</span><br></pre></td></tr></table></figure><strong>ChatGPT:</strong><br>当你在执行命令行时,使用Runtime.getRuntime().exec()方法或ProcessBuilder类的start()方法会创建一个新的进程来运行命令。这个新的进程与你的Java程序是独立的,它在操作系统中运行,并与你的Java程序并行执行。这意味着在主线程中执行命令行时,主线程将会被阻塞(即暂停执行),直到命令行执行完毕。</li></ol><p>如果命令行的输出量较大,或者命令行执行时间较长,主线程被阻塞的时间会很长,可能导致你的界面无响应,因为界面的更新和事件处理通常也是在主线程中进行的。</p><p>通过创建一个新的线程来执行命令行,我们实现了并发执行。这意味着在主线程中调用registration()方法时,新线程会被启动,然后在新线程中执行命令行,而主线程会继续执行接下来的代码,保持界面的响应。这样,即使命令行执行时间很长,主线程也不会被阻塞,界面仍然可以响应用户的交互。</p><p>在新线程中,我们使用BufferedReader来读取命令行的输出流,并实时将输出内容追加到JTextArea中,通过调用pluginMain.logMessage.repaint()来强制刷新文本区域,使得输出内容在JTextArea中动态显示。</p><p>使用新线程来执行耗时操作,如命令行执行、网络请求等,是一种常见的做法,它能够有效地保持界面的响应性,提升用户体验。在Java中,你可以通过创建Thread对象,或者使用ExecutorService等高级并发工具来管理线程的执行。</p></div></li><li>调用transform方法时,JTextArea中的内容为什么没有更新<div class="note info flat"><p><strong>ChatGPT:</strong><br>根据你提供的Registration类中的registration()和transform()方法,我注意到在调用transform()方法之前,你通过创建线程来执行了elastix命令。在这种情况下,可能出现elastix命令尚未执行完成,就开始执行transform()方法。</p><p>由于两个命令都是通过独立的线程执行的,所以在elastix命令执行期间,可能会同时执行transform()方法。因此,你可能会看到命令输出结果交错显示,甚至transform()方法的输出可能会被elastix命令的输出覆盖。</p><p>为了确保elastix命令执行完毕后再执行transform()方法,你可以在registration()方法中等待elastix命令执行完成后再调用transform()方法。可以使用Process对象的waitFor()方法,该方法会阻塞当前线程,直到命令执行完成。</p></div><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">registration</span><span class="params">()</span> {</span><br><span class="line"> <span class="type">String</span> <span class="variable">elastixUrl</span> <span class="operator">=</span> <span class="string">"D:/Desktop/brainPro/elastix"</span>;</span><br><span class="line"> <span class="type">String</span> <span class="variable">brainUrl</span> <span class="operator">=</span> <span class="string">"D:/Desktop/brainPro/registration/resizedImage.tif"</span>;</span><br><span class="line"> <span class="type">String</span> <span class="variable">regisTempUrl</span> <span class="operator">=</span> <span class="string">"D:/Desktop/brainPro/registration/regisTemp.tif"</span>;</span><br><span class="line"></span><br><span class="line"> <span class="type">String</span> <span class="variable">cmd</span> <span class="operator">=</span> elastixUrl + <span class="string">" -f "</span> + brainUrl + <span class="string">" -m "</span> + regisTempUrl + <span class="string">" -out "</span> + output_1 + <span class="string">" -p "</span> + GlobalPath+<span class="string">"params/para-Standard_bspline.txt"</span>;</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">new</span> <span class="title class_">Thread</span>(() -> {</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="type">Process</span> <span class="variable">ps</span> <span class="operator">=</span> Runtime.getRuntime().exec(cmd);</span><br><span class="line"> <span class="type">BufferedReader</span> <span class="variable">br</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">BufferedReader</span>(<span class="keyword">new</span> <span class="title class_">InputStreamReader</span>(ps.getInputStream()));</span><br><span class="line"> String line;</span><br><span class="line"> <span class="keyword">while</span> ((line = br.readLine()) != <span class="literal">null</span>) {</span><br><span class="line"> pluginMain.logMessage.append(line + <span class="string">"\n"</span>);</span><br><span class="line"> pluginMain.logMessage.setCaretPosition(pluginMain.logMessage.getDocument().getLength()); <span class="comment">// 滚动到文本末尾</span></span><br><span class="line"> pluginMain.logMessage.repaint(); <span class="comment">// 强制刷新文本区域</span></span><br><span class="line"> }</span><br><span class="line"> ps.waitFor(); <span class="comment">// 等待命令执行完成</span></span><br><span class="line"> transform(); <span class="comment">// 在elastix命令执行完成后调用transform()方法</span></span><br><span class="line"> } <span class="keyword">catch</span> (Exception e) {</span><br><span class="line"> e.printStackTrace();</span><br><span class="line"> }</span><br><span class="line"> }).start();</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li><li>如何确定配准全部完成后再执行接下来的程序?<div class="note info flat"><p><strong>ChatGPT:</strong><br>当我们在Java中定义一个接口,实际上是在创建一种契约,定义了一组方法的签名,而不包含方法的实现。其他类可以实现这个接口并提供实际的方法实现,从而达到对某种功能或行为的规范和约束。在这里,我们要使用接口来实现回调机制,回调机制是一种异步通信的方式,允许一个对象在特定事件发生时通知另一个对象执行特定的操作。</p><p>首先,我们定义一个接口RegistrationCallback,其中包含方法:onTransformCompleted()。</p><p>这个接口中并没有实现任何方法,只是规定了这两个方法的签名。现在我们将在Registration类中使用这个接口。在Registration类中添加一个私有成员变量callback,用于保存实现了RegistrationCallback接口的对象。</p><p>在registration()方法中,我们可以接收一个实现了RegistrationCallback接口的对象,并将它保存在callback变量中。</p><p>在transform()方法中的合适时机调用回调方法。在onTransformFinished()方法中,我们会首先检查callback是否为null,如果不为null,则调用回调对象的对应方法。</p><p>现在,当我们在pluginMain类的registrationBtn监听器中调用Registration类的registration()方法时,我们可以传递一个实现了RegistrationCallback接口的对象。这样,在配准和转换完成后,Registration类会调用回调方法,并在回调方法中执行相应的操作。</p><p>这样可以确保在配准和转换都完成后再执行相关操作。</p></div><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 新建一个接口RegistrationCallback.java</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">interface</span> <span class="title class_">RegistrationCallback</span> {</span><br><span class="line"><span class="keyword">void</span> <span class="title function_">onTransformCompleted</span><span class="params">()</span>;</span><br><span class="line">}</span><br><span class="line"><span class="comment">// Registration.java</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Registration</span> {</span><br><span class="line"><span class="keyword">private</span> RegistrationCallback callback;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="type">String</span> <span class="variable">GlobalPath</span> <span class="operator">=</span> <span class="string">"D:/Desktop/brainPro/"</span>;</span><br><span class="line"><span class="keyword">public</span> String output_1= <span class="string">"D:/Desktop/brainPro/registration/temp1"</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">registration</span><span class="params">(RegistrationCallback callback)</span> {</span><br><span class="line"><span class="built_in">this</span>.callback = callback;</span><br><span class="line"><span class="type">String</span> <span class="variable">elastixUrl</span> <span class="operator">=</span> <span class="string">"D:/Desktop/brainPro/elastix"</span>;</span><br><span class="line"><span class="type">String</span> <span class="variable">brainUrl</span> <span class="operator">=</span> <span class="string">"D:/Desktop/brainPro/registration/resizedImage.tif"</span>;</span><br><span class="line"><span class="type">String</span> <span class="variable">regisTempUrl</span> <span class="operator">=</span> <span class="string">"D:/Desktop/brainPro/registration/regisTemp.tif"</span>;</span><br><span class="line"></span><br><span class="line"><span class="type">String</span> <span class="variable">cmd</span> <span class="operator">=</span> elastixUrl + <span class="string">" -f "</span> + brainUrl + <span class="string">" -m "</span> + regisTempUrl + <span class="string">" -out "</span> + output_1 + <span class="string">" -p "</span> + GlobalPath+<span class="string">"params/para-Standard_bspline.txt"</span>;</span><br><span class="line"><span class="keyword">new</span> <span class="title class_">Thread</span>(() -> {</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="type">Process</span> <span class="variable">ps</span> <span class="operator">=</span> Runtime.getRuntime().exec(cmd);</span><br><span class="line"> <span class="comment">// ps.getInputStream() 获取进程的输出流</span></span><br><span class="line"> <span class="type">BufferedReader</span> <span class="variable">br</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">BufferedReader</span>(<span class="keyword">new</span> <span class="title class_">InputStreamReader</span>(ps.getInputStream()));</span><br><span class="line"> String line;</span><br><span class="line"> <span class="keyword">while</span> ((line = br.readLine()) != <span class="literal">null</span>) {</span><br><span class="line"> pluginMain.logMessage.append(line + <span class="string">"\n"</span>);</span><br><span class="line"> pluginMain.logMessage.setCaretPosition(pluginMain.logMessage.getDocument().getLength()); <span class="comment">// 滚动到文本末尾</span></span><br><span class="line"> pluginMain.logMessage.repaint(); <span class="comment">// 强制刷新文本区域</span></span><br><span class="line"> }</span><br><span class="line"> ps.waitFor();</span><br><span class="line"> transform();</span><br><span class="line"> } <span class="keyword">catch</span> (Exception e) {</span><br><span class="line"> e.printStackTrace();</span><br><span class="line"> }</span><br><span class="line"> }).start();</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">transform</span><span class="params">()</span> {</span><br><span class="line"><span class="type">String</span> <span class="variable">transformixUrl</span> <span class="operator">=</span> <span class="string">"D:/Desktop/brainPro/transformix"</span>;</span><br><span class="line"><span class="type">String</span> <span class="variable">outputDir</span> <span class="operator">=</span> <span class="string">"D:/Desktop/brainPro/registration/temp2"</span>;</span><br><span class="line"><span class="type">String</span> <span class="variable">regisAnnoUrl</span> <span class="operator">=</span> <span class="string">"D:/Desktop/brainPro/registration/regisAnno.tif"</span>;</span><br><span class="line"></span><br><span class="line"><span class="type">String</span> <span class="variable">cmd</span> <span class="operator">=</span> transformixUrl + <span class="string">" -in "</span> + regisAnnoUrl + <span class="string">" -out "</span> + outputDir + <span class="string">" -tp "</span> + output_1 + <span class="string">"/TransformParameters.0.txt"</span>;</span><br><span class="line"><span class="keyword">new</span> <span class="title class_">Thread</span>(() -> {</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> <span class="type">Process</span> <span class="variable">ps</span> <span class="operator">=</span> Runtime.getRuntime().exec(cmd);</span><br><span class="line"> <span class="type">BufferedReader</span> <span class="variable">br</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">BufferedReader</span>(<span class="keyword">new</span> <span class="title class_">InputStreamReader</span>(ps.getInputStream()));</span><br><span class="line"> String line;</span><br><span class="line"> <span class="keyword">while</span> ((line = br.readLine()) != <span class="literal">null</span>) {</span><br><span class="line"> pluginMain.logMessage.append(line + <span class="string">"\n"</span>);</span><br><span class="line"> pluginMain.logMessage.setCaretPosition(pluginMain.logMessage.getDocument().getLength()); <span class="comment">// 滚动到文本末尾</span></span><br><span class="line"> pluginMain.logMessage.repaint(); <span class="comment">// 强制刷新文本区域</span></span><br><span class="line"> }</span><br><span class="line"> ps.waitFor();</span><br><span class="line"> onTransformFinished();</span><br><span class="line"> } <span class="keyword">catch</span> (Exception e) {</span><br><span class="line"> e.printStackTrace();</span><br><span class="line"> }</span><br><span class="line"> }).start();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title function_">onTransformFinished</span><span class="params">()</span> {</span><br><span class="line"><span class="keyword">if</span> (callback != <span class="literal">null</span>) {</span><br><span class="line"> callback.onTransformCompleted();</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"><span class="comment">// pluginMain.java</span></span><br><span class="line">registrationBtn.addActionListener(<span class="keyword">new</span> <span class="title class_">ActionListener</span>() {</span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">actionPerformed</span><span class="params">(ActionEvent e)</span> {</span><br><span class="line"> <span class="keyword">new</span> <span class="title class_">Registration</span>().registration(<span class="keyword">new</span> <span class="title class_">RegistrationCallback</span>() {</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">onTransformCompleted</span><span class="params">()</span> {</span><br><span class="line"> <span class="comment">// TODO Auto-generated method stub</span></span><br><span class="line"> regisAnno = <span class="keyword">new</span> <span class="title class_">ImagePlus</span>(<span class="string">"D:/Desktop/brainPro/registration/temp2/result.tif"</span>);</span><br><span class="line"> logMessage.append(<span class="string">"4. 配准已完成"</span>);</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> });</span><br><span class="line"> </span><br><span class="line"> </span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line">});</span><br></pre></td></tr></table></figure></li></ol><h1 id="参考文章"><a href="#参考文章" class="headerlink" title="参考文章"></a>参考文章</h1><ul><li><a href="https://blog.csdn.net/weixin_43853855/article/details/117073100">maven环境的搭建+eclipse中配置Maven(详细)</a></li><li><a href="https://blog.csdn.net/weixin_41287260/article/details/94317629">Java的AWT控件Button内容乱码的处理方案</a></li><li><a href="https://blog.csdn.net/sweetgirl520/article/details/51346076">java Swing布局管理之BoxLayout布局</a></li><li><a href="https://blog.csdn.net/paullinjie/article/details/51727753">JPanel左对齐</a></li><li><a href="https://blog.csdn.net/m0_46428066/article/details/115073560">eclipse中在pom.xml添加依赖</a></li><li><a href="https://blog.csdn.net/liang5630/article/details/25651491">JFileChooser (Java Swing提供的文件选择对话框)</a></li><li><a href="https://www.cnblogs.com/jone-chen/p/14270358.html">Java整数间的除法运算那点事</a></li><li><a href="https://blog.csdn.net/One_castle/article/details/100177788">java中如何将String类型转化为double类型</a></li><li><a href="https://blog.csdn.net/qq_35573326/article/details/79974366">Java除法运算(保留小数)</a></li></ul>]]></content>
<categories>
<category> 项目实战 </category>
</categories>
<tags>
<tag> Eclipse </tag>
</tags>
</entry>
<entry>
<title>认识你自己</title>
<link href="/2023/07/16/life-review/"/>
<url>/2023/07/16/life-review/</url>
<content type="html"><![CDATA[<p>不知道是从什么时候开始,我变了。刚入学那会我多么希望可以有个朋友和我一起上课、吃饭、坐校车啊,那种一个人走在路上突然冒出来的孤独感,我已经很久没有感受到了。我的内心愈发平静,我的喜好愈发明确,我似乎看见了一个更清晰的自我。</p><p>说实话,我对自己之前的学习习惯不是很满意,知识不成体系,记笔记零零散散,记忆随着时间的推移渐渐消退,我却好像什么也没留下,总有一种学了但没学扎实的感觉。这个习惯被我带到了新学校,每天八点半来到实验室,一整天的时间点开了各种网页,检索了各种知识,看过了但不清楚自己是否记住了,下次遇到问题又是同样的搜索路径。我分析数据、写应用程序,却总觉得这种东拼西凑的知识来得不踏实。</p><p>大约是两周前我开始尝试写博客记录每天的学习内容,不是在一天结束的时候写,而是从早上来到工位开始,每日计划、优质博客、学习进展、方法教程等,什么都可以写,总之就是每天结束时要有所收获。和之前全是随笔的博客相比,工作日写下的博客可以说是干货满满。如果我是做一个小项目或是翻译教材,会在博客标题中标上序号,这个小细节在无形之中转化为我坚持的动力。</p><p>我原本就喜欢写博客,但一般把写博客安排在周末,但周末有时又有别的事情,所以总是断断续续的写。现在把自己喜欢的事情融入到每天的学习中,我的情绪变得更稳定,做事更有底气,效率也更高了。最近这几天不到九点回到宿舍,竟觉得待在宿舍好无聊,明明再有两个小时就要睡觉了,可我却觉得非常难熬,刷短视频没意思,对电视剧、电影或者综艺节目没有任何兴趣,有时躺在床上还会怀念白天的工作时光,真怪。</p><p>之前我总想着早早下班,周末坚决不来实验室,但现在我觉得我想在实验室多学一会,周末在宿舍也没事干不如来实验室,我知道我不是在做给老板看,也不是在为他学,我是为我自己的成长和进步付出时间和精力。</p><p>最近还有一个神奇的变化,我现在晚上十一点基本上倒头就睡,早上六点会自然醒,虽然我现在还是会再睡到闹钟响起,但我还是为这个小小的变化感到惊喜。今天早上买了几本字帖,打算以后六点醒来洗漱完练会字,这是我能想到的相对不打扰舍友又能充分利用清晨时间的一种方式,我想变得更好。</p><p>我很享受现在的生活,自我与工作近乎达到平衡状态,我没有因为忙碌的工作丢掉自我,而是将主动权掌握在自己手中,努力借助更优质的平台实现能力跃迁。</p>]]></content>
<categories>
<category> 生活随笔 </category>
</categories>
</entry>
<entry>
<title>Imairs细胞计数教程</title>
<link href="/2023/07/14/imaris-cell-counting/"/>
<url>/2023/07/14/imaris-cell-counting/</url>
<content type="html"><![CDATA[<h1 id="操作步骤"><a href="#操作步骤" class="headerlink" title="操作步骤"></a>操作步骤</h1><ol><li>将<code>fuseImage</code>导入<code>Imaris</code></li><li><code>Ctrl+D</code>打开通道面板</li><li>点击<code>Slice</code>测量细胞的直径(取个平均值即可)</li><li>点击<code>Add new Spots</code>(图标为一团黄色的小球) → 点击▶️ → 选择source channel(此处为红色) → 填写直径(此处为1.5µm)→ 点击▶️ → 根据实际情况调整阈值 → 点击绿色箭头 → 点击折线图即可看到整张脑片的细胞计数情况</li><li>点击<code>Add new Surfaces</code>(图标为蓝色的椭球) → 点击<code>Skip automatic creation, edit manually</code> → 界面右侧改为<code>Select</code> → 左下角<code>Draw</code> → 沿着要统计的脑区轮廓绘制闭合曲线 → 点击<code>Create Surface</code> → 点击<code>Edit</code>(图标为一支铅笔✏)选择<code>Mask Selection</code> → 保持勾选<code>Duplicate channel before applying mask</code> → 点击<code>OK</code>之后可以在右侧通道处看到新增的通道(Channel 4) → 取消左侧界面<code>Surfaces</code>的勾选,右侧通道仅保留刚刚复制的通道,其余通道取消勾选 → 接下来对该区域进行细胞计数</li><li>点击<code>Add new Spots</code>(图标为一团黄色的小球) → 点击▶️ → 选择source channel(此处注意改为Channel 4) → 填写直径(此处为1.5µm)→ 点击▶️ → 根据实际情况调整阈值 → 点击绿色箭头 → 点击折线图即可看到特定脑区的细胞计数情况</li></ol><h1 id="操作演示"><a href="#操作演示" class="headerlink" title="操作演示"></a>操作演示</h1><iframe src="https://img.cwxhmk.top/gif/1689321542547-1.mp4" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" width="800px" height="470px"> </iframe><h1 id="参考文章"><a href="#参考文章" class="headerlink" title="参考文章"></a>参考文章</h1><ul><li><a href="https://zhuanlan.zhihu.com/p/66408698">手把手教你用软件便捷地统计染色图中不同区域的数据</a></li><li><a href="https://www.freeconvert.com/">免费的视频压缩网站</a></li></ul>]]></content>
<categories>
<category> 方法教程 </category>
</categories>
<tags>
<tag> Imaris </tag>
</tags>
</entry>
<entry>
<title>BIRDS插件代码学习【07】</title>
<link href="/2023/07/14/imagej-plugin-7/"/>
<url>/2023/07/14/imagej-plugin-7/</url>
<content type="html"><![CDATA[<h1 id="图像降采样"><a href="#图像降采样" class="headerlink" title="图像降采样"></a>图像降采样</h1><div class="note info flat"><p>原始脑片分辨率过高,与Allen平均脑模板的分辨率相差过大,为得到更好的配准效果,需要将原始脑片的分辨率降低。<br>😎我原本是在ImageJ软件上操作的,没想到用代码实现也并不复杂!</p></div><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> I.plugin;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> ij.ImagePlus;</span><br><span class="line"><span class="keyword">import</span> ij.gui.NewImage;</span><br><span class="line"><span class="keyword">import</span> ij.io.FileSaver;</span><br><span class="line"><span class="keyword">import</span> ij.process.ImageProcessor;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Test07</span> {</span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> {</span><br><span class="line"><span class="type">ImagePlus</span> <span class="variable">brainImage</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ImagePlus</span>(<span class="string">"D:/Desktop/elastix-5.1.0-win64/input/result1.tif"</span>);</span><br><span class="line"><span class="type">ImageProcessor</span> <span class="variable">bp</span> <span class="operator">=</span> brainImage.getProcessor();</span><br><span class="line"><span class="type">int</span> <span class="variable">width</span> <span class="operator">=</span> bp.getWidth();</span><br><span class="line"><span class="type">int</span> <span class="variable">height</span> <span class="operator">=</span> bp.getHeight();</span><br><span class="line">brainImage.show();</span><br><span class="line"></span><br><span class="line"><span class="type">double</span> <span class="variable">scale</span> <span class="operator">=</span> <span class="number">0.1</span>;</span><br><span class="line"><span class="type">int</span> <span class="variable">newWidth</span> <span class="operator">=</span> (<span class="type">int</span>)(width*scale);</span><br><span class="line"><span class="type">int</span> <span class="variable">newHeight</span> <span class="operator">=</span> (<span class="type">int</span>)(height*scale);</span><br><span class="line"><span class="type">ImagePlus</span> <span class="variable">resizedImage</span> <span class="operator">=</span> NewImage.createByteImage(<span class="string">"resizedImage"</span>, newWidth, newHeight, <span class="number">0</span>, NewImage.FILL_BLACK);</span><br><span class="line"><span class="type">ImageProcessor</span> <span class="variable">rp</span> <span class="operator">=</span> resizedImage.getProcessor();</span><br><span class="line"></span><br><span class="line">rp = bp.resize(newWidth, newHeight, <span class="literal">false</span>);</span><br><span class="line">resizedImage.setProcessor(rp);</span><br><span class="line">resizedImage.show();</span><br><span class="line"></span><br><span class="line"><span class="keyword">new</span> <span class="title class_">FileSaver</span>(resizedImage).saveAsTiff(<span class="string">"D:/Desktop/elastix-5.1.0-win64/input/resized-result1.tif"</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h1 id="脑区识别"><a href="#脑区识别" class="headerlink" title="脑区识别"></a>脑区识别</h1><div class="note info flat"><p>代码效果:鼠标移动到图片的哪个位置,就在Eclipse控制台输出对应的脑区,超出全脑范围则输出null。</p></div><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> I.plugin;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.awt.Point;</span><br><span class="line"><span class="keyword">import</span> java.awt.event.MouseEvent;</span><br><span class="line"><span class="keyword">import</span> java.awt.event.MouseListener;</span><br><span class="line"><span class="keyword">import</span> java.awt.event.MouseMotionListener;</span><br><span class="line"><span class="keyword">import</span> java.io.File;</span><br><span class="line"><span class="keyword">import</span> java.io.IOException;</span><br><span class="line"><span class="keyword">import</span> java.util.HashMap;</span><br><span class="line"><span class="keyword">import</span> java.util.Map;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> ij.ImagePlus;</span><br><span class="line"><span class="keyword">import</span> ij.ImageStack;</span><br><span class="line"><span class="keyword">import</span> ij.gui.NewImage;</span><br><span class="line"><span class="keyword">import</span> ij.io.FileSaver;</span><br><span class="line"><span class="keyword">import</span> ij.plugin.RGBStackMerge;</span><br><span class="line"><span class="keyword">import</span> ij.process.ImageProcessor;</span><br><span class="line"><span class="keyword">import</span> jxl.Cell;</span><br><span class="line"><span class="keyword">import</span> jxl.Sheet;</span><br><span class="line"><span class="keyword">import</span> jxl.Workbook;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Test06</span> <span class="keyword">implements</span> <span class="title class_">MouseListener</span>, MouseMotionListener {</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="type">ImagePlus</span> <span class="variable">fuseImage</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="type">ImagePlus</span> <span class="variable">brainImage</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="type">ImagePlus</span> <span class="variable">annoImage</span> <span class="operator">=</span> <span class="literal">null</span>;</span><br><span class="line"><span class="keyword">public</span> Map<Integer,String> grayMap = <span class="keyword">new</span> <span class="title class_">HashMap</span><>();</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 提取脑区轮廓</span></span><br><span class="line"><span class="keyword">public</span> ImageProcessor <span class="title function_">getLineImg</span><span class="params">(ImageProcessor ip, ImageProcessor op)</span> {</span><br><span class="line"><span class="type">int</span> <span class="variable">lenX</span> <span class="operator">=</span> ip.getWidth();</span><br><span class="line"><span class="type">int</span> <span class="variable">lenY</span> <span class="operator">=</span> ip.getHeight();</span><br><span class="line"><span class="keyword">for</span>(<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i < lenX; i ++) { <span class="comment">//按列</span></span><br><span class="line"><span class="type">int</span> <span class="variable">begin</span> <span class="operator">=</span> <span class="number">0</span>; <span class="comment">//初始像素值为黑色</span></span><br><span class="line"><span class="keyword">for</span>(<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">0</span>; j < lenY; j ++) {</span><br><span class="line"><span class="type">int</span> <span class="variable">temp</span> <span class="operator">=</span> (<span class="type">int</span>)ip.getPixelValue(i, j);</span><br><span class="line"><span class="keyword">if</span>(temp != begin) {</span><br><span class="line">op.set(i, j, <span class="number">255</span>);</span><br><span class="line">begin = temp;</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"><span class="keyword">for</span>(<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">0</span>; j < lenY; j ++) {</span><br><span class="line"><span class="type">int</span> <span class="variable">begin</span> <span class="operator">=</span> <span class="number">0</span>; <span class="comment">//初始像素值为黑色</span></span><br><span class="line"><span class="keyword">for</span>(<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i < lenX; i ++) {</span><br><span class="line"><span class="type">int</span> <span class="variable">temp</span> <span class="operator">=</span> (<span class="type">int</span>)ip.getPixelValue(i, j);</span><br><span class="line"><span class="keyword">if</span>(temp != begin) {</span><br><span class="line">op.set(i, j, <span class="number">255</span>);</span><br><span class="line">begin = temp;</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"><span class="keyword">return</span> op;</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 监听鼠标 将excel中的灰度值-脑区读取到HashMap中</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">addMouseListener</span><span class="params">()</span> <span class="keyword">throws</span> Exception, IOException {</span><br><span class="line"><span class="type">File</span> <span class="variable">file</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">File</span>(<span class="string">"D:/Desktop/rgb_name.xls"</span>);</span><br><span class="line"><span class="type">Workbook</span> <span class="variable">wb</span> <span class="operator">=</span> Workbook.getWorkbook(file);</span><br><span class="line"><span class="type">Sheet</span> <span class="variable">sheet</span> <span class="operator">=</span> wb.getSheet(<span class="string">"test1"</span>);</span><br><span class="line"><span class="keyword">for</span>(<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i < sheet.getRows(); i ++) {</span><br><span class="line">Cell[] cell = sheet.getRow(i);</span><br><span class="line">grayMap.put(Integer.valueOf(cell[<span class="number">0</span>].getContents()),cell[<span class="number">1</span>].getContents());</span><br><span class="line">}</span><br><span class="line"><span class="comment">//System.out.println(grayMap);</span></span><br><span class="line">wb.close();</span><br><span class="line"></span><br><span class="line">fuseImage.show();</span><br><span class="line">fuseImage.getCanvas().addMouseListener(<span class="built_in">this</span>);</span><br><span class="line">fuseImage.getCanvas().addMouseMotionListener(<span class="built_in">this</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">mouseClicked</span><span class="params">(MouseEvent e)</span> {}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">mousePressed</span><span class="params">(MouseEvent e)</span> {}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">mouseReleased</span><span class="params">(MouseEvent e)</span> {}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">mouseEntered</span><span class="params">(MouseEvent e)</span> {}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">mouseExited</span><span class="params">(MouseEvent e)</span> {}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">mouseDragged</span><span class="params">(MouseEvent e)</span> {}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">mouseMoved</span><span class="params">(MouseEvent e)</span> {</span><br><span class="line"><span class="comment">// 监听鼠标的移动</span></span><br><span class="line"><span class="type">int</span> <span class="variable">currentSlice</span> <span class="operator">=</span> fuseImage.getCurrentSlice();</span><br><span class="line"><span class="type">Point</span> <span class="variable">point</span> <span class="operator">=</span> fuseImage.getCanvas().getCursorLoc();</span><br><span class="line"><span class="type">int</span> <span class="variable">val</span> <span class="operator">=</span> (<span class="type">int</span>)annoImage.getImageStack().getVoxel(point.x, point.y, currentSlice-<span class="number">1</span>);</span><br><span class="line"></span><br><span class="line">System.out.println(grayMap.get(val));</span><br><span class="line">}</span><br><span class="line"><span class="comment">// 主程序</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> IOException, Exception {</span><br><span class="line">brainImage = <span class="keyword">new</span> <span class="title class_">ImagePlus</span>(<span class="string">"D:\\Desktop\\elastix-5.1.0-win64\\input\\result1-1.tif"</span>);</span><br><span class="line"><span class="type">ImageStack</span> <span class="variable">brainStack</span> <span class="operator">=</span> brainImage.getStack();</span><br><span class="line"></span><br><span class="line">annoImage = <span class="keyword">new</span> <span class="title class_">ImagePlus</span>(<span class="string">"D:\\Desktop\\elastix-5.1.0-win64\\result\\result.tif"</span>);</span><br><span class="line"><span class="type">ImageProcessor</span> <span class="variable">ap</span> <span class="operator">=</span> annoImage.getProcessor();</span><br><span class="line"><span class="type">int</span> <span class="variable">width</span> <span class="operator">=</span> ap.getWidth();</span><br><span class="line"><span class="type">int</span> <span class="variable">height</span> <span class="operator">=</span> ap.getHeight();</span><br><span class="line"></span><br><span class="line"><span class="type">ImagePlus</span> <span class="variable">lineImage</span> <span class="operator">=</span> NewImage.createByteImage(<span class="string">"lineImage"</span>, width, height, <span class="number">0</span>, NewImage.FILL_BLACK);</span><br><span class="line"><span class="type">ImageStack</span> <span class="variable">lineStack</span> <span class="operator">=</span> lineImage.getStack();</span><br><span class="line"><span class="type">ImageProcessor</span> <span class="variable">lp</span> <span class="operator">=</span> lineImage.getProcessor();</span><br><span class="line"></span><br><span class="line"><span class="type">ImageProcessor</span> <span class="variable">op</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Test06</span>().getLineImg(ap, lp);</span><br><span class="line"></span><br><span class="line">lineImage.setProcessor(op);</span><br><span class="line">lineImage.show();</span><br><span class="line"> </span><br><span class="line">fuseImage = NewImage.createByteImage(<span class="string">"fuseImage"</span>, width, height, <span class="number">0</span>, NewImage.FILL_BLACK);</span><br><span class="line"></span><br><span class="line"><span class="type">ImageStack</span> <span class="variable">fuseStack</span> <span class="operator">=</span> RGBStackMerge.mergeStacks(brainStack, lineStack, <span class="literal">null</span>, <span class="literal">true</span>);</span><br><span class="line">fuseImage.setStack(fuseStack);</span><br><span class="line"><span class="keyword">new</span> <span class="title class_">FileSaver</span>(fuseImage).saveAsTiff(<span class="string">"D:/Desktop/fuseImage-1.tif"</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">new</span> <span class="title class_">Test06</span>().addMouseListener();</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h1 id="操作演示"><a href="#操作演示" class="headerlink" title="操作演示"></a>操作演示</h1><p><img src="https://img.cwxhmk.top/gif/20230714-birds-test.gif" alt="操作演示"></p><h1 id="注意事项"><a href="#注意事项" class="headerlink" title="注意事项"></a>注意事项</h1><ol><li>Eclipse中导入jxl.jar包,具体方法可参考<a href="https://blog.csdn.net/qq_48455576/article/details/111871181">博客</a>,需要注意jxl.jar包只能处理.xls文件</li><li>脑片降低分辨率后统计出的各个脑区的细胞数目,需要与人工计数的结果进行对比,如果差别不大,则后续采用降低分辨率的脑片进行配准。</li><li>配准后的图像使用<code>Imaris</code>软件计数,具体操作步骤见文章<a href="https://chen.cwxhmk.top/2023/07/14/imaris-cell-counting/">Imairs细胞计数教程</a></li></ol><h1 id="参考文章"><a href="#参考文章" class="headerlink" title="参考文章"></a>参考文章</h1><ul><li><a href="https://blog.csdn.net/qq_48455576/article/details/111871181">Java读取Excel表格中的数据</a></li><li><a href="https://blog.csdn.net/yincheng_917/article/details/82685492">Java键值对的使用</a></li><li><a href="https://www.aliyundrive.com/s/SErQkyqyvie">jxl.jar包下载地址</a></li><li><a href="https://beecut.cn/video-to-gif-online">视频转Gif在线工具</a></li><li><a href="https://zhuanlan.zhihu.com/p/66408698">手把手教你用软件便捷地统计染色图中不同区域的数据</a></li><li><a href="https://imaris.oxinst.com/learning/?businesses=bitplane">Imaris官方视频教程</a></li></ul>]]></content>
<categories>
<category> 项目实战 </category>
</categories>
<tags>
<tag> ImageJ </tag>
<tag> Java </tag>
<tag> Eclipse </tag>
</tags>
</entry>
<entry>
<title>《神经动力学》学习笔记【01】</title>
<link href="/2023/07/13/neuronal-dynamics-1/"/>
<url>/2023/07/13/neuronal-dynamics-1/</url>
<content type="html"><![CDATA[<div class="note info flat"><p>课程地址:<a href="https://www.bilibili.com/video/BV1U4411Y77o">[进入哔哩哔哩观看 资源1]</a> <a href="https://www.bilibili.com/video/BV1x7411Z715/">[进入哔哩哔哩观看 资源2]</a> <a href="https://lcnwww.epfl.ch/gerstner/NeuronalDynamics-MOOCall.html">[进入youtube观看]</a><br>课件汇总:<a href="https://neuronaldynamics.epfl.ch/lectures.html">[PPT下载]</a><br>参考教材:Neuronal Dynamics: From Single Neurons to Networks and Models of Cognition<br><a href="https://www.aliyundrive.com/s/LxiP8SVFtZN">[下载地址]</a><br>提取码: <span class="hide-inline"><button type="button" class="hide-button" style="">点击查看<br> </button><span class="hide-content">rk96</span></span></p></div><h1 id="神经动力学:从单个神经元到网络和认知模型"><a href="#神经动力学:从单个神经元到网络和认知模型" class="headerlink" title="神经动力学:从单个神经元到网络和认知模型"></a>神经动力学:从单个神经元到网络和认知模型</h1><p>当我们做决策时,我们的大脑中发生了什么?是什么触发了神经元发送信号?神经编码是什么?</p><p>这本面向高年级本科生和初级研究生的教科书,为计算和理论神经科学提供了全面而最新的的介绍。它涵盖了经典的主题,包括<code>Hodgkin-Huxley</code>方程和<code>Hopfield</code>模型,以及该领域在现代的发展,如广义线性模型和决策理论。概念通过清晰的逐步解释引入,适合仅有基础微分方程和概率知识的读者,并辅以丰富的图表和详细的实例说明。</p><p>章末总结和随堂练习使本书非常适合课堂教学或者自学。作者也指出了文献和大量的参考数目,对于有兴趣进一步研究的读者来说将非常有价值。</p><h1 id="目录"><a href="#目录" class="headerlink" title="目录"></a>目录</h1><div class="row"> <embed src="https://img.cwxhmk.top/pdf/catalog.pdf" width="100%" height="550" type="application/pdf"></div><h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>这本面向高年级本科生和初级研究生的教科书系统地介绍了关于神经建模、神经动力学、神经编码以及神经网络领域。它可以作为计算和理论神经科学的入门课程的教材,也可以作为研究生级别更加专注于神经动力学和神经建模的课程的主要教材。对于想学习不同神经元模型和神经活动描述之间关系的研究人员和学生来说,本书也是一个有用的资源。</p><p>所有的数学概念都以一步一步的方式进行介绍。所有的章节都有丰富的图表和实例。每一章都以简短的总结和一系列数学练习结尾。在作者的<a href="https://neuronaldynamics-exercises.readthedocs.io/en/latest/">网页</a>上提供了用于数值模拟的<code>python</code>源代码,以阐述章节的主要观点和模型。</p><p>本书分为4部分,共20章。<strong>Part I</strong>对计算神经科学及其数学工具的基础知识进行了概括性介绍。它涵盖了经典的内容,比如<code>Hodgkin-Huxley</code>模型、离子通道和树突等,以及二维微分方程系统的相平面分析。本书特别关注在<code>Hodgkin-Huxley</code>模型和<code>Morris-Lecar</code>模型等简化的二维神经元模型中触发动作电位的阈值问题。</p><p><strong>Part II</strong>着重介绍单个神经元动力学的简化模型。它涵盖了带有适应性和不带适应性的非线性积分-放电模型<code>integrate-and-fire model</code>,尤其是二次和指数的积分-放电模型,以及<code>Izhikevich</code>模型和自适应指数积分-发放模型。还讨论了神经动力学中噪声的问题,并呈现了两种经典的噪声描述。首先,通过随机尖峰到达引起的随机性:这个方法导致电压微分方程中的噪声项,可以用朗之万方程表示。其次,神经元内在的随机性导致在亚阈区域时跨越触发阈值的“逃逸”:这个方法引出了广义线性模型的框架,该模型会在神经编码和解码的应用中系统地介绍和讨论。强调第二部分中神经元模型和生物数据之间的关系,并介绍了系统的参数优化算法。</p><p><strong>Part III</strong>将第二部分得出的简化模型用于构建网络。以群体活动方程,也称为群体发放率,描述神经网络动力学的集体特性。确定了可以使用标准发放速率模型描述群体活动的条件。</p><p><strong>Part IV</strong>将动力学与认知联系起来。使用群体活动方程分析计算和认知神经科学中著名的范式,比如在决策或记忆检索过程中的神经活动。在第四部分,我们也概述了与突触可塑性相关的学习理论。本书以极有吸引力的神经动力学原理帮助帕金森病人的应用结尾。</p><p>本书的一小部分内容基于《Spiking Neuron Models》,该书于2002年首次出版,并在此后多次重印。与此同时,这个领域在发生变化,我们认为简单更新《Spiking Neuron Models》的第二版不足以肯定到目前所出现的发展。</p><p>从更一般的角度来看,我们设计一本从一开始就作为教科书而不是专题著作的书将非常有用。因此,本书更突出与实验数据的联系,有更多解释性文字,并且最重要的是,提供了一系列在多年的课堂教学中已经经过测试的练习题。</p><p>我们希望这本书对学生和研究人员都能有所帮助。</p><h1 id="给读者的建议"><a href="#给读者的建议" class="headerlink" title="给读者的建议"></a>给读者的建议</h1><p>每一章以一个具体的问题开始,并在第一节给出直观的答案。随着章节的进行,内容变得更加高级,呈现方式也更加技术化。在第一次阅读本书时,可以先只阅读每一章的第一节或前两节,然后快速浏览后续节。</p><p>更具体的建议取决于读者的背景。比如,建议初次接触计算神经科学领域的读者在开始第二部分和第四部分之前,建议花足够的时间学习第一部分的经典材料。专业的读者可以完全跳过第一部分,直接开始阅读第二部分。</p><p>在第三部分,主要思想在第12章和第15章进行了阐述,这些章节为第四部分的速率模型打下了基础。第三部分更具技术性的章节在第一次阅读时可以跳过,但有必要对当下计算神经科学领域的最新发展有一个深入的理解。</p><p>第四部分涉及神经动力学到认知问题的应用,可以按任意的顺序阅读。</p><p><code>*</code>标记的小节在数学上更高级,第一次阅读本书时可以忽略。</p>]]></content>
<categories>
<category> 学习笔记 </category>
</categories>
<tags>
<tag> 神经动力学 </tag>
</tags>
</entry>
<entry>
<title>RNN学习笔记【01】</title>
<link href="/2023/07/12/RNN-1/"/>
<url>/2023/07/12/RNN-1/</url>
<content type="html"><![CDATA[<div class="note info flat"><p>第一次找到和我要做的课题那么接近的教程,人工翻译一遍不过分吧!😎<br>本文对应的代码在这里!😽<a href="https://colab.research.google.com/drive/1e-bXFhYU-uBsNb1MqpDXRG6pdi0kjepf?usp=sharing">[Open in colab]</a>😽</p></div><h1 id="任务优化的循环神经网络建模"><a href="#任务优化的循环神经网络建模" class="headerlink" title="任务优化的循环神经网络建模"></a>任务优化的循环神经网络建模</h1><h2 id="引言"><a href="#引言" class="headerlink" title="引言"></a>引言</h2><p>这里,我们基于人工神经网络的方法构建循环神经网络。学习人工神经网络或深度学习,不仅是当今机器学习的主导框架,对计算神经科学而言也是一个有用的工具。</p><p>深度学习本身可能并不符合生物现实。然而,深度学习最终的结果可能是有用的大脑模型(不保证,但是可能)。由于人工神经网络的复杂性,它们可以模拟复杂的行为和神经活动。</p><p>从优化的角度来说,人工神经网络建模可以提供规范性解释,即为什么一个网络可以以某种方式完成某个任务,因为我们可以设计目标函数,类似于生物进化的视角。</p><h2 id="任务介绍"><a href="#任务介绍" class="headerlink" title="任务介绍"></a>任务介绍</h2><p><img src="https://img.cwxhmk.top/post/rnn_obj.png" alt="2AFC"></p><div class="note info flat"><p>双向强迫选择任务<a href="https://neurogym.github.io/envs/PerceptualDecisionMaking-v0.html">PerceptualDecisionMaking</a>,被试需要整合两个刺激来决定哪一个刺激的平均水平更高。<br>在刺激阶段会呈现一个有噪声的刺激。刺激的强度(coherence)在每个试次中是随机抽样的。因为刺激中存在噪声,智能体需要随时间整合刺激信息。<br><strong>参数介绍:</strong><br><code>dt</code>:Timestep duration. (def: 100 (ms) int)<br><code>rewards</code>: </p><ul><li><code>R_ABORTED</code>: given when breaking fixation. (def: -0.1 float) </li><li><code>R_CORRECT</code>:given when correct. (def: +1. float) </li><li><code>R_FAIL</code>:given when incorrect. (def: 0. float)</li></ul><p><code>timing</code>:Description and duration of periods forming a trial.<br><code>stim_scale</code>:Controls the difficulty of the experiment. (def: 1., float)<br><code>cohs</code>:list of float, coherence levels controlling the difficulty of the task<br><code>sigma</code>:float, input noise level<br><code>dim_ring</code>:int, dimension of ring input and output</p></div><h2 id="环境配置"><a href="#环境配置" class="headerlink" title="环境配置"></a>环境配置</h2><ul><li><a href="https://neurogym.github.io/">NeuroGym</a>是一个精选的神经科学任务集合,具有统一的接口。其目标是促进关于神经科学任务的神经网络模型的训练。<br><img src="https://img.cwxhmk.top/post/2023-pipeline.png" alt="NeuroGym"></li><li><a href="https://colab.research.google.com/">Google Colab</a>是一个基于云端的免费Jupyter笔记本环境,为用户提供了方便、免费的编码环境,并具备强大的计算资源和协作功能,适用于数据科学家、研究人员和机器学习工程师等进行代码开发、实验和协作。<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># install neurogym (for training environments)</span></span><br><span class="line">! git clone https://github.com/gyyang/neurogym.git</span><br><span class="line">%cd neurogym</span><br><span class="line">! pip install -e .</span><br><span class="line"></span><br><span class="line"><span class="comment"># import packages</span></span><br><span class="line"><span class="keyword">import</span> time <span class="comment"># for measuring time</span></span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np <span class="comment"># for numerical computation</span></span><br><span class="line"><span class="keyword">from</span> matplotlib <span class="keyword">import</span> cm <span class="comment"># for plotting figures</span></span><br><span class="line"><span class="keyword">import</span> matplotlib <span class="keyword">as</span> mpl</span><br><span class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</span><br><span class="line"><span class="keyword">from</span> matplotlib.colors <span class="keyword">import</span> ListedColormap, LinearSegmentedColormap</span><br><span class="line"><span class="keyword">from</span> matplotlib.lines <span class="keyword">import</span> Line2D</span><br><span class="line"><span class="keyword">from</span> IPython <span class="keyword">import</span> display <span class="comment"># for controlling colab</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> gym <span class="comment"># for neurogym</span></span><br><span class="line"><span class="keyword">import</span> neurogym <span class="keyword">as</span> ngym <span class="comment"># for training environments</span></span><br><span class="line"><span class="keyword">import</span> torch <span class="comment"># for training neural nets</span></span><br><span class="line"><span class="keyword">import</span> torch.nn.functional <span class="keyword">as</span> F</span><br><span class="line"></span><br><span class="line"><span class="keyword">from</span> sklearn.decomposition <span class="keyword">import</span> PCA <span class="comment"># for principal component analysis</span></span><br><span class="line"><span class="keyword">from</span> scipy.special <span class="keyword">import</span> softmax</span><br><span class="line">mpl.rcParams.update(mpl.rcParamsDefault)</span><br></pre></td></tr></table></figure></li></ul><h2 id="模型概览"><a href="#模型概览" class="headerlink" title="模型概览"></a>模型概览</h2><p><img src="https://img.cwxhmk.top/post/2023-RNN-model.png" alt="RNN模型概览"></p><div class="note info flat"><p>$x(t)$:输入变量</p><p>$r(t)$:循环变量</p><p>$o(t)$:输出</p><p>$W_x$:输入权重【可训练】</p><p>$W_r, b_r$:循环权重 & 偏置</p><p>$W_o, b_o$:输出权重 & 偏置</p><p>$\alpha=\frac{\bigtriangleup t}{\tau }$ </p></div><p>此外,在人工神经网络建模中,我们可以使用各种各样的激活函数,比如<code>ReLU</code>、<code>sigmoid</code>和<code>softplus</code>函数。</p><img src="https://img.cwxhmk.top/post/2023_act_fun.png" alt="激活函数" width="50%" height="50%" /> <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Parameter definition</span></span><br><span class="line"><span class="comment"># Hyperparameters</span></span><br><span class="line">hpar = <span class="built_in">dict</span>(</span><br><span class="line"> <span class="comment"># Task parameters</span></span><br><span class="line"> dt = <span class="number">20</span>, <span class="comment"># simulation time step [ms]</span></span><br><span class="line"> stim_len = <span class="number">1000</span>, <span class="comment"># stimulus input duration [ms]</span></span><br><span class="line"> stim_noise = <span class="number">0.3</span>, <span class="comment"># stimulus input noise [unitless]</span></span><br><span class="line"> seq_len = <span class="number">60</span>, <span class="comment"># trial duration in time steps</span></span><br><span class="line"> <span class="comment"># Network parameters</span></span><br><span class="line"> n_neurons = <span class="number">64</span>, <span class="comment"># number of recurrent neurons</span></span><br><span class="line"> network_noise = <span class="number">0.1</span>, <span class="comment"># noise to network [unitless]</span></span><br><span class="line"> tau = <span class="number">100</span>, <span class="comment"># network time constant [ms]</span></span><br><span class="line"> activation_fun = <span class="string">'relu'</span>, <span class="comment"># activation function(sigmoid, relu, softplus)</span></span><br><span class="line"> <span class="comment"># Network parameters:training</span></span><br><span class="line"> batch_size = <span class="number">16</span>, <span class="comment"># size of batch</span></span><br><span class="line"> n_iteration = <span class="number">1000</span>, <span class="comment"># number of epochs</span></span><br><span class="line"> learning_rate = <span class="number">0.01</span>, <span class="comment"># training learning rate</span></span><br><span class="line"> optimizer = <span class="string">'Adam'</span>, <span class="comment"># optimizer(Adam, RMSprop, SGD)</span></span><br><span class="line"> loss = <span class="string">'CrossEntropy'</span> <span class="comment"># loss function(CrossEntropy, L1, L2)</span></span><br><span class="line">)</span><br></pre></td></tr></table></figure><div class="note info flat"><p><code>batch</code>:指每次迭代中用于训练模型的样本数量。批大小的选择会影响训练的效果和速度。较大的批大小可以提高训练的效率,因为可以同时处理更多的样本,但会消耗更多的内存。较小的批大小可以提供更多的随机性和模型收敛的稳定性,但可能会导致训练时间增加。<br><code>iteration</code>:指完成整个训练数据集的一次遍历。迭代的数量取决于训练数据集的大小和训练过程的要求。通常,较大的数据集需要更多的迭代来使模型收敛,而较小的数据集可能需要较少的迭代。</p></div><h2 id="训练-RNN-执行任务"><a href="#训练-RNN-执行任务" class="headerlink" title="训练 RNN 执行任务"></a>训练 RNN 执行任务</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># make neurogym environment</span></span><br><span class="line">task_name = <span class="string">'PerceptualDecisionMaking-v0'</span></span><br><span class="line">kwargs = {<span class="string">'dt'</span>: hpar[<span class="string">'dt'</span>],</span><br><span class="line"> <span class="string">'timing'</span>: {<span class="string">'stimulus'</span>: hpar[<span class="string">'stim_len'</span>]},</span><br><span class="line"> <span class="string">'sigma'</span>: hpar[<span class="string">'stim_noise'</span>]}</span><br><span class="line">env = gym.make(task_name, **kwargs) </span><br><span class="line"></span><br><span class="line"><span class="comment"># make supervised dataset</span></span><br><span class="line">dataset = ngym.Dataset(env, batch_size=hpar[<span class="string">'batch_size'</span>], seq_len=hpar[<span class="string">'seq_len'</span>])</span><br><span class="line"></span><br><span class="line"><span class="comment"># generate one batch of data when called</span></span><br><span class="line">inputs, target = dataset()</span><br><span class="line"><span class="built_in">print</span>(<span class="string">'Input to network has shape(SeqLen,Batch,Dim)='</span>, inputs.shape)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">'Target to network has shape(SeqLen,Batch)='</span>, target.shape)</span><br><span class="line"><span class="comment"># 输出</span></span><br><span class="line"><span class="comment"># Input to network has shape(SeqLen,Batch,Dim)= (60, 16, 3)</span></span><br><span class="line"><span class="comment"># Target to network has shape(SeqLen,Batch)= (60, 16)</span></span><br></pre></td></tr></table></figure><div class="note info flat"><p><code>gym.make(task_name, **kwargs)</code>:是OpenAI Gym库中用于创建一个与特定任务相关的环境对象。<code>task_name</code>表示要创建的任务的名称,例如<code>CartPole-v1</code>,每个名称对应一个特定的任务环境。<code>**kwargs</code>是一个可选的关键字参数,用于传递额外的配置选项给环境。<br>在Python中,<code>**</code>用于将一个字典(dictionary)解包为关键字参数传递给函数。字典的关键字需与函数的参数名称匹配,参数顺序可以改变。</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Task structure</span></span><br><span class="line">i_trial = np.random.choice(hpar[<span class="string">'batch_size'</span>]) <span class="comment"># 随机从一个batch内选择一个trial</span></span><br><span class="line">end = <span class="built_in">sum</span>([v <span class="keyword">for</span> _,v <span class="keyword">in</span> env.timing.items()])/<span class="number">1000</span> <span class="comment"># 单位换为s</span></span><br><span class="line">times = np.arange(end, step=env.dt/<span class="number">1000</span>)</span><br><span class="line">rules = end - env.timing[<span class="string">'decision'</span>]/<span class="number">1000</span>, end</span><br><span class="line"></span><br><span class="line">f, ax = plt.subplots(<span class="number">1</span>, <span class="number">2</span>, figsize=(<span class="number">16</span>,<span class="number">5</span>))</span><br><span class="line">ax[<span class="number">0</span>].axvspan(rules[<span class="number">0</span>], rules[<span class="number">1</span>], facecolor=<span class="string">'grey'</span>, alpha=<span class="number">0.2</span>)</span><br><span class="line">ax[<span class="number">0</span>].plot(times, inputs[:,i_trial,<span class="number">1</span>], <span class="string">'blue'</span>, label=<span class="string">'Evidence for right motion'</span>)</span><br><span class="line">ax[<span class="number">0</span>].plot(times, inputs[:,i_trial,<span class="number">2</span>], <span class="string">'red'</span>, label=<span class="string">'Evidence for left motion'</span>)</span><br><span class="line">ax[<span class="number">0</span>].plot(times, inputs[:,i_trial,<span class="number">0</span>], <span class="string">'green'</span>, label=<span class="string">'Fixation rule'</span>)</span><br><span class="line">ax[<span class="number">0</span>].set_ylabel(<span class="string">'input'</span>)</span><br><span class="line">ax[<span class="number">0</span>].set_ylim([-<span class="number">0.1</span>,<span class="number">1.1</span>])</span><br><span class="line">ax[<span class="number">0</span>].legend(loc=<span class="string">'upper left'</span>)</span><br><span class="line">ax[<span class="number">0</span>].set_xlabel(<span class="string">'time(s)'</span>)</span><br><span class="line">ax[<span class="number">0</span>].set_title(<span class="string">f'Input to RNN(trial number=<span class="subst">{i_trial}</span>)'</span>)</span><br><span class="line"></span><br><span class="line">ax[<span class="number">1</span>].axvspan(rules[<span class="number">0</span>], rules[<span class="number">1</span>], facecolor=<span class="string">'grey'</span>, alpha=<span class="number">0.2</span>)</span><br><span class="line">ax[<span class="number">1</span>].hlines(y=<span class="number">1</span>, xmin=times[<span class="number">0</span>], xmax=times[-<span class="number">1</span>], color=<span class="string">'gray'</span>, linestyle=<span class="string">"dashed"</span>)</span><br><span class="line">ax[<span class="number">1</span>].hlines(y=<span class="number">2</span>, xmin=times[<span class="number">0</span>], xmax=times[-<span class="number">1</span>], color=<span class="string">'gray'</span>, linestyle=<span class="string">"dashed"</span>)</span><br><span class="line">ax[<span class="number">1</span>].text(<span class="number">0</span>, <span class="number">0.08</span>, <span class="string">'Fixation'</span>)</span><br><span class="line">ax[<span class="number">1</span>].text(<span class="number">0</span>, <span class="number">0.9</span>, <span class="string">'Right Decision'</span>)</span><br><span class="line">ax[<span class="number">1</span>].text(<span class="number">0</span>, <span class="number">1.9</span>, <span class="string">'Left Decision'</span>)</span><br><span class="line">ax[<span class="number">1</span>].plot(times, target[:,i_trial], <span class="string">'k'</span>)</span><br><span class="line">ax[<span class="number">1</span>].set_ylabel(<span class="string">'desired output'</span>)</span><br><span class="line">ax[<span class="number">1</span>].set_ylim([-<span class="number">0.1</span>,<span class="number">2.1</span>])</span><br><span class="line">ax[<span class="number">1</span>].set_xlabel(<span class="string">'time(s)'</span>)</span><br><span class="line">ax[<span class="number">1</span>].set_title(<span class="string">f'Desired output from RNN(trial number=<span class="subst">{i_trial}</span>)'</span>)</span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><p><img src="https://img.cwxhmk.top/post/2023-sample-trial.png" alt="示例trial的输入和输出"></p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Model definition</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">RNN</span>(torch.nn.Module):</span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">__init__</span>(<span class="params">self, input_size, output_size, **hpar</span>):</span><br><span class="line"> <span class="built_in">super</span>().__init__()</span><br><span class="line"> self.input_size = input_size</span><br><span class="line"> self.output_size = output_size</span><br><span class="line"> self.hidden_size = hpar[<span class="string">'n_neurons'</span>]</span><br><span class="line"> self.noise = hpar[<span class="string">'network_noise'</span>]</span><br><span class="line"> self.tau = hpar[<span class="string">'tau'</span>]</span><br><span class="line"> self.alpha = hpar[<span class="string">'dt'</span>]/self.tau</span><br><span class="line"> self.input2rec = torch.nn.Linear(self.input_size, self.hidden_size, bias=<span class="literal">False</span>)</span><br><span class="line"> self.rec2rec = torch.nn.Linear(self.hidden_size, self.hidden_size)</span><br><span class="line"> self.rec2output = torch.nn.Linear(self.hidden_size, self.output_size)</span><br><span class="line"> self.normal = torch.distributions.normal.Normal(<span class="number">0</span>,<span class="number">1</span>)</span><br><span class="line"> self.set_activation_fun(**hpar)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">set_activation_fun</span>(<span class="params">self, **hpar</span>):</span><br><span class="line"> <span class="keyword">if</span> hpar[<span class="string">'activation_fun'</span>] == <span class="string">'sigmoid'</span>:</span><br><span class="line"> self.activation = torch.sigmoid</span><br><span class="line"> <span class="keyword">elif</span> hpar[<span class="string">'activation_fun'</span>] == <span class="string">'relu'</span>:</span><br><span class="line"> self.activation = torch.relu</span><br><span class="line"> <span class="keyword">elif</span> hpar[<span class="string">'activation_fun'</span>] == <span class="string">'softplus'</span>:</span><br><span class="line"> self.activation = F.softplus</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">raise</span> NotImplementedError(<span class="string">'Activation functions should be either ReLU, Sigmoid, or Softplus'</span>)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">init_hidden</span>(<span class="params">self, input_shape</span>):</span><br><span class="line"> batch_size = input_shape[<span class="number">1</span>]</span><br><span class="line"> <span class="keyword">return</span> torch.zeros(batch_size, self.hidden_size)</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">recurrence</span>(<span class="params">self, <span class="built_in">input</span>, hidden</span>):</span><br><span class="line"> noise = self.noise * self.normal.sample(hidden.shape)</span><br><span class="line"> h_new = self.activation(self.input2rec(<span class="built_in">input</span>) + self.rec2rec(hidden))</span><br><span class="line"> h_new = hidden * (<span class="number">1</span>-self.alpha) + h_new * self.alpha</span><br><span class="line"> h_new += noise * (<span class="number">2</span>*self.alpha) ** <span class="number">0.5</span></span><br><span class="line"> <span class="keyword">return</span> h_new</span><br><span class="line"></span><br><span class="line"> <span class="keyword">def</span> <span class="title function_">forward</span>(<span class="params">self, <span class="built_in">input</span>, hidden=<span class="literal">None</span></span>):</span><br><span class="line"> <span class="keyword">if</span> hidden <span class="keyword">is</span> <span class="literal">None</span>:</span><br><span class="line"> hidden = self.init_hidden(<span class="built_in">input</span>.shape).to(<span class="built_in">input</span>.device)</span><br><span class="line"> rnn_output = []</span><br><span class="line"> steps = <span class="built_in">range</span>(<span class="built_in">input</span>.size(<span class="number">0</span>))</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> steps:</span><br><span class="line"> hidden = self.recurrence(<span class="built_in">input</span>[i], hidden)</span><br><span class="line"> rnn_output.append(hidden)</span><br><span class="line"> </span><br><span class="line"> rnn_output = torch.stack(rnn_output, dim=<span class="number">0</span>)</span><br><span class="line"> output = self.rec2output(rnn_output)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> output, rnn_output</span><br><span class="line"></span><br><span class="line">input_size = env.observation_space.shape[<span class="number">0</span>]</span><br><span class="line"><span class="built_in">print</span>(input_size) <span class="comment"># </span></span><br><span class="line">output_size = env.action_space.n</span><br><span class="line">net = RNN(input_size, output_size, **hpar)</span><br><span class="line"><span class="built_in">print</span>(net)</span><br><span class="line"><span class="keyword">for</span> name, param <span class="keyword">in</span> net.named_parameters():</span><br><span class="line"> <span class="keyword">if</span> param.requires_grad:</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">'\t'</span>, name, <span class="string">","</span> , param.data.shape)</span><br><span class="line"><span class="comment"># 输出</span></span><br><span class="line"><span class="comment"># RNN(</span></span><br><span class="line"><span class="comment"># (input2rec): Linear(in_features=3, out_features=64, bias=False)</span></span><br><span class="line"><span class="comment"># (rec2rec): Linear(in_features=64, out_features=64, bias=True)</span></span><br><span class="line"><span class="comment"># (rec2output): Linear(in_features=64, out_features=3, bias=True)</span></span><br><span class="line"><span class="comment"># )</span></span><br><span class="line"><span class="comment"># input2rec.weight , torch.Size([64, 3])</span></span><br><span class="line"><span class="comment"># rec2rec.weight , torch.Size([64, 64])</span></span><br><span class="line"><span class="comment"># rec2rec.bias , torch.Size([64])</span></span><br><span class="line"><span class="comment"># rec2output.weight , torch.Size([3, 64])</span></span><br><span class="line"><span class="comment"># rec2output.bias , torch.Size([3])</span></span><br></pre></td></tr></table></figure><div class="note info flat"><p><code>__init__</code>:在Python中,__init__是一个特殊的方法(也称为构造方法),用于在创建类的实例时进行初始化操作。__init__方法在创建类的实例时自动调用,并用于设置对象的初始状态。它接受类的实例作为第一个参数(通常被命名为self),以便可以访问和操作该实例的属性和方法。除了self参数外,__init__方法可以接受其他参数,这些参数可以用来初始化对象的属性。<br><code>super().__init__()</code>:调用父类的构造方法,确保父类的初始化操作得以执行。<br><code>Activation function</code>:ReLU、Sigmoid、Softplus<br><code>Optimizer</code>:Adam、RMSprop、SGD<br><code>loss function</code>:CrossEntropy、L1、L2</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># train model</span></span><br><span class="line">learning_rate = <span class="number">0.01</span></span><br><span class="line">optimizer = <span class="string">'Adam'</span></span><br><span class="line">loss_function = <span class="string">'CrossEntropy'</span></span><br><span class="line"></span><br><span class="line">hpar[<span class="string">'learning_rate'</span>] = learning_rate</span><br><span class="line">hpar[<span class="string">'optimizer'</span>] = optimizer</span><br><span class="line">hpar[<span class="string">'loss_function'</span>] = loss_function</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">train_model</span>(<span class="params">net, dataset, **hpar</span>):</span><br><span class="line"> <span class="comment"># define an optimizer</span></span><br><span class="line"> learning_rate = hpar[<span class="string">'learning_rate'</span>]</span><br><span class="line"> <span class="keyword">if</span> hpar[<span class="string">'optimizer'</span>] == <span class="string">'Adam'</span>:</span><br><span class="line"> optimizer = torch.optim.Adam(net.parameters(), lr=learning_rate)</span><br><span class="line"> <span class="keyword">elif</span> hpar[<span class="string">'optimizer'</span>] == <span class="string">'RMSprop'</span>:</span><br><span class="line"> optimizer = torch.optim.RMSprop(net.parameters(), lr=learning_rate)</span><br><span class="line"> <span class="keyword">elif</span> hpar[<span class="string">'optimizer'</span>] == <span class="string">'SGD'</span>:</span><br><span class="line"> optimizer = torch.optim.SGD(net.parameters(), lr=learning_rate)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">raise</span> NotImplementedError(<span class="string">'Optimizer should be either Adam, RMSprop, or SGD'</span>)</span><br><span class="line"> <span class="comment"># define a loss function</span></span><br><span class="line"> <span class="keyword">if</span> hpar[<span class="string">'loss'</span>] == <span class="string">'CrossEntropy'</span>:</span><br><span class="line"> criterion = torch.nn.CrossEntropyLoss()</span><br><span class="line"> <span class="keyword">elif</span> hpar[<span class="string">'loss'</span>] == <span class="string">'L1'</span>:</span><br><span class="line"> criterion = torch.nn.L1loss()</span><br><span class="line"> <span class="keyword">elif</span> hpar[<span class="string">'loss'</span>] == <span class="string">'L2'</span>:</span><br><span class="line"> criterion = torch.nn.MSELoss()</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">raise</span> NotImplementedError(<span class="string">'Loss function should be either CrossEntropy, l1, or L2'</span>)</span><br><span class="line"></span><br><span class="line"> start_time = time.time()</span><br><span class="line"> losses = []</span><br><span class="line"> accs = []</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Plot</span></span><br><span class="line"> fig = plt.figure(figsize=[<span class="number">18</span>,<span class="number">6</span>])</span><br><span class="line"> plt.tight_layout()</span><br><span class="line"> ax0 = fig.add_subplot(<span class="number">121</span>)</span><br><span class="line"> ax0.set_xlim([<span class="number">0</span>,hpar[<span class="string">'n_iteration'</span>]])</span><br><span class="line"> plt.ylim([<span class="number">0</span>,<span class="number">0.5</span>])</span><br><span class="line"> ax0.set_xlabel(<span class="string">'Number of iteration'</span>)</span><br><span class="line"> ax0.set_ylabel(<span class="string">'Loss'</span>)</span><br><span class="line"> ax0.set_title(<span class="string">'RNN model training curve'</span>)</span><br><span class="line"> ax1 = fig.add_subplot(<span class="number">121</span>, sharex=ax0, frameon=<span class="literal">False</span>)</span><br><span class="line"> ax1.yaxis.tick_right()</span><br><span class="line"> ax1.yaxis.set_label_position(<span class="string">'right'</span>)</span><br><span class="line"> ax1.set_ylabel(<span class="string">'Accuracy(%)'</span>)</span><br><span class="line"> ax1.set_ylim([<span class="number">0</span>,<span class="number">100</span>])</span><br><span class="line"> ax1.yaxis.label.set_color(<span class="string">'r'</span>)</span><br><span class="line"> ax0.spines[<span class="string">'right'</span>].set_color(<span class="string">'r'</span>)</span><br><span class="line"> ax1.tick_params(axis=<span class="string">'y'</span>, colors=<span class="string">'r'</span>)</span><br><span class="line"> ax2 = fig.add_subplot(<span class="number">122</span>)</span><br><span class="line"> ax2.set_title(<span class="string">'RNN model recurrent weight $W_r$'</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Loop</span></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(hpar[<span class="string">'n_iteration'</span>]):</span><br><span class="line"> inputs, labels = dataset() <span class="comment"># 一个batch的数据</span></span><br><span class="line"> inputs = torch.from_numpy(inputs).<span class="built_in">type</span>(torch.<span class="built_in">float</span>)</span><br><span class="line"> labels = torch.from_numpy(labels.flatten()).<span class="built_in">type</span>(torch.long)</span><br><span class="line"></span><br><span class="line"> optimizer.zero_grad() <span class="comment"># clear the gradient buffers</span></span><br><span class="line"> output, _ = net(inputs) <span class="comment"># run the network</span></span><br><span class="line"> output = output.view(-<span class="number">1</span>, output_size)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> hpar[<span class="string">'loss'</span>] == <span class="string">'CrossEntropy'</span>:</span><br><span class="line"> loss = criterion(output, labels)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> loss = criterion(output, F.one_hot(labels).<span class="built_in">type</span>(torch.<span class="built_in">float</span>))</span><br><span class="line"> loss.backward() <span class="comment"># backpropagation</span></span><br><span class="line"> optimizer.step() <span class="comment"># gradient descent</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># compute the running loss every 100 steps</span></span><br><span class="line"> losses.append(loss.item())</span><br><span class="line"> <span class="comment"># 将输出张量转换为 NumPy 数组,然后选择最后 hpar['batch_size'] 行,并找到选定数组中每个样本的预测类别的索引。最终,pred 是一个包含每个样本预测类别索引的数组。</span></span><br><span class="line"> pred = np.argmax(output.detach().numpy()[(-hpar[<span class="string">'batch_size'</span>]):,:],axis=-<span class="number">1</span>)</span><br><span class="line"> true = labels.detach().numpy()[(-hpar[<span class="string">'batch_size'</span>]):]</span><br><span class="line"> accs.append((pred==true).mean()*<span class="number">100</span>)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> i % <span class="number">100</span> == <span class="number">99</span>:</span><br><span class="line"> accs_ma = accs.copy()</span><br><span class="line"> accs_ma[<span class="number">10</span>:] = np.convolve(accs_ma, np.ones(<span class="number">10</span>)/<span class="number">10</span>, mode=<span class="string">'valid'</span>)</span><br><span class="line"></span><br><span class="line"> ax0.plot(losses, color=<span class="string">'k'</span>, linewidth=<span class="number">2</span>)</span><br><span class="line"> ax1.plot(accs_ma, color=<span class="string">'r'</span>, linewidth=<span class="number">1</span>)</span><br><span class="line"></span><br><span class="line"> recurrent_weight = net.get_parameter(<span class="string">'rec2rec.weight'</span>).detach().numpy()</span><br><span class="line"> im = ax2.imshow(recurrent_weight, clim=[-<span class="number">0.6</span>,<span class="number">0.6</span>], cmap=<span class="string">'RdBu_r'</span>)</span><br><span class="line"> ax2.set_xlabel(<span class="string">'Presynaptic neuron index'</span>)</span><br><span class="line"> ax2.set_ylabel(<span class="string">'Postsynaptic neuron index'</span>)</span><br><span class="line"> cb = plt.colorbar(im, ax=ax2)</span><br><span class="line"></span><br><span class="line"> display.clear_output(wait=<span class="literal">True</span>)</span><br><span class="line"> display.display(plt.gcf())</span><br><span class="line"> <span class="keyword">if</span> i != hpar[<span class="string">'n_iteration'</span>] -<span class="number">1</span>:</span><br><span class="line"> cb.remove()</span><br><span class="line"> <span class="keyword">if</span> i == hpar[<span class="string">'n_iteration'</span>] -<span class="number">1</span>:</span><br><span class="line"> display.clear_output(wait=<span class="literal">True</span>)</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f'Final training loss=<span class="subst">{np.<span class="built_in">round</span>(np.mean(losses[(-<span class="number">100</span>):]),<span class="number">2</span>)}</span>'</span>)</span><br><span class="line"> <span class="built_in">print</span>(<span class="string">f'Final training accuracy(%)=<span class="subst">{np.<span class="built_in">round</span>(np.mean(accs[(-<span class="number">100</span>):]),<span class="number">2</span>)}</span>'</span>)</span><br><span class="line"> <span class="keyword">return</span> net</span><br><span class="line">net = RNN(input_size, output_size, **hpar)</span><br><span class="line">net = train_model(net, dataset, **hpar)</span><br></pre></td></tr></table></figure><p><img src="https://img.cwxhmk.top/post/2023-train-result.png" alt="训练误差及准确率"></p><h2 id="分析训练好的-RNN-模型"><a href="#分析训练好的-RNN-模型" class="headerlink" title="分析训练好的 RNN 模型"></a>分析训练好的 RNN 模型</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Analysis</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">run_model</span>(<span class="params">net, env, num_trial=<span class="number">200</span></span>):</span><br><span class="line"> env.reset(no_step=<span class="literal">True</span>)</span><br><span class="line"> input_dict = {}</span><br><span class="line"> activity_dict = {}</span><br><span class="line"> trial_infos = {}</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(num_trial):</span><br><span class="line"> trial_info = env.new_trial()</span><br><span class="line"> ob, gt = env.ob, env.gt <span class="comment"># observation and ground-truth</span></span><br><span class="line"> inputs = torch.from_numpy(ob[:, np.newaxis, :]).<span class="built_in">type</span>(torch.<span class="built_in">float</span>)</span><br><span class="line"></span><br><span class="line"> action_pred, rnn_activity = net(inputs)</span><br><span class="line"> action_pred = action_pred.detach().numpy()[:, <span class="number">0</span>, :]</span><br><span class="line"> choice = np.argmax(action_pred[-<span class="number">1</span>, :])</span><br><span class="line"> correct = choice==gt[-<span class="number">1</span>]</span><br><span class="line"></span><br><span class="line"> _<span class="built_in">input</span> = inputs[:, <span class="number">0</span>, :].detach().numpy()</span><br><span class="line"> rnn_activity = rnn_activity[:, <span class="number">0</span>, :].detach().numpy()</span><br><span class="line"> input_dict[i] = _<span class="built_in">input</span></span><br><span class="line"> activity_dict[i] = rnn_activity</span><br><span class="line"> trial_infos[i] = trial_info</span><br><span class="line"> trial_infos[i].update({</span><br><span class="line"> <span class="string">'correct'</span>: correct,</span><br><span class="line"> <span class="string">'pred'</span>: action_pred,</span><br><span class="line"> <span class="string">'target'</span>: dataset.env.gt</span><br><span class="line"> })</span><br><span class="line"> <span class="keyword">return</span> input_dict, activity_dict, trial_infos</span><br><span class="line"></span><br><span class="line">run_inputs, activity_dict, trial_infos = run_model(net, dataset.env)</span><br><span class="line">test_acc = np.<span class="built_in">round</span>(np.mean([val[<span class="string">'correct'</span>] <span class="keyword">for</span> val <span class="keyword">in</span> trial_infos.values()])*<span class="number">100</span>, <span class="number">2</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">f'Testing accuracy(%)=<span class="subst">{test_acc}</span>'</span>)</span><br></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># randomly choose an example trial</span></span><br><span class="line">i_trial = np.random.choice(<span class="number">200</span>)</span><br><span class="line">coh = trial_infos[i_trial][<span class="string">'coh'</span>]</span><br><span class="line"><span class="built_in">print</span>(<span class="string">f'coherence=<span class="subst">{coh}</span>'</span>)</span><br><span class="line"><span class="comment"># dict_items([('fixation', 100), ('stimulus', 1000), ('delay', 0), ('decision', 100)])</span></span><br><span class="line">end = <span class="built_in">sum</span>([v <span class="keyword">for</span> _,v <span class="keyword">in</span> env.timing.items()])/<span class="number">1000</span> </span><br><span class="line">times = np.arange(end, step=env.dt/<span class="number">1000</span>) <span class="comment"># 0~(end-1)</span></span><br><span class="line">rules = end - env.timing[<span class="string">'decision'</span>]/<span class="number">1000</span>, end</span><br><span class="line"></span><br><span class="line">f, ax = plt.subplots(<span class="number">1</span>, <span class="number">2</span>, figsize=(<span class="number">16</span>,<span class="number">5</span>))</span><br><span class="line">ax[<span class="number">0</span>].axvspan(rules[<span class="number">0</span>], rules[<span class="number">1</span>], facecolor=<span class="string">'grey'</span>, alpha=<span class="number">0.2</span>)</span><br><span class="line">ax[<span class="number">0</span>].plot(times, run_inputs[i_trial][:,<span class="number">1</span>], <span class="string">'blue'</span>, label=<span class="string">'Evidence for right motion'</span>)</span><br><span class="line">ax[<span class="number">0</span>].plot(times, run_inputs[i_trial][:,<span class="number">2</span>], <span class="string">'red'</span>, label=<span class="string">'Evidence for left motion'</span>)</span><br><span class="line">ax[<span class="number">0</span>].plot(times, run_inputs[i_trial][:,<span class="number">0</span>], <span class="string">'green'</span>, label=<span class="string">'Fixation rule'</span>)</span><br><span class="line">ax[<span class="number">0</span>].legend(loc=<span class="string">'upper left'</span>)</span><br><span class="line">ax[<span class="number">0</span>].set_xlabel(<span class="string">'time(s)'</span>)</span><br><span class="line">ax[<span class="number">0</span>].set_ylabel(<span class="string">'input'</span>)</span><br><span class="line">ax[<span class="number">0</span>].set_title(<span class="string">f'Input to RNN(trial number=<span class="subst">{i_trial}</span> coherence=<span class="subst">{coh}</span>)'</span>)</span><br><span class="line"></span><br><span class="line">im = ax[<span class="number">1</span>].imshow(softmax(trial_infos[i_trial][<span class="string">'pred'</span>],axis=-<span class="number">1</span>).T, extent=[times[<span class="number">0</span>],end,-<span class="number">0.5</span>,<span class="number">2.5</span>], aspect=<span class="string">'auto'</span>, origin=<span class="string">'lower'</span>)</span><br><span class="line">ax[<span class="number">1</span>].text(<span class="number">0.05</span>,<span class="number">0.1</span>,<span class="string">'Fixation'</span>, color=<span class="string">'r'</span>)</span><br><span class="line">ax[<span class="number">1</span>].text(<span class="number">0.05</span>,<span class="number">1</span>,<span class="string">'Right decision'</span>, color=<span class="string">'r'</span>)</span><br><span class="line">ax[<span class="number">1</span>].text(<span class="number">0.05</span>,<span class="number">2</span>,<span class="string">'Left decision'</span>, color=<span class="string">'r'</span>)</span><br><span class="line">ax[<span class="number">1</span>].plot(times, trial_infos[i_trial][<span class="string">'target'</span>], <span class="string">'k'</span>, linewidth=<span class="number">5</span>, label=<span class="string">'ground truth'</span>)</span><br><span class="line">ax[<span class="number">1</span>].set_xlabel(<span class="string">'time(s)'</span>)</span><br><span class="line">ax[<span class="number">1</span>].set_ylabel(<span class="string">'RNN output'</span>)</span><br><span class="line">ax[<span class="number">1</span>].set_yticks([<span class="number">0</span>,<span class="number">1</span>,<span class="number">2</span>])</span><br><span class="line">ax[<span class="number">1</span>].set_title(<span class="string">f'RNN output(trial number=<span class="subst">{i_trial}</span> coherence=<span class="subst">{coh}</span>)'</span>)</span><br><span class="line">ax[<span class="number">1</span>].legend()</span><br><span class="line"></span><br><span class="line">cb = plt.colorbar(im, ax=ax[<span class="number">1</span>])</span><br><span class="line">cb.ax.set_title(<span class="string">'Predicted probabolity'</span>)</span><br><span class="line">plt.tight_layout()</span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><p><img src="https://img.cwxhmk.top/post/2023-sample-output.png" alt="示例试次输出结果展示"></p><div class="note info flat"><p>RNN模型测试准确率达到90%以上时,PCA分析不同运动一致比例条件下RNN群体活动轨迹比较容易分开。如果模型的准确率不高,则轨迹比较集中。🦁也就是说,模型是否训练好要设定一个performance threshold~</p></div><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># PCA(2 principal components)</span></span><br><span class="line">activity = np.concatenate(<span class="built_in">list</span>(activity_dict[i] <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">200</span>)), axis=<span class="number">0</span>)</span><br><span class="line">pca = PCA(n_components=<span class="number">3</span>)</span><br><span class="line">pca.fit(activity)</span><br><span class="line">activity_pc = pca.transform(activity)</span><br><span class="line"></span><br><span class="line">blues = cm.get_cmap(<span class="string">'Blues'</span>, <span class="built_in">len</span>(env.cohs)+<span class="number">1</span>)</span><br><span class="line">reds = cm.get_cmap(<span class="string">'Reds'</span>, <span class="built_in">len</span>(env.cohs)+<span class="number">1</span>)</span><br><span class="line"></span><br><span class="line">figure = plt.figure(figsize=([<span class="number">7</span>,<span class="number">7</span>]))</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">100</span>):</span><br><span class="line"> activity_pc = pca.transform(activity_dict[i])</span><br><span class="line"> trial = trial_infos[i]</span><br><span class="line"> color_c = blues <span class="keyword">if</span> trial[<span class="string">'ground_truth'</span>] == <span class="number">0</span> <span class="keyword">else</span> reds</span><br><span class="line"> color = color_c(np.where(env.cohs == trial[<span class="string">'coh'</span>])[<span class="number">0</span>][<span class="number">0</span>])</span><br><span class="line"> plt.plot(activity_pc[:,<span class="number">0</span>], activity_pc[:,<span class="number">1</span>], <span class="string">'o-'</span>, color=color)</span><br><span class="line"></span><br><span class="line"> plt.plot(activity_pc[<span class="number">0</span>,<span class="number">0</span>], activity_pc[<span class="number">0</span>,<span class="number">1</span>], <span class="string">'^'</span>, color=<span class="string">'black'</span>, markersize=<span class="number">10</span>)</span><br><span class="line"></span><br><span class="line">handles, labels = plt.gca().get_legend_handles_labels()</span><br><span class="line">dot = Line2D([], [], marker=<span class="string">'^'</span>, label=<span class="string">'Starting point'</span>, color=<span class="string">'black'</span>, linestyle=<span class="string">'None'</span>, markersize=<span class="number">10</span>)</span><br><span class="line">lines = []</span><br><span class="line"><span class="keyword">for</span> i_coh, v_coh <span class="keyword">in</span> <span class="built_in">reversed</span>(<span class="built_in">list</span>(<span class="built_in">enumerate</span>(env.cohs))): <span class="comment"># index value</span></span><br><span class="line"> line_r = Line2D([], [], label=<span class="string">f'L motion trial, c=<span class="subst">{v_coh}</span>'</span>, color=reds(i_coh))</span><br><span class="line"> lines.append(line_r)</span><br><span class="line"><span class="keyword">for</span> i_coh, v_coh <span class="keyword">in</span> <span class="built_in">enumerate</span>(env.cohs):</span><br><span class="line"> line_b = Line2D([], [], label=<span class="string">f'R motion trial, c=<span class="subst">{v_coh}</span>'</span>, color=blues(i_coh))</span><br><span class="line"> lines.append(line_b)</span><br><span class="line">handles.extend([dot]+lines)</span><br><span class="line">plt.legend(title=<span class="string">'Legend'</span>, bbox_to_anchor=(<span class="number">1.4</span>,<span class="number">1.0</span>), handles=handles, frameon=<span class="literal">False</span>)</span><br><span class="line">plt.xlabel(<span class="string">'PC 1'</span>)</span><br><span class="line">plt.ylabel(<span class="string">'PC 2'</span>)</span><br><span class="line">plt.title(<span class="string">'State space based on principal component analysis'</span>)</span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><img src="https://img.cwxhmk.top/post/2023-PC-2.png" alt="图片说明" width="80%" height="70%" /> <figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># PCA(3 principal components)</span></span><br><span class="line"><span class="keyword">from</span> mpl_toolkits.mplot3d <span class="keyword">import</span> Axes3D</span><br><span class="line">activity = np.concatenate(<span class="built_in">list</span>(activity_dict[i] <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">200</span>)), axis=<span class="number">0</span>)</span><br><span class="line">pca = PCA(n_components=<span class="number">3</span>)</span><br><span class="line">pca.fit(activity)</span><br><span class="line">activity_pc = pca.transform(activity)</span><br><span class="line"></span><br><span class="line">blues = cm.get_cmap(<span class="string">'Blues'</span>, <span class="built_in">len</span>(env.cohs)+<span class="number">1</span>)</span><br><span class="line">reds = cm.get_cmap(<span class="string">'Reds'</span>, <span class="built_in">len</span>(env.cohs)+<span class="number">1</span>)</span><br><span class="line"></span><br><span class="line">fig = plt.figure(figsize=([<span class="number">7</span>,<span class="number">7</span>]))</span><br><span class="line">ax = fig.add_subplot(<span class="number">111</span>, projection=<span class="string">'3d'</span>)</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">100</span>):</span><br><span class="line"> activity_pc = pca.transform(activity_dict[i])</span><br><span class="line"> trial = trial_infos[i]</span><br><span class="line"> color_c = blues <span class="keyword">if</span> trial[<span class="string">'ground_truth'</span>] == <span class="number">0</span> <span class="keyword">else</span> reds</span><br><span class="line"> color = color_c(np.where(env.cohs == trial[<span class="string">'coh'</span>])[<span class="number">0</span>][<span class="number">0</span>])</span><br><span class="line"> ax.plot(activity_pc[:,<span class="number">0</span>], activity_pc[:,<span class="number">1</span>], activity_pc[:,<span class="number">2</span>], <span class="string">'o-'</span>, color=color)</span><br><span class="line"></span><br><span class="line"> ax.plot(activity_pc[<span class="number">0</span>,<span class="number">0</span>], activity_pc[<span class="number">0</span>,<span class="number">1</span>], activity_pc[<span class="number">0</span>,<span class="number">2</span>],<span class="string">'^'</span>, color=<span class="string">'black'</span>, markersize=<span class="number">10</span>)</span><br><span class="line"></span><br><span class="line">handles, labels = plt.gca().get_legend_handles_labels()</span><br><span class="line">dot = Line2D([], [], marker=<span class="string">'^'</span>, label=<span class="string">'Starting point'</span>, color=<span class="string">'black'</span>, linestyle=<span class="string">'None'</span>, markersize=<span class="number">10</span>)</span><br><span class="line">lines = []</span><br><span class="line"><span class="keyword">for</span> i_coh, v_coh <span class="keyword">in</span> <span class="built_in">reversed</span>(<span class="built_in">list</span>(<span class="built_in">enumerate</span>(env.cohs))): <span class="comment"># index value</span></span><br><span class="line"> line_r = Line2D([], [], label=<span class="string">f'L motion trial, c=<span class="subst">{v_coh}</span>'</span>, color=reds(i_coh))</span><br><span class="line"> lines.append(line_r)</span><br><span class="line"><span class="keyword">for</span> i_coh, v_coh <span class="keyword">in</span> <span class="built_in">enumerate</span>(env.cohs):</span><br><span class="line"> line_b = Line2D([], [], label=<span class="string">f'R motion trial, c=<span class="subst">{v_coh}</span>'</span>, color=blues(i_coh))</span><br><span class="line"> lines.append(line_b)</span><br><span class="line">handles.extend([dot]+lines)</span><br><span class="line">ax.set_xlabel(<span class="string">'PC 1'</span>)</span><br><span class="line">ax.set_ylabel(<span class="string">'PC 2'</span>)</span><br><span class="line">ax.set_zlabel(<span class="string">'PC 3'</span>)</span><br><span class="line">ax.set_title(<span class="string">'State space based on principal component analysis'</span>)</span><br><span class="line">plt.legend(title=<span class="string">'Legend'</span>, bbox_to_anchor=(<span class="number">1.6</span>,<span class="number">0.9</span>), handles=handles, frameon=<span class="literal">False</span>)</span><br><span class="line">plt.show()</span><br></pre></td></tr></table></figure><p><img src="https://img.cwxhmk.top/post/2023-PC-3.png" alt="PCA(三个主成分)"></p><h1 id="补充知识"><a href="#补充知识" class="headerlink" title="补充知识"></a>补充知识</h1><h2 id="kwargs"><a href="#kwargs" class="headerlink" title="**kwargs"></a>**kwargs</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">kwargs = {<span class="string">'arg1'</span>: <span class="number">10</span>, <span class="string">'arg3'</span>: <span class="literal">True</span>, <span class="string">'arg2'</span>: <span class="string">'hello'</span>}</span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">example_function</span>(<span class="params">arg1, arg2, arg3</span>):</span><br><span class="line"> <span class="built_in">print</span>(arg1)</span><br><span class="line"> <span class="built_in">print</span>(arg2)</span><br><span class="line"> <span class="built_in">print</span>(arg3)</span><br><span class="line"></span><br><span class="line">example_function(**kwargs)</span><br><span class="line"><span class="comment"># 10</span></span><br><span class="line"><span class="comment"># hello</span></span><br><span class="line"><span class="comment"># True</span></span><br></pre></td></tr></table></figure><h2 id="字典"><a href="#字典" class="headerlink" title="字典"></a>字典</h2><p>在Python中,字典是一种可变的数据结构,用于存储键-值对的集合。字典可以使用<code>{}</code>来创建,也可以通过<code>dict()</code>函数创建。<br><code>update</code>方法可以接受一个字典对象或包含键值对的可迭代对象作为参数,并将其中的键值对添加到调用<code>update</code>方法的字典中。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">my_dict = {<span class="string">'key1'</span>: <span class="string">'value1'</span>, <span class="string">'key2'</span>: <span class="string">'value2'</span>}</span><br><span class="line">my_dict = <span class="built_in">dict</span>(</span><br><span class="line"> key1 = value1,</span><br><span class="line"> key2 = value2,</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line">my_dict = {<span class="string">'key1'</span>: <span class="string">'value1'</span>, <span class="string">'key2'</span>: <span class="string">'value2'</span>}</span><br><span class="line">new_dict = {<span class="string">'key3'</span>: <span class="string">'value3'</span>, <span class="string">'key4'</span>: <span class="string">'value4'</span>}</span><br><span class="line"></span><br><span class="line">my_dict.update(new_dict)</span><br><span class="line"><span class="built_in">print</span>(my_dict)</span><br><span class="line"><span class="comment"># 输出:{'key1': 'value1', 'key2': 'value2', 'key3': 'value3', 'key4': 'value4'}</span></span><br></pre></td></tr></table></figure><h2 id="time-time"><a href="#time-time" class="headerlink" title="time.time()"></a>time.time()</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> time</span><br><span class="line"></span><br><span class="line">start_time = time.time()</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">10</span>):</span><br><span class="line"> <span class="built_in">print</span>(i)</span><br><span class="line">end_time = time.time() <span class="comment"># 可用于计算程序运行的时间</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">f'程序用时:<span class="subst">{end_time-start_time}</span>s'</span>)</span><br></pre></td></tr></table></figure><h1 id="参考内容"><a href="#参考内容" class="headerlink" title="参考内容"></a>参考内容</h1><ul><li><a href="https://colab.research.google.com/drive/1jv51d1VfMvWNSc6YeJeoSRvNdO5c1UJW?usp=sharing">Methods of BCS: Mathematical modeling and simulation(Part II)</a></li><li><a href="https://www.nature.com/articles/s41593-019-0520-2">A deep learning framework for neuroscience</a></li><li><a href="https://github.com/neurogym/neurogym">NeuroGym</a></li><li><a href="https://colab.research.google.com/github/HurleyJames/GoogleColabExercise/blob/master/Intro_to_PyTorch.ipynb">Introduction to PyTorch</a></li><li><a href="https://neurogym.github.io/understanding_neurogym_task.html">Understanding Neurogym Task</a></li><li><a href="https://www.gymlibrary.dev/content/environment_creation/">Gym: Make your own custom environment</a></li></ul>]]></content>
<categories>
<category> 学习笔记 </category>
</categories>
<tags>
<tag> RNN </tag>
</tags>
</entry>
<entry>
<title>windows设置代理及取消代理</title>
<link href="/2023/07/11/set-proxy/"/>
<url>/2023/07/11/set-proxy/</url>
<content type="html"><![CDATA[<div class="note warning flat"><p>本来想用<code>coursera-dl</code>下载coursera上面的网课,结果一直报错,想找找下载视频的插件,也没找到好用的,最终还是回归伟大的哔哩哔哩!😽</p></div><h1 id="设置代理"><a href="#设置代理" class="headerlink" title="设置代理"></a>设置代理</h1><figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"># 翻墙后设置代理</span><br><span class="line"><span class="built_in">set</span> http_proxy=http://<span class="number">127</span>.<span class="number">0</span>.<span class="number">0</span>.<span class="number">1</span>(代理的IP地址):<span class="number">1080</span>(代理的端口号)</span><br><span class="line"><span class="built_in">set</span> https_proxy=http://<span class="number">127</span>.<span class="number">0</span>.<span class="number">0</span>.<span class="number">1</span>(代理的IP地址):<span class="number">1080</span>(代理的端口号)</span><br><span class="line"># 不翻墙的话需要取消代理,否则打开一些页面会很慢</span><br><span class="line"><span class="built_in">set</span> http_proxy=</span><br><span class="line"><span class="built_in">set</span> https_proxy=</span><br></pre></td></tr></table></figure><h1 id="油猴插件"><a href="#油猴插件" class="headerlink" title="油猴插件"></a>油猴插件</h1><p>点击网站右上角(篡改猴)图标→获取新脚本→搜索用户脚本→安装</p><h1 id="参考文章"><a href="#参考文章" class="headerlink" title="参考文章"></a>参考文章</h1><ul><li><a href="https://blog.csdn.net/z784561257/article/details/89380423">windows下使用代理并取消代理</a></li></ul>]]></content>
<categories>
<category> 方法教程 </category>
</categories>
<tags>
<tag> 代理 </tag>
</tags>
</entry>
<entry>
<title>BrainPy学习笔记【01】</title>
<link href="/2023/07/10/brainpy-1/"/>
<url>/2023/07/10/brainpy-1/</url>
<content type="html"><![CDATA[<h1 id="安装教程(Windows环境)"><a href="#安装教程(Windows环境)" class="headerlink" title="安装教程(Windows环境)"></a>安装教程(Windows环境)</h1><figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">conda env list</span><br><span class="line">conda create --name bdp python=<span class="number">3</span>.<span class="number">9</span> -y</span><br><span class="line">conda activate bdp</span><br><span class="line"></span><br><span class="line">python -m pip install git+https://git.openi.org.cn/OpenI/BrainPy</span><br><span class="line">conda install numpy</span><br><span class="line">pip install "jax[cpu]" -f https://whls.blob.core.windows.<span class="built_in">net</span>/unstable/index.html</span><br><span class="line">python -m pip install brainpylib # 报错 需要安装matplotlib</span><br><span class="line">conda install matplotlib</span><br><span class="line">python -m pip install brainpylib</span><br><span class="line"></span><br><span class="line">conda install ipykernel</span><br></pre></td></tr></table></figure><h1 id="参考文章"><a href="#参考文章" class="headerlink" title="参考文章"></a>参考文章</h1><ul><li><a href="https://github.com/c-xy17/NeuralModeling">《神经计算建模实战》代码</a></li><li><a href="https://brainpy.readthedocs.io/en/latest/quickstart/installation.html">BrainPy文档</a></li><li><a href="https://blog.csdn.net/Fellyhosn/article/details/129903163?spm=1001.2014.3001.5502">【brainpy学习笔记】基础知识1(安装、JIT编译与编程基础)</a></li></ul>]]></content>
<categories>
<category> 学习笔记 </category>
</categories>
<tags>
<tag> BrainPy </tag>
<tag> 计算建模 </tag>
</tags>
</entry>
<entry>
<title>BIRDS插件代码学习【06】</title>
<link href="/2023/07/10/imagej-plugin-6/"/>
<url>/2023/07/10/imagej-plugin-6/</url>
<content type="html"><![CDATA[<h1 id="今日计划"><a href="#今日计划" class="headerlink" title="今日计划"></a>今日计划</h1><ul><li><input checked="" disabled="" type="checkbox"> 准备和刘越老师讨论的PPT,主要整理计算建模的思路以及难点</li><li><input checked="" disabled="" type="checkbox"> 提取单张脑片的脑区轮廓</li><li><input checked="" disabled="" type="checkbox"> BrainPy环境搭建</li><li><input checked="" disabled="" type="checkbox"> 整理计算神经科学领域比较有名的实验室和科学家</li></ul><h1 id="提取脑区轮廓"><a href="#提取脑区轮廓" class="headerlink" title="提取脑区轮廓"></a>提取脑区轮廓</h1><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> I.plugin;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> ij.ImagePlus;</span><br><span class="line"><span class="keyword">import</span> ij.ImageStack;</span><br><span class="line"><span class="keyword">import</span> ij.gui.NewImage;</span><br><span class="line"><span class="keyword">import</span> ij.io.FileSaver;</span><br><span class="line"><span class="keyword">import</span> ij.plugin.RGBStackMerge;</span><br><span class="line"><span class="keyword">import</span> ij.process.ImageProcessor;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Test06</span> {</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> ImageProcessor <span class="title function_">getLineImg</span><span class="params">(ImageProcessor ip, ImageProcessor op)</span> {</span><br><span class="line"><span class="type">int</span> <span class="variable">lenX</span> <span class="operator">=</span> ip.getWidth();</span><br><span class="line"><span class="type">int</span> <span class="variable">lenY</span> <span class="operator">=</span> ip.getHeight();</span><br><span class="line"><span class="keyword">for</span>(<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i < lenX; i ++) { <span class="comment">//按列</span></span><br><span class="line"><span class="type">int</span> <span class="variable">begin</span> <span class="operator">=</span> <span class="number">0</span>; <span class="comment">//初始像素值为黑色</span></span><br><span class="line"><span class="keyword">for</span>(<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">0</span>; j < lenY; j ++) {</span><br><span class="line"><span class="type">int</span> <span class="variable">temp</span> <span class="operator">=</span> (<span class="type">int</span>)ip.getPixelValue(i, j);</span><br><span class="line"><span class="keyword">if</span>(temp != begin) {</span><br><span class="line">op.set(i, j, <span class="number">255</span>);</span><br><span class="line">begin = temp;</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"><span class="keyword">for</span>(<span class="type">int</span> <span class="variable">j</span> <span class="operator">=</span> <span class="number">0</span>; j < lenY; j ++) {</span><br><span class="line"><span class="type">int</span> <span class="variable">begin</span> <span class="operator">=</span> <span class="number">0</span>; <span class="comment">//初始像素值为黑色</span></span><br><span class="line"><span class="keyword">for</span>(<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i < lenX; i ++) {</span><br><span class="line"><span class="type">int</span> <span class="variable">temp</span> <span class="operator">=</span> (<span class="type">int</span>)ip.getPixelValue(i, j);</span><br><span class="line"><span class="keyword">if</span>(temp != begin) {</span><br><span class="line">op.set(i, j, <span class="number">255</span>);</span><br><span class="line">begin = temp;</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"><span class="keyword">return</span> op;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> {</span><br><span class="line"><span class="type">ImagePlus</span> <span class="variable">brainImage</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ImagePlus</span>(<span class="string">"D:/Desktop/downSampleImage0160.tif"</span>);</span><br><span class="line"><span class="type">ImageStack</span> <span class="variable">brainStack</span> <span class="operator">=</span> brainImage.getStack();</span><br><span class="line"></span><br><span class="line"><span class="type">ImagePlus</span> <span class="variable">annoImage</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ImagePlus</span>(<span class="string">"D:/Desktop/anno_output/result0160.tif"</span>);</span><br><span class="line"><span class="type">ImageProcessor</span> <span class="variable">ap</span> <span class="operator">=</span> annoImage.getProcessor();</span><br><span class="line"><span class="type">int</span> <span class="variable">width</span> <span class="operator">=</span> ap.getWidth();</span><br><span class="line"><span class="type">int</span> <span class="variable">height</span> <span class="operator">=</span> ap.getHeight();</span><br><span class="line"></span><br><span class="line"><span class="type">ImagePlus</span> <span class="variable">lineImage</span> <span class="operator">=</span> NewImage.createByteImage(<span class="string">"lineImage"</span>, width, height, <span class="number">0</span>, NewImage.FILL_BLACK);</span><br><span class="line"><span class="type">ImageStack</span> <span class="variable">lineStack</span> <span class="operator">=</span> lineImage.getStack();</span><br><span class="line"><span class="type">ImageProcessor</span> <span class="variable">lp</span> <span class="operator">=</span> lineImage.getProcessor();</span><br><span class="line"></span><br><span class="line"><span class="type">ImageProcessor</span> <span class="variable">op</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Test06</span>().getLineImg(ap, lp);</span><br><span class="line"></span><br><span class="line">lineImage.setProcessor(op);</span><br><span class="line">lineImage.show();</span><br><span class="line"> </span><br><span class="line"><span class="type">ImagePlus</span> <span class="variable">fuseImage</span> <span class="operator">=</span> NewImage.createByteImage(<span class="string">"fuseImage"</span>, width, height, <span class="number">0</span>, NewImage.FILL_BLACK);</span><br><span class="line"></span><br><span class="line"><span class="type">ImageStack</span> <span class="variable">fuseStack</span> <span class="operator">=</span> RGBStackMerge.mergeStacks(brainStack, lineStack, <span class="literal">null</span>, <span class="literal">true</span>);</span><br><span class="line"></span><br><span class="line">fuseImage.setStack(fuseStack);</span><br><span class="line">fuseImage.show();</span><br><span class="line"> <span class="comment">// 保存图片</span></span><br><span class="line"> <span class="keyword">new</span> <span class="title class_">FileSaver</span>(fuseImage).saveAsTiff(<span class="string">"D:/Desktop/fuseImage.tif"</span>);</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h1 id="细胞计数"><a href="#细胞计数" class="headerlink" title="细胞计数"></a>细胞计数</h1><div class="note info flat"><p>没想到BIRDS里细胞计数是通过调用Imaris的方法实现的,看来还是要学一下这个软件的用法🥲运行Imaris前记得先运行<code>license server.bat</code>~<br>.tif → .ims可以通过<code>ImarisFileConverter.exe</code>实现,Imaris默认安装在C盘。<br>没有找到很方便的API,看代码似乎是要现在Imaris里面操作完成之后,Java再获取对应的数据,这好像和我想要达到的效果不一样。<br>👻不想动脑子,怎么办!!!</p></div><h1 id="流程测试"><a href="#流程测试" class="headerlink" title="流程测试"></a>流程测试</h1><div class="note info flat"><p>⭐脑片与标准脑模板的尺寸要大致相同,为了不过度损失脑片分辨率,此处对标准脑模板进行上采样<br>⭐<code>elastix.exe</code>配准的参数使用<code>para-Standard_bspline.txt</code>、<code>para-Standard_affine.txt</code>和<code>para-Standard_rigid.txt</code>(去掉了对图片维度的限制)效果比较好<br>👻不知道为什么提取的脑区轮廓有很明显的锯齿,难道是因为我把注释图片分辨率调高了?不过问题不大~<br>👻由于原始脑片本身边缘有破损,因此与轮廓边缘处会出现明显的变形</p></div><ol><li>将标准脑模板和注释图片的分辨率提高至与脑片匹配的程度(尽量不损失原始脑片的图像分辨率)<figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> PIL <span class="keyword">import</span> Image</span><br><span class="line"></span><br><span class="line">Image.MAX_IMAGE_PIXELS = <span class="literal">None</span></span><br><span class="line">raw = Image.<span class="built_in">open</span>(<span class="string">r"D:/Desktop/elastix-5.1.0-win64/input/result1.tif"</span>)</span><br><span class="line">img = Image.<span class="built_in">open</span>(<span class="string">r"D:/Desktop/elastix-5.1.0-win64/out_anno/annotationImage0270.tif"</span>)</span><br><span class="line"><span class="comment"># img = Image.open(r"D:/Desktop/elastix-5.1.0-win64/out_temp/tempImage0270.tif")</span></span><br><span class="line"></span><br><span class="line">target_width = raw.size[<span class="number">0</span>]</span><br><span class="line">scale = <span class="built_in">round</span>(target_width/img.size[<span class="number">0</span>],<span class="number">1</span>)</span><br><span class="line">width = <span class="built_in">int</span>(img.size[<span class="number">0</span>]*scale)</span><br><span class="line">height = <span class="built_in">int</span>(img.size[<span class="number">1</span>]*scale)</span><br><span class="line"></span><br><span class="line">out = img.resize((width, height))</span><br><span class="line"><span class="built_in">type</span> = img.<span class="built_in">format</span></span><br><span class="line">out.save(<span class="string">'D:/Desktop/elastix-5.1.0-win64/out_anno/annotationImage0270-1.tif'</span>,<span class="built_in">type</span>)</span><br><span class="line"><span class="comment"># out.save('D:/Desktop/elastix-5.1.0-win64/out_temp/tempImage0270-1.tif',type)</span></span><br></pre></td></tr></table></figure></li><li>脑片与图谱配准<figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">elastix -f input/result1.tif -m out_temp/tempImage0270-<span class="number">1</span>.tif -out output -p input/para-Standard_rigid.txt -p input/para-Standard_affine.txt -p input/para-Standard_bspline_2.txt</span><br><span class="line"></span><br><span class="line">transformix -<span class="keyword">in</span> out_anno/annotationImage0270-<span class="number">1</span>.tif -out result -tp output/TransformParameters.<span class="number">2</span>.txt</span><br></pre></td></tr></table></figure></li></ol><h1 id="参考文章"><a href="#参考文章" class="headerlink" title="参考文章"></a>参考文章</h1><ul><li><a href="https://imagej.nih.gov/ij/developer/api/ij/ij/plugin/package-summary.html">Package ij.plugin</a></li><li><a href="https://github.com/utsavdj/automated-cell-counter-java-code">Automated Cell Counter in Java</a></li><li><a href="https://www.zhihu.com/question/265785687">如何用Imaris数细胞?</a></li><li><a href="https://imaris.github.io/imglib2-imaris-bridge/">ImgLib2-Imaris-Bridge</a></li><li><a href="https://imaris.github.io/imglib2-imaris-bridge/apidocs/">imglib2-imaris-bridge 9.7.2.0 API</a></li></ul>]]></content>
<categories>
<category> 项目实战 </category>
</categories>
<tags>
<tag> ImageJ </tag>
<tag> Java </tag>
<tag> Eclipse </tag>
</tags>
</entry>
<entry>
<title>解决mac电脑更新后V2rayU无法启动</title>
<link href="/2023/07/09/v2rayu-mac/"/>
<url>/2023/07/09/v2rayu-mac/</url>
<content type="html"><![CDATA[<div class="note warning flat"><p>电脑更新完以后,突然一直弹出警告让我卸载V2rayU,┭┮﹏┭┮,这可是我的宝贝软件,怎么能卸载呢???在网上搜索了半天,终于找到解决方案了!</p></div><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 1. 命令行输入</span></span><br><span class="line">sudo codesign --force --deep --sign - /Applications/V2rayU.app</span><br><span class="line"><span class="comment"># 2. 右键单击软件→显示简介→勾选☑️覆盖恶意软件保护</span></span><br><span class="line"><span class="comment"># 3. 打开软件</span></span><br><span class="line"><span class="comment"># 4. 命令行输入</span></span><br><span class="line">sudo codesign --force --deep --sign - ~/.V2rayU/V2rayUTool</span><br><span class="line">sudo codesign --force --deep --sign - ~/.V2rayU/v2ray-core/v2ray</span><br></pre></td></tr></table></figure><h1 id="参考文章"><a href="#参考文章" class="headerlink" title="参考文章"></a>参考文章</h1><ul><li><a href="https://github.com/yanue/V2rayU/releases">v2raU下载链接</a></li><li><a href="https://zhuanlan.zhihu.com/p/641261094">应用程序“V2rayU.app”无法打开的解决方法</a></li><li><a href="https://github.com/yanue/V2rayU/issues/1234">应用程序“V2rayU.app”无法打开的解决办法</a></li></ul>]]></content>
<categories>
<category> 方法教程 </category>
</categories>
<tags>
<tag> V2rayU </tag>
</tags>
</entry>
<entry>
<title>BIRDS插件代码学习【05】</title>
<link href="/2023/07/08/imagej-plugin-5/"/>
<url>/2023/07/08/imagej-plugin-5/</url>
<content type="html"><![CDATA[<h1 id="Java-调用命令行"><a href="#Java-调用命令行" class="headerlink" title="Java 调用命令行"></a>Java 调用命令行</h1><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> java.io.BufferedReader;</span><br><span class="line"><span class="keyword">import</span> java.io.InputStreamReader;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Test05</span> {</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> {</span><br><span class="line"><span class="type">String</span> <span class="variable">cmd</span> <span class="operator">=</span> <span class="string">"calc"</span>;</span><br><span class="line"><span class="keyword">try</span> {</span><br><span class="line"><span class="type">Process</span> <span class="variable">ps</span> <span class="operator">=</span> Runtime.getRuntime().exec(cmd);<span class="comment">//打开计算器</span></span><br><span class="line"><span class="comment">// ps.getInputStream() 获取进程的输出流</span></span><br><span class="line"><span class="type">BufferedReader</span> <span class="variable">br</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">BufferedReader</span>(<span class="keyword">new</span> <span class="title class_">InputStreamReader</span>(ps.getInputStream()));</span><br><span class="line">String line;</span><br><span class="line"><span class="keyword">while</span>((line = br.readLine()) != <span class="literal">null</span>) {</span><br><span class="line">System.out.println(line);</span><br><span class="line">}</span><br><span class="line">}<span class="keyword">catch</span>(Exception e) {</span><br><span class="line">e.printStackTrace();</span><br><span class="line">}</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h1 id="elastix-使用"><a href="#elastix-使用" class="headerlink" title="elastix 使用"></a>elastix 使用</h1><ol><li>下载 <a href="https://github.com/SuperElastix/elastix/releases">elastix-5.1.0-win64</a>,解压后得到<code>elastix.exe</code>和<code>transformix.exe</code></li><li>下载 elastix 用户手册<div class="row"> <embed src="https://img.cwxhmk.top/pdf/elastix-5.1.0-manual.pdf" width="100%" height="550" type="application/pdf"></div></li><li>命令行调用<code>elastix.exe</code>和<code>transformix.exe</code>得到配准后的脑片<figure class="highlight cmd"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">elastix.exe --<span class="built_in">help</span></span><br><span class="line">elastix -f input/downSampleImage.tif -m input/tempImage.tif -out output -p input/Parameters_BSpline.txt</span><br><span class="line"></span><br><span class="line">transformix.exe --<span class="built_in">help</span></span><br><span class="line">transformix -<span class="keyword">in</span> input/annotationImage.tif -out result -tp output/TransformParameters.<span class="number">0</span>.txt</span><br><span class="line"># 参数文件中可以设置输出格式,默认为mhd,此处修改为tif</span><br></pre></td></tr></table></figure></li></ol><h1 id="ImageJ-合并通道"><a href="#ImageJ-合并通道" class="headerlink" title="ImageJ 合并通道"></a>ImageJ 合并通道</h1><ol><li>将待合并的两张图像载入ImageJ<div class="fj-gallery"><p><img src="https://img.cwxhmk.top/post/20230709-1.png" alt="脑片"><br><img src="https://img.cwxhmk.top/post/20230709-2.png" alt="脑区轮廓"></p> </div></li><li>Image→Color→Merge Channels</li><li>脑片保留红色通道,脑区轮廓保留绿色通道(注意不要勾选create composite,以免保存时仅有最上层的通道)<br><img src="https://img.cwxhmk.top/post/20230709-3.png" alt="合并通道"></li><li>保存为tif文件<img src="https://img.cwxhmk.top/post/20230709-4.png" alt="合并后的图像" width="50%" height="50%" /></li></ol><h1 id="二维脑片配准关键步骤"><a href="#二维脑片配准关键步骤" class="headerlink" title="二维脑片配准关键步骤"></a>二维脑片配准关键步骤</h1><ol><li>定位与脑片最匹配的图谱(相似度最高)</li><li>获取Allen全脑平均模板<code>tempImage</code>和对应的注释文件<code>annotationImage</code></li><li>通过<code>elastix.exe</code>和<code>transformix.exe</code>对脑片配准(模板→脑片 注释→脑片)</li><li>根据注释文件获取脑区轮廓<code>lineImage</code></li><li>轮廓与脑片合并得到<code>fuseImage</code></li><li>根据annotationImage的像素值匹配脑区</li><li>脑区细胞计数<br><img src="https://img.cwxhmk.top/post/20230709-5.png" alt="二维脑片配准流程图"></li></ol><h1 id="今日总结"><a href="#今日总结" class="headerlink" title="今日总结"></a>今日总结</h1><p>到目前为止感觉BIRDS的配准是通过elastix实现的,需要看一下elastix的论文,然后试一下elastix进行脑片配准的效果。</p><p>不管老板对我的要求是怎样的,我对自己的要求就是把一个小项目做完再做下一个小项目,不能三心二意。我的课题要根据我自己的兴趣来,广泛涉猎给自己找一条出路,我现在没有能力回绝老板的各种要求就是因为我没有能够给出其他方案,要行动起来。</p><p>每天拿出1~2个小时跟着吴思老师实验室出的书《神经计算建模实战——基于brainpy》实操一下,总要下点功夫入门计算神经科学吧!可能需要补一下微积分的知识😎</p><h1 id="参考文章"><a href="#参考文章" class="headerlink" title="参考文章"></a>参考文章</h1><ul><li><a href="https://github.com/SuperElastix/elastix">elastix image registration toolbox</a></li><li><a href="https://blog.csdn.net/calabash_man/article/details/108266692">Java 调用命令行</a></li><li><a href="https://blog.csdn.net/Joker00007/article/details/112402763">医学图像配准工具Elastix的配置和入门</a></li><li><a href="https://elastix.lumc.nl/modelzoo/">elastix Model Zoo</a></li><li><a href="https://github.com/SuperElastix/ElastixModelZoo/tree/master/models/Par0009">elatix 参数</a></li><li><a href="https://github.com/Brainpy/Brainpy">BrainPy</a></li><li><a href="https://blog.csdn.net/Fellyhosn/article/details/129903163?spm=1001.2014.3001.5502">【brainpy学习笔记】基础知识1(安装、JIT编译与编程基础)</a></li><li><a href="https://www.jingege.wang/2020/07/22/%e5%88%a9%e7%94%a8image-j%e6%8b%86%e5%88%86%e5%92%8cmerge%e8%8d%a7%e5%85%89%e5%9b%be%e7%89%87/">利用ImageJ拆分和Merge荧光图片</a></li></ul>]]></content>
<categories>
<category> 项目实战 </category>
</categories>
<tags>
<tag> ImageJ </tag>
<tag> Java </tag>
<tag> Eclipse </tag>
</tags>
</entry>
<entry>
<title>BIRDS插件代码学习【04】</title>
<link href="/2023/07/06/imagej-plugin-4/"/>
<url>/2023/07/06/imagej-plugin-4/</url>
<content type="html"><![CDATA[<h1 id="体素-voxel"><a href="#体素-voxel" class="headerlink" title="体素 voxel"></a>体素 voxel</h1><div class="note success simple"><p>体素是三维空间的像素。体素网格是用固定大小的立方块作为最小单元来表示三维物体的一种数据结构。</p></div><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 该程序实现鼠标事实获取stack当前图像(slice)的体素值(16unit 颜色值)</span></span><br><span class="line"><span class="comment"> * 备注:通过该体素值可以进一步匹配到对应的脑区(该程序不包含此部分)</span></span><br><span class="line"><span class="comment"> * 代码主要参考了BIRDS配准源码</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@author</span> 文欣</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@version</span> 1.0</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">package</span> I.plugin;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.awt.Point;</span><br><span class="line"><span class="keyword">import</span> java.awt.event.MouseEvent;</span><br><span class="line"><span class="keyword">import</span> java.awt.event.MouseListener;</span><br><span class="line"><span class="keyword">import</span> java.awt.event.MouseMotionListener;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> ij.IJ;</span><br><span class="line"><span class="keyword">import</span> ij.ImageJ;</span><br><span class="line"><span class="keyword">import</span> ij.ImagePlus;</span><br><span class="line"><span class="keyword">import</span> ij.ImageStack;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Test04</span> <span class="keyword">implements</span> <span class="title class_">MouseListener</span>,MouseMotionListener{</span><br><span class="line"><span class="keyword">private</span> <span class="title function_">Test04</span><span class="params">()</span> {}</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> ImagePlus brainImg;</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> {</span><br><span class="line"><span class="keyword">new</span> <span class="title class_">ImageJ</span>();</span><br><span class="line"></span><br><span class="line">brainImg = IJ.openImage(<span class="string">"D:/Desktop/annotationOrgImage.tif"</span>);</span><br><span class="line">brainImg.show();</span><br><span class="line"></span><br><span class="line">System.out.println(brainImg.getTitle());</span><br><span class="line">System.out.println(brainImg.getStackSize());</span><br><span class="line"><span class="keyword">new</span> <span class="title class_">Test04</span>().addMouseListener();</span><br><span class="line">}</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">addMouseListener</span><span class="params">()</span> {</span><br><span class="line"> </span><br><span class="line">brainImg.getCanvas().addMouseListener(<span class="built_in">this</span>);</span><br><span class="line">brainImg.getCanvas().addMouseMotionListener(<span class="built_in">this</span>);</span><br><span class="line">}</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">mouseMoved</span><span class="params">(MouseEvent e)</span> {</span><br><span class="line"><span class="type">ImageStack</span> <span class="variable">brainStack</span> <span class="operator">=</span> brainImg.getImageStack();</span><br><span class="line"><span class="type">int</span> <span class="variable">currentSlice</span> <span class="operator">=</span> brainImg.getCurrentSlice(); </span><br><span class="line"><span class="type">Point</span> <span class="variable">tempPoint</span> <span class="operator">=</span> brainImg.getCanvas().getCursorLoc();</span><br><span class="line"><span class="type">int</span> <span class="variable">val</span> <span class="operator">=</span> (<span class="type">int</span>)(brainStack.getVoxel(tempPoint.x, tempPoint.y, currentSlice-<span class="number">1</span>));<span class="comment">//16位像素值</span></span><br><span class="line">System.out.println(val); <span class="comment">//打印</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">mouseDragged</span><span class="params">(MouseEvent e)</span> {}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">mouseClicked</span><span class="params">(MouseEvent e)</span> {}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">mousePressed</span><span class="params">(MouseEvent e)</span> {}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">mouseReleased</span><span class="params">(MouseEvent e)</span> {}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">mouseEntered</span><span class="params">(MouseEvent e)</span> {}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">mouseExited</span><span class="params">(MouseEvent e)</span> {}</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure><h1 id="参考文章"><a href="#参考文章" class="headerlink" title="参考文章"></a>参考文章</h1><ul><li><a href="https://blog.csdn.net/u010858605/article/details/113663883">Class.getClassLoader().getResourceAsStream()</a></li><li><a href="https://zhuanlan.zhihu.com/p/348563616">什么是体素(Voxel)?</a></li></ul>]]></content>
<categories>
<category> 项目实战 </category>
</categories>
<tags>
<tag> ImageJ </tag>
<tag> Java </tag>
<tag> Eclipse </tag>
</tags>
</entry>
<entry>
<title>BIRDS插件代码学习【03】</title>
<link href="/2023/07/05/imagej-plugin-3/"/>
<url>/2023/07/05/imagej-plugin-3/</url>
<content type="html"><![CDATA[<h1 id="图像预处理过程"><a href="#图像预处理过程" class="headerlink" title="图像预处理过程"></a>图像预处理过程</h1><h2 id="图像介绍"><a href="#图像介绍" class="headerlink" title="图像介绍"></a>图像介绍</h2><p>DownSample.java文件中主要涉及了以下图像:</p><ul><li><code>ourBrainImage</code>:导入ImageJ的原始图像</li><li><code>Atlas132labelImage</code>:Allen小鼠脑图谱(冠状面)570×400×660</li><li><code>tempInvertOrgImage</code>:Allen小鼠脑平均模板反转</li><li><code>tempOrgImage</code>:Allen小鼠脑平均模板</li><li><code>annotationImage</code>:注释图谱<br>其中Atlas132labelImage、annotationImage、tempOrgImage和tempInvertOrgImage是直接存入cache的。Atlas132labelImage仅仅是用于展示脑图谱,并没有做过多的处理。tempOrgImage和annotationImage均由Allen Brain提供(<a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC8152789/">CCFv3</a>)。</li></ul><h2 id="获取CCFv3小鼠全脑平均模板和注释"><a href="#获取CCFv3小鼠全脑平均模板和注释" class="headerlink" title="获取CCFv3小鼠全脑平均模板和注释"></a>获取CCFv3小鼠全脑平均模板和注释</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> nrrd <span class="comment"># pip install pynrrd</span></span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</span><br><span class="line"><span class="keyword">from</span> PIL <span class="keyword">import</span> Image</span><br><span class="line"></span><br><span class="line">AVGT, metaAVGT = nrrd.read(<span class="string">'average_template_25.nrrd'</span>); <span class="comment"># 25 voxel</span></span><br><span class="line">ANO, metaANO = nrrd.read(<span class="string">'CCFv3_annotation_25.nrrd'</span>);</span><br><span class="line"></span><br><span class="line">AVGT.shape <span class="comment"># (528, 320, 456)</span></span><br><span class="line"><span class="comment"># 存储average template</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">526</span>):</span><br><span class="line"> <span class="built_in">slice</span> = AVGT[i+<span class="number">1</span>,:,:].astype(<span class="built_in">float</span>)</span><br><span class="line"> <span class="built_in">slice</span> /= np.<span class="built_in">max</span>(<span class="built_in">slice</span>)</span><br><span class="line"> im = Image.fromarray(np.uint8(plt.cm.gray(<span class="built_in">slice</span>)*<span class="number">255</span>))</span><br><span class="line"> im.save(<span class="string">'avgt/avgt_coronal_%d.png'</span>%(i+<span class="number">1</span>))</span><br><span class="line"><span class="comment"># 存储annotation</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">526</span>):</span><br><span class="line"> <span class="built_in">slice</span> = ANO[i+<span class="number">1</span>,:,:].astype(<span class="built_in">float</span>)</span><br><span class="line"> <span class="built_in">slice</span> /= <span class="number">2000</span></span><br><span class="line"> im = Image.fromarray(np.uint8(plt.cm.gray(<span class="built_in">slice</span>)*<span class="number">255</span>))</span><br><span class="line"> im.save(<span class="string">'anno/ano_coronal_%d.png'</span>%(i+<span class="number">1</span>))</span><br></pre></td></tr></table></figure><h1 id="今日总结"><a href="#今日总结" class="headerlink" title="今日总结"></a>今日总结</h1><p>我之前并没有留意BIRDS插件一开始载入缓存文件夹中的内容,本以为就是把github下载下来的压缩包解压,但今天仔细看了一下代码,才发现中间调用了AddtionalFile.java,用于生成orgInvertImage.tif,该代码又使用了InverTool.java,看来细节还是蛮多的。</p><p>我花了很长时间找annotationImage的原始出处,最终发现最有可能的来源是CCFv3,但下载后是nrrd格式,用ImageJ打开是矢状面。我在github、Allen社区以及文章提供的数据中下载到的模板和注释,打开后都是矢状面。晚上回到宿舍以后我还是不甘心,总觉得作者不应该没有提供冠状面的模板,我从nrrd这个文件格式入手,意外看到了一篇博客下面的评论,ImageJ里面可以查看stacks的正交视角!!!我试了一下,果然可以看到冠状面!</p><p>接下来的问题就是怎么把全脑冠状面存储为tif格式,昨天没想到好的解决办法,今天早上试了一下Allen提供的API,写了个循环获取冠状面(按顺序命名),然后用ImageJ读取Image sequence并存储为tif格式。(我没有找到BIRDS里面用的voxel是20µm的模板,但感觉问题不大~)</p><p>┭┮﹏┭┮ 今天早上喜提周六文献汇报,看论文去了!</p><h1 id="参考文章"><a href="#参考文章" class="headerlink" title="参考文章"></a>参考文章</h1><ul><li><a href="https://atlas.brain-map.org/atlas?atlas=602630314">Allen Adult Mouse Brain Reference Atalases</a></li><li><a href="http://download.alleninstitute.org/informatics-archive/current-release/">CCFv3 资源</a></li><li><a href="http://help.brain-map.org/display/mouseconnectivity/API#API-DownloadAtlas3-DReferenceModels">Allen API</a></li><li><a href="http://download.alleninstitute.org/publications/allen_mouse_brain_common_coordinate_framework/">allen_mouse_brain_common_coordinate_framework</a></li><li><a href="https://blog.csdn.net/gaohanggaolegao/article/details/85222482">NRRD文件格式-基本定义</a></li></ul>]]></content>
<categories>
<category> 项目实战 </category>
</categories>
<tags>
<tag> ImageJ </tag>
<tag> Java </tag>
<tag> Eclipse </tag>
</tags>
</entry>
<entry>
<title>BIRDS插件代码学习【02】</title>
<link href="/2023/07/04/imagej-plugin-2/"/>
<url>/2023/07/04/imagej-plugin-2/</url>
<content type="html"><![CDATA[<h1 id="ImageJ常用方法"><a href="#ImageJ常用方法" class="headerlink" title="ImageJ常用方法"></a>ImageJ常用方法</h1><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 创建新的图像窗口</span></span><br><span class="line"><span class="type">ImagePlus</span> <span class="variable">lineImage</span> <span class="operator">=</span> NewImage.createByteImage(<span class="literal">null</span>, <span class="number">500</span>, <span class="number">300</span>, <span class="number">10</span>, NewImage.FILL_WHITE);</span><br><span class="line"><span class="type">ImageStack</span> <span class="variable">lineImageStack</span> <span class="operator">=</span> PreciseRegistration.lineImage.getImageStack();</span><br><span class="line">PreciseRegistration.lineImage.setStack(lineImageStack);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 展示图像</span></span><br><span class="line">lineImage.show();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 查看stack的某一张</span></span><br><span class="line"><span class="comment">// getProcessor:Returns an ImageProcessor for the specified slice, where 1<=n<=nslices.</span></span><br><span class="line"><span class="type">ImageProcessor</span> <span class="variable">imageProcessor</span> <span class="operator">=</span> annotationImageStack.getProcessor(<span class="number">120</span>);</span><br><span class="line"><span class="type">ImagePlus</span> <span class="variable">myImg</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">ImagePlus</span>(<span class="string">"ip2"</span>, imageProcessor);</span><br><span class="line">myImg.show();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 保存图像</span></span><br><span class="line"><span class="keyword">new</span> <span class="title class_">FileSaver</span>(PreciseRegistration.lineImage).saveAsTiff(GlobalValue.URL+<span class="string">"/registration/precise/line.tif"</span>);</span><br></pre></td></tr></table></figure><h1 id="线程"><a href="#线程" class="headerlink" title="线程"></a>线程</h1><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">创建一个 CountDownLatch 对象时,需要指定一个初始计数值,该计数值表示需要等待的线程数量。</span></span><br><span class="line"><span class="comment">每当一个线程完成了其任务,它调用 CountDownLatch 的 countDown() 方法,计数器的值就会减一。</span></span><br><span class="line"><span class="comment">当计数器的值变成 0 时,等待的线程就会被唤醒,继续执行它们的任务。</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">import</span> java.util.concurrent.CountDownLatch;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title class_">Test03</span> {</span><br><span class="line"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title function_">main</span><span class="params">(String[] args)</span> <span class="keyword">throws</span> InterruptedException {</span><br><span class="line"></span><br><span class="line"> <span class="type">CountDownLatch</span> <span class="variable">count</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">CountDownLatch</span>(<span class="number">5</span>);<span class="comment">//在线程执行完之前,会阻塞主程序的执行</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> <span class="variable">i</span> <span class="operator">=</span> <span class="number">0</span>; i < <span class="number">5</span>; i++) {</span><br><span class="line"> <span class="keyword">final</span> <span class="type">int</span> <span class="variable">num</span> <span class="operator">=</span> i;</span><br><span class="line"> <span class="keyword">new</span> <span class="title class_">Thread</span>(()->{</span><br><span class="line"> System.out.println(Thread.currentThread().getName()+<span class="string">" "</span>+(num+<span class="number">1</span>));</span><br><span class="line"> count.countDown();</span><br><span class="line"> }).start();</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> count.await();</span><br><span class="line"> } <span class="keyword">catch</span>(Exception e){</span><br><span class="line"> System.out.println(e.getMessage());</span><br><span class="line"> }</span><br><span class="line"> System.out.println(Runtime.getRuntime().availableProcessors()); <span class="comment">// 返回可用的计算资源</span></span><br><span class="line"> System.out.println(Thread.currentThread().getName()+<span class="string">" 执行完毕···"</span>);</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">输出结果:</span></span><br><span class="line"><span class="comment">Thread-0 1</span></span><br><span class="line"><span class="comment">Thread-4 5</span></span><br><span class="line"><span class="comment">Thread-3 4</span></span><br><span class="line"><span class="comment">Thread-2 3</span></span><br><span class="line"><span class="comment">Thread-1 2</span></span><br><span class="line"><span class="comment">16</span></span><br><span class="line"><span class="comment">main 执行完毕···</span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure><p><img src="https://img.cwxhmk.top/post/20230704-2.png" alt="使用多线程处理图像"></p><h1 id="脑片配准-fuseImage"><a href="#脑片配准-fuseImage" class="headerlink" title="脑片配准 fuseImage"></a>脑片配准 fuseImage</h1><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">RGBStackMerge</span> <span class="variable">rgbStackMerge</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">RGBStackMerge</span>();</span><br><span class="line">fuseImageStack = rgbStackMerge.mergeStacks(lenX, lenY, lenZ, downSampleImageStack, lineImageStack, <span class="literal">null</span>, <span class="literal">true</span>);</span><br><span class="line">PreciseRegistration.getPreciseregistration().fuseImage.setStack(fuseImageStack);</span><br></pre></td></tr></table></figure><div class="fj-gallery"><p><img src="https://img.cwxhmk.top/post/20230704-7.png" alt="templateImage"><br><img src="https://img.cwxhmk.top/post/20230704-8.png" alt="invertImage"><br><img src="https://img.cwxhmk.top/post/20230704-3.png" alt="downSampleImage"><br><img src="https://img.cwxhmk.top/post/20230704-4.png" alt="annotationImage"><br><img src="https://img.cwxhmk.top/post/20230704-5.jpg" alt="lineImage"><br><img src="https://img.cwxhmk.top/post/20230704-6.png" alt="fuseImage"></p> </div><h1 id="脑区识别"><a href="#脑区识别" class="headerlink" title="脑区识别"></a>脑区识别</h1><p><img src="https://img.cwxhmk.top/post/20230704-1.png" alt="鼠标悬停即可识别脑区"></p><h1 id="今日总结"><a href="#今日总结" class="headerlink" title="今日总结"></a>今日总结</h1><p>昨天看了一整天代码,今天再看这些java和ImageJ的方法就没有那么生疏了,今天还掌握了一个java新技能:多线程!(本科四年一直听说但从未使用过的谜之知识)。昨天研究了半天的ImageProcessor,今天发现BIRDS里很多地方也用到了,不过主要是对stack的处理。昨天发现界面中切换到precise面板时,会弹出配准后的脑片,即使不手动校正,效果已经能达到我的预期了,所以今天就从这个地方入手,希望能找到脑片配准的核心代码。</p><p>BIRDS中主要涉及了annotationImage、lineImage、fuseImage和downsampleImage这四组图片,脑片配准的效果就是通过合并downsampleImage和lineImage得到的。起初我主要在看脑区的轮廓线是如何得到的,似乎是遍历像素,特定位置赋为白色,但我最开始不懂为什么annotationImage会实现这种效果。后面我发现脑区识别也是获取鼠标位置以后根据像素灰度值与脑区进行匹配(提前存在一个excel文件里面),这些功能的实现都不算复杂,最关键的点就是如何给不同的脑区赋不同的颜色(虽然我还没有找到这部分代码,但大胆猜测是将脑图谱直接灰度化,不过怎么脑区和对应的灰度值是怎么得到的我还没想清楚)。</p><p>本以为图像预处理部分不是很重要,但今天的代码看下来,downsample部分是必须要看的,里面就包括我比较关心的annotationImage.tif,coarse部分也会得到一个类似的图像文件,只不过是和脑片配准之后的。明天可以重点看预处理这部分代码,慢慢来。</p><h1 id="参考文章"><a href="#参考文章" class="headerlink" title="参考文章"></a>参考文章</h1><ul><li><a href="https://docs.oracle.com/javase/8/docs/api/overview-summary.html">Java™ Platform, Standard Edition 8 API Specification</a></li><li><a href="https://docs.oracle.com/javase/8/docs/api/java/awt/event/package-summary.html">Package java.awt.event</a></li><li><a href="https://docs.oracle.com/javase/8/docs/api/javax/swing/event/package-summary.html">Package javax.swing.event</a></li><li><a href="https://imagej.nih.gov/ij/developer/api/ij/ij/ImagePlus.html">Class ImagePlus</a></li><li><a href="https://imagej.nih.gov/ij/developer/api/ij/ij/gui/package-summary.html">Package ij.gui</a></li><li><a href="https://zhuanlan.zhihu.com/p/619615713">JAVA 多线程编程之CountDownLatch</a></li><li><a href="https://www.cnblogs.com/Andya/p/12925634.html">Java—CountDownLatch使用详解</a></li><li><a href="https://www.cnblogs.com/xiaofuge/p/14040715.html">Thread.start() ,它是怎么让线程启动的呢? </a></li><li><a href="https://blog.csdn.net/u010519674/article/details/108435107">Java 线程计数器</a></li></ul>]]></content>
<categories>
<category> 项目实战 </category>
</categories>
<tags>
<tag> ImageJ </tag>
<tag> Java </tag>
<tag> Eclipse </tag>
</tags>
</entry>
<entry>
<title>BIRDS插件代码学习【01】</title>
<link href="/2023/07/03/imagej-plugin/"/>
<url>/2023/07/03/imagej-plugin/</url>
<content type="html"><![CDATA[<h1 id="BIRDS简介"><a href="#BIRDS简介" class="headerlink" title="BIRDS简介"></a>BIRDS简介</h1><p><a href="https://github.com/bleach1by1/BIRDS_plugin">BIRDS</a>(Bi-channel Image Registration and Deep-learning Segmentation for efficient, versatile mapping of mouse brain)是ImageJ的一个插件,由费鹏老师实验室开发,主要用于小鼠脑片配准和细胞计数。BIRDS改进了脑片与图谱的配准算法,并借助Imaris实现了全脑的三维可视化。 </p><img src="https://img.cwxhmk.top/post/20230703-1.png" alt="BIRDS界面" width="50%" height="50%" /> <p>BIRDS主要包括downsample、coarse、precise、visual和setSeg五个部分,分别用于图像预处理、图片配准、可视化检查和手动校正以及脑区分割预测。</p><p>我关注的主要是前三部分,核心是脑片和图谱的配准,具体流程如下图。</p><p><img src="https://img.cwxhmk.top/post/20230703-2.png" alt="BIRDS脑片配准流程"></p><h1 id="Java-GUI-组件"><a href="#Java-GUI-组件" class="headerlink" title="Java GUI 组件"></a>Java GUI 组件</h1><h2 id="JPanel-面板"><a href="#JPanel-面板" class="headerlink" title="JPanel 面板"></a>JPanel 面板</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">JPanel</span> <span class="variable">northPanel</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">JPanel</span>();</span><br></pre></td></tr></table></figure><h2 id="JLabel-标签"><a href="#JLabel-标签" class="headerlink" title="JLabel 标签"></a>JLabel 标签</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">JLabel</span> <span class="variable">urlLabel</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">JLabel</span>(<span class="string">"url:"</span>);</span><br></pre></td></tr></table></figure><h2 id="JTextField-单行文本框"><a href="#JTextField-单行文本框" class="headerlink" title="JTextField 单行文本框"></a>JTextField 单行文本框</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">JTextField</span> <span class="variable">urlText</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">JTextField</span>(<span class="number">20</span>);</span><br></pre></td></tr></table></figure><h2 id="JOptionPane"><a href="#JOptionPane" class="headerlink" title="JOptionPane"></a>JOptionPane</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">JOptionPane.showMessageDialog(<span class="literal">null</span>,<span class="string">"Pay attention to the cache url!"</span>,<span class="string">"warning"</span>,JOptionPane.WARNING_MESSAGE);</span><br></pre></td></tr></table></figure><h2 id="JTabbedPane"><a href="#JTabbedPane" class="headerlink" title="JTabbedPane"></a>JTabbedPane</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">JTabbedPane centerPanel;</span><br><span class="line"><span class="type">JPanel</span> <span class="variable">mypanel</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">JPanel</span>();</span><br><span class="line"><span class="type">Button</span> <span class="variable">mybutton</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">Button</span>(<span class="string">"import"</span>);</span><br><span class="line">mypanel.add(mybutton);</span><br><span class="line">centerPanel.addTab(<span class="string">"rawImg"</span>, <span class="keyword">new</span> <span class="title class_">ImageIcon</span>(tabImage), mypanel);</span><br><span class="line">centerPanel.setSelectedIndex(<span class="number">0</span>);</span><br></pre></td></tr></table></figure><h2 id="JButton-按钮"><a href="#JButton-按钮" class="headerlink" title="JButton 按钮"></a>JButton 按钮</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">JButton</span> <span class="variable">urlButton</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">JButton</span>(<span class="string">"choose"</span>);</span><br></pre></td></tr></table></figure><h2 id="JTextArea-多行文本框"><a href="#JTextArea-多行文本框" class="headerlink" title="JTextArea 多行文本框"></a>JTextArea 多行文本框</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">JTextArea</span> <span class="variable">logText</span> <span class="operator">=</span> <span class="keyword">new</span> <span class="title class_">JTextArea</span>(<span class="string">"Welcome!"</span>);</span><br></pre></td></tr></table></figure><h2 id="JFrame-窗"><a href="#JFrame-窗" class="headerlink" title="JFrame 窗"></a>JFrame 窗</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">frame = <span class="keyword">new</span> <span class="title class_">JFrame</span>(<span class="string">"BIRDS01"</span>);</span><br><span class="line">frame.add(southJsp, BorderLayout.SOUTH);</span><br><span class="line">frame.add(centerPanel, BorderLayout.CENTER);</span><br><span class="line">frame.add(northPanel, BorderLayout.NORTH);</span><br><span class="line">frame.setSize(<span class="number">500</span>, <span class="number">600</span>);</span><br><span class="line">frame.setVisible(<span class="literal">true</span>);</span><br><span class="line"><span class="comment">//frame.setLocation(600, 300);</span></span><br><span class="line">frame.setLocationRelativeTo(<span class="literal">null</span>);</span><br></pre></td></tr></table></figure><h1 id="组件触发事件"><a href="#组件触发事件" class="headerlink" title="组件触发事件"></a>组件触发事件</h1><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">urlButton.addActionListener(<span class="keyword">new</span> <span class="title class_">ActionListener</span>() {</span><br><span class="line"> <span class="meta">@Override</span></span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">actionPerformed</span><span class="params">(ActionEvent e)</span> {</span><br><span class="line"> System.out.println(<span class="string">"o((>ω< ))o"</span>);</span><br><span class="line"> }</span><br><span class="line">});</span><br><span class="line">centerPanel.addChangeListener(<span class="keyword">new</span> <span class="title class_">ChangeListener</span>(){</span><br><span class="line"> <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">stateChanged</span><span class="params">(ChangeEvent e)</span>{</span><br><span class="line"> System.out.println(<span class="string">"目前选中的是面板"</span> + centerPanel.getSelectedIndex());</span><br><span class="line"> }</span><br><span class="line">})</span><br></pre></td></tr></table></figure><h1 id="获取ImageJ图片"><a href="#获取ImageJ图片" class="headerlink" title="获取ImageJ图片"></a>获取ImageJ图片</h1><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> ij.ImageJ;</span><br><span class="line"><span class="keyword">import</span> ij.IJ;</span><br><span class="line"></span><br><span class="line"><span class="keyword">new</span> <span class="title class_">ImageJ</span>(); <span class="comment">//打开ImageJ</span></span><br><span class="line">brainImg = IJ.getImage(); <span class="comment">//获取导入ImageJ的图片</span></span><br></pre></td></tr></table></figure><h1 id="今日总结"><a href="#今日总结" class="headerlink" title="今日总结"></a>今日总结</h1><p>不知道是不是因为把显示器搬到实验室的原因,今天工作非常有动力,面对BIRDS源码中超级多的包和类,一点都没有害怕,就奔着一个很小的目标去了:我要搞清楚这个插件是怎么获取到我导入ImageJ中的图片的。今天主要就是学习了BirdsPlugin.java这个文件的代码,对应的是BIRDS插件的GUI,组件布局和触发事件等都在这个文件里面。虽然还不太熟悉java中图像处理的一些方法,但今天学会了看API(要是有具体的使用示例就更好了),也是一个进步!</p><p>下一步还是要明确目标:学习脑片与图谱配准的算法!!!BirdsPlugin.java中case2要仔细读一下,我一切换到precise板块,极短的时间内就会弹出配准后的脑片序列,而且也不像提前存好的图片,这个tab触发的逻辑要仔细读一下。不过脑片与图谱配准的核心算法应该是在coarse那部分,明天认真读一下!!!</p><h1 id="参考文章"><a href="#参考文章" class="headerlink" title="参考文章"></a>参考文章</h1><ul><li><a href="https://blog.csdn.net/coolyuan/article/details/107061996">JAVA中图片缩放getscaledinstance使其自适应JFrame</a></li><li><a href="https://docs.oracle.com/javase/8/docs/api/overview-summary.html">Java™ Platform, Standard Edition 8 API Specification</a></li><li><a href="https://docs.oracle.com/javase/tutorial/">The Java™ Tutorials</a></li><li><a href="https://blog.csdn.net/qq_21808961/article/details/80657491">Java GUI编程3—基本容器:JFrame</a></li><li><a href="https://blog.csdn.net/qq_21808961/article/details/80658063">Java GUI编程4—标签组件JLabel</a></li><li><a href="https://blog.csdn.net/qq_21808961/article/details/80667554">Java GUI编程7—其他容器</a></li><li><a href="https://blog.csdn.net/qq_21808961/article/details/80711384">Java GUI编程10—事件处理</a></li><li><a href="https://blog.csdn.net/qq_42103091/article/details/103746492">Java中的高级组件面板——JTabbedPane(选项卡面板)</a></li><li><a href="https://blog.csdn.net/m0_47646824/article/details/120607711">【通俗易懂学JAVA】——public void与public static void的区别</a></li><li><a href="https://blog.csdn.net/zht666/article/details/7869383">Java中@Override的作用</a></li><li><a href="https://www.cnblogs.com/yangzhou5/articles/12088096.html">图片处理——图片处理工具ImageJ(转)</a></li><li><a href="https://www.saoniuhuo.com/article/detail-210424.html">ij.ImagePlus.getProcessor()方法的使用及代码示例</a></li></ul>]]></content>
<categories>
<category> 项目实战 </category>
</categories>
<tags>
<tag> ImageJ </tag>
<tag> Java </tag>
<tag> Eclipse </tag>
</tags>
</entry>
<entry>
<title>做选择</title>
<link href="/2023/07/02/making-choices/"/>
<url>/2023/07/02/making-choices/</url>
<content type="html"><![CDATA[<div class="note warning flat"><p>我不得不承认,除了友情上的一些小挫折,我的大学生活真的是太顺利了,似乎没有太用力就一步一步走到了保研升学这个岔路口。曾经我并没有觉得这样有什么问题,直到我读博一年以后,我愈发觉得做出明智的选择是多么重要,而大学时的我是多么稚嫩和无知。</p></div><h1 id="那些年少无知做出的选择"><a href="#那些年少无知做出的选择" class="headerlink" title="那些年少无知做出的选择"></a>那些年少无知做出的选择</h1><ol><li>关于学习:身边的老师、同学都说成绩很重要,学校的保研政策也只有加权排名这一项,我在大学的工作重心就只放在的课程学习上,准确的说是应试上。缺少了知识体系的构建和课程内容的实践,课程设计和实践项目代码也没有很好的归档,导致毕业以后沉淀的内容很少。</li><li>关于比赛:其实我一直对自己的能力没有太多自信,大家对计算机专业的第一印象就是编程能力强,可我却没参加过程序设计竞赛,除了学校开设的课程以外,我没有花额外的时间提升自己的编程水平。现在在课题组内做一些具体的任务,我可以很明显的感觉到解决问题没有一个完整的思路,写代码也离不开CSDN(呜呜呜),太丢人了!</li><li>关于自学:大学的时候,尤其是大三、大四的时候,我有大把的空余时间,明明知道项目很重要,机器学习和人工智能很火,但却始终没有学起来,网课反复观看前几集。我现在的数据分析大量需要机器学习的算法,导师天天提神经网络,可我脑子里却没有一个成型的概念。</li><li>关于文档:我大学里学习专业课程,每次考完试笔记和学习资料就扔一边了,从来没有试着整理成电子文档保存下来,或者和其他课程建立联系。课程设计完成以后代码就丢一边了,没有系统的保管代码。现在做项目需要用到以前的专业知识,我都差不多要重新学,知识储备干净地像一张白纸。</li><li>关于跨专业:我之前对专业没有什么概念,什么专业好,什么专业天坑,我都没怎么了解过。关于跨专业到神经生物学,我当时只是觉得我不是很喜欢用别人写好的模型做项目,我想有自己的东西,做研究也挺好的,这个专业挺需要计算机的,于是我就跨专业了。但我当时至少应该了解一下这个专业是干什么的,就业前景如何,也可以试着听几节神经生物学相关的课,看看自己是否对这个专业真的感兴趣。这样我也不会来到新的课题组之后不知道自己可以干什么,不知道自己对什么研究方向感兴趣,苦苦摸索。</li><li>关于选导师:保研那段时间,除了上科大是我主动联系的导师以外,我入营的其他学校都是老师主动联系的我。我当时很天真,我认为应该答应第一个联系我的老师,毕竟是这个老师先联系我的,却忽视了选导师最重要的是适合自己。如果时光机让我回到一年前,我会对当时的我说:了解一下这个老师的研究方向、课题组规模和人员配置、工资情况、有无科研助理、出勤要求、课题组氛围、课题组内部对导师的评价,不要不好意思问,不要轻易做决定,在提交系统之前,你有选择导师的主动权。</li><li>关于直博:当时脑院只招直博生,于是我稀里糊涂直博了。我知道直博只需要五年就可以拿到博士学位,但我不知道导师会上来就拿博士生的标准要求一个本科毕业的学生,不知道博士延毕的比例这么高,不知道博士读不完会一无所有。如果可以重来,我希望自己先读一个硕士,既可以从本科慢慢过渡提升自己的能力,也可以探索自己是否有意愿读博。既然走上了这条路,就好好地走下去吧!</li></ol><h1 id="建议"><a href="#建议" class="headerlink" title="建议"></a>建议</h1><ol><li>无论是做计划还是做选择,给自己至少三个选项,从中选最优的那一个</li><li>现在过得难一点是好事,未来或许会轻松一点</li><li>我们的记忆是有限的,学到的知识要及时整理,不要觉得麻烦,这些都是宝贵的财富</li><li>在决定做出改变之前,先进行原型设计,以最小的成本体验要做出的改变(有点类似于创业过程中的MVP)</li><li>不要害怕向别人寻求帮助和建议,事前暴露自己的无知也比掉坑里再呼救要好得多</li><li>时刻保持清醒</li><li>学习要有连续性,不要每个东西都只学个皮毛</li><li>成事之根本:行动起来</li></ol>]]></content>
<categories>
<category> 生活随笔 </category>
</categories>
<tags>
<tag> 思考 </tag>
</tags>
</entry>
<entry>
<title>图像风格迁移</title>
<link href="/2023/06/26/style-transfer/"/>
<url>/2023/06/26/style-transfer/</url>
<content type="html"><![CDATA[<h1 id="数据集准备"><a href="#数据集准备" class="headerlink" title="数据集准备"></a>数据集准备</h1><p>按照该链接下载coco数据集的指定类,作为训练数据集。<a href="https://github.com/KaranJagtiani/YOLO-Coco-Dataset-Custom-Classes-Extractor">YOLO-Coco-Dataset-Custom-Classes-Extractor</a></p><h1 id="开源模型介绍"><a href="#开源模型介绍" class="headerlink" title="开源模型介绍"></a>开源模型介绍</h1><p>风格迁移模型参照该github开源项目。<a href="https://github.com/kleinicke/onnx_small_style">onnx_small_style</a> 。</p><ul><li>images/目录下包含输入图片文件夹、输出图片文件夹及风格图片文件夹</li><li>model/目录下有按特定风格图片及尺寸训练好的模型,可以直接使用</li><li>风格迁移在线demo1:<a href="https://vicalloy.github.io/image-transformer/">风格迁移网站</a></li><li>风格迁移在线demo2:<a href="https://huggingface.co/spaces/akhaliq/AnimeGANv2">风格迁移网站</a></li></ul><p><img src="https://img.cwxhmk.top/post/230626_1.png" alt="项目内容介绍"> </p><h1 id="模型训练及测试"><a href="#模型训练及测试" class="headerlink" title="模型训练及测试"></a>模型训练及测试</h1><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 使用训练好的模型</span></span><br><span class="line">python neural_style/neural_style.py <span class="built_in">eval</span> --content-image images/content-images/birds.jpeg --model model/rain_princess.model --output-image images/output-images/birds_rain.jpg --cuda <span class="number">0</span> <span class="comment"># cpu</span></span><br><span class="line"><span class="comment"># 训练自己的模型</span></span><br><span class="line">python neural_style/neural_style.py train --dataset dataset --style-image images/style-images/girl.jpg --save-model-<span class="built_in">dir</span> model --epochs <span class="number">2</span> --cuda <span class="number">1</span> <span class="comment"># gpu</span></span><br></pre></td></tr></table></figure><h2 id="注意事项"><a href="#注意事项" class="headerlink" title="注意事项"></a>注意事项</h2><ol><li>训练过程中报内存不足时,考虑风格图片的尺寸是否过大,或者减小batchsize</li><li>如果使用自己的笔记本训练数据,最好不要使用完整的coco数据集,可以只选取某些类别的图像数据</li></ol>]]></content>
<categories>
<category> 项目实战 </category>
</categories>
<tags>
<tag> Python </tag>
<tag> 计算机视觉 </tag>
<tag> Pytorch </tag>
</tags>
</entry>
<entry>
<title>爬取网站数据</title>
<link href="/2023/06/26/spider/"/>
<url>/2023/06/26/spider/</url>
<content type="html"><![CDATA[<h1 id="爬虫基本步骤"><a href="#爬虫基本步骤" class="headerlink" title="爬虫基本步骤"></a>爬虫基本步骤</h1><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line">url = <span class="string">'https://www.google.com/'</span> <span class="comment">#以爬取谷歌页面为例</span></span><br><span class="line">headers = {</span><br><span class="line"> <span class="string">'User-Agent'</span>:<span class="string">"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537 36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.58"</span></span><br><span class="line">}</span><br><span class="line">proxies={</span><br><span class="line"> <span class="string">'http'</span>:<span class="string">'http://127.0.0.1:10808'</span> <span class="comment">#依据本地代理端口填写地址</span></span><br><span class="line">}</span><br><span class="line">r = requests.get(url=url, headers=headers, proxies=proxies)</span><br><span class="line"><span class="built_in">print</span>(r.status_code) <span class="comment">#200</span></span><br><span class="line"><span class="built_in">print</span>(r.text)</span><br></pre></td></tr></table></figure><h1 id="经验-●’◡’●"><a href="#经验-●’◡’●" class="headerlink" title="经验(●’◡’●)"></a>经验(●’◡’●)</h1><ol><li>静态页面一般可以直接通过get请求获得网页数据</li><li>需要js动态渲染的页面获取数据会稍微复杂一点,可以先查看返回的xhr或json文件是否有想要的数据(预览),或者ctrl+F搜索关键词</li><li>通过“发起程序”可以查看文件的请求程序发起链</li><li>爬虫的关键是抓包!找到我们感兴趣的数据!</li></ol><h1 id="应用案例1:爬取网站课件"><a href="#应用案例1:爬取网站课件" class="headerlink" title="应用案例1:爬取网站课件"></a>应用案例1:爬取网站课件</h1><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">import</span> json</span><br><span class="line"><span class="keyword">import</span> os</span><br><span class="line"></span><br><span class="line">url = <span class="string">"https://classroom.zju.edu.cn/pptnote/v1/schedule/search-ppt?course_id=49219&sub_id=848702&per_page=100"</span></span><br><span class="line">headers = {</span><br><span class="line"> <span class="string">"User-Agent"</span> : <span class="string">"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.43"</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">page_num = <span class="number">2</span></span><br><span class="line">date = <span class="string">'20230615'</span></span><br><span class="line">save_dir = <span class="string">'D:/Desktop/ppt_img/'</span> + date + <span class="string">'/'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(page_num):</span><br><span class="line"> params = {<span class="string">'page'</span>:i+<span class="number">1</span>}</span><br><span class="line"> r = requests.get(url=url, headers=headers, params=params)</span><br><span class="line"> <span class="comment"># print(r.status_code)</span></span><br><span class="line"> text = r.text</span><br><span class="line"> text_dict = json.loads(text)</span><br><span class="line"> ppt_list = text_dict[<span class="string">'list'</span>]</span><br><span class="line"> <span class="built_in">print</span>(<span class="built_in">len</span>(ppt_list))</span><br><span class="line"> folder = os.path.exists(save_dir + <span class="built_in">str</span>(i))</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> folder:</span><br><span class="line"> os.makedirs(save_dir + <span class="built_in">str</span>(i))</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(ppt_list)):</span><br><span class="line"> content = json.loads(ppt_list[j][<span class="string">'content'</span>])</span><br><span class="line"> img_url = content[<span class="string">'pptimgurl'</span>]</span><br><span class="line"> r = requests.get(img_url,headers=headers)</span><br><span class="line"> save_path = save_dir + <span class="built_in">str</span>(i) + <span class="string">'/'</span> + <span class="built_in">str</span>(i) + <span class="string">'_'</span> + <span class="built_in">str</span>(j) + <span class="string">'.jpg'</span></span><br><span class="line"> <span class="keyword">with</span> <span class="built_in">open</span>(save_path, <span class="string">'wb'</span>) <span class="keyword">as</span> f:<span class="comment">#把图片数据写入本地,wb表示二进制储存</span></span><br><span class="line"> f.write(r.content)</span><br></pre></td></tr></table></figure><h1 id="应用案例2:爬取Allen小鼠脑图谱"><a href="#应用案例2:爬取Allen小鼠脑图谱" class="headerlink" title="应用案例2:爬取Allen小鼠脑图谱"></a>应用案例2:爬取Allen小鼠脑图谱</h1><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">import</span> json</span><br><span class="line"><span class="keyword">import</span> os</span><br><span class="line"></span><br><span class="line">url = <span class="string">"https://atlas.brain-map.org/atlasviewer/atlases/602630314/576985993.json"</span></span><br><span class="line"></span><br><span class="line">headers = {</span><br><span class="line"> <span class="string">"User-Agent"</span> : <span class="string">"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.58"</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">r = requests.get(url=url, headers=headers)</span><br><span class="line"><span class="built_in">dict</span> = json.loads(r.text)</span><br><span class="line">num = <span class="built_in">len</span>(<span class="built_in">dict</span>[<span class="string">'msg'</span>][<span class="number">0</span>][<span class="string">'section_images'</span>])</span><br><span class="line">img_dict = <span class="built_in">dict</span>[<span class="string">'msg'</span>][<span class="number">0</span>][<span class="string">'section_images'</span>]</span><br><span class="line"><span class="comment"># print(img_dict[130]['path'])</span></span><br><span class="line">add_1 = <span class="string">"https://atlas.brain-map.org/cgi-bin/imageservice?path="</span></span><br><span class="line">add_2 = <span class="string">"&mime=1&zoom=3&width=1140&height=800"</span></span><br><span class="line"></span><br><span class="line">save_dir = <span class="string">"D:/Desktop/allen_img/"</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(num):</span><br><span class="line"> path = img_dict[i][<span class="string">'path'</span>]</span><br><span class="line"> img_url = add_1 + path[:-<span class="number">4</span>] + <span class="string">'_rendered.aff'</span> + add_2</span><br><span class="line"> r = requests.get(img_url, headers=headers)</span><br><span class="line"> save_path = save_dir + <span class="built_in">str</span>(i+<span class="number">1</span>) + <span class="string">'.jpg'</span></span><br><span class="line"> <span class="keyword">with</span> <span class="built_in">open</span>(save_path, <span class="string">'wb'</span>) <span class="keyword">as</span> f:</span><br><span class="line"> f.write(r.content)</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> 方法教程 </category>
</categories>
<tags>
<tag> 爬虫 </tag>
</tags>
</entry>
<entry>
<title>Stray Birds</title>
<link href="/2023/03/11/stray-birds/"/>
<url>/2023/03/11/stray-birds/</url>
<content type="html"><![CDATA[<p>我至今还未在生活中遇到过一个见到鸟会和我一样兴奋的人,无论是眼前掠过的阴影,还是耳边传来的鸟啼,我都会忍不住抬头四处找寻源头。很多时候朋友会顺着我的目光,看一眼,“嗯”一声,然后继续之前的话题。其实,我曾经也不怎么关注“天上飞的”,只认得马路上随处可见的麻雀和阴雨天低飞的燕子,其余一律称为鸟。</p><p>除了麻雀和燕子,我认识的第一种鸟是喜鹊。大二阳光长跑,我常去河边的红色跑道,下午的阳光透过树木的枝叶照得跑道颜色更加鲜亮。我总能看见几只黑白相间、胖乎乎的鸟,在地上蹦跳着找食物。后来是好朋友根据我描述的特征,告诉我:全身黑的地方很黑,白的地方很白,个头中等的鸟就是喜鹊。从那以后,我就记住了,然后我惊奇地发现,校园里竟然有那么多喜鹊。</p><p>大学时,我在不懂得如何独处也不愿独处时不得不孤身一人。那时我最喜欢的事情就是在校园里闲逛,生活中偶然遇到的鸟带给我很多快乐。在西操场门口看到金翅雀展开的金黄色的翅膀,在大草坪前看到白鹡鸰在小水洼里梳理羽毛,走出宿舍惊奇地看到落在山楂树上的红嘴蓝鹊,和妈妈视频的时候意外发现脖子上一圈花纹的珠颈斑鸠,去北餐厅吃饭的路上看到立在树干上的啄木鸟,连着好多天去同一个地方终于拍到了鹊鸲···每次凭借着记忆里的特征百度搜索到看到的鸟时,我都觉得很有成就感。</p><p>爱看鸟的这个习惯被我带到了新的学校,很幸运每天去坐校车会有一段步行的路程,我有足够的时间和距离去感受清晨。我看到两只身体纤长的小鸟衔着树枝筑巢,一前一后,分工明确;我看到一只圆鼓鼓、白肚皮的小鸟没站稳,用嘴咬住一根细树枝荡到了下面的树杈上(我想那一刻小鸟是不是忘记了自己会飞);我看到飞到半路的鸟突然在空中“刹车”、掉头回到原来停驻的树上···有时看着看着会笑出声来,发觉生命是多么奇妙啊!</p><p>大学毕业那天,我没有像平日里那么有仪式感,没有发什么感慨的小长文,而是直接坐上了去西安的高铁。在去车站的出租车上,我一直在哭,但我是快乐的。我想:终于解脱了。不会有恶语相加,不会有孤立无援,不会在路上边走边哭,不会再害怕睡觉时被人晃醒,都不会了。我可以去奔赴新的生活了。但我舍不得那些见过我伤疤、仍选择陪我一起对抗苦难的好朋友,舍不得那些一直肯定和鼓励我的老师,舍不得一起同窗四年的同学···</p><p>我常常想,除了学习之外,大学教会了我什么呢?杨绛先生曾说,世态人情,可作书读,可当戏看。也许我看了一场大戏,我是看客,却也是戏中人。我学会独处,一个人消遣时光也是一大幸事;我学会感恩,感激在我人生中某个阶段出现且对我施以最大善意的过客;我变得平和与知足,和过去相比,现在的自由生活仿佛是天堂。</p><p>我曾经的QQ昵称借用泰戈尔的《飞鸟集》(Stray Birds),但我想自己更愿意把stray birds翻译为离群的鸟,在人际关系上我不太主动,有时有些迟钝,但我愿意相信好的友情磁场一定是互相吸引的。会不会即使离群,仍有人作陪?</p><p>我相信一切能够听见<br>甚至预见离散,遇见另一个自己<br>而有些瞬间无法把握<br>任凭东走西顾,逝去的必然不返<br>请看我头置簪花,一路走来一路盛开<br> ——《生如夏花》</p>]]></content>
<categories>
<category> 生活随笔 </category>
</categories>
</entry>
<entry>
<title>Matlab常用命令</title>
<link href="/2023/01/10/matlab-skills/"/>
<url>/2023/01/10/matlab-skills/</url>
<content type="html"><![CDATA[<ol><li>矩阵拼接<figure class="highlight matlab"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cat</span>(<span class="number">2</span>,A,B) <span class="comment">% 相当于[A,B]</span></span><br><span class="line"><span class="built_in">cat</span>(<span class="number">1</span>,A,B) <span class="comment">% 相当于[A;B]</span></span><br></pre></td></tr></table></figure></li><li>去除重复元素<figure class="highlight matlab"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">unique(A,<span class="string">'sorted'</span>) <span class="comment">% 去除重复元素,且升序排列('sorted'一般省略)</span></span><br><span class="line">unique(A,<span class="string">'stable'</span>) <span class="comment">% 去除重复元素,不排序</span></span><br><span class="line">unique(A,<span class="string">'rows'</span>); <span class="comment">% 去除重复的行</span></span><br></pre></td></tr></table></figure></li><li>查找元素下标<figure class="highlight matlab"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">find</span>(X):返回一个包含元素索引的向量</span><br><span class="line"><span class="built_in">find</span>(X,n):返回 X 中元素的前n个索引</span><br><span class="line"><span class="built_in">find</span>(X,n,Direction):根据Direction在X中找到n个索引,其中Direction-<span class="string">'first'</span>或<span class="string">'last'</span></span><br><span class="line">[row,col] = <span class="built_in">find</span>():返回数组中元素的行列下标</span><br><span class="line">[row,col,V] = <span class="built_in">find</span>():返回包含非零元素的向量V</span><br></pre></td></tr></table></figure></li><li>查看矩阵中是否有某个元素<figure class="highlight matlab"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">ismember</span>(<span class="number">1</span>,A) <span class="comment">% 若包含则返回值为1,否则为0</span></span><br></pre></td></tr></table></figure></li><li>打开matlab出现警告“名称不存在或不是目录”<figure class="highlight matlab"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">edit pathdef <span class="comment">% 把对应的路径删掉即可</span></span><br></pre></td></tr></table></figure></li><li>保存变量<figure class="highlight matlab"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">save(<span class="string">'abc.mat'</span>,<span class="string">'m'</span>,<span class="string">'n'</span>) <span class="comment">% 将变量m和 保存到abc.mat文件</span></span><br></pre></td></tr></table></figure></li></ol>]]></content>
<categories>
<category> 方法教程 </category>
</categories>
<tags>
<tag> Matlab </tag>
</tags>
</entry>
<entry>
<title>愉快的周末</title>
<link href="/2023/01/08/a-happy-weekend/"/>
<url>/2023/01/08/a-happy-weekend/</url>