我使用三星设备偏多,从S9系列入坑,S9+,S10 5G,Tab S7+,到S22U,耳机手表还用过buds+,buds pro,watch active2和watch classic4,最近还给女票淘了个美丽小废物flip3做热点备用机。实际自折叠屏发售以来我就觊觎已久,特别是fold系列的大折叠,但奈何感觉技术不成熟,加上价格也偏贵,一直没有入手。Fold5作为三星最新屏幕终于能够完整合上的新一代折叠,戳中了我的心窝。由于自己有root的需求,fold系列唯有欧版可以轻易的解锁且能使用相机,在海鲜市场蹲候多时终于入手。天蓝色12+256,屏幕完美,边框有一点点掉漆,不过6300,还要什么自行车,带个凯夫拉壳美滋滋。
三星折叠最与其他品牌折叠不同的点就在于它独特的屏幕比例,折叠情况下23:9的比例,导致它握起来更像是一个遥控器。自带默认的OneUI主屏幕固然可以,在展开内屏的情况下,合理显示布局,加上自带的下面一条任务栏,使用起来非常舒适。但是合起使用外屏时,拥挤的状态不够优雅。Niagara Launcher作为一个第三方启动器,其简洁的滑动字母布局和通知直接呈现提醒非常适合三星狭长的外屏。于是需求产生了,是否可以在外屏使用Niagara主屏幕,而打开内屏后自动切换为有任务栏的OneUI主屏幕呢?
答案显然是可以的,Android是可以选取拿个应用作为默认启动器的。在查阅和综合了相关资料后,结合实际使用情况,这个问题的解决方案可以进一步细化为以下三个部分:
理论上,只要手机厂商允许修改默认启动器,那么在其他牌子折叠屏上也同样可以实现。
大多情况下,手机是没有root的,这里需要借助Tasker和它的一个插件 AutoTools。Tasker是一个自动化工具,有点类似苹果的快捷指令和三星的日常程序,不过它能够做到的东西更加广泛一些。软件可以试用,tasker建议直接入手,autotools看广告免费用。
tasker使用adb命令去激活read logs的功能,连接adb后,输入以下命令:
adb shell pm grant net.dinglisch.android.taskerm android.permission.READ_LOGS
adb shell am force-stop net.dinglisch.android.taskerm
之后就需要使用tasker创建对应任务和触发条件,这里引用两个其他帖子的方法(本质一样),自行配置,不重复造轮子了。
[Tasker] Auto-switch Launcher for folded/unfolded screen
How to Set Different Launcher for Folded/Unfolded Screen
如果觉得配置起来有点迷糊,这里也有reddit网友给出的tasker一键导入,一共三配置,分别对应思路拆解的三个部分:
这里分别解释一下三个配置文件
在自定义设置情况下,执行Folded这个任务。自定义设置为判断条件,edge_panel_width值为401即折叠情况下。Folded任务有以下步骤:
在特定app打开的情况下,执行Hold Refresh这个任务;在app关闭后,执行Pause Refresh这个任务。特定app可以根据自己需要选中即可。
其中,Hold Refresh任务定义了一个变量,名称为PauseRefresh,并设定为1。Pause Refresh任务将PauseRefresh这个变量值进行清楚。
因此这个配置文件的逻辑为:在特定选中的app打开时,变量PauseRefresh被设置为1,在app关闭退出时,变量PauseRefresh变为未设置状态。这个主要是为了配合下面一个配置文件做判断。
在自定义设置情况下,执行Unfolded这个任务。自定义设置为判断条件,edge_panel_width值为362即展开情况下。UnFolded任务有以下步骤:
在导入完三个配置文件后,一定要将默认启动器设置为AutoTools,不然无效。
因为本质上还是借助AutoTools作为一个中间应用,去启动两个不同的桌面,AutoTools才是默认的桌面,因此有点小瑕疵:比如桌面长按应用无法使用shortcuts;手机重启后展开大屏无法显示状态栏,需要手动把默认桌面先切换回OneUI主屏幕,保证状态栏显示,再修改为AutoTools。不过这些瑕疵无伤大雅,因为99%的时间你不会去调整桌面,也不会经常去重启手机。所以体验还算舒服。
不过既然我都已经root,当然要展现root的优势。主要改进就一点,使用tasker直接调用shell命令,在root的环境下切换默认桌面。这样就可以和AutoTools说拜拜了。
至于切换的命令,探索后发现是这个:
adb shell cmd package set-home-activity com.example.launcher/com.example.launcher.MainActivity
com.example.launcher为启动器的包名,
在tasker中选择将选择Autotools的命令改为运行shell命令,输入语句,例如展开时OneUI启动器:
cmd package set-home-activity com.sec.android.app.launcher/com.sec.android.app.launcher.MainActivity
折叠时Niagara 启动器
cmd package set-home-activity bitpit.launcher/bitpit.launcher.MainActivity
其他更改不变,这样就可以直接切换到默认的启动器,而且小瑕疵问题也解决了。
我图中还借助rotation这个应用,实现折叠小屏强制竖屏,展开大屏强制旋转。另外我发现,用大屏情况下,转到后置摄像头自拍,且用小屏控制时会回到桌面,所以我还设置了一个变量Camera Set,检测如何变为小屏时相机打开了,那么还是再开启相机,实现一个无缝后置摄像头自拍的情况。这种设置很灵活,配合自己的需求修改就好。
Fold5到手已经用了快10天了,我用起来还算满意。可能是这种屏幕比例,我更倾向于展开使用屏幕,真的就像在用一个小平板一样,阅读文字和漫画的体验非常舒服。自己也不是追求那么极致的拍照体验,所以从S22U换下来感觉也还好。而且折叠屏最重要的一点,我拍照的时候可以打开后置预览,这样拍人物的时候对方可以在外屏看到呈现效果,调整姿势表情。这简直感动哭了好吧,拍女朋友时候难度直接降低一个等级,增进情侣和睦的好机器呀。
而且8gen2真的出色,尽管Fold5只有4400毫安的电池,当感觉比我8gen1的S22U续航还要好,外出续航焦虑至少是没有了。虽然25w充电,但三星45和25w在充满时间上没太大区别,也感知不强了。
目前时这些,后续如果再有啥体验再补充吧。
自己由于是root玩家,淘一个可以轻易root且不锁相机的欧版也算是花了大功夫。最后我只建议三星你不要不识好歹,把你那针对除了欧版其他版本解锁后相机不能用的规矩给我取消了,让人能好好的玩玩机喽!
]]>2024年2月25日,我受邀去参加了高中同学的婚礼。作为这么多年还联络的朋友,外加正好是自己的生日,去参加婚礼时的心情十分开心。虽然说同学邀请了我和我的女朋友,但奈何她正好在项目上出差,只能我一个人带着她的心意去赴宴。
回想起来,这还是我第一次以自己的名义去参加朋友的婚礼,虽然小的时候和老妈一起去参加过婚礼,但那都是以一种儿童的视角。以前印象中参加的婚宴都是晚上进行,而现在很多人都是中午进行婚礼,不知道这是风俗习惯的不同还是时代演化的差异。
宴会厅在合肥滨湖的富茂大酒店,酒店比较红火,今天这个日子有九对新人喜结连理,据说要预定场所都得提前一年预约。酒店门前大大的粉色系花墙,喜庆中透露出温馨。同学的场子在二楼,穿过长长的电梯,婚照便呈现在眼前。比较遗憾的是,我没有与新郎新娘合照,可能是去的时候正好卡点了,和新郎说几句话后他正好要去下面拍,导致没能拍几张俊男靓女合照。
一同参与婚礼的还有几位高中的同学,当然都是经常聚聚的朋友。有时候难免会感叹,这么多年还能保持联络,真的是很难得。人与人之间的关系就是在一点点失去联络之中逐渐疏远的。回想起之前还有几个经常一起上下学的同学,当时觉得关系挺不错的,但是长久没有保持联络,毕业后也就渐渐淡出生活了。
桌台前有高高的花束,摆的比人都高很多。男方女方加起来大概有20多桌。同学们坐一桌,两个同学是新郎的伴郎,穿起礼服来还真是那么回事,俊得很。大家婚礼上又再起相聚,当然还是很开心的,没心没肺的拌拌嘴,唠唠嗑,调调侃,日子仿佛回到了以前。
婚礼上有个小乐队,说是小乐队,主要是就只有主唱,吉他手和一个键盘手。等待的过程中,他们演唱了「你是如此的相信」,「温柔」等歌,还挺好听的。
在12:18的时候,结婚仪式正式开始了,在司仪烘托完气氛后,终于等到新郎和新娘的入场。在庄重的婚礼进行曲中,在众人的欢笑注视中,在漫天气球爆开的包围中,新郎牵着新娘,缓缓地向舞台中间走去。虽然新郎之前给我们吐槽很紧张,但是我发现了,正式流程他也确实是肉眼可见的紧张。在相互宣读完誓词,父母代表发言后,大致的婚礼流程也就结束了。这里实际新郎新娘没有说太多的话,如果要在上面说很多很多的话,那真的是有点心理压力哩。
在祝福完最美好的场景后,饭局开始。安徽人这边似乎对古井贡酒情有独钟,桌子上的白酒是古16,我和一个同学打开来喝了喝,应该是清香型的,喝起来不是那么上头,不容易发昏,虽然我下午回家还是去躺着睡得挺舒服就是。宴会的菜基本上有的都有,螃蟹,虾,甲鱼,石斑鱼,红烧肉等等一大桌子。大家吃吃喝喝相互敬酒和饮料,扯扯淡中时间就过去了。在新郎新娘敬完了所有桌子后,婚礼也基本上到了尾声,拿完喜糖,我们又聊了聊相互祝福后基本上就离场了。
这次去参加婚礼,不仅仅是去给他们送去祝福,也有一部分是想看看未来的自己。自己终将也会经历人生的这么一个过程,结婚是一件重要的事,也是个麻烦事。这些东西的选购,场地预定,相互沟通等等都要花费大量的精力。不过参加朋友的婚礼,也能给我带来一些经验的积累。小时候的我看的更多是热闹,吃的更多是喜糖,现在的我看着红毯上的他们,也会带入自己和女朋友的情境,吃着生活这道酸甜苦辣并存的菜,憧憬着美好的未来。
]]>2023年已然过去,惯例还是需要总结一下一年的过程。
总体来说今年的状态不算满意,因为生活的主轴并没有步入正轨,从而进入一种混沌的浑浑噩噩状态。我将通过去年的Flag一一对应今年的收获。
这是最大的硬伤,自从一月份离职回家后,由于各种原因一直也没有再全职工作。这就产生一种巨大的落差,没有一种稳定收入与投入的事情。虽然自己兼职也接了一些项目,也有一部分的收入,但是那终究不能作为全部。职业技能方面,虽然一直没有拉下,没有太大的退步,但是看待事物难免会眼界落于局限之中,最新最潮的事物肯定弄不明白,也没有那个自制力去弄。
目前并没有房子和车子之类负债资产。但是由于没有稳定的收入,投资方面也暂时停下了脚步。从目前自己的投资看来,经过这几年的实验,确实发现市场是一个起起落落的过程。今年的行情尤其不好,投资一片绿油油,不过这个本身就是个过程,顺其自然不断改变吧。投资的理念学习不足,还是需要多读书。
财务的记录方面记账基本坚持了下来,通过小星记账完美的记录了自己的每一笔支出,能明确的看到自己每一步前都花在了哪里。过程是有所收获的,记账是一个长期的过程,未来有了更多的资产,开源节流,才能不断积攒财富。虽然住在家里,但是花费还是不少。设备上主要是增加了一台台式机,用于跑跑代码。其他零零散散软件支出也不少,不过由于有明确的账单,明年重新调整预算还是有所依据的。
这一年自己的记录方面基本确定了下来。个人笔记以Obsidian本地为主,Notion表格线上为辅。滴答清单作为轻量级的记录主力使用。之前总是在不同的应用间换来换去,现在越来越趋于简单化。基本形成了一套记录体系,软件如果不出意外的话不会太换了。
输出方面,长篇文章用博客记录,短篇想法用memos表达,除了软件更新,基本上也不想再折腾了。但是落实到今年具体的细节,输出的内容还是太少了,尽管很多时候有很多想法,但是都没有及时的记录进行反思。博客只更新了8篇,一月一篇都没有做到,memos也分享了才大概40个。基本处于想到这东西才去做。这个流程和心理的负担还是需要减少,逼着自己进行输出。因为这些对于自己也是一种回首与反思。
这一部分基本没有完成,大部分的精力被奶头乐所消耗,没有充足的动力让我去执行。但是我渐渐也发现自己似乎可以并不用把全部的注意力集中在一件事上也可以大致的完成内容,或许需要从某些细节上验证这个问题。不过注意力分散和好奇心有点消退确实是个问题,需要好好调整。
不过今年还是读了几本书的,也算有点收获。游戏方面,单机游戏玩了王国之类,艾尔登法环,杀戮尖塔等等,联机游戏中,游戏王大师决斗,皇室战争等,都带我领略了电子游戏的魅力。
睡觉作息方面,尽管在家里,但是整体的作息还是比较规律的。日常起床,吃饭,基本可以保证正常的日常生活与学习。
身体健康方面,中途有四个月根据b站的课程进行健身,肌肉量有所增长,不过最近天冷了又有所懈怠。但是最近发现明显腰痛,这说明最近明显缺少锻炼,锻炼还是要融入生活中,成为习惯才能坚持下去呀。
心理精神方面,由于直接的压力较小,还是比较愉悦的,而且现在遇到问题好像不会特别着急,仿佛知道急也没有用,如何解决才是硬道理,似乎心智有一些提升。
在这个方面,由于时间比较充足,和女朋友约会了35次,和朋友相聚了14次,和家人聚餐了19次,外地出行了5次。这点我还是比较满意的,能够有较多的时间陪陪家人,陪陪朋友,看看世界还是很不错的。
自己也快27岁了,这几年也算是非常重要的黄金时间,今年的日子不算好,有很重要的事情没有推进。时间不等人,自己不能懈怠。我每周都会根据清单做一个简单的复盘,所以明白今年在一日一点点过后后的无奈与焦虑。明年真的需要更加努力了。希望明年回顾后能看到更优秀的自己。
]]>女朋友说,迪士尼是世界上最快乐的地方。尽管她已经去过两次上海迪士尼了,但是我们两个一起去倒是未体验过。正好上迪的疯狂动物城园区也正式开幕了,安排好一切事项后,28号开启一趟轰轰烈烈的迪士尼之旅。
用女朋友的话讲,这是她最晚的一次进园。选定的酒店离园区不远,尽管我们6点就已经起床,在洗漱,化妆,吃早饭完毕后不知不觉已经7点半了。打车到迪士尼的地铁口,拿到网上租借的达菲发箍,差不多已经8点多了。虽然八点半才正式开园,但是从此刻开始,一天的奔跑计划就已然拉开序幕!
远远望去,人山人海,为了能够更快一点入园,我被拽着穿过一波又一波的人流。真正排队入园后,大概8点50,外加满头大汗。迪士尼的官方app可以看到地图和各个项目的大致排队入园时间,我们没有犹豫选择最新开的疯狂动物城作为初始目标。经过整整4个大棚的排队后,终于在10点多一点进入了动物城的园区内。整个动物城还原了很多动画中的元素,豹警官,牛局长,充满俏皮可爱。动物城警局,动物城监狱,场景惟妙惟肖。项目「热力追踪」不算刺激,但是绝对精彩,大屏幕的震撼仿佛身临其境,在动画世界中。城中还有很多奇妙的小景点,比如小动物红绿灯,巨大座椅,迷你乐器店等等,还是非常有趣的。
拍拍照出来疯狂动物城园区大概快12点了,正好到了花车巡游的时候,伴随着振奋人心的乐曲,浩浩荡荡的队伍缓缓走来。疯狂动物城,玩具总动员,小飞象,美女与野兽,海底总动员,冰雪奇缘等各路IP都出来亮相,还有他们招牌的各种动画角色,唐老鸭,小熊维尼,玲娜贝儿,达菲等等。这些人物和场景浩浩荡荡的从你眼前经过时,会让你瞬间进入他们营造的世界中,不经意的嘴角上扬。
出来后由于没赶上预约米奇妙游童话书内容,先去排队玩了加勒比海盗,不过内容与剧情不能说是一模一样,只能说是毫不相关。结束差不多快2点了,终于去迪士尼小镇炫完了中午饭。15点左右终于看上了预约的米奇妙游童话书,这个类似于舞台剧,整体场景还是十分迷幻的,虚实结合,配合表演者的演唱和舞蹈共同呈现。一开始我还以为是对嘴型,结果原来真的是在唱,Let it go响起时鸡皮疙瘩起立。整体大概30min,质量上乘。
后续又七零八落的把各个项目都排队玩了一遍。排队的过程是痛苦与漫长的,平均大概排队一个小时,爽一小会儿,创极速光轮,抱抱龙冲天赛车,七个小矮人矿山车。当然还玩了一些休闲小场景,旋转木马,旋转疯蜜罐等等。过程中感觉自己的腿已经不是自己的了,走路不可怕,怕的是站着老半天不动。
在排排等等玩玩后,时间来到了21点,这时最大也是最值得的内容开始了:灯光烟火秀。激昂的歌曲加上变换的场景,灯光投射出斑斓的效果,喷泉交相辉映,甚至在空中映射出虚幻的场景。在不同的IP变换后,巨大的烟火腾空而起,在城堡上方绽放开来,场景震撼且令人着迷。之前我一直以为烟火是重点,看过不少的视频,也看过几次户外烟火表演,然而真正体验过才发现,迪士尼将灯光与烟火结合,加上音乐与喷泉,配合着自己的主题内容一切显得浑然得体。百闻不如一见的明确诠释了。
烟火结束后,这场旅途也接近了尾声,我们去商店逛逛买了达菲后,22点左右离开了园区。一天下来,筋疲力尽,浑身大汗,腰酸脚痛,最后到酒店后有根筋都差点抽了。虽然很累,但是一整天下来也玩到了很多的项目很充实。女朋友说这是世界上最快乐的地方,确实,来到这里你可以抛弃一切的烦恼去享受。我最喜欢的还是花车巡游与灯光烟火,其他自家IP的项目也令人充满喜悦,相较于一些令人肾上腺素飙升的刺激项目,这些在其他地方都无法体会到的独一无二梦幻时刻。另外,与重要的人共同享受这份快乐,创造美好回忆,这也是这趟旅程更重要的事吧。
]]>自己很喜欢看漫画,从小学到现在,国漫,日漫,韩漫都有所涉及。但是由于媒介问题,也渐渐从购买实体书籍转换到直接线上观看。有付费,也有白嫖,这里整理一下自己看电子漫画用到的一些软件与资源,以作存档和抛砖引玉。
电子漫画阅读通常有两种媒介,线上观看和本地下载观看。由于漫画都是以章节为单位更新的,所以自己大部分时候都是线上直接追更新。如果遇到那种出了单行本并且自己非常喜欢的漫画,或者一些没有线上资源的小众漫画,才会去寻找资源下载到本地,观看和收藏用。
线上漫画服务我通常使用webtoon和 tachiyomi,并用漫画人作为辅助。
webtoon主要用来看一些韩漫和台湾的漫画。作为官方正版软件,既可以白嫖慢慢追漫画,也可以花钱抢先看。webtoon这个平台的漫画基本是为了迎合手机,所有的漫画都可以一划到底,不会产生较大的割裂,同时彩色漫画也显得更加现代,很多漫画质量都巨高。
tachiyomi作为一个android漫画终端阅读软件,可以通过插件的形式阅读各种网站源的漫画,像是一个聚合器,动漫之家,漫画人,爱米推甚至哔咔这种r18平台都有相关插件。软件本身涉及也符合android规范,没有任何广告。由于是开源软件,也有着其他修改版本,比如tachiyomij2k ,其增加了一些功能比如横屏下的双页布局。我主要用来白嫖阅读日漫和一些国漫,体验较好。
漫画人是自己从初中一直使用的应用,看日漫,主要是用出习惯了,主打一个方便。
腾讯动漫用于看一些国产和日漫,氪点金图方便。
有时候我也会用一下集英社旗下的在线漫画网站MANGA Plus by SHUEISHA看一些生肉,不过看起来还是有点费劲,更多是用它发现漫画。
漫画的格式通常是包含jpg的压缩包,或者是cbz这种带有一些信息的压缩格式,再有一些会制作成epub这种电子书格式的文件。我更多的时候是喜欢将那种线上图源不是很高清的精美漫画(例如烙印勇士)或者非常有意思的短篇(例如蓦然回首)下载下来,没事本地品味一下。喜欢的作品直接网上搜索就可以找到,这里推荐一下Kox.moe,可以用于下载epub格式的漫画。质量和数量都有保障。
个人经常在android平板和手机,外加windows电脑上进行本地漫画阅读。
在android设备上,我通常使用librera 阅读epub格式的漫画,主要是他可以实现平板上横屏双页外加从右向左的翻页模式阅读,这一点我暂时没有找到替代品。另外我也使用Kuro reader来阅读cbz等专用漫画格式的漫画,主要是ui实在好看,颜值党狂喜。
在windows上,我推荐使用YACReader,既可以进行漫画管理,也可以支持多格式完美的漫画阅读。
当然有时候资源是纯粹的图源,为了较好的进行管理我通常会进行格式转换,这里推荐kcc这个项目,可以将包含漫画的文件夹转化为cbz,epub等格式。省时省力。
每个人的漫画口味不一样,但是大众喜欢的作品通常也不会太差,虽然可能剧情老套,但是很多热门的漫画还是值得一看的。除了在各大漫画app中直接看人气推荐的作品,我还会在kox.moe上用评价从高到低去筛选一些作品,也能发现很多人气虽然不高但精良的佳作。或者在cmoa这类卖书的网站上看看人气作品。
有时候会沉迷于特定类型的漫画,比如我很长一段时候忠实于「智斗」这个标签,为了找到相关类型的漫画,实际最有效的方法是找网上的讨论。贴吧讨论或者知乎回答都是不错的参考,把大家的推荐记录下来,一个个去翻就好了,很多时候都能找到自己想要的。
通常你在日常生活中能看到有人讨论漫画,那漫画大概率已经是现象级的作品了。但是如何知道比较小众且高热度的新连载作品呢?这个问题基本就是一个信息的差异。看的多了,就知道哪里会讨论多,会更有趣。
第一种方法是通过平台的投喂。像webtoon经常会推新的漫画,直接看看前两章,感兴趣就直接订阅,很舒服的流程体验。除此之外还可以看看manga plus上的新作,不过他们通常是英语生肉,遇到有趣的作品想看汉化版的还是需要有段时间的,建议精进自己的英语水平。
第二种是推荐。这里可以参考漫画评选网站,例如这本漫画真厉害, 每年评选一次,上榜的都看看还是很有趣的,不过这个评选是日漫。还有就是一些youtuber主,例如孫沁岳, 嘎不拉嘎, 井川一等等,他们会帮我们收集一些漫画资讯,看看他们的视频也会有所收获。
想想看自己已经看漫画有快20年了。小学时的漫画大王,漫画party,初中的动漫水晶,各种日漫单行本,高中知音漫客,加上网络看日漫,大学后转向纯线上,webtoon,腾讯动漫等等。从实体到线上,从国产到国际,阅读漫画已经变成了我的兴趣。晚上睡前基本有空闲时间就打开漫画软件,看看有啥更新了,看个10min,收获的都是快乐。
漫画中能看到各种题材,各种剧情,各种点子。还有漫画家的画风,分镜,叙述逻辑都各不相同。看过史诗级的佳作,也看过烂的不行的大便作。但是各有各的乐趣。作为一种文字与图像结合的艺术创作,漫画真的能够承载很多的东西。它可以展现出文字也描绘不出的场景,又能回避了影像的一些表现阉割。不得不说漫画也养大了我的胃口,以至于看很多热播影视剧时,都会产生这种老套也能吹的想法。漫画着实有趣,我也会一直保留这个兴趣,然后也会多多支持正版为我长久的白嫖买买单。最后也希望我们国家的漫画产业也能像日本韩国那样更加蓬勃的发展。
]]>记笔记这件事,从小到大一直都在做。小学时候,老师家长就教育,好记性不如烂笔头。实际核心是说瞬时记忆想要转化为长久记忆需要不断的反复。学习东西,当时好像明白记住,但是可能明天再看已然不记得细节。通过一些媒介记录下来,时常看看,才能够内化这些知识,更好是做到「温故而知新」。笔记更多的时候是作为一个外脑存在,并辅助将一些内容烙印在真实的大脑中。
在不同的阶段,记笔记的目标和策略也有所不同。高考前的学生时期更多是为了应试考试,把密密麻麻的知识点,老师的精解在纸质的本子上抄下来,用作复习与反思。这个阶段记笔记很纯粹,记录完的一沓沓笔记会感到很满足。
步入大学往后阶段,考试这种东西在生命中占比有所减少。而且这段时间我们也不仅仅是需要记下来一些知识性的问题,生活中的记录,必要性的文章等一些其他的东西同样需要记录。时间多了,看的东西多了,觉得自己之前的眼界太短浅,涉猎东西又都想记下来,于是基于网络化的电子笔记似乎逐渐替代纸质笔记。这个时候的行为会从单纯的「记笔记」转化为一个更为高级的术语:「知识管理」。
我觉得电子化笔记优于纸质笔记的核心一点就是易于整理与搜寻。电子媒介借助特定的格式(如markdown),或是独有的结构(单位块),可以轻松的将大部分的内容进行调整和编辑。依托于搜索功能,也能够将之前记录的内容迅速查找调用,极大的提高使用效率。
在我个人探索的过程中,接触到了很多关于如何记好笔记的术和方便记笔记的器。术的方面多种多样,每种都有自己的特色与精进。从用于整理文件夹的图书馆分类法,到打标签多维度检索,再到突出双链以块为单位的卡片盒笔记法。新的方法一直在涌现,这其中有的是互补,有的是方法的精炼。
然而在器方面,才是更加的百花齐放。小到各厂家自带的备忘录,到专业的如印象笔记,为知笔记,Notion,Roam Research,Obsidian等等。我有很长一段时间在不同的软件之间来回折腾,似乎研究用什么做笔记比做笔记本身更有意思,工具越用越多,内容记了屁点。颇有大部分独立博客的文章都是只有「如何搭建一个独立博客」的意味。
要问如何记电子笔记,选择一个合适的应用很重要的。数据如何保存,格式是否友好,更新频率如何,开发团队情况,这些都需要考虑在内。
我最开始使用印象笔记,一开始还是很优秀的。它能存放任何的东西,图片,视频,音频,文件等等,加上强大的剪藏功能,真的是个完美的笔记软件。甚至开始还有那种得到的课程直接通过印象笔记进行分享的黑产,用起来很舒服。但是后面慢慢加了很多冗余的东西,随之而来的是越来越多的vip,svip,ssvip。在看有优惠一口气续了三年的会员,它还推出10年会员后,我终于怕了。害怕它倒闭我所有东西都付之一炬,我决定快跑,同时也看到一个新的应用向我招手,那就是Notion。
Notion作为一个可以All in one的应用,在最开始推出的时候就展现出了极大的潜力,所有文章都可以以块为最小单位随意任意链接,其强大的表格功能,过滤功能,再加上用户们分享的各种模板,用起来真的觉得是有无限的可能性。我个人尤其喜欢它的表格统计功能,做各种汇总的时候真的很方便。要说缺点,就是功能有点太多比较复杂,同时需要依赖科学的网络环境。
除此之外我还有使用Obsidian,目前逐渐将一些重要的笔记使用这个软件进行记录。经历了印象笔记那种体验,笔记能掌控在自己手里并进行分享是我一个很看重的点。作为一个本地应用,能够把数据存放在本地,可以使用自己搭建的云服务进行同步。软件社区维护积极,借助插件,应用可以使用的很简单,也可以很折腾,适合各种需求的人。要说麻烦的地方,就是由于基本格式是markdown,图片之类的保存不会像其他软件那么集成,不过借助图床插件也还算方便。
上周想起我很久之前买的印象笔记会员要到期了,于是打算把里面有用的笔记迁移一下。这一整理,发现有用的东西寥寥无几,这也让我重新思考了一遍什么东西才是值得记录的。从前的自己沉迷稍后读,配合印象笔记的剪藏功能,有些有价值的文章就直接整篇剪贴进来,但是读倒是没读多少。再以现在的眼光看那些文章,它们中很多已经没有太大价值了。笔记这种东西,不仅需要有摘录,更要有自己的思考。剪藏这个过程有时候很必要,但不一定要在笔记中呈现。就我而言,真正需要记录的东西如下:
这种类型的最终目的是内化。这也是最原始的形式,类似于从小到大纸质的笔记。但是这并不是大段的复制,那样没有价值的。需要有自己的归纳总结,可以记的很简单,写好引用,以便查阅的时候可以溯源。
这种类型的最终目的是输出。人是有表达欲的,写博客的目的也是如此,碎片化的想法可能很短,但也很珍贵,全部作为笔记收集起来也是一笔财富。在一个合适的时间段总结整理一下,发个大文章也好,全部发到吐槽里也罢,都是一种不错的选择。
这种主要就是为了记录,信息统计,或者经验记录,还有总结思考之类的。比如每周周报,一些表格信息,这些也都可以放在其中用作查用。
至于工具上,我觉得也不用都归一于同一应用,写自己笔记我用Obsidian,它比较好管理;碎片化想法可能用滴答清单顺便就记了,到时候再整理;统计使用Notion的表格更方便,每种软件取其长处用就好了。
总体感觉自己对于记笔记这事是一个螺旋上升的过程,一个时间段感觉自己悟了,但后面又觉得之前做的不对,但貌似在否定之否定中还是处于进步的过程中。术有很多,但每个人适合的都不一样,这个过程与平衡只能慢慢探索了。
]]>提起听演唱会,上次一次的记忆还是大学时代五月天的现场版,大体育馆内的千人合唱,想起来很是享受。然而会与近些年兴起的live house形式的演出自己一直没有参加过,正好八三夭来合肥,女朋友又从闲鱼上购入了两张票,正好去体验一下。
live house(ライブハウス)诞生于上世纪的日本,作为一种于体育馆截然不同的形式,live house为那些名气不是特别大的音乐人提供了一个很好的舞台,三五百人的容纳提供了更好的氛围与形式。这次去的奕空间正好位于合肥奥体中心旁边,是一个篮球场改造的,场馆内部是一整个空间,大概容纳了五百人左右。舞台空间上,音响质量还可以,正前方,左前方和右前方各有一个大屏幕,基本上就是体育馆演唱会的微缩版。
八三夭是台湾的乐队,和五月天一样都是来自相信音乐旗下的艺人。他们最广为人知的歌曲应该是2019年电视剧《想见你》的主题曲「想见你想见你想见你」
但实际我大概在14年左右就关系喜欢了这个乐队,他们当时比现在还是差点,不过也是把他们的专辑都听了一遍,最后的831,东区东区,我怎么哭了等等直到现在都是他们主打的歌曲。然而不知道为啥,可能是听的音乐太多了,他们渐渐消失在了我的音乐列表,后续只有一些现象级的歌曲听过(如想见你想见你想见你,不摇滚,一事无成的伟大等等)。因此去听他们的live house,也有一些现充的成分,因为很多新歌都只听过一两次,远远达不到之前单专辑不断循环的地步。
演出8点正式开始,不过7点半有暖场嘉宾,魏嘉莹,小姐姐之前没听过,不过唱的还是挺好的,感觉现场还是蛮稳的,多是那种放松抒情的歌。
八点整,重点来了,八三夭来了,上来先是几首较燃的歌曲引爆全场的气氛。个人觉得八三夭的很多哥都适合与这种演唱会的形式,强劲的节奏和鼓点,就算没听过这首歌也能跟着奏乐跟着摇摆的那种感觉。
感觉主场阿噗颜值忽高忽低哈哈🤣
调动观众气氛是一件非常重要的事情,八三夭这点做的很好,身为一个乐队,不断的重复介绍自己的团员,每个人都进行富有特点的talking,给乐迷和路人都会留下很深的印象,不会觉得只有主唱在唱,其他人不过是打工的可有可无的情况。
另外他们将一些歌曲进行简化,让观众跟着旋律唱一些简单的句子,进而提高互动率,让我这种对新歌不太熟悉的现充也有很好的参与感😘。
还有和体育馆演唱会一样的翻唱Encore,老传统了。说是最后一首歌,然后唱完下去了,舞台灯也熄灭了,乐迷们大喊「八三夭,八三夭」,在声声呼唤中再回来继续奏乐继续舞~
最终持续到10点多结束,整体的现场还是很嗨的,能明显的感受到,如果想跳,还是能够跳起来的,就是小腿有点酸痛罢了。
个人觉得,这场live house还是很值的。演唱会这种东西现场和屏幕前完全是两种概念,那种快乐的氛围简直是天差地别。生活中能够蹦蹦跳跳的机会不多,能够和有着一起喜好的人嗨的机会不多,疫情的封闭让大家太压抑了,唱跳完感觉很爽,全身都是汗。生活本身平淡,热烈的事情还是需要去寻找。
]]>阈值处理有很多种,有三种形式:
需要手动确定阈值T
# apply basic thresholding -- the first parameter is the image
# we want to threshold, the second value is is our threshold
# check; if a pixel value is greater than our threshold (in this
# case, 200), we set it to be *black, otherwise it is *white*
(T, threshInv) = cv2.threshold(blurred, 200, 255,
cv2.THRESH_BINARY_INV)
cv2.imshow("Threshold Binary Inverse", threshInv)
cv2.threshold
第一个参数为需要处理的图像,第二个为阈值T,第三个为高于阈值后需要变化为的数值(通常为255,表示变为黑色),第四个为阈值处理方法。
输出结果 第一个T表示阈值,第二个表示阈值后的图像。
OTUS可以帮助我们自动设置阈值。Otsu的方法假设我们的图像像素强度的灰度直方图是双模态的,这仅仅意味着直方图是两个峰。[[opencv直方图对比|直方图详解]]
例如如下图像,第一个尖峰对应于图像的统一背景颜色,而第二个峰值对应于药丸区域本身。
(T, threshInv) = cv2.threshold(blurred, 0, 255,
cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)
使用OTSU第二个参数设置为了0,因为它会自动帮助我们计算阈值。
import argparse
import cv2
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", type=str, required=True,
help="path to input image")
args = vars(ap.parse_args())
# load the image and display it
image = cv2.imread(args["image"])
cv2.imshow("Image", image)
# convert the image to grayscale and blur it slightly
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (7, 7), 0)
# apply Otsu's automatic thresholding which automatically determines
# the best threshold value
(T, threshInv) = cv2.threshold(blurred, 0, 255,
cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)
cv2.imshow("Threshold", threshInv)
print("[INFO] otsu's thresholding value: {}".format(T))
# visualize only the masked regions in the image
masked = cv2.bitwise_and(image, image, mask=threshInv)
cv2.imshow("Output", masked)
cv2.waitKey(0)
注意一下cv2.threshold
中的阈值方法参数:
参考 OpenCV Thresholding ( cv2.threshold ) - PyImageSearch
对于一些复杂的图像,全局只有一个阈值分割效果可能会不好,因此使用自适应阈值。而且可以避免训练专用Mask R-CNN或U-Net分割网络的耗时和计算昂贵的过程。
具体思想是在小块的领域确定阈值,选取区域大小是个需要调整的参数。区域阈值计算方法可以选择算术平均值或高斯平均值,算数平均更加常用。
thresh = cv2.adaptiveThreshold(blurred, 255,
cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 21, 10)
输入参数 第一个为目标图像;第二个为输入阈值;第三个为自适应阈值方法,可选cv2.ADAPTIVE_THRESH_MEAN_C
或 cv2.ADAPTIVE_THRESH_GAUSSIAN_C
;第四个如同手动阈值方法;第五个是领域大小,这里表示21×21;最后一个为微调常数值C,通过加减C来进行调整阈值。
image = cv2.imread('test.png')
cv2.imshow("Image", image)
# convert the image to grayscale and blur it slightly
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (7, 7), 0)
# instead of manually specifying the threshold value, we can use
# adaptive thresholding to examine neighborhoods of pixels and
# adaptively threshold each neighborhood
thresh = cv2.adaptiveThreshold(blurred, 255,
cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 21, 4)
cv2.imshow("Mean Adaptive Thresholding", thresh)
cv2.waitKey(0)
参考 Adaptive Thresholding with OpenCV ( cv2.adaptiveThreshold )
平滑和模糊是计算机视觉和图像处理中最常见的预处理步骤之一。在应用边缘检测或阈值分割等技术之前,通过平滑图像,能够减少高频内容的数量,如噪声和边缘(即图像的细节)。
取中心像素周围的像素区域,将所有这些像素平均在一起,并用平均值替换中心像素。通常使用 M×N (M N为奇数)的内核进行平均。随着内核大小的增加,图像模糊的数量也会增加。
kernelSizes = [(3, 3), (9, 9), (15, 15)]
# loop over the kernel sizes
for (kX, kY) in kernelSizes:
# apply an "average" blur to the image using the current kernel
# size
blurred = cv2.blur(image, (kX, kY))
cv2.imshow("Average ({}, {})".format(kX, kY), blurred)
cv2.waitKey(0)
高斯模糊类似于平均模糊,但不是简单的平均值,而是加权平均值,其中更接近中心像素的邻域像素对平均值贡献更多的权重。借助M×N 的内核(M N为奇数),基于这种加权,将能够保留图像中更多的边缘。
x和y方向上的高斯函数如下:
当内核的大小增加时,应用于输出图像的模糊量也会增加。
kernelSizes = [(3, 3), (9, 9), (15, 15)]
# loop over the kernel sizes again
for (kX, kY) in kernelSizes:
# apply a "Gaussian" blur to the image
blurred = cv2.GaussianBlur(image, (kX, kY), 0)
cv2.imshow("Gaussian ({}, {})".format(kX, kY), blurred)
cv2.waitKey(0)
最后一个参数为高斯分布的标准差。通过将这个值设置为0,我们指示OpenCV根据内核大小自动计算。更多细节可以参考 OpenCV documentation
中值模糊方法是去除椒盐噪声最有效的方法。该方法的内核大小必须是正方形。并且用邻域的中值代替中心像素。
中值模糊在从图像中去除椒盐风格噪声时更有效的原因是每个中心像素总是被图像中存在的像素强度所取代。由于中位数对异常值具有稳健性,与平均值等其他统计方法相比,椒盐噪声对中位数的影响较小。
kernelSizes = [(3, 3), (9, 9), (15, 15)]
# loop over the kernel sizes a final time
for k in (3, 9, 15):
# apply a "median" blur to the image
blurred = cv2.medianBlur(image, k)
cv2.imshow("Median {}".format(k), blurred)
cv2.waitKey(0)
上面几种模糊方法往往会失去图像的边缘,为了在保持边缘的同时减少噪声,可以使用双边模糊(利用两个高斯分布)。但是它的速度会慢很多。
blurred = cv2.bilateralFilter(image, diameter, sigmaColor, sigmaSpace)
第一个参数为需要模糊的图像;第二个参数为像素邻域的直径。直径越大,模糊计算中包含的像素就越多;第三个参数是颜色标准偏差,更大的值意味着在计算模糊时将考虑附近更多的颜色。第四个参数为坐标空间中的sigma值。它的值越大,说明有越多的点能够参与到滤波计算中来。
参考 OpenCV Smoothing and Blurring - PyImageSearch
形态学运算是应用于二值或灰度图像的简单变换。形态学操作探测带有结构元素(structuring elements)的图像。这个结构元素定义了每个像素周围要检查的邻域。根据给定的操作和结构元素的大小,我们可以调整输出图像。
有时候很多东西根本不配用上特别高级的算法,例如机器学习,深度学习。
结构元素在opencv中用cv2.getStructuringElement
定义,如下与定义4邻域和8邻域的一个例子
图像中物体边界附近的像素将被丢弃侵蚀掉。
侵蚀通过定义结构元素,然后在输入图像上从左到右、从上到下滑动这个结构元素。只有当结构元素中的所有像素都是> 0时,输入图像中的前景像素才会被保留。否则,像素被设置为0(即背景)。
使用 cv2.erode
# apply a series of erosions
for i in range(0, 3):
eroded = cv2.erode(gray, None, iterations=i + 1)
cv2.imshow("Eroded {} times".format(i + 1), eroded)
cv2.waitKey(0)
第一个参数为需要侵蚀的图像;第二个为侵蚀的结构元素,设为None
表示3×3的8领域结构;第三个为膨胀迭代次数。
膨胀可以增加前景对象的大小,尤其适用于将图像的破碎部分连接在一起。通过定义结构元素,若任意一个像素为> 0,则结构元素的中心像素p将被设置为白色。
使用 cv2.dilate
# apply a series of dilations
for i in range(0, 3):
dilated = cv2.dilate(gray.copy(), None, iterations=i + 1)
cv2.imshow("Dilated {} times".format(i + 1), dilated)
cv2.waitKey(0)
参数类似侵蚀,基本同理
开操作是侵蚀之后的膨胀。该操作可以从图像中删除小斑点:首先应用侵蚀来删除小斑点,然后应用膨胀来重新增长原始对象的大小。
kernelSizes = [(3, 3), (5, 5), (7, 7)]
# loop over the kernels sizes
for kernelSize in kernelSizes:
# construct a rectangular kernel from the current size and then
# apply an "opening" operation
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, kernelSize)
opening = cv2.morphologyEx(gray, cv2.MORPH_OPEN, kernel)
cv2.imshow("Opening: ({}, {})".format(
kernelSize[0], kernelSize[1]), opening)
cv2.waitKey(0)
cv2.getStructuringElement用来定义一个结构元素。第一个参数结构元素类型:cv2.MORPH_RECT
表示正方形结构(8邻域),cv2.MORPH_CROSS
表示十字形结构(4邻域),cv2.MORPH_ELLIPSE
表示圆形结构。第二个参数表示大小。
这里开操作使用 cv2.morphologyEx 函数,不过实际上它能够传递任何想要的形态操作。这里操作方式选择cv2.MORPH_OPEN
表示开操作。
闭操作是膨胀之后的侵蚀。它可以将物体内部的孔或将组件连接在一起。
kernelSizes = [(3, 3), (5, 5), (7, 7)]
for kernelSize in kernelSizes:
# construct a rectangular kernel form the current size, but this
# time apply a "closing" operation
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, kernelSize)
closing = cv2.morphologyEx(gray, cv2.MORPH_CLOSE, kernel)
cv2.imshow("Closing: ({}, {})".format(
kernelSize[0], kernelSize[1]), closing)
cv2.waitKey(0)
与开操作类似,不过cv2.morphologyEx 函数中方法选择 cv2.MORPH_CLOSE
形态学梯度是膨胀和侵蚀之间的差异。它对于确定图像的特定对象的轮廓很有用
kernelSizes = [(3, 3), (5, 5), (7, 7)]
for kernelSize in kernelSizes:
# construct a rectangular kernel and apply a "morphological
# gradient" operation to the image
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, kernelSize)
gradient = cv2.morphologyEx(gray, cv2.MORPH_GRADIENT, kernel)
cv2.imshow("Gradient: ({}, {})".format(
kernelSize[0], kernelSize[1]), gradient)
cv2.waitKey(0)
cv2.morphologyEx 函数中方法选择 cv2.MORPH_GRADIENT
top hat用于在深色背景上显示图像的明亮区域。
image = cv2.imread(args["image"])
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# construct a rectangular kernel (13x5) and apply a blackhat
# operation which enables us to find dark regions on a light
# background
rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (13, 5))
blackhat = cv2.morphologyEx(gray, cv2.MORPH_BLACKHAT, rectKernel)
# similarly, a tophat (also called a "whitehat") operation will
# enable us to find light regions on a dark background
tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, rectKernel)
# show the output images
cv2.imshow("Original", image)
cv2.imshow("Blackhat", blackhat)
cv2.imshow("Tophat", tophat)
cv2.waitKey(0)
分别使用 cv2.MORPH_BLACKHAT
和 cv2.MORPH_TOPHAT
去进行操作
参考 OpenCV Morphological Operations
主要基于 cv2.cvtColor 函数
照明条件对于计算机视觉处理流程有着重要的影响。光的质量是图像进入算法前就应该积极考虑的,它可能是最重要的因素。
高对比度 High contrast
尽量确保环境的背景和前景之间有很高的对比度,这将使编写代码更容易准确地理解背景和前景。
可推广的 Generalizable
照明条件应该足够一致,以至于它们从一个物体到另一个对象都可以很好地工作。
稳健性 Stable
拥有稳定、一致和可重复的照明条件是计算机视觉应用开发重要因素。
由RGB三个通道组成,每个通道范围为[0,255]。RGB颜色空间是加色空间的一个例子:每种颜色加的越多,像素就变得越亮,越接近白色。需要将三个通道都加起来才能表示一种颜色。
HSV颜色空间会改变RGB的颜色空间,将其重塑为圆柱体而不是立方体。在RGB部分中看到的,颜色的白色或明度是每个红色、绿色和蓝色组件的相加组合。但现在在HSV颜色空间中,亮度被赋予了自己的独立维度。
Hue:检查哪种“纯”颜色。例如,颜色“红色”的所有阴影和色调都具有相同的色调。
Saturation:颜色是多么“白色”。完全饱和的颜色将是“纯”,如“纯红色”。零饱和的颜色将是纯白色。
value:控制颜色的明度。0将表示纯黑色,而增加将产生较浅的颜色
不同的计算机视觉库将使用不同的范围来表示每个色相、饱和度和值组件。
在OpenCV中,图像表示为8位无符号整数数组。因此,Hue值被定义为范围[0,179] (总共有180个可能的值,因为[0,359]共360对于8位无符号数组是不可能的),Hue实际上是HSV颜色圆柱上的度数。Saturation和value范围都在[0,255]。
转换方式使用cv2.COLOR_BGR2HSV
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
Value组件本质上是一个灰度图像,这是因为Value控制了颜色的实际明度,而Hue和Saturation定义了实际的颜色和阴影。HSV颜色空间在计算机视觉应用中被大量使用,特别是当我们对跟踪图像中某些物体的颜色感兴趣时。使用HSV定义一个有效的颜色范围比使用RGB要容易得多。
该方法目标是模仿人类观察和解释颜色的方法。L* a* b* 颜色空间中任意两种颜色之间的欧几里得距离具有实际的感知意义。L* a* b* 颜色空间是一个3轴系统
L* a* b* 颜色空间不像HSV和RGB颜色空间那么直观,但它在计算机视觉中被大量使用。这是因为颜色之间的距离具有实际的感知意义,使我们能够克服各种光照条件问题。它还可以作为一个强大的彩色图像描述符。
转换方式使用cv2.COLOR_BGR2LAB
lab = cv2.cvtColor(image, cv2.COLOR_BGR2LAB)
L* 通道,用于显示给定像素的亮度。然后,a* 和b* 决定像素的阴影和颜色。
转换方式使用cv2.COLOR_BGR2GRAY
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
转化为单一通道像素范围在[0,255]的图像。转化公式如下
不平均主要是由于我们视觉感知RGB三种颜色敏感度不同。
参考 OpenCV Color Spaces ( cv2.cvtColor )
图像梯度的作用
通常检测到图像的边缘叫做edge map
关于图像梯度手动计算的方法参考这里
Sobel使用了两个核,一个用于检测水平方向的变化,另一个用于检测垂直方向的变化
Scharr类似,不过核不太一样,效果会更好一些。
代码使用
import argparse
import cv2
# construct the argument parser and parse the arguments
# scharr 参数为0表示使用sobel内核,>0表示使用scharr内核
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", type=str, required=True,
help="path to input image")
ap.add_argument("-s", "--scharr", type=int, default=0,
help="path to input image")
args = vars(ap.parse_args())
image = cv2.imread(args["image"])
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv2.imshow("Gray", gray)
# set the kernel size, depending on whether we are using the Sobel
# operator of the Scharr operator, then compute the gradients along
# the x and y axis, respectively
ksize = -1 if args["scharr"] > 0 else 3
gX = cv2.Sobel(gray, ddepth=cv2.CV_32F, dx=1, dy=0, ksize=ksize)
gY = cv2.Sobel(gray, ddepth=cv2.CV_32F, dx=0, dy=1, ksize=ksize)
# the gradient magnitude images are now of the floating point data
# type, so we need to take care to convert them back a to unsigned
# 8-bit integer representation so other OpenCV functions can operate
# on them and visualize them
gX = cv2.convertScaleAbs(gX)
gY = cv2.convertScaleAbs(gY)
# combine the gradient representations into a single image
combined = cv2.addWeighted(gX, 0.5, gY, 0.5, 0)
# show our output images
cv2.imshow("Sobel/Scharr X", gX)
cv2.imshow("Sobel/Scharr Y", gY)
cv2.imshow("Sobel/Scharr Combined", combined)
cv2.waitKey(0)
参考 Image Gradients with OpenCV (Sobel and Scharr)
通常会使用Canny边缘检测器,opencv中使用cv2.Canny函数
在边缘检测过程中,梯度幅值对噪声极其敏感。Canny检测中,边被定义为像素强度的不连续,或者更简单地说,像素值的急剧差异和变化。
噪声去除:使用[[Opencv高级处理#高斯模糊 cv2.GaussianBlur|高斯模糊]]等去除图片噪声,做平滑处理
计算图像梯度:对平滑后的图像使用[[Opencv高级处理#Sobel and Scharr kernels|Sobel算子]]计算水平方向和竖直方向的一阶导数(Gx 和Gy)。根据得到的这两幅梯度,找到边界梯度和方向
非极大值抑制( Non-maxima suppression):在获得梯度的方向和大小之后,对整幅图像进行扫描(通常是3×3),去除那些非边界上的点。对每一个像素进行检查,看这个点的梯度是不是周围具有相同梯度方向的点中最大的(如果中心像素的大小大于与之比较的两个像素,则保留,否则丢弃)
滞后阈值( Hysteresis thresholding):确定真正的边界,设置两个阈值: TminVal 和TmaxVal。当图像的灰度梯度高于TmaxVal时被认为是真的边界,低于TminVal的边界会被抛弃
调用方法,需要设定上下界的阈值
image = cv2.Canny(blurred, TminVal, TmaxVal)
实际上这个auto_canny代码已经集成在了imutils中,可以直接调用
import argparse
import cv2
import numpy as np
def auto_canny(image, sigma=0.33):
v = np.median(image)
# apply automatic Canny edge detection using the computed median
lower = int(max(0, (1.0 - sigma) * v))
upper = int(min(255, (1.0 + sigma) * v))
edged = cv2.Canny(image, lower, upper)
return edged
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True, help="Path to the image")
args = vars(ap.parse_args())
image = cv2.imread(args["image"])
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (3, 3), 0)
wide = cv2.Canny(blurred, 10, 200)
tight = cv2.Canny(blurred, 225, 250)
auto = auto_canny(blurred)
cv2.imshow("Original", image)
cv2.imshow("Wide", wide)
cv2.imshow("Tight", tight)
cv2.imshow("Auto", auto)
cv2.waitKey(0)
参考 OpenCV Edge Detection ( cv2.Canny )
OpenCV Contour Approximation,称为Ramer–Douglas–Peucker 算法
目的是通过减少给定阈值的折线顶点来简化折线。通俗地说,我们取一条曲线,减少它的顶点数量,同时保留它的大部分形状
主要使用cv2.findContours函数寻找所有的轮廓,再使用cv2.approxPolyDP对轮廓进行近似。
import numpy as np
import argparse
import imutils
import cv2
# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", type=str, default="shape.png",
help="path to input image")
args = vars(ap.parse_args())
# load the image and display it
image = cv2.imread(args["image"])
cv2.imshow("Image", image)
# convert the image to grayscale and threshold it
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 200, 255,
cv2.THRESH_BINARY_INV)[1]
cv2.imshow("Thresh", thresh)
# find the largest contour in the threshold image
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
c = max(cnts, key=cv2.contourArea)
# draw the shape of the contour on the output image, compute the
# bounding box, and display the number of points in the contour
output = image.copy()
cv2.drawContours(output, [c], -1, (0, 255, 0), 3)
(x, y, w, h) = cv2.boundingRect(c)
text = "original, num_pts={}".format(len(c))
cv2.putText(output, text, (x, y - 15), cv2.FONT_HERSHEY_SIMPLEX,
0.9, (0, 255, 0), 2)
# show the original contour image
print("[INFO] {}".format(text))
cv2.imshow("Original Contour", output)
cv2.waitKey(0)
# to demonstrate the impact of contour approximation, let's loop
# over a number of epsilon sizes
for eps in np.linspace(0.001, 0.05, 10):
# approximate the contour
peri = cv2.arcLength(c, True) # 计算周长
approx = cv2.approxPolyDP(c, eps * peri, True)
# draw the approximated contour on the image
output = image.copy()
cv2.drawContours(output, [approx], -1, (0, 255, 0), 3)
text = "eps={:.4f}, num_pts={}".format(eps, len(approx))
cv2.putText(output, text, (x, y - 15), cv2.FONT_HERSHEY_SIMPLEX,
0.9, (0, 255, 0), 2)
# show the approximated contour image
print("[INFO] {}".format(text))
cv2.imshow("Approximated Contour", output)
cv2.waitKey(0)
通过改变eps的值,一步步的近似轮廓边缘。
]]>最近在复习和学习OpenCV这个库,罗列一下知识点供以后整理查阅
OpenCV坐标为x向右为正,y向下为负。在代码中表示一个坐标 先y后x
例如下面要选择x,y=(90,40)这个点
代码表示如下:
# pixel coordinates
x = 90
y = 40
pixel_flame_gray16 = gray16_image [y, x]
另外opencv读取的RGB图像的顺序是B,G,R
# images are simply NumPy arrays -- with the origin (0, 0) located at
# the top-left of the image
(b, g, r) = image[0, 0]
print("Pixel at (0, 0) - Red: {}, Green: {}, Blue: {}".format(r, g, b))
使用cv2.imread 前3个维度分别为Height,width和channels
import argparse
import cv2
# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True,
help="path to input image")
args = vars(ap.parse_args())
# load the image from disk via "cv2.imread" and then grab the spatial
# dimensions, including width, height, and number of channels
image = cv2.imread(args["image"])
(h, w, c) = image.shape[:3]
# display the image width, height, and number of channels to our
# terminal
print("width: {} pixels".format(w))
print("height: {} pixels".format(h))
print("channels: {}".format(c))
# show the image and wait for a keypress
cv2.imshow("Image", image)
cv2.waitKey(0)
# save the image back to disk (OpenCV handles converting image
# filetypes automatically)
cv2.imwrite("newimage.jpg", image)
直接使用切片操作即可。例如需要提取一个图像的矩形区域,从(85,85)开始,到(220,250)结束。
OpenCV将图像表示为NumPy数组,高度在前(行编号#),宽度在后(列编号#)。
cropped = image[startY:endY, startX:endX]
import cv2
# load the input image and display it to our screen
image = cv2.imread('test.png')
cv2.imshow("Original", image)
# cropping an image with OpenCV is accomplished via simple NumPy
# array slices in startY:endY, startX:endX order -- here we are
# cropping the face from the image (these coordinates were
# determined using photo editing software such as Photoshop,
# GIMP, Paint, etc.)
face = image[85:250, 85:220]
cv2.imshow("Face", face)
cv2.waitKey(0)
在进行图像运算时,需要注意颜色空间和数据类型的数值限制。通常来说,RGB图像的像素在[0, 255]范围内。如果在这个运算中超出这个范围,opencv和numpy的处理方法是不一样的。
import numpy as np
import cv2
# images are NumPy arrays stored as unsigned 8-bit integers (unit8)
# with values in the range [0, 255]; when using the add/subtract
# functions in OpenCV, these values will be *clipped* to this range,
# even if they fall outside the range [0, 255] after applying the
# operation
added = cv2.add(np.uint8([200]), np.uint8([100]))
subtracted = cv2.subtract(np.uint8([50]), np.uint8([100]))
print("max of 255: {}".format(added))
print("min of 0: {}".format(subtracted))
>>> max of 255: [[255]]
>>> min of 0: [[0]]
# using NumPy arithmetic operations (rather than OpenCV operations)
# will result in a modulo ("wrap around") instead of being clipped
# to the range [0, 255]
added = np.uint8([200]) + np.uint8([100])
subtracted = np.uint8([50]) - np.uint8([100])
print("wrap around: {}".format(added))
print("wrap around: {}".format(subtracted))
>>> wrap around: [44]
>>> wrap around: [206]
通常像素值0为黑,255为纯白,如果只有0和255,实际可以抽象为二值化图像。
opencv中处理逻辑运算使用命令bitwise_and
, bitwise_or
, bitwise_xor
, bitwise_not
.
import numpy as np
import cv2
# draw a rectangle
rectangle = np.zeros((300, 300), dtype="uint8")
cv2.rectangle(rectangle, (25, 25), (275, 275), 255, -1)
cv2.imshow("Rectangle", rectangle)
# draw a circle
circle = np.zeros((300, 300), dtype = "uint8")
cv2.circle(circle, (150, 150), 150, 255, -1)
cv2.imshow("Circle", circle)
# a bitwise 'AND' is only 'True' when both inputs have a value that
# is 'ON' -- in this case, the cv2.bitwise_and function examines
# every pixel in the rectangle and circle; if *BOTH* pixels have a
# value greater than zero then the pixel is turned 'ON' (i.e., 255)
# in the output image; otherwise, the output value is set to
# 'OFF' (i.e., 0)
bitwiseAnd = cv2.bitwise_and(rectangle, circle)
cv2.imshow("AND", bitwiseAnd)
cv2.waitKey(0)
# a bitwise 'OR' examines every pixel in the two inputs, and if
# *EITHER* pixel in the rectangle or circle is greater than 0,
# then the output pixel has a value of 255, otherwise it is 0
bitwiseOr = cv2.bitwise_or(rectangle, circle)
cv2.imshow("OR", bitwiseOr)
cv2.waitKey(0)
# the bitwise 'XOR' is identical to the 'OR' function, with one
# exception: the rectangle and circle are not allowed to *BOTH*
# have values greater than 0 (only one can be 0)
bitwiseXor = cv2.bitwise_xor(rectangle, circle)
cv2.imshow("XOR", bitwiseXor)
cv2.waitKey(0)
# finally, the bitwise 'NOT' inverts the values of the pixels;
# pixels with a value of 255 become 0, and pixels with a value of 0
# become 255
bitwiseNot = cv2.bitwise_not(circle)
cv2.imshow("NOT", bitwiseNot)
cv2.waitKey(0)
本质上使用bitwise_and
操作即可
import numpy as np
import cv2
image = cv2.imread('test.png')
cv2.imshow("Original", image)
# a mask is the same size as our image, but has only two pixel
# values, 0 and 255 -- pixels with a value of 0 (background) are
# ignored in the original image while mask pixels with a value of
# 255 (foreground) are allowed to be kept
mask = np.zeros(image.shape[:2], dtype="uint8")
cv2.rectangle(mask, (0, 90), (290, 450), 255, -1)
cv2.imshow("Rectangular Mask", mask)
# apply our mask -- notice how only the person in the image is
# cropped out
masked = cv2.bitwise_and(image, image, mask=mask)
cv2.imshow("Mask Applied to Image", masked)
cv2.waitKey(0)
当调整图像大小时,重要的是要记住宽度与高度比值,即图像的宽高比(aspect_ratio)。忽略纵横比可能会导致调整图像大小,看起来压缩和扭曲。另外图像放大过程需要注意插值(interpolation)方法。
直接使用cv2.resize
方法需要手动计算宽高比,以保证缩放比例正确
aspect_ratio = image_width / image_height
import numpy as np
import cv2
image = cv2.imread('test.png')
# 调整为150像素宽度
r = 150.0 / image.shape[1]
dim = (150, int(image.shape[0] * r))
# perform the actual resizing of the image
resized = cv2.resize(image, dim, interpolation=cv2.INTER_AREA)
cv2.imshow("Resized (Width)", resized)
# 调整为50像素高度
r = 50.0 / image.shape[0]
dim = (int(image.shape[1] * r), 50)
# perform the resizing
resized = cv2.resize(image, dim, interpolation=cv2.INTER_AREA)
cv2.imshow("Resized (Height)", resized)
cv2.waitKey(0)
可以使用imutils自动调整大小功能
import imutils
import cv2
image = cv2.imread('test.png')
# calculating the ratio each and every time we want to resize an
# image is a real pain, so let's use the imutils convenience
# function which will *automatically* maintain our aspect ratio
# for us
resized = imutils.resize(image, width=100)
cv2.imshow("Resized via imutils", resized)
cv2.waitKey(0)
cv2.INTER_NEAREST 最近邻域插值
cv2.INTER_LINEAR 双线性插值
cv2.INTER_AREA 区域间插值
以下为样条插值,使用情况较少,速度较慢
cv2.INTER_CUBIC based on a 4 x 4 pixel neighbor
cv2.INTER_LANCZOS4 based on an 8 x 8 pixel neighborhood
通常,cv2.INTER_NEAREST
非常快,但没有提供最高质量的结果。在非常受到资源约束的环境中,可以考虑该方法。
增加图像大小(上采样)时,考虑使用cv2.INTER_LINEAR
和 cv2.INTER_CUBIC
。cv2.INTER_LINEAR
方法往往比 cv2.INTER_CUBIC
方法稍快,哪种更好自己尝试。
减小图像大小(下采样)时,OPENCV文档建议使用cv2.INTER_AREA
。也可以使用cv2.INTER_NEAREST
方法,但是cv2.INTER_AREA
通常效果更好。
最后,作为一般规则,建议使用cv2.INTER_LINEAR
插值方法作为默认方法,上下采样都有较好的效果。
0表示垂直翻转(x轴),1表示水平翻转(y轴),-1表示两种操作都进行(180度)
import cv2
image = cv2.imread('test.png')
# flip the image horizontally
print("[INFO] flipping image horizontally...")
flipped = cv2.flip(image, 1)
cv2.imshow("Flipped Horizontally", flipped)
# flip the image vertically
flipped = cv2.flip(image, 0)
print("[INFO] flipping image vertically...")
cv2.imshow("Flipped Vertically", flipped)
# flip the image along both axes
flipped = cv2.flip(image, -1)
print("[INFO] flipping image horizontally and vertically...")
cv2.imshow("Flipped Horizontally & Vertically", flipped)
cv2.waitKey(0)
旋转原理
通常来说,旋转需要选择一个旋转中心和旋转角度,opencv还可以将图片进行缩放操作。
使用cv2.getRotationMatrix2D
定义一个旋转矩阵,第一个参数为旋转中心点,第二个为旋转角度(顺时针),第三个为缩放尺度。注意:在OpenCV中,正度表示逆时针旋转,负度表示顺时针旋转。
使用cv2.warpAffine
应用旋转,第一个参数是想要旋转的图像。之后指定旋转矩阵M和图像的输出维度(宽度和高度)。
```python
import cv2
image = cv2.imread('test.png')
# grab the dimensions of the image and calculate the center of the
# image
(h, w) = image.shape[:2]
(cX, cY) = (w // 2, h // 2)
# rotate our image by 45 degrees around the center of the image
M = cv2.getRotationMatrix2D((cX, cY), 45, 1.0)
rotated = cv2.warpAffine(image, M, (w, h))
cv2.imshow("Rotated by 45 Degrees", rotated)
# rotate our image by -90 degrees around the image
M = cv2.getRotationMatrix2D((cX, cY), -90, 1.0)
rotated = cv2.warpAffine(image, M, (w, h))
cv2.imshow("Rotated by -90 Degrees", rotated)
但是OpenCV并不会自动为我们整个旋转的图像分配空间以适应大小,可能会翻转到图像外面去。这个就需要调整cv2.warpAffine
中的(w,h)来改变,比较麻烦。
imutils.convenience.rotate
为一个封装的方法,代码显得简化许多。
import cv2
import imutils
image = cv2.imread('test.png')
# use our imutils function to rotate an image 180 degrees
rotated = imutils.rotate(image, 180)
cv2.imshow("Rotated by 180 Degrees", rotated)
如果旋转过程中图像的一部分被切断,OpenCV不会分配足够的空间来存储整个图像,这时候可以使用imutils.convenience.rotate_bound
解决
# rotate our image by 33 degrees counterclockwise, ensuring the
# entire rotated image still renders within the viewing area
rotated = imutils.rotate_bound(image, -33)
cv2.imshow("Rotated Without Cropping", rotated)
cv2.waitKey(0)
使用cv2.split
和 cv2.merge
即可
import cv2
import imutils
image = cv2.imread('test.png')
# load the input image and grab each channel -- note how OpenCV
# represents images as NumPy arrays with channels in Blue, Green,
# Red ordering rather than Red, Green, Blue
image = cv2.imread(args["image"])
(B, G, R) = cv2.split(image)
# show each channel individually
cv2.imshow("Red", R)
cv2.imshow("Green", G)
cv2.imshow("Blue", B)
cv2.waitKey(0)
# merge the image back together again
merged = cv2.merge([B, G, R])
cv2.imshow("Merged", merged)
cv2.waitKey(0)
cv2.destroyAllWindows()
常用命令
cv2.line
: 在图像上绘制一条直线,从指定的(x, y)坐标开始,结束于另一个(x, y)坐标cv2.circle
: 在由中心(x, y)坐标和提供的半径指定的图像上绘制一个圆cv2.rectangle
: 在左上角和右下角(x, y)坐标指定的图像上绘制矩形cv2.ellipse
: 绘制椭圆形cv2.polylines
: 绘制由一组(x, y)坐标指定的多边形的轮廓cv2.fillPoly
: 绘制一个多边形,但不是绘制轮廓,而是填充多边形cv2.arrowedLine
: 绘制一个箭头,从起始(x, y)坐标指向结束(x, y)坐标# import the necessary packages
import numpy as np
import cv2
# initialize our canvas as a 300x300 pixel image with 3 channels
# (Red, Green, and Blue) with a black background
canvas = np.zeros((300, 300, 3), dtype="uint8")
# draw a green line from the top-left corner of our canvas to the
# bottom-right
green = (0, 255, 0)
cv2.line(canvas, (0, 0), (300, 300), green)
cv2.imshow("Canvas", canvas)
cv2.waitKey(0)
# draw a 3 pixel thick red line from the top-right corner to the
# bottom-left
red = (0, 0, 255)
cv2.line(canvas, (300, 0), (0, 300), red, 3)
cv2.imshow("Canvas", canvas)
cv2.waitKey(0)
# draw a green 50x50 pixel square, starting at 10x10 and ending at 60x60
cv2.rectangle(canvas, (10, 10), (60, 60), green)
cv2.imshow("Canvas", canvas)
cv2.waitKey(0)
# draw another rectangle, this one red with 5 pixel thickness
cv2.rectangle(canvas, (50, 200), (200, 225), red, 5)
cv2.imshow("Canvas", canvas)
cv2.waitKey(0)
# draw a final rectangle (blue and filled in )
blue = (255, 0, 0)
cv2.rectangle(canvas, (200, 50), (225, 125), blue, -1) #-1表示全部填充
cv2.imshow("Canvas", canvas)
cv2.waitKey(0)
画圈
# re-initialize our canvas once again
canvas = np.zeros((300, 300, 3), dtype="uint8")
# let's draw 25 random circles
for i in range(0, 25):
# randomly generate a radius size between 5 and 200, generate a
# random color, and then pick a random point on our canvas where
# the circle will be drawn
radius = np.random.randint(5, high=200)
color = np.random.randint(0, high=256, size=(3,)).tolist()
pt = np.random.randint(0, high=300, size=(2,))
# draw our random circle on the canvas
cv2.circle(canvas, tuple(pt), radius, color, -1)
# display our masterpiece to our screen
cv2.imshow("Canvas", canvas)
cv2.waitKey(0)
与图像旋转类似,需要先定义一个平移矩阵,之后使用cv2.warpAffine
方法进行调用
平移矩阵如下:
其中第一行表示左右移动,shiftX为负,向左移动,shiftX为正,向右移动。
第二行表示上下移动,shiftY为负,向下移动,shiftY为正,向上移动。
M = np.float32([
[1, 0, shiftX],
[0, 1, shiftY]
])
import cv2
image = cv2.imread('test.png')
# shift the image 25 pixels to the right and 50 pixels down
M = np.float32([[1, 0, 25], [0, 1, 50]])
shifted = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))
cv2.imshow("Shifted Down and Right", shifted)
同时也可以用imutils.translate
方法,更加简洁一点。
# use the imutils helper function to translate the image 100 pixels
# down in a single function call
shifted = imutils.translate(image, 0, 100)
cv2.imshow("Shifted Down", shifted)
cv2.waitKey(0)
]]>虽然晚了一些,但是2023年的Flag还是要立下的。去年的目标实现的并不是很好,今年还是要改进一下方法和反馈机制。决定以年为单位使用OKR的方法来进行实践。
OKR(Objectives and Key Results) 目标与关键成果法,这其中:
具体一些其他人的实践案例可以参考这两篇文章:
其中第二篇文章给我带来了很大的启发,本文中很多东西都是参考他的体系去构建的。
由于涉及到个人的管理,所以参考生命之花模型,定义上来说,生命之花模型分为下面八个组成:
职业发展、财务状况、个人健康、娱乐休闲、家庭生活、朋友他人、个人成长、自我实现。
接下来我将家庭生活和朋友他人两项合并一下。共计七个方面指定下计划。
之前在公司工作,技术水平去完成那份工作是适合的。不过有些时候还是觉得力不从心,需要不断精进自己的技术,加强自己的专业性。
虽然之前学习过很多机器学习和深度学习的相关知识,但是没有整体上把他们整理过。借助整理的过程,把一些技术的知识点和代码整体复习一遍。
之前都是断断续续的学习python,没有一个完整并反馈的流程,虽然上一份工作不需要那么严格的python代码技术,但是有些基础的思想还是需要重新去系统的学习一下。
pytorch的代码技术水平一般,需要多读读别人的相关与源码,同时技术革新较快,需要大致了解一下其他技术的更迭项目以保证不落后。包括但不仅限于分类任务,分割任务,检测任务等等。同时OpenCV也希望好好学习一下。
新工作希望回到合肥进行发展,而且工作内容希望能够偏向上一份工作的医学影像处理。但是不仅仅限于这些,需要一些机遇结合实力去进行调整。
找工作不是一件容易的事情,而且我还有特定的专业性,因此需要沉住气,自己的应届生身份已经没有了,所以也不需要特别的着急。稳定好自己的情绪,多多关注自己的目标行业,寻找合适的机会。
计划赶不上变化,特别是工作,需要好好地动态调整自己的目的。我更在意工作对自己的影响而不是工作本身。
坚持记账几年了,还是比较有经验的。但是渐渐的需要步入人生新的阶段,还是需要不断调整预算完善系统。
之前学习过一段时间,但是没有系统的记录与整理。今年需要整理这方面的知识。
这些知识更新的比较快,也有一些其他投资者的感想,所以需要去好好跟进学习整理。
系统性的学习少不了专业书记的帮助,阅读并做好笔记内容。
学生时代实践过一段时间,碍于手头的资金等等没有持续进行。不过得到的经验是,没有充足的时间与精力不要参与股票的交易,水还是比较深。今年还是继续跟着投长线吧。
被动性的输入多且杂,希望能够将自己的信息源进行筛选改进,并改进消化流程。
包含但不限于rss,newsletter,telegram频道,视频网站,播客等等。分别使用不同的工具进行管理。
现在在用的有很多软件,obsidian,notion,滴答清单等等。需要整理好自己完善的笔记系统,并做好备份工作,不断收集消化新的知识。
有些东西有价值的东西可以分享出来,也便于后续自己查阅。
自己不喜欢用朋友圈,觉得负担太大。之前一直用flomo记录,但是发现也用的不多,双链功能自己也基本上用不上。不过发现了一个开源项目memos。它类似于备忘录,但是可以公开分享的内容,正好是一个好的分享平台。希望简短的内容可以通过他进行分享,同时也在自己的telegram频道中进行记录。
在自己的博客进行写作是一件坚持了很久的事情,新的一年也要继续,去年只写了9篇,虽然说不是因为没有时间,总是感觉差点思考与意思。新的一年希望能够保证至少每月一篇的输出且内容更加丰富。
大学时期组建过乐队,和朋友度过一段快乐的时光。前段时间看了「孤独摇滚」,重新想起了以前在音乐中的日子。虽然我无法将它作为自己的职业,但是我仍然不想抛弃它们,作为一种兴趣不断陶冶自己也是好的体现。
好久没玩过它了,继续重新回来吧。
由于买了midi键盘,也回到家了。重新系统的学习一下乐理知识,练习一下即兴技巧,不然永远只是一个单单模仿的笨蛋。
希望能够实现,但是有点难度。
英语一直是我的一个痛,虽然很多东西差不多能看懂,翻译软件也很方便,但是还是需要去刻意练习提升一下。
从日常中去阅读是最有效的方法,通过读一些英文文章和文献,把不会的单次用欧路词典记录下来。直接学习背诵。
刻意去听一些英语的相关内容,去培养增强自己的词汇量。
每周能够保持40个睡眠周期(1.5小时算一个,中午小憩30min算一个)。工作日期望睡眠时间:0:30~8:00 共5个睡眠周期。
使用瑜伽垫在家里锻炼。每周至少3次。一次时间不用多,20~30min。
跑步或者骑行,锻炼下肢力量。真的很久都没有跑步了。
之前我们俩一直是异地,见面在一起的日子真的很少。之后在可以的日子希望每周都能够见面,好好地培养感情。
聚会是很好的过程,增进情感与联系,和好朋友留下和的回忆。
虽然现在一直住在家里,但是之后随算搬出去住也要时刻保持联系。之前在外地是每周六都会和家人视频,以后也要坚持。
在新的地方去吃些好吃的,并记录下来,吃吃吃还是很有意思的。
读万卷书,行万里路,希望能够去不同的地方与城市,去看看不一样的风景。
之前也会立flag,但是往往不能够完成,这次使用新学习到的OKR系统来重新指定一次目标,并做好量化与追踪的方式,希望新的一年能够有更大的收获。
在了解生命之花模型之后,我发现工作实际上应该只占据人生的一小部分,而且它也应该只占据生命的一小部分。之前的一段工作经历感觉工作真繁忙,占据了大部分时间。而且觉得现在社会真心的卷,妈妈他们一辈也没有这么辛苦,兄弟姐妹也不少,照样能够把孩子各个都拉扯大。甚至看一些其他国家人民讲述以前的故事,往往都是爸爸在一家工厂里工作,也能够养活一家子人。而现在社会感觉养活自己都很不容易,这还挺奇怪的。不过生命更多的是应该为自己活,活得有价值与成就感就好了。
]]>