Jack Huang's Blog


  • 首页

  • 标签

  • 归档

  • 搜索

HSV转RGB的效率问题探讨

发表于 2024-10-12

最近朋友遇到一个技术难题,我也没相关经验,只能记录以下,方便以后解决。

问题描述

朋友想高效地在一块嵌入式的板子上实现 640*480 HSV格式的图片转换成 RGB格式的图片,要求处理时延不能超过20ms。

解决方案

朋友试了很多中解决方案,包括:

  • 使用OpenCV的cvtColor函数,性能太差,可能是嵌入式板子的CPU处理器性能差的原因。
  • 使用OpenGL进行图像格式转换,性能还是不够。
  • 采用GPU加速图像处理,性能还是不够,GPU可能能够快速处理图像,但是图像数据在CPU和GPU之间的数据搬运也很耗时。
  • 使用OpenGL帧缓存双缓冲,性能还是不够

最后建议优化HSV转RGB格式的算法,提高CPU执行效率。

参考链接

  1. 数字图像处理——RGB与HSV图像互相转换原理,by 萌萌哒程序猴.
  2. OpenGL帧缓存,by 先锋小牛.
  3. OpenCV 自学笔记21. RGB色彩空间和HSV色彩空间的理解,by 两鬓已不能斑白.
  4. opencv中使用cuda加速图像处理,by 我是一个对称矩阵.

多传感器多目标跟踪方法研究学习笔记

发表于 2024-09-28

最近遇到一个问题,需要将多传感器多目标跟踪获得的航迹进行关联,因此学习研究一下。

关键技术

分布式多传感器多目标跟踪涉及的目标跟踪、传感器配准、航迹关联、数据融合4项关键技术。

目标跟踪

目标跟踪是指利用传感器获得的带噪声量测数据,对目标的状态和个数进行估计的过程。

目标跟踪按目标探测个数可分为单目标跟踪和多目标跟踪,通常它们都基于贝叶斯框架进行递归滤波。

单目标跟踪

多目标跟踪

传感器配准

在分布式多传感器多目标跟踪过程中,需要把来自多个传感器的数据转换到相同的时空参照系中。由于不同传感器传输速率及采样周期不同,而且存在传感器系统偏差和量测误差,直接进行转换会降低数据融合精度,因此在对多传感器数据处理时需要进行传感器时空配准。

时间配准

时间配准就是将各传感器对同一目标的异步量测信息配准到同一时刻。

空间配准

空间配准是利用多传感器对空间公共目标的探测信息对传感器的系统偏差进行估计和补偿的过程,它可以提高信息融合精度。

航迹关联

由于传感器间的探测区域存在重叠,来自不同系统的航迹可能代表同一目标。因此,如何找出同一目标对应的航迹就是分布式数据融合系统中的航迹关联问题。

航迹关联算法主要分为两类,一类是基于统计类的方法,一类是基于模糊数学的方法。

数据融合

分布式多传感器多目标跟踪又称分布式多传感器数据融合。在该系统中,各局部传感器首先基于单传感器多目标跟踪算法,形成各自目标航迹,
接着各传感器将目标航迹送入融合中心完成时空配准与航迹关联,然后融合中心基于某种融合准则对来自同一目标的航迹进行估计融合,最终形成稳定、
高精度的全局航迹。

参考链接

  1. 分布式多传感器多目标跟踪方法综述,by 曾雅俊, 王俊, 魏少明, 等.

HTML视频点击自动最大化播放技术学习

发表于 2024-09-23 | 更新于 2024-09-25

最近遇到一个小需求,就是在网页前端实现点击视频播放的同时,实现视频最大化,简单学习一下。

技术原理

网页前端实现点击视频播放的同时,实现视频最大化的技术原理如下:

  • 捕捉点击视频播放的事件,在该事件中执行视频最大化方法

技术实现

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
<!doctype html>
<html>
<head>
<meta http-equiv=Content-Type content="text/html; charset=utf-8">
<title>视频技术测试</title>
<style>
html, body {
width: 100%;
height: 100%;
margin: 0;
padding:0;
}

#max{
margin: 5% auto;
width: 600px;
}
</style>
</head>

<body>
<div id="max">
<video id="media" controls width="600">
<source src="./media/cc0-videos/flower.webm" type="video/webm" />

<source src="./media/cc0-videos/flower.mp4" type="video/mp4" />

Download the
<a href="./media/cc0-videos/flower.webm">WEBM</a>
or
<a href="./media/cc0-videos/flower.mp4">MP4</a>
video.
</video>
</div>
</body>

<script>
const video = document.querySelector("#media");

video.addEventListener("play", (event) => {
video.requestFullscreen();
});

</script>

</html>

参考链接

  1. 深入理解HTML5视频标签:掌握全方位的播放控制和交互技巧,by 未闻花名_review.

HTML图片自动轮播技术学习

发表于 2024-09-23 | 更新于 2024-09-25

最近遇到一个小需求,就是在网页前端实现图片自动轮播,简单学习一下。

技术原理

网页前端实现图片自动轮播的技巧如下:

  • 图片所在容器元素采用绝对定位,从而实现所有图片叠加到一块。
  • 通过CSS实现左右箭头
  • 通过js调整图片所在容器的透明度,从而实现图片的轮播。同时调整播放顺序按钮的背景色,从而实现顺序指示的功能。

技术实现

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
<!DOCTYPE html>
<html>

<head>
<meta http-equiv=Content-Type content="text/html; charset=utf-8">
<title>图片轮播技术测试</title>
<style>
html,
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}

#max {
width: 900px;
margin: 0 auto;
margin-top: 0%;
}

.re {
position: relative;
}

.arrow {
height: 20px;
width: 20px;
border: solid #333;
border-width: 0 4px 4px 0;
display: inline-block;
padding: 3px;
}

.left {
transform: rotate(135deg);
cursor: pointer;
margin-top: 240px;
margin-left: 20px;
float: left;
}

.right {
transform: rotate(-45deg);
cursor: pointer;
margin-top: 240px;
margin-right: 10px;
float: right;
}

.re ul {
list-style-type: none;
padding: 0;
margin: 0;
}

.re ul>li {
position: absolute;
transition: 2s;
opacity: 0;
}

.re ul>li img {
width: 900px;
height: 500px;
border-radius: 1%;
border: 5px solid #fffbd6;
}

#max ol {
position: relative;
display: grid;
grid-template-columns: repeat(5, 75px);
grid-template-rows: auto;
grid-gap: 1em;
gap: 1em;
float: right;
margin-top: 450px;
list-style: none;
top: 0;
left: 0;
}

#max ol li {
width: 20px;
height: 20px;
font-size: 15px;
line-height: 20px;
float: left;
text-align: center;
border-radius: 2em;
border: 5px solid #999999;
}
</style>
</head>

<body>
<div id="max">
<div class="re" onmouseover="mouseover()" onmouseout="mouseout()">
<ul>
<li><img src="./pic/big_size/p1.jpg" alt=""></li>
<li><img src="./pic/big_size/p2.jpg" alt=""></li>
<li><img src="./pic/big_size/p3.jpg" alt=""></li>
<li><img src="./pic/big_size/p4.jpg" alt=""></li>
<li><img src="./pic/big_size/p5.jpg" alt=""></li>
</ul>
<div class="arrow left" onClick="prev()"></div>
<div class="arrow right" onClick="next()"></div>
<ol>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ol>
</div>
</div>
</body>

<script>
function fun(i, j) {//转换图片函数,就是把透明度改了一下
lik[i].style.opacity = 1;
lik[j].style.opacity = 0;
lik[i + 5].style.backgroundColor = "#ffffff";//改一下小图标
lik[j + 5].style.backgroundColor = "#00000000"
}

function auto() {//轮播循环函数
if (++i >= 5) {
i = 0;
fun(0, 4);
}
else fun(i, i - 1);
}

function mouseover(){
console.log('clear timer!');
clearInterval(timer);
}

function mouseout(){
console.log('set timer!');
timer = setInterval(auto, transition); //调用定时器
}

function prev(){
if (--i < 0) {
i = 4;
fun(4, 0);
}
else fun(i, i + 1);
}

function next(){
if (++i >= 5) {
i = 0;
fun(0, 4);
}
else fun(i, i - 1);
}

var transition = 5000;
var box = this.document.getElementsByClassName("re")[0];
var lik = box.getElementsByTagName("li");

fun(0, 1);//初始化下
var i = 0;

timer = this.setInterval(auto, transition);

var j = 0;
for (; j < 5; j++) {//点击小图标也可以转换图片
lik[j + 5].ind = j;
lik[j + 5].onclick = function () {
fun(this.ind, i)
i = this.ind;
}
}
</script>

</html>

参考链接

  1. 超简单全面的html图片自动轮播,by 学习是人类进化的阶梯.
  2. 简单的HTML网页图片轮播自动切换,by 时钟与夏蝉.
  3. 利用CSS实现上下左右箭头,by 墨初.

C语言中的位域使用方法

发表于 2024-09-18

C语言中的位域(Bit-fields)可以用于对结构体成员进行位级别的控制和优化。在一些应用中,比如网络协议,经常会涉及对数据的某些比特位进行操作,尽管可以使用位的相关运算,但是C语言提供了位域用以支持对一个字节的某几个位进行访问,操作起来也更加方便。

位域的定义与引用

位域不同于一般的结构体成员,它以位为单位来定义成员的长度,因此在结构体中定义位域时,必须要指明位域成员所需要占用的二进制位数。

1
2
3
4
5
6
struct MsgHeader {
int a: 5; // 数据类型名 变量名:二进制位数
int b: 3;
int c: 2;
int d:6;
};

由于位域本质上是一种特殊的结构体成员,因此一般结构体成员的引用方法同样适用于位域成员。不过,需要特别注意的是,位域成员存储是以二进制位作为单位的,而内存的最小寻址单元是字节,所以不能直接引用位域成员的地址。

位域与大小端

结构体内位域成员在大小端系统上的内存分配规则如下:

  • 无论是大端或小端模式,位域的存储都是由内存低地址向高地址分配,即从低地址字节的低位bit开始向高地址字节的高位bit分配空间;
  • 位域成员在已分配的内存区域内,按照机器定义的比特序对数据的各个bit位进行排列。即在小端模式中,位域成员的最低有效位存放在内存低bit位,最高有效位存放在内存高bit位;大端模式则相反。

参考链接

  1. C语言中位域(Bit-fields)的高级玩法,8个案例代码告诉你怎么玩,by
    晓亮Albert.
  2. C语言结构体位域及其存储,by Aspiresky.
  3. 3分钟理解C语言结构体位域(小白扫盲篇),by 天黑黑.

合同管理知识学习笔记

发表于 2024-08-23 | 更新于 2025-04-23

项目采购管理过程围绕合同进行,采购管理过程所涉及的各种活动过程了合同生命周期。

合同类型

按项目范围分:

  • 项目总承包合同
  • 项目单项承包合同
  • 项目分包合同

按项目付款方式划分:

  • 总价合同
  • 成本补偿合同
  • 工料合同

合同管理过程

合同的签订管理

合同的履行管理

工程验收的基本流程通常包括预验收、初步验收和最终验收三个阶段。在预验收阶段,施工单位需要自查自纠,确保工程各项指标符合设计要求和施工规范。初步验收则是在预验收的基础上,由建设单位组织设计、监理等相关部门共同参与,对工程质量进行全面检查。最终验收是在初步验收合格后,经过一段时间的试运行,确认工程无重大问题后进行的正式验收。

有幸作为专家参加一个合同的最终验收,记录一下最终验收的具体流程:

  • 建设方项目介绍
  • 承建方和监理方介绍预验收或初步验收之后存在的问题和整改情况
  • 专家组现场查看项目建设成果
  • 专家组评审项目材料,查漏补缺(因评审时间有限,重点对评审材料的完备性和科学性进行审查)
  • 专家组出具评审意见

合同的变更管理

合同的档案管理

合同违约索赔管理

参考链接

  1. 信息系统项目管理师教程(第4版),by douban.

人工智能领域术语学习笔记

发表于 2024-07-31 | 更新于 2024-12-22

记录学习一些人工智能领域的专业名词含义,方便理解。

人工智能

1956年夏天,计算机科学家约翰·麦卡锡(John McCarthy)首次提出”人工智能”(AI)这个概念。

人工智能指的是,通过软件和硬件,来完成通常需要人类智能才能完成的任务。它的研究对象,就是在机器上模拟人类智能。

机器学习

早期,人工智能研究分成两个阵营。

第一个阵营是规则式(rule-based)方法,又称专家系统(expert systems),指的是人类写好一系列逻辑规则,来教导计算机如何思考。

可想而知,对于复杂的、大规模的现实问题,很难写出完备的、明确的规则。所以,这种方法的进展一直很有限。

第二个阵营就是机器学习(machine learning),指的是没有预置的规则,只是把材料提供给计算机,让机器通过自我学习,自己发现规则,给出结果。

神经网络

神经网络(neural network)是机器学习的一种主要形式。

神经网络就是在机器上模拟人脑的结构,构建类似生物神经元的计算网络来处理信息。

一个计算节点就是一个神经元,大量的计算节点组成网络,进行协同计算。

神经网络需要极大的算力,以及海量的训练材料。以前,这是难以做到的,所以20世纪70年代开始,就陷入了停滞,长期没有进展。

深度学习

深度学习是神经网络的一种实现方法,在20世纪80年代由杰弗里·辛顿提出。它让神经网络研究重新复活。

深度学习是一种让多层神经元可以进行有效计算的方法,大大提高了神经网络的性能。”深度学习”这个名字,就是比喻多层神经元的自主学习过程。

多层神经元包括一个输入层和一个输出层,它们之间有很多中间层(又称隐藏层)。以前,计算机算力有限,只能支撑一两个中间层,深度学习使得我们可以构建成千上万个中间层的网络,具有极大的”深度”。

Transformer

早些年,深度学习用到的方法是卷积神经网络(CNN)和循环神经网络(RNN)。

2017年,谷歌的研究人员发明了一种新的深度学习处理方法,叫做 Transformer(转换器)。

Transformer 不同于以前的方法,不再一个个处理输入的单词,而是一次性处理整个输入,对每个词分配不同的权重。

这种方法直接导致了2022年 ChatGPT 和后来无数生成式 AI 模型的诞生,是神经网络和深度学习目前的主流方法。

由于基于 Transformer 的模型需要一次性处理整个输入,所以都有”上下文大小”这个指标,指的是一次可以处理的最大输入。

比如,GPT-4 Turbo 的上下文是 128k 个 Token,相当于一次性读取超过300页的文本。上下文越大,模型能够考虑的信息就越多,生成的回答也就越相关和连贯,相应地,所需要的算力也就越多。

Token 词元

Token,也称为标记或词元,是语言处理中的一个基本单元。它通常代表一个单词、标点符号或一个特定的符号序列。Token是文本的基本组成单元,用于表示文本中的有意义的语言元素。例如,“Hello, world!”这个句子可以被划分为多个Token:“Hello”、“,”、“world”和“!”。

深度学习成为当今显学的原因

深度学习成为当今显学的主要原因是性能优越。实际上深度学习的基础技术几十年前就已经提出来了,那为什么最近十多年深度学习才开始火热?这主要是制约深度学习的两大因素:大数据集和高性能硬件在十多年前才达到深度学习的门槛。大数据集使深度学习能够充分的进行训练,而高性能硬件如CPU和GPU使深度学习的训练速度以指数级提升。

参考链接

  1. 自然语言处理中的文本token和tokenization详解,by KAKAKA.
  2. 深度学习基础介绍,by Yunhui1998.
  3. It all started with a Perceptron,by Vincent.
  4. 科技爱好者周刊(第 330 期):李开复梳理人工智能,by 阮一峰.

CPlusPlus反射机制研究

发表于 2024-07-21

反射是指在程序运行时,动态获取类或对象的所有属性和方法。这种语言的反射机制可以提高程序设计的通用性和便利性。但遗憾的是,当前C++标准不支持反射机制。

参考链接

  1. C++ 反射机制(实例讲解),by 那年聪聪.
  2. C++ 实现反射机制,by –Allen–.
  3. [C++11札记]: type traits简介,by 云水木石.
  4. 重大变更(一):关于C++26的十大猜想,by 极客时间APP.
  5. C++ type traits的学习,by 燃脂二师兄.

CPlusPlus数据访问层设计

发表于 2024-07-14 | 更新于 2024-07-18

三层架构是软件架构中常用的架构,它从上往下分为表示层、业务逻辑层、数据访问层。下面重点介绍 C++ 程序的数据访问层设计。

什么是 DAO

在计算机软件中,数据访问对象(data access object,DAO)是为某种类型的数据库或其他持久性机制提供一个抽象接口的对象。通过映射应用程序对持久层的调用,DAO 提供一些特定的数据操作,而无需暴露数据库细节。这种隔离支持单一功能原则。

数据访问对象模式(Data Access Object Pattern)或 DAO 模式用于把低级的数据访问 API 或操作从高级的业务服务中分离出来。

数据访问对象模式的参与者主要有:

  • 数据访问对象接口(Data Access Object Interface) - 该接口定义了在一个模型对象上要执行的标准操作。
  • 数据访问对象实体类(Data Access Object concrete class) - 该类实现了上述的接口。该类负责从数据源获取数据,数据源可以是数据库,也可以是 xml,或者是其他的存储机制。
  • 模型对象/数值对象(Model Object/Value Object, VO) - 该对象是简单的 POJO,包含了 get/set 方法来存储通过使用 DAO 类检索到的数据。

主流的 ORM 框架

C++ 中主流的 ORM 框架有以下几个:

  • LiteSQL:https://sourceforge.net/projects/litesql/
  • ODB:https://www.codesynthesis.com/products/odb/
  • QxOrm:https://www.qxorm.com/qxorm_en/home.html
  • Wt::Dbo:https://www.webtoolkit.eu/wt/doc/tutorial/dbo.html

其中,LiteSQL 和 ODB 不依赖于特定的框架,而 QxOrm 依赖于 Qt,Wt::Dbo 依赖于 Wt。由于使用QT进行开发,最终决定使用QxOrm。本想使用QDB,但是在QT上开发太麻烦。

参考链接

  1. C++实现的DAO(数据访问对象模式),by Jinkai.
  2. QxOrm使用教程(ORM for C++ 对象关系映射),by ljjyy.
  3. 浅谈C++三层架构,by eric0803.
  4. C++架构之美:设计卓越应用,by qt.video.
  5. Dao层设计,by c++天下第一.
  6. 如何设计一个简单的 C++ ORM,by bot-man-jl.
  7. C++ ORM ODB入门,by aliyun.
  8. TinyORM:一个简单的C++ ORM框架,by davidpp.
  9. C++版本 ORM 访问数据库之ODB 的Window环境编译(一),by Software_hul.
  10. Windows下Qt5.5.1中使用ODB,by 严慈善.
  11. 【一】ODB - C++ 访问数据库的利器–Hello World On Windows(Version-24),by C++程序员Carea.
  12. error LNK2001: 无法解析的外部符号 “__declspec(dllimport) public 解决办法,by 鸡啄米的时光机.
  13. qxBlog project - blog management in C++,by QxOrm.
  14. Qt三层架构应用程序设计及开发,by wyh20171105.
  15. Qt项目架构经验总结,by cps666.
  16. Qt SQL的使用 MySQL,by 一杯清酒邀明月.

Java注解学习笔记

发表于 2024-06-29

注解是JDK1.5版本开始引入的一个特性,用于对代码进行说明,可以对包、类、接口、字段、方法参数、局部变量等进行注解。它是框架学习和设计者必须掌握的基础。

注解作用

主要的作用有以下四方面:

  • 生成文档,通过代码里标识的元数据生成javadoc文档。

  • 编译检查,通过代码里标识的元数据让编译器在编译期间进行检查验证。

  • 编译时动态处理,编译时通过代码里标识的元数据动态处理,例如动态生成代码。

  • 运行时动态处理,运行时通过代码里标识的元数据动态处理,例如使用反射注入实例。

注解分类

注解的常见分类:

  • Java自带的标准注解,包括@Override、@Deprecated和@SuppressWarnings,分别用于标明重写某个方法、标明某个类或方法过时、标明要忽略的警告,用这些注解标明后编译器就会进行检查。

  • 元注解,元注解是用于定义注解的注解,包括@Retention、@Target、@Inherited、@Documented,@Retention用于标明注解被保留的阶段,@Target用于标明注解使用的范围,@Inherited用于标明注解可继承,@Documented用于标明是否生成javadoc文档。

  • 自定义注解,可以根据自己的需求定义注解,并可用元注解对自定义注解进行注解。

参考链接

  1. Java 基础 - 注解机制详解,by pdai.
  2. Java注解,by 何学长在奔跑.
上一页1…345…53下一页

Jack Huang

523 日志
67 标签
© 2025 Jack Huang
由 Hexo 强力驱动
|
主题 — NexT.Muse