
实现
文章平均质量分 53
bluesen
C/C++,通讯软件开发,图像识别和图像处理,大规模数据处理
展开
-
机器学习:钻石鉴定
准确区分天然钻石和培育钻石,在珠宝行业成了迫切的需求。最近为客户做了个机器学习算法来区分钻石的光谱。钻石判定本质上是个分类问题,可以有多个分类,如天然钻、尼莫石、培育之CVD、培育之HPHT(高温高压)等。分类问题很适合用机器学习的方法解决。我训练出来的模型,效果很不错,准确率很高,而且很具通用性。原创 2022-12-27 17:53:23 · 365 阅读 · 0 评论 -
串口隔离内外网的通信协议设计
市面上有很多USB转RS232串口的转接线,可以买一跟公头、一根母头,分别插在两台电脑的USB或Type-C口上,系统通常会自动安装驱动,映射为一个COM口。但实际的应用又需要访问内网的某些服务,怎么办呢?最后一点意味着,串口通可能偶尔不可靠,不能把它当成类似TCP那样的可靠连接,但也不能把它当成UDP那样的独立数据包进行处理。tcp连接句柄号,即socket的整数转换为数字字符串,后续数据都是这个连接的数据,直到新的协议头。2、服务端收到后,创建和目标地址的连接,程序将此连接和对端连接11进行关联;原创 2022-09-30 10:54:08 · 2035 阅读 · 0 评论 -
安卓手机检测水表的帧率问题
虽然可以,也不是那么容易。第一个是需要找到合适的手机,从成本的角度,如果大量部署不能太贵,所幸检测用的手机并不需要很多高级功能,比如不需要5G——甚至4G也不需要,只需要自带的WiFi在局域网内和控制机通信即可。通常手机相机的帧率是30fps,根据香农采样定律,帧率实际上决定了对旋转仪表的分辨率,如果水表的流速较快,30帧率是不足以分辨的,会带来误差。我们基于安卓手机做的水表检测有多种模式,在固定的时间内进行检测,一种模式是检测红色指针的旋转角度(圈数),另一种模式是检测黑色梅花轮转过的齿数。...原创 2022-07-26 11:53:06 · 497 阅读 · 0 评论 -
Android OpenCV竖屏处理策略和底层代码修改
在Android上做机器视觉,不可避免地都会用到OpenCV for Android库,视频流的捕获和预览通常使用 JavaCamera2View 控件,但这个控件在横屏下运作良好,竖屏下问题很多。本文用最小代价解决了这个问题,并给出了关键源代码。...原创 2022-07-01 10:10:05 · 694 阅读 · 1 评论 -
纯属好玩:我做的“截图续弈”
在线下棋有一个常见的苦恼,局势紧张的时候算不清楚,如果能摆一下变化就好了。我做的这个软件就是为了解决这个苦恼,可以将正在进行的对局截图,然后进行试下。原创 2022-02-22 15:36:12 · 250 阅读 · 0 评论 -
精确射箭识别:环数和坐标
需求背景:射箭馆射出一支箭,如果人工报靶,危险、繁琐而且人力成本高。人一直盯着靶子,会眼睛疲劳,靶面上出现十多支密集的箭时,眼花缭乱也弄不清那支是新射入的了。因此,考虑完全使用摄像头程序方式完成,摄像头对准靶面,当有箭射入时,准确判断第几环。靶面图片:射入一支箭:射入多支箭:解决之道:使用OpenCV。首先将图像二值化,搜索出一个个环的边界,并转换成极坐标:上面准确地定位环,为了便于调试和观察将之用彩色点进行了标识。射箭的识别,需要对前后两张图像相减然原创 2021-07-03 20:31:18 · 5939 阅读 · 11 评论 -
高精度定时器在windows10下失效及其解决方法
很多地方要用到高精度定时器,比如实时通信、多媒体处理、游戏开发等。我开发的软交换系统中,多媒体处理要用到高精度的定时器,在windows下常见的做法是:先设置定时器精度为1毫秒:timeBeginPeriod(1);这步很关键,否则定时器的精度很低,大概只有15.6毫秒,基本不能用。然后使用这样一组函数:CreateTimerQueue();CreateTimerQueueTimer(&t, timer,(WAITORTIMERCALLBACK)OneMilliSeco.原创 2021-04-02 18:03:08 · 5419 阅读 · 0 评论 -
从曲线图片恢复数据
很多应用是将传感器采集的数据绘制成曲线,如随时间变化的电流、电压或者功率。目前有个应用反过来,有数百张存放在pdf文档上的曲线截图,这些历史图片缺失了原始数据,需要根据分辨率很低的图片将数据恢复过来。这类应用通常是AI大数据分析的前端,恢复效果直接影响数据的质量。原始图片:以上图为例,是一幅功率图,由2条不同颜色的曲线组成,红色表示实际值和青色表示平均值。横坐标是时间轴,0-7.25秒,纵坐标表示功率,最大功率1800瓦。恢复数据的难点:1、两种颜色的曲线有叠加的地方,分离不容易;2、背景原创 2020-12-20 12:16:27 · 1708 阅读 · 3 评论 -
Linux下gettimeofday()的问题
windows下有GetTickCount()和GetTickCount64()函数,返回的是毫秒tick,通常用来计算两个时间差。我在Linux下封装了一个同名的函数:unsigned long long GetTickCount64(){ timeval ts; gettimeofday(&ts,0); return(ts.tv_sec * 1000 + ts.tv_usec / 1000);}使用起来很简单:uint64_t t1 = GetTickCount6原创 2020-08-10 10:13:15 · 1303 阅读 · 0 评论 -
画面中定位汉字串的外轮廓
我们做的项目需要匹配两张图片,比如机顶盒输出的视频,设置的菜单画面有很多汉字,并不需要认出这些汉字,通过标注汉字串的轮廓,对比两张图片的轮廓位置和大小,就可以判断画面相似度,进而判断当前处于哪个菜单。那么,如何定位这些汉字串的轮廓呢?请看原图:最容易想到的方法是先使用opencv的findContours()函数找出所有的轮廓,然后再对每个轮廓去找矩形----使用的是boundingRect()函数。但这样找出来的矩形并不能完全覆盖汉字字符串的外部,只能在比较方正的汉字中定位到少数几个矩形框原创 2020-06-01 20:17:15 · 356 阅读 · 0 评论 -
大规模sip信令存储、查询和实时跟踪的实现
15年前运营商的核心网还是七号信令(SS7),那时候的信令采集、监控和检测系统还很落后,基本上就是给交换部门一个实时跟踪呼叫的工具,如果需要查询历史信令,很麻烦,需要倒库,查询速度超慢。当时一个朋友想挖掘呼叫的数据,于是我在本地网已经收敛好的信令上,做了一个信令采集、存储和快速检索系统,性能远超当时的中创信测系统,颇得运营商搞交换的弟兄好评。现在的IMS核心网已经是SIP了,如果重新设计一个类似的系统,可能吗?信令采集系统需要采集全部的信令消息,其特点是数据很大,除了呼叫相关的信令消息还有注册消息,堪称原创 2020-05-10 15:23:01 · 1359 阅读 · 0 评论 -
如何实现单机大规模并发SIP语音呼叫?
锁定目标:单机5千多大叫大,1千还是1万?好吧,暂定为5000或以上。带宽不够?千兆网。硬盘太慢?SSD。本文不考虑IO的限制,只讨论结构和模式。开源世界Voip领域最响亮的牌子应该是FreeSwitch,使用者众多,它能实现如此大规模的单机并发吗?我认为:不行。为什么不行?因为它线程太多,一个通道一个线程,上5000个线程,玩不转:“CPU忙着切换线程上下文了,哪有时间干正事”(...原创 2020-03-11 16:55:13 · 1281 阅读 · 0 评论 -
程序员如何辅导儿子做数学?
靠山吃山,当然是借助编程了。我家的孩子上小学三年级,比较喜欢数学,课外在深圳上学而思的创新预备班。去年寒假开始我教他学习C语言编程,每天1个小时左右,说是教,其实大部分时间是他自己看大部头的《C Primer Plus》,也算是半自学。每天在我给他的旧13寸MacBook Pro上用VS Code敲入书上的代码,或者自己改写,然后在Mac的终端下gcc编译,测试,倒也自得其乐。也许有人会问...原创 2020-02-20 14:48:26 · 575 阅读 · 0 评论 -
GSM音频编码的优化和写入wav文件
GSM是voip中较为常见的一种编码,压缩率比很高,写到wav文件每秒只占用1.6k字节(接近于g729),是普通g711格式的五分之一,对录音来说可节省大量磁盘空间。生成的wav文件,可能是不牵涉到专利的原因,在各种操作系统下都能够播放。1、使用IPP的codecGSM的编解码通常使用开源C代码,入口文件是gsm_encode.c和gsm_decode.c,能用,但不够优化。我使用I...原创 2019-12-24 14:33:10 · 1851 阅读 · 0 评论 -
录音程序移植到Linux心得
我曾经写过一篇文章“如何实现一个voip录音系统”,后来还描述了持续改进的思路,但该程序只支持64位windows环境,现在很多主流的软交换--如常见的Asterisk、vos等--都运行在linux下,移植到Linux很有必要,很多情况下可以不用交换机镜像就进行录音。程序是使用C/C++开发的,语言层面的移植是相对容易的,毕竟C/C++是通用编程语言,而且C++11以后的多线程库等在多个平台...原创 2019-11-25 11:22:44 · 312 阅读 · 0 评论 -
使用ipp静态库,ipp-samples在linux下的make过程
折腾了两天终于搞定,现在把折腾的过程记录一下。1、先安装ipp8,运行install.sh进行安装,安装过程选择评估版,因为我们也只是需要它的库,使用并不影响。2、安装cpp_studio_xe_2013_sp1_update2,和1一样,运行install.sh,比较简单。----我现在怀疑第1步可以省略,因为intel的cpp studio xe里面实际上包含了ipp的头文件和库,...原创 2019-11-21 15:46:40 · 1305 阅读 · 0 评论 -
移植C/C++到嵌入式Linux下程序崩溃的问题
最近将自己开发的SIP协议栈移植到ARM芯片下的嵌入式Linux,遇到一个奇怪问题,这篇小文简要记录解决过程。相同的代码在windows下、CentOS Linux下都正常,交叉编译到ARM芯片的64位Linux下总是崩溃,估计堆栈、内存被破坏,用Valgrind没办法定位到具体的出错位置。经过多次用最原始的printf()跟踪,发现和md5加密函数有关,筛查了代码死活也没发现错误。如此折腾了...原创 2019-08-06 16:28:33 · 619 阅读 · 0 评论 -
无锁:高性能录音系统根本性改进
当并发呼叫增加到1千以上(交换机端口镜像过来的流量达150M),含多种语音编码时(如g711A、U和g729等),录音系统性能出现下降,如丢录音,丢包,卡顿甚至崩溃等情况。经过彻底改进和优化,录音系统运行非常顺畅,可以长时间稳定运行而不会丢失任何数据。下面记录一下改进的关键部分。1、抓包改进抓包库使用的pcap_开头的函数,有很多可优化的地方,如设置缓冲区大小,读包延时(最好就不要...原创 2018-09-19 11:33:22 · 504 阅读 · 1 评论 -
eyeBeam采用TCP传输的一个BUG
最近在给自己开发的SIP协议栈增加了TCP传输,需要找其他SIP客户端测试。免费的xlite版本只能使用UDP,但专业版eyeBeam可以指定UDP、TCP或TLS。不知道eyeBeam使用的什么SIP协议栈,TCP存在下面的问题:由eyeBeam发起呼叫,Invite是用TCP传输的,对端顺着这个连接回100,180,200,这时候eyeBeam应该在这个同样的TCP连接上发送ACK原创 2012-04-13 23:03:09 · 2491 阅读 · 0 评论 -
如何对Intel IPP库进行静态链接
在多媒体codec方面,IPP库公认是高性能的库,而且价格也不贵,对发布也没什么限制。我们的客户强烈需要G729的codec,最近我尝试使用IPP库,效果确实不错。不过最新IPP(v7.1)的全部运行时动态库多达85个,225M,如果每次发布都要带这么多dll,就算带来所谓的自动识别CPU并进行优化的好处,也太麻烦了。静态方式连接后的程序只是多了不到2M,是比较好的发布方式。可要顺利配置并原创 2012-09-17 11:04:10 · 5293 阅读 · 2 评论 -
多进程互斥对象排队
写了个操作硬件端口的程序,会被5个进程调用,但硬件端口在同一时刻只能被一个进程独占调用。最简单的方法是通过操作系统提供的互斥对象: // 获取互斥标志int WaitProcessIdle(){ while(1){ _processHd = CreateMutex(NULL, false, "LxjOpPort"); if( _processH原创 2013-04-21 20:46:22 · 2370 阅读 · 0 评论 -
使用线程间通信之条件变量
最近用C++写安卓下的一个通讯程序,作为jni库给java调用,采用多线程轮询遇到一个问题描述如下:A线程收到数据,放入队列,是生产者。B、C、D若干个线轮询训消息队列,如果队列有数据就取出进行处理,没数据就Sleep(T)休息,问题是这个T值取多大合适?取大了消息处理不及时,取小了手机cpu上升电池很快耗光。这个问题最佳解法是采用条件变量,可以比较完美解决问题原创 2014-09-29 21:31:38 · 3175 阅读 · 1 评论 -
我实现的内存数据库JDBC驱动
我去年做了个内存数据库,自以为功能很强大。内存数据库是独立运行的程序,客户端通过socket访问,传送SQL语句并得到结果,为此我提供了一个C接口的客户端API。但如果要做到更好的通用性,必须照顾IT世界数量最多的两类人:java程序员和c#程序员。c#我的同事封装了ado.net驱动。这几天我实现了jdbc的驱动,本文记录实现过程的一些心得。原创 2015-05-08 17:41:48 · 1811 阅读 · 0 评论 -
如何实现一个voip录音系统
如何实现一个高效率的voip录音系统?采用了无锁缓冲区--环形队列。sip消息处理和rtp包处理采用独创的写锁和读锁。原创 2015-07-18 11:27:51 · 7524 阅读 · 3 评论 -
跨平台、高性能的媒体转发服务器实现
最近实现了一个媒体转发服务器,代码可以编译成windows(64位或32位,可以编译为service),Linux,Mac OS X等多种平台。sip客户端一般是躲在内网,要跨nat如果采用stun一类的技术,除了客户端麻烦外,需要部署stun服务器,而且不能解决所有类型的nat,最佳解决方案是部署一个支持媒体转发的全代理服务器,运营商的IMS网络,在网络边缘部署的SBC--会话边界控制器--原创 2016-01-23 17:54:57 · 3309 阅读 · 2 评论 -
C++动态配置的实现
先说一下需求,是在做录音系统中遇到的:录音文件名需要生成唯一的字符串,这个串一般由主叫号码、被叫号码、日期、时间等加上下划线作为分隔符组成,但出于兼容性考虑,某些用户希望能按他们自己的顺序来构成文件名。除了文件名,录音文件存放路径也需要动态的配置,比如:基础路径/日期/或:基础路径/被叫号码/日期/我的解决方案是设计这样的配置文件:// 配置项的值可使用变量原创 2016-11-12 23:04:25 · 1693 阅读 · 0 评论 -
在C++Builder6中使用DCEF3嵌入谷歌内核浏览器
历史原因,我有个客户端程序是使用BCB6写的,里面使用了CppWebBrowser控件,众所周知,这个控件使用的是IE内核,对HTML5的兼容性太差,面临很多问题,有些问题甚至即使改注册表将内核版本强制使用为IE11也解决不了。于是寻找Chrome内核的嵌入使用。一开始走了不少弯路,想直接使用CEF的C++接口,发现很困难。再后来发现有人将这个框架封装成了Delphi控件,于是拿来一用,当然这原创 2016-12-19 18:28:09 · 4366 阅读 · 7 评论 -
关于Linux下的高精度定时器
操作系统的默认定时器的精度是很低的,比如在windows下调用Sleep(20)延时20毫秒,实际上80毫秒都可能。做媒体服务器,免不了需要高精度的定时器,比如语音会议,需要很精确地每20毫秒进行一次混音并通过rtp发送。我们的媒体库原来只在windows下实现,使用了windows写的高性能定时器的一组函数:CreateTimerQueue()CreateTi原创 2017-03-20 10:16:01 · 3074 阅读 · 0 评论 -
IP录音增加对H248即MEGACO协议的支持
传统的媒体网关设备的控制协议是基于H248即MEGACO协议,这个协议和SIP协议不一样。而且,H248的底层传输协议一般采用SCTP协议。这给IP录音软件开发带来了挑战。实现思路:1、最大限度兼容原有录音系统结构,使用原有的SIP机制;MEGACO消息中的Context值相当于SIP消息中的Call-ID头域。2、抓包过滤除udp,tcp外增加sctp,并剔除掉16个字节原创 2017-04-18 12:14:08 · 1223 阅读 · 0 评论 -
使用谷歌浏览器内核控件DCEF3拦截弹出的新页面到新标签页
DCEF3控件TChromium有个事件OnBeforePopup,我们可以在这个事件函数里加上自己的逻辑,最后一个参数是返回参数bool &Result,置为true表示自己来处理,置为false表示使用默认行为,即弹出一个新的窗口。对于构造多标签页浏览器,我们的应用逻辑是在事件处理函数中取得url参数,重新new一个TChromium放置在新标签页,但这样做有问题,总是卡住然后崩溃原创 2017-05-20 15:03:53 · 3171 阅读 · 0 评论 -
SIP服务器提供REST格式的API并新增分段录音
底层的API要用较为复杂的状态机,开发起来有一定难度。REST即Http+Json方式,相对容易集成。新增分段录音,即在录音时进行VAD(活动语音检测),检测到开始说话,上报一个消息,说话中检测到足够长的停顿,再上报一个消息,并另起一个新录音文件。分段录音应用于智能交互(AI),侦听到说话可打断正在进行的放音,侦听到停顿,可开始对该段语音进行识别。简易的REST接口如下(可进一步扩展,如增加桥接、...原创 2018-04-08 16:54:24 · 926 阅读 · 3 评论 -
更聪明的电话语音机器人
有人说AI应用最重要的是工程实现,而不仅仅是算法,诚哉斯言。电话语音机器人目前应用最多的是电话营销,我接过几个这样的电话,挺傻的,基本听不懂人话。我也见过一些所谓的电话机器人界面,配置十分复杂,每个关键字要配置一个节点,存储到数据库,运行的时候关键字匹配,需要在数据库里做上百个sql查询,查来查去,效率极低不说,灵活性反而大受限制。我实现的电话语音机器人,就是解决上述两个根本性问题,而且接口十分简...原创 2018-07-14 12:37:22 · 842 阅读 · 0 评论 -
编程两得
1、dll导出函数,不可用stdcall:最近写了个Dll,同时编译了64位和32位版本,64位一切正常,32位版本有问题。调用程序使用动态加载方法,GetProcAddress()定位函数地址总是返回NULL。后来发现导出函数名不应该使用_stdcall描述。错误:extern "C" __declspec(dllexport) int _stdcall ServerFun1(...);...原创 2018-07-22 17:34:18 · 303 阅读 · 0 评论 -
改进后的电话语音机器人
拙文“更聪明的电话语音机器人”解决了电话语音机器人的两个痛点,即模糊识别和关键词配置,但从实际的效果看,关键词(词槽)配置还是简单了一些,实际应用需要将词槽串接起来。经过改进后的例子如下:cfg = """ { "init":{"voc/welcome1.wav","voc/welcome2.wav",}, "keys":{ {{"额度","原创 2018-08-06 16:12:26 · 391 阅读 · 0 评论 -
实现了一个Full Proxy SIP服务器
简单的完成SIP客户端注册和消息转发到服务器,媒体流不必关心,由客户端之间直接rtp,这类服务器较容易实现,收费的产品如mixiSipServer(老外开发的,较为常见),我写的免费LxjSipServer(没有路数限制,无需安装,没有广告,在这里可以免费下载:http://ww原创 2011-09-22 11:29:34 · 2386 阅读 · 3 评论