本站废弃公告
本站即将废弃,域名也将会在保留一年后注销,博客将迁移至 https://blog.tianli0.top/ 如果您有本站的友情链接请及时更换!
本站即将废弃,域名也将会在保留一年后注销,博客将迁移至 https://blog.tianli0.top/ 如果您有本站的友情链接请及时更换!
在平静的一天,著名开发平台Github突然出现一个名为CEC-IDE,在readme叠满了各种buff的仓库(目前已删库)
在仓库出现后,紧接着就有人扒出来一个官网(目前无法正常打开)
这些buff叠起来不免让人好奇是个什么样的项目 兼容vscode插件
保护开发成果
自主研发
,这些还只是我截图的一部分内容。
各路开发者看见这种东西当然很“兴奋”,很快啊,就有人进行了下载,与现存IDE(如果你不知道什么是IDE的话,白话就是写代码的工具)进行了比较。不过我们先看看近处的安装包吧,家人们~
欸,这个logo,是不是和你手机中的某一个绿色APP很像呢????
不过等等,好像还有一处不对劲。
版权来自微软!!!国产软件怎么可能版权来自微软呢???哦,我知道了,肯定是这个自主研发的IDE用的windows系统打包的可执行程序吧。那没事了,一定是windows偷偷改的。
怀着对国产的期待,便有开发者与著名IDE vscode进行了比较
(截图自网友:云默安喵~)
欸,又不对啊?怎么一模一样啊?不会是抄袭吧!
当然不会抄袭,此时仓库迎来更新,甚至支持了鸿蒙平台!!也说明了“致敬”vscode。
甚至还有VIP功能,一定是提供非常高档的服务才需要VIP吧。
⛵到此结束,到这里事情已经明了了,直接拿着Microsoft的vscode开源项目改了几个词几个logo就直接包装成自主研发,自主可控的国产IDE了,从仓库中的emoji以及其他相关句就能知道这是个整活仓库。开发者们显然是对于这种事情无法忍受,在仓库被删前已经出现了许多issue对这种行为(指国产IDE)进行“鼓励”。
不幸的是CEC—IDE的开发公司显然已经知道了这件事,即使在官网已经被关闭的情况下也进行了更新
是因为他套皮不说?是因为他使用了开源项目自己却不开源?是因为国产?
显然,都不是,国产有错吗?当然没错;遵守开源协议了吗?MIT,基本上开放的;套皮不说?只有这个恐怕也不会让大家反应这么强烈。
那我简单举几个例子:红芯浏览器 木兰开发语言 汉芯一号 等等等等
如果你都不知道,建议百度一下这些事情,知乎都有详细说明。
在以上的例子中我们发现其中基本上都离不开几个关键词“国产”,“自主”,“卡脖子”。这些词有错吗?不,我不认为有错,北斗导航,复兴号动车组,C919等等这些有很多其实在研发单位发出的文章或宣传或多或少都有一些上面提到的关键词,这难道不是成果吗?(注:C919没有做到100%国产,这是其所属单位承认的,但是在部分媒体宣传口径可能与实际不符,请注意官方单位宣传与媒体宣传差异。)
其中,最出名的当属汉芯事件,其涉案金额之大,范围之广直接导致了现目前科研领域的经费审批严格,让许多真正想搞科研的没钱审批下来,一颗老鼠屎坏了一锅汤,当然,不止一颗老鼠屎,仍有不少人搞科研经费。
今天这个CEC-IDE居然拿着开源项目加几个插件就敢说自己自主可控,还要建设数字_____。但是IDE可不是只有科研人员要用到的东西,IDE可以说是深入群众的基础工具,最小小学可能都已经会用vscode,但是不了解这方面或者没有编码需求根本不知情,这就导致了即使是换皮,上面也不知道。这么一款深入不少群众的工具对于开发者们来说自然无法接受,所以才会让各个开发者如此激烈,基本上我所在的有开发者的群都在转。
大家可以想象,如果有很多这种垃圾天天打着国产自研的名号招摇撞骗,以后你如果看见北斗这类真正务实的新闻你会持什么态度?🤣👉🏻
8月24日晚,我司获悉有网友发帖讨论我司CEC-IDE系统,公司管理层高度重视。我司感谢网友对CEC-IDE系统的支持与关注,诚恳接受网友批评,并认真开展核查。
CEC-IDE系统由开发工具、后端系统和组件库组成,其中开发工具使用开源VSCode,进行了少量改造,增加了部分功能,后端系统开发了用户、权限、项目、需求等管理,以及任务协作和知识共享等功能,组件库中开发了公共能力组件。今年7月投入试运行,目前仍处在探索阶段,未用于商业用途。
经初步核查,因版本迭代更新中出现疏忽,近几个版本中缺失了MIT协议文件,产品表述中“自主研发”等用语被网友质疑,对此,我们深感愧疚和自责,公司已责令相关工作团队进行认真整改,今后,我们将进一步完善产品研发管理机制。
开源软件的使用极大提升了我司产品研发效率,开源项目为我司提供了巨大帮助,开源精神是程序员共同的同心圆,数字广东公司向所有开源贡献者致以衷心的感谢和崇高的敬意。
数字广东网络建设有限公司
2023年8月26日
注:以下仿真模拟可能存在部分错误,欢迎指正
望远镜的历史可以追溯到1608年,荷兰人Hans Lippershey以平凸透镜作为物镜,凹透镜作为目镜,构成了世界上第一台望远镜,值得一提的是,当时Hans Lippershey想依靠望远镜申请专利,或许是太多人都自称是发明者[1],因此,此项专利并没有得到批复,但是这项发明很快传遍了整个欧洲。伽利略在第二年基于此改进了这一型望远镜观测天象,因此这种望远镜被称为伽利略望远镜。开普勒在1611年描述了如何用凸透镜的物镜和目镜制作出更有用的望远镜;而克里斯蒂安·惠更斯配合复合目镜制造出倍数高但视野不广的开普勒望远镜。
图 1伽利略型望远镜与开普勒型望远镜示意图
1668年,牛顿结合斜置对角的小平面镜将光线反射至望远镜侧边的目镜,制造出第一架"实用"的反射镜。洛朗·卡塞格林在1672年描述使用一个小凸透镜作为第二反射镜,将光线反射穿过主镜中心洞孔的设计。[2]
图 2牛顿反射镜示意图
图 3卡塞格兰反射镜示意图
消色差透镜在1733年出现在贾斯特·摩尔·霍尔制做的望远镜,大大的降低了物镜的色差,使望远镜可以制做得更短并且有更多的功能,但是它没有公布。约翰·多隆德学到了霍尔的发明,并且在1758年制作出望远镜,开始商业的量产。
在1721年,约翰·哈德利制造出大的抛物面镜,这标志着反射镜望远镜发展的重要事件。莱昂·傅科在1857年引入了在玻璃镜面上镀银的程序,进一步提高了反射镜的性能。到了1932年,人们开始采用可以持久的渗铝涂层反射镜,使反射镜的性能更加稳定和持久。[3]
图 4抛物面镜锅
然而,在1850–1900年间,反射镜遭受了金属镜面材料的问题,这使得许多"伟大的折射望远镜"得以诞生,口径从60公分到1米的折射望远镜,例如叶凯士天文台在1897年建造的。但从1900年代初期开始,一系列口径越来越大的,以玻璃做为镜面的反射镜陆续建造出来,包括威尔逊山的60英寸、100英寸(2.5米)的虎克望远镜(1917年),和200英寸的海尔望远镜(1948年)。基本上,从1900年以来所有主要的研究望远镜一直都是反射望远镜。[4]
图 5虎克望远镜
在1975–1985年代,一些4米级(160英寸)的望远镜在夏威夷的火山岛和智利沙漠中的高海拔地点被建造起来。在1970年代,发展出由电脑控制的经纬仪架台,和1980年代的主动光学,使新一代更巨大的望远镜诞生,从在1993年和1996年完成的两架10米的凯克望远镜,以及一些8米的望远镜,包括ESA的甚大望远镜、双子望远镜和昴星团望远镜。[5]
图 6凯克望远镜
另一方面,电波天文学的发展也对望远镜的历史产生了重要影响。在1931年,卡尔·央斯基偶然意外发现一个电波源,开启了电波望远镜(连同电波天文学)的纪元。许多类型的望远镜,从无线电到伽玛射线的广阔波长范围,都是在20世纪发展起来的。在1960年以后发展的太空望远镜,可以观测在地面上观测不到的几个波段,包括X射线和波长更长的红外线波段。
随着科技的不断进步,现代望远镜已经演变成为极其复杂和强大的天文观测工具。在性能上的飞跃主要得益于光学设计的创新、材料科学的发展,以及电子技术和计算机技术的应用。
在口径的大小上,为了捕获更多的光线以提高观测的灵敏度,现代望远镜的尺寸在不断增加。例如,位于智利的甚大望远镜(VLT)由四个8.2米的主镜组成,而正在建造中的大型望远镜,如欧洲极大望远镜(ELT),其主镜口径达到了39.3米,预示着未来地基望远镜在集光能力方面的新纪元。[6]
图 7ELT
不止于地基望远镜,在1990年4月24日由发现号航天飞机,于STS-31航次将哈勃空间望远镜成功的送入计划中的轨道。其中,地基望远镜所没有的好处:影像不受大气湍流的扰动、视宁度绝佳,且无大气散射造成的背景光,还能观测会被臭氧层吸收的紫外线。其于1990年被发射之后,成为了天文史上最重要的仪表。它成功弥补了地面观测的不足,帮助天文学家解决了许多天文学上的基本问题,使得人类对天文物理有更多的认识,直至今日,哈勃空间望远镜仍为人类提供重要科研数据。[7]在未来,中国也将使用运载火箭发射巡天空间望远镜,在功能参数上巡天号比哈勃望远镜视野范围更大一点,像素也更高一点,观测效率也更高。[8]
图 8哈勃空间空间望远镜
现代望远镜不再仅限于传统意义上的可见光学望远镜,也包括射电望远镜等。射电望远镜是一个专门的天线和无线电接收机,在射电天文学用来接收天空中从天文射电源的无线电波。射电望远镜的外形差别很大,有固定在地面的单一口径的球面射电望远镜,有能够全方位转动的类似卫星接收天线的射电望远镜,有射电望远镜阵列,还有金属杆制成的射电望远镜。[9]射电望远镜观测高能射线和深远宇宙方面有着独特的优势,使得宇宙的观测变得更加全面。比如中国FAST射电望远镜,到现在工作不到十年时间里,已经发现超900颗脉冲星。[10]
图 9射电望远镜使用的干涉原理示意图
参考文献:
具体参数:对无穷远物体成像,需要一个光学系统能满足下面技术指标:长(前透镜到像面距离)200mm,工作距离(从后透镜到像面距离)80mm,焦距(efl)50mm,速度f/4.0,视场 11.4°(±0.1rad),零渐晕,孔径光阑位于后透镜上。
要求:1.采用透射式结构,计算物镜、目镜各自的焦距fa、fb和光在两个透镜上的投射高度D1、D2。假设初始结构采用的是BK7玻璃,(要求写明计算步骤)。
根据要求设置f 4.0、视场11.4°,需要转为弧度制,约为0.198,再输入三个镜片参数
此时结果如下:
再设置镜面5为光阑面,并且将6个镜面均设置为变量:
优化,评价函数勾选删除渐晕,新增EFFL设置为50mm:
优化后结果如下:
具体参数:设计一个天文望远镜R-C系统,要求主镜口径为2160毫米,整个系统的相对孔径为1:9,系统的焦距为19440mm,主镜的曲率半径为-12960mm,次镜的曲率半径为:-5797.5mm,两镜直径的距离为4547.5mm,焦点需引出主镜之后,焦点伸出量为1250mm.
要求:用光学软件进行反射式望远镜物镜结构设计,用软件进行优化,并展示点列图,MFT曲线,及衍射圈入能量分析。
首先,根据要求设置孔径,设置2个视场,半视场角为0.1度,波长选择可见光,再设置主镜曲率半径为-12960mm,次镜的曲率半径为:-5797.5mm,再设置两镜直径的距离为4547.5mm。
此时结果如下:
下一步新增空气面并移除遮挡:
此时结果如下:
下一步需要完成光学系统的优化:
设置两镜圆锥系数均为变量而非定值,再使用默认评价函数设置PTV和主光线,再将EFFL设置为焦距19440,设置CTGT(焦点伸长量)为1250,最后运行优化,最后结果如下:
观前提醒:笔者非医学生,非专业学习图像处理,如有任何表述不明,有失偏驳,请在评论区提出意见。
现如今,大众越来越重视个人健康或者运动,在此基础上国内各种可穿戴设备也发展飞速,小米手环、华为Watch、OPPOwatch等设备在国内外广受好评,各种手环/手表最基础的身体健康监测使用PPG传感器(Photoplethysmography 光电容积脉搏波描迹法),体现心率同时进行健康评测(例如心脏早搏,房颤等等,PPG并非心电图,所反应心脏信息有限,一般是各种厂商联合医疗研究机构使用AI进行判断,例如华为心脏健康研究,OPPO心脏健康研究),以及通过相关算法完成各种多维数据(体能等)的测算。
在文章开始前,我们需要先知道PPG实现原理,想必大家小学都知道,心脏跳动是将血液泵送至全身,底层原理类似于老中医把脉,通过脉搏来获取心脏跳动。但是可穿戴设备无法像老中医一样自行寻找到脉搏明显起伏的地方,也不可能像血压计一样通过充气紧紧束缚手腕从而获取心脏跳动(PS:事实上早已有了充气测血压的可穿戴设备,但其主要作用是为亚健康人群提供随时可用的血压计,且作为可穿戴设备舒适性不够)。
随着每个心跳周期,心脏将血液传送到身体周边。虽然这个脉膊压到达皮肤时有所衰减,但此脉膊压足以使动脉和小动脉在皮下组织中扩张。如果脉搏血氧仪没有压迫皮肤,脉膊压的第二波峰可以在静脉丛中看到。
使用发光二极管的光线照射皮肤,并用光电二极管测量光透射或反射到的光量,就可以得到一张表示脉冲压引起的体积变化的图表。因为流向皮肤的血液可以被多种其他生理系统调节,PPG也可以用来监测呼吸、血容量不足及其他循环状况。另外,PPG波形的形状会随着受试者的不同而不同,同时也与脉搏血氧仪所放置的位置和方式而有所不同。[1]
如果你买过智能手环与智能手表设备那么你可能有这样的问题,大晚上的睡觉翻身可能会有一束绿光从手腕闪入眼睛,这就是你的手环/手表心率传感器在工作,但是你可能会疑惑这个绿光是干什么的,为什么非得用绿光,这个问题我们先按下不表。你可能知道血液呈现红色,因此对于红光反射更强,实际上最初PPG传感器做出来使用的红光,而不是现在随处可见的绿光PPG。首先,让我们欣赏一首古诗,看看古人如何评价气色好的人:《诗经·卫风·硕人》中的“颜如花荣,目如秋水 ”这里的“花荣”指的是花朵盛开的样子,用来形容面色红润,从古诗出发你能够注意到人类好气色都是会偏向红润的,你在仔细观察一下你的皮肤,可能会有一点泛红,虽然不明显,但是即使是黑人皮肤也是红黑而不是纯黑色。这样就好解释为什么不用红光了,红光会受皮肤吸收,从而导致传感器获取到的信号较弱或失真,不适合进行心率测算。(PS:这里补充说明,红光仅仅不用于心率测算,但是有着其他的用途,比如说与红外光组合加上光电传感器能够测得血氧,本文不涉及因此不过多赘述,详情可查看:智能手环测量血氧是用的什么原理,是否准确?)
这里我用一篇我认为解释的很浅显易懂的图来描述:
同样的光强的绿光,射到大杯和小杯红色的水里,由于红色的水对于绿色吸收率高,水量不一样反射回去的光强差别较大。
而同样光强的红光,射到大杯和小杯红色的水里,由于红色的水对于红色吸收率低,水量不一样反射回去的光强差别较小。
现在我们想象血管就是上面的水,随着心脏搏动,水量变多变少。
如果入射光是绿光,心脏搏动导致的反射光变化较大;
如果入射光是红光,心脏搏动导致的反射光变化较小。
换句话说,用绿光得到的信号会比用红光得到的信号变化幅度要大。[2]
在上述图示中我们可以很简单的理解到心率传感器使用绿光的原因,接下来,我们再来了解一下心跳规律。
心脏一次规则的跳动可以用以下心电图表示:
如果你体检时做心电图,心电图报告正是由这一个一个单位图示波形组成,不过体检心电图使用的是多导联,不同导联所展示心电图信息与图示信息可能会有差异,能够反应更多的心率信息,同时,由于肌肉电信号与仪器影响,实际心电图并不会有这样规范,当然,我不是医学生,并不能做出更多解释。
心电图其实就是相当于在你身体加了个电流计,测量电流随时间的变化,实际上更为复杂,需要处理各种电信号及滤波。
至于各种波我这里不做出过多讲解,您可以参考以下图示就能理解心脏跳动规律了。
你可以看见心电图R波非常高,实际上PPG传感器就是监测这个R波,所以叫脉搏波描迹法,再用R波单位时间出现频率就可获得人体心率(以下图示由于超出图示范围在顶峰显示为平波,实际上是一个类正弦波形,同时,心电图使用单导联以及肌肉电信号干扰,并不能表示图示中的完美示例,由于电信号速度远大于血液传输速度,因此脉搏波相比心电信号有明显滞后性,值得一提的是,由此可以推算出血液传输速率,从而进行各种健康评估,比如血管健康)
在以上图示中可以很明显的看出来PPG已经能够估算出心脏跳动频率,但是实际上PPG并不能如此完美的体现出人体脉搏波动,因为毕竟是光电传感器,会受各种干扰,比如自然光,或者测试者的运动,因此需要各种滤波算法,才能较为准确的体现心率信号。
可能此时会有读者有疑问,你这篇文章不是说的rPPG吗,为什么你这里一直讲的PPG。本质上是一个东西,PPG指Photoplethysmography,rPPG则指Remote Photoplethysmography ,多了个Remote,大家都知道可穿戴设备是接触式的,在买来时APP或说明书都会告诉你如何佩戴测量心率最准确,这里的rPPG则是远程实现心率测量。
那么,远程依靠什么远程,测量什么呢?
在众多研究中,大家基本上均采用额头和面颊来测得心率数据,一方面,除了监控外,现在数码设备的摄像头一般面朝自己脸部,另一方面额头相比其他人体裸露在外部的部位能更加明显的体现人体心脏跳动,不知道你有没有这样的经历,当压力大或者心情不好时能很明显的感受到你的太阳穴脉搏跳动,这种微小的变动会影响光强大小的改变,那么我只需要获取到额头平均光强也就可以得到P波了。
在此基础上,我们可以通过人脸识别定位出人脸,从比例上再定位额头,这里使用golang opencv(这里使用Golang实现,而不使用python以及MatLAB这种专注于图像处理的编程语言及工具,起初是想做成网页端,让每个人都可以测试,同时增加样本数据,更有助于我学习并优化算法,但是考虑到隐私及成本影响因此停止实现)库实现人脸识别定位:
// 忽略前面的代码
classifierFace := gocv.NewCascadeClassifier()
defer classifierFace.Close()
if !classifierFace.Load("haar/haarcascade_frontalface_default.xml") {
log.Fatalf("加载人脸分类器文件时出错")
}
// 忽略中间处理
faces := classifierFace.DetectMultiScale(img)
if len(faces) == 0 {
continue
}
maxFace = faces[0]
for _, r := range faces {
if r.Dx()*r.Dy() > maxFace.Dx()*maxFace.Dy() {
maxFace = r
}
}
以上代码中使用了opencv haar库实现了简单且精准的haar级别库来定位人脸,并引入一个for循环来找到图像中最大的人脸,至于为什么需要引入for循环找最大人脸,是为了尽可能的排除掉非测试者走动经过摄像头拍摄区域影响。
在接下来的流程中还需要定位额头
forehead = maxFace
forehead.Min.Y = maxFace.Min.Y + maxFace.Dy()/10
forehead.Max.Y = maxFace.Min.Y + maxFace.Dy()*2/10
forehead.Min.X = maxFace.Min.X + maxFace.Dx()/2 - maxFace.Dx()/10
forehead.Max.X = maxFace.Min.X + maxFace.Dx()/2 + maxFace.Dx()/10
gocv.Rectangle(&img, forehead, color.RGBA{255, 0, 0, 0}, 1)
gocv.Rectangle(&img, maxFace, color.RGBA{0, 255, 0, 0}, 1)
以上代码中定位额头我比较简单粗暴,根据选择的人脸,计算前额的位置。这里假设前额占据人脸高度的1/10,宽度为人脸宽度的1/5,位于人脸上部中间位置。但是这样并不能直接使用,因为由程序定位的人脸会时刻发生小幅度变化,在实际测量中我们应该尽可能排除掉程序影响,因此为了方便我通过代码实现了输入“5”实现固定额头位置,不再实时监测人脸位置,再按下“5”解除释放,这里就不放出代码了,仅需一个Flag+if else就可以实现。
额头如上图红框所示。
实时人脸监测活动就像这样。
实际上,在众多研究项目及论文中均使用面颊+额头计算,但是笔者算法太菜,就不过多纠结了。
前面提到,最适合的测量心率的光线颜色是绿光,那么我们将使用RGB颜色系统中的G通道表示,也有研究中使用HSV颜色模型进行测算。
那么我们先看看额头RGB颜色系统各个分量光强随时间变化的曲线。
各个通道平均光强可使用以下示例代码实现:
greenChannel := gocv.NewMat()
gocv.ExtractChannel(img.Region(forehead), &greenChannel, 1)
greenChannelData := greenChannel.ToBytes()
for i := 0; i < len(greenChannelData); i++ {
greenChannelSum += float64(greenChannelData[i])
}
greenChannelCount = len(greenChannelData)
greenChannelAvg := greenChannelSum / float64(greenChannelCount)
blueChannel := gocv.NewMat()
gocv.ExtractChannel(img.Region(forehead), &blueChannel, 0)
blueChannelData := blueChannel.ToBytes()
blueChannelSum := 0
for i := 0; i < len(blueChannelData); i++ {
blueChannelSum += int(blueChannelData[i])
}
blueChannelAvg := float64(blueChannelSum) / float64(len(blueChannelData))
redChannel := gocv.NewMat()
gocv.ExtractChannel(img.Region(forehead), &redChannel, 2)
redChannelData := redChannel.ToBytes()
redChannelSum := 0
for i := 0; i < len(redChannelData); i++ {
redChannelSum += int(redChannelData[i])
}
redChannelAvg := float64(redChannelSum) / float64(len(redChannelData))
(注,几个比较明显的波动是由于头部活动导致)
根据以上图可以看见,红光平均光强更高,这是由于人体反射红光水平更强,而且波动幅度太大,但是蓝光平均光强更低,而且人造光源(屏幕等)通常包含部分蓝色杂光,较容易影响人体心率数据采集。
通过观察波形我们可以看见会有一些小起伏,这些起伏中就可能包含脉搏波数据。
作为对比,下面放出稳定后的摄像头识别白墙区域RGB平均光强变化波形图
前面的起伏是由于程序写好的先人脸锁定后再开始记录,可以看见波动后几乎为直线,不过由于测试时为晚上,人造光源存在部分频闪,因此会出现些微规律波动(亦或是摄像头规格限制),但不明显,就像我前面提到的,人造光蓝光较多,且人造光源存在着频闪,导致蓝光光强随时间变化波动最大。
接下来,我们要进行滤波。根据相关文献,正常成年人静息心率为50-100左右,也就是心脏每分钟跳动次数。[3]
但是在部分情况下,例如运动较多人群或者刚运动完,心率会更低或更高,因此我们需要筛选掉一些数据,我将所需BPM设定为45-240,也就是心率范围0.75-4Hz的数据,代码如下所示(结合注释查看)
var BPMMin float64 = 45 // 所需最小心率
var BPMMax float64 = 240 // 所需最大心率
func calculateBPM(data []float64, times []float64) float64 {
if len(data) < 2 {
return 0
}
timeDiff := times[len(times)-1] - times[0]
if timeDiff <= 0 {
return 0
}
samplesPerSecond := float64(len(data)) / timeDiff
// 引入带通滤波器以减少噪声
filteredData := bandPassFilter(data, samplesPerSecond)
// 应用汉宁窗以减少频谱泄漏
windowedData := make([]float64, len(filteredData))
for i, d := range filteredData {
windowedData[i] = d * 0.5 * (1 - math.Cos(2*math.Pi*float64(i)/float64(len(filteredData)-1)))
}
// 将数据转换为复数
complexData := make([]complex128, len(windowedData))
for i, d := range windowedData {
complexData[i] = complex(d, 0)
}
// 应用FFT
fftResult := fft.FFT(complexData)
// 计算每个频率点代表的实际频率(单位:Hz)
freqs := make([]float64, len(data)/2+1)
for i := range freqs {
freqs[i] = float64(i) * samplesPerSecond / float64(len(data))
}
maxMag := 0.0
maxIdx := 0
for i, c := range fftResult[:len(data)/2+1] {
mag := cmplx.Abs(c)
if freqs[i] >= BPMMin/60 && freqs[i] <= BPMMax/60 {
if mag > maxMag {
maxMag = mag
maxIdx = i
}
}
}
bpm := freqs[maxIdx] * 60 // 转换为每分钟的心跳次数
return bpm
}
func bandPassFilter(data []float64, samplesPerSecond float64) []float64 {
// 创建一个带通滤波器,将频率限制在0.75-4 Hz之间
lowFreq := BPMMin / 60.0
highFreq := BPMMax / 60.0
// 创建一个带通滤波器
filteredData := make([]float64, len(data))
for i := range data {
if i == 0 {
filteredData[i] = data[i]
continue
}
// 计算当前频率
freq := float64(i) * samplesPerSecond / float64(len(data))
// 计算带通滤波器的系数
lowPassCoef := 1 / (1 + math.Pow(freq/lowFreq, 4))
highPassCoef := 1 / (1 + math.Pow(highFreq/freq, 4))
// 应用带通滤波器
filteredData[i] = lowPassCoef * highPassCoef * data[i]
}
return filteredData
}
calculateBPM
函数接受时间序列的光强度数据,首先通过FFT转换得到频域数据。转换到频域后,信号被表示为一系列频率和对应的幅度。每一个频率成分的幅度表明了该频率在原始时域信号中的强度。在心率测量的上下文中,我们特别关注那些与心脏跳动频率相对应的频率成分。
设定搜索范围:人的正常心率大约在每分钟45次(0.75 Hz)到240次(4 Hz)之间,这对应于频率的0.75 Hz到4 Hz。FFT分析结果中,只有这个频率范围内的成分才是我们关注的目标。
寻找最大幅度的频率:在上述范围内,程序寻找幅度最大的频率点,因为最大幅度表明了信号中最显著的周期性成分,即心跳引起的周期性变化最强烈的部分。
一旦识别出心跳对应的主要频率,将这个频率乘以60(每分钟的秒数),就可以得到心率的估计值,单位是“每分钟的心跳次数(bpm)”,在实际程序设计中需要优化,我这里非常简单并没有实现采样时间限制,实际上采样时间应该至少5S以获取更为准确的心率。
大起伏为人脸活动造成的影响,小起伏可以视为心脏跳动时的P波(实际上由于算法存在太多问题,会有干扰信号),至此,此代码就告一段落了,对于滤波相关,严格意义上需要对图像进行降噪处理并进行更复杂的滤波。但是在ECG与实验结果对比情况下已经知足了,图一为瞬时心率,图二为30S平均心率,笔者睡眠不好,有窦性心律不齐,某种意义上来讲已经符合事实了。
不过在实际应用中rPPG范围太窄已经淹没于历史的洪流中,就算是现在一线厂商的PPG传感器及算法也不能做到医疗级别的监测,rPPG由于受各种环境影响,变量更多,其能反应身体健康状态信息较少,也仅限于学术研究中,不过相信这项技术在未来更高精度的摄像头发展中,这项技术将被重新使用,在未来为智能设备用户提供更准确的身体健康反馈。
引用文献:
[1] 维基百科 光体积变化描记图法
[2] 知乎 绿or红?心率监测使用哪种光比较好?
[3] 医学百科 心率正常值
参考文献:
[1] Akselrod S, Gordon D, Ubel F A, Shannon D C, Berger A C, Cohen R J. 1981. Power spectrum analysis of heart rate fluctuation:a quantitative probe of beat-to-beat cardiovascular control. Science, 213(4504): 220-222 [DOI:10.1126/science.6166045]
[2] Niu X S, Han H, Shan S G . 2020. Remote photoplethysmography-based physiological measurement: a survey. Journal of Image and Graphics, 25(11): 2321-2336. (牛雪松, 韩琥, 山世光. 2020. 基于rPPG的生理指标测量方法综述. 中国图象图形学报, 25(11): 2321-2336.) [DOI: 10.11834/jig.200341]
[3] Chen X, Cheng J, Song R C, Liu Y, Ward R, Wang Z J. 2019. Video-based heart rate measurement:recent advances and future prospects. IEEE Transactions on Instrumentation and Measurement, 68(10): 3600-3615 [DOI:10.1109/TIM.2018.2879706]
[4] De Haan, Gerard, and Arno Van Leest. "Improved motion robustness of remote-PPG by using the blood volume pulse signature." Physiological measurement 35.9 (2014): 1913.
[5] Wang, Wenjin, et al. "Algorithmic principles of remote PPG." IEEE Transactions on Biomedical Engineering 64.7 (2016): 1479-1491.
在去年的这个时候,我和Heo,轻笑共同开发了AI摘要,AI摘要一经问世饱受各网站开发者/博主/站长喜爱,在有限的数据统计中,我们发现AI摘要显著提高了站点的用户留存率,很多访客会等待AI摘要加载完再滑动页面。同时,非常有利于访客对信息进行有效筛选,而且部署方便,实用性强,网站接入非常便捷。
今天,由我和Heo共同开发的PostChat正式上线,能够轻松在你的网站接入AI,并且能够自动将你网站的内容上传到知识库,并在前端展示,使用户方便/快捷的使用AI,如果您是技术型博客站点,也能够辅助您站点访客的问题进行解答。
参考网站上方TianliGPT。
超大的文章摘要空间,可以支持上万个网页嵌入AI摘要功能,定价请参考
PostChat使用订阅制度,在用户有效期内无限额生成网站摘要,且自动上传到知识库用于搜索以及AI问答。
将网站的搜索功能接入到PostChat,体验更加精准的大模型搜索方式。
搜索基于AI索引,结合AI摘要,为用户提供摘要与标题结合的搜索方式,能够让用户更准确的搜索到需要的内容。
通过以上的对比,我们可以发现传统的模糊搜索方式,如果不包含相关关键词就无法索引,但是在AI搜索中,仍然能够精准匹配搜索结果。
PostChat采用了与AI摘要相结合的方式,让AI摘要不局限于摘要,更能够通过摘要赋能对话能力,根据您网站内容进行回答内容,使其作为您网站的专属AI助手,并且提供专属建议。
不止于此,即使你没有网站,需要对相关笔记或者文章进行知识库问答,您可以在后台自主上传文件进行向量化,然后在PostChat官网进行知识库问答,亦或是搜索,PostChat将生成独立页面进行展示。
除此之外,我们还为大家开放了Prompt编写能力,让你的AI更懂你,更符合您的生产需求。
预设参考PostChat主页,需要包含两个参数方可确认修改:
{{question}}
:即用户提出的第一个问题,PostChat将会把用户提出来的第一个问题植入此处,再回传至AI。
{{answer}}
:即根据用户提出的问题,PostChat根据相关算法召回出来的可能的衔接上下文内容,用于辅助AI回答。
为大家提供了常规AI对话能力,日常使用中一些简单的代码或者生活疑问都可以询问AI,AI使用了多种大模型进行负载均衡保证速度和稳定性。
您可以参考https://postchat.zhheo.com 官方文档进行代码安装。
AI提供了相关交互能力,因此您在备案期间建议关闭PostChat。
PostChat使用AI赋能,可能产生错误的信息,请您注意核实。
还有更多的使用方法,待您发掘。
您也可以通过此链接进行注册https://ai.tianli0.top/?InviteID=8NQ710QE
通过此链接注册成功后被邀请用户从未开通过会员,使用邀请链接登录即可绑定。被邀请用户在注册一年内每次开通会员,均可获得额外的会员时长奖励。
被邀请用户开通1年,双方获得31日奖励。被邀请用户开通1个月,双方获得7天奖励。
最失败的一年:
得到了些什么
做错了些什么
失去了些什么
还是没有找到职业/未来方向,迫于学历与能力,不想从事专业相关,迷茫于方向。
人生中第一次坐飞机
拿到驾照
吃了罚单
挂了科
服务器运营成本越来越高,不得不降本增效。
被网络攻击让我手足无措,但是没想到以前做的公益项目让很多用过的用户帮我回血(很感谢大家)。
和志趣相投的网友一起写了人生第一个盈利项目,虽然我很菜,bug很多,但是当自己写的东西被很多开发者使用的时候内心还是非常高兴的。
放弃一些东西/事情/想法。
反思
暑假因为家人常住医院,为了一些事情不得不两城跑,在医院写代码。
为了家人不得不通宵几天。 没有时间和高中舍友聚会。
独立写项目。
找到了几个一起打游戏的朋友。
参加了几个大厂的开发者大会(感觉这几年各种开发者大会的主要基调就是AI。)
申请了人生第一个软件著作权。
申请了人生第一个发明专利。
尝试和校友起一个新项目。
对于一些问题有自己的想法,不再像以前一样,跟风。
逃避现实。
越来越喜欢听老歌。
懒
域名被江苏反诈中心制裁,想尽办法申诉。
域名解封。
想法远大,然而没有能力实现。
越来越缺乏独立思考。
网站很少更新。
年度关键词: 废,寝,忘,食
2024就二十了,没有别的想法,只想自己早点找到方向。
验证节点:
江苏省公益反诈拦截很迷惑,不知道具体的触发条件,正规运营的站点(即使你有ICP备案号以及网安备案号)也有可能被拦截,至于申诉,在经历了一些波折后只能说拨打025-66096110按照提示提交相关信息即可。在提交当天相关部门就会联系你让你提交域名地址,如果没有问题会两天内解封。
注:网警哥哥声音真好听
优雅的暗色主题
VSC图标补全
CSV高亮插件
代码缩进高亮,更方便的展示缩进
HTML标签高亮
日志输出高亮
Github的AI,能够辅助编码,在遇到步骤繁琐但逻辑简单的部分时非常的方便,基本上能猜到你想干什么。但是不建议初学者使用,过多的辅助只会减少对于语言的熟悉程度(不得不说对于Go的err处理机制这AI太方便了)
格式化JSON
YAML语言支持,适用于.yml .yaml文件
VSC的WSL支持,让你在WSL使用vsc更方便
时间管理大师(雾) 记录编码时间,编码行数等,本地存储
展示正则表达式匹配项
Hex编辑器
Git可视化插件,功能太多了,受限于篇幅,这里不过多赘述,具体请参考官方文档
gitignore模板,可以迅速的添加gitignore模板
自动重命名HTML标签
多语言支持的代码片段运行插件
单片机等设备开发集成环境
多种编码格式转换插件
Excel文件的查看支持
Github Actions 支持,支持管理及runs log查看
规范化commit格式的可视化插件
集成edge,使前端开发更加方便
上面仅展示了我所使用的一部分插件,还有不少插件是根据开发语言需要自行配置的,包括语言支持,格式化,数据库等插件。
希望以上内容能帮助到你。