惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

爱范儿
爱范儿
博客园 - 【当耐特】
量子位
Engineering at Meta
Engineering at Meta
博客园_首页
大猫的无限游戏
大猫的无限游戏
IT之家
IT之家
V
Visual Studio Blog
小众软件
小众软件
阮一峰的网络日志
阮一峰的网络日志
美团技术团队
Jina AI
Jina AI
The Cloudflare Blog
T
Tailwind CSS Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
雷峰网
雷峰网
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
宝玉的分享
宝玉的分享
WordPress大学
WordPress大学
有赞技术团队
有赞技术团队
酷 壳 – CoolShell
酷 壳 – CoolShell
Last Week in AI
Last Week in AI
人人都是产品经理
人人都是产品经理
博客园 - 聂微东

洛屿的小站

脉冲线性加减速曲线的DDA实现 STM32F407 IAR环境下uC/OS-III移植完整指南 STM32 UCOS3+HAL库集成中的FPU HardFault问题 一种简单的卡尔曼滤波器设计 Cadence - 应律而动,落指成音 Zephyr - 聆风之息,为你而奏 不改一行插件代码,实现消息优先级与阻断 洛玖定时任务系统 在 butterfly 主题中添加首页点集动画(基于p2line项目) 你好,2026 stm32f4xx-ads1256驱动 stm32f4xx-ad9854并行驱动 主动式网站状态监测实现及其应用 右键菜单加入用Trae打开文件和文件夹 三角洲行动ID映射表 洛玖SDK说明 为网页文章开头添加原文连接 Hexo-Butterfly主题在主页添加GitHub贡献日历 Proteus中555定时器仿真问题 装饰器 洛玖开发日记 STS3032舵机获取力矩输出 kotlin网页前后端那些事 mspm0g3507-ad9850 奇怪的bug Paddle模型转PaddleLite 人工智能考核 构建一个yolov3网络 yolo和paddle模型常见输出参数 PaddleDetection
随便写的一些东西
洛屿 · 2024-01-05 · via 洛屿的小站
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
def get_annotations(label_list, datadir, Annotations = 'annotations', Images = 'images'):
filenames = os.listdir(os.path.join(datadir, Annotations))
records = []
ct = 0
for fname in filenames:
fid = fname.split('.')[0]
fpath = os.path.join(datadir, Annotations, fname)
img_file = os.path.join(datadir, Images, fid + '.jpg')
tree = ET.parse(fpath)

if tree.find('id') is None:
im_id = np.array([ct])
else:
im_id = np.array([int(tree.find('id').text)])

objs = tree.findall('object')
im_w = float(tree.find('size').find('width').text)
im_h = float(tree.find('size').find('height').text)
gt_bbox = np.zeros((len(objs), 4), dtype=np.float32)
gt_class = np.zeros((len(objs), ), dtype=np.int32)
is_crowd = np.zeros((len(objs), ), dtype=np.int32)
difficult = np.zeros((len(objs), ), dtype=np.int32)
for i, obj in enumerate(objs):
cname = obj.find('name').text
gt_class[i] = label_list[cname]
_difficult = int(obj.find('difficult').text)
x1 = float(obj.find('bndbox').find('xmin').text)
y1 = float(obj.find('bndbox').find('ymin').text)
x2 = float(obj.find('bndbox').find('xmax').text)
y2 = float(obj.find('bndbox').find('ymax').text)
x1 = max(0, x1)
y1 = max(0, y1)
x2 = min(im_w - 1, x2)
y2 = min(im_h - 1, y2)
# 这里使用xywh格式来表示目标物体真实框
gt_bbox[i] = [(x1+x2)/2.0 , (y1+y2)/2.0, x2-x1+1., y2-y1+1.]
is_crowd[i] = 0
difficult[i] = _difficult

voc_rec = {
'im_file': img_file,
'im_id': im_id,
'h': im_h,
'w': im_w,
'is_crowd': is_crowd,
'gt_class': gt_class,
'gt_bbox': gt_bbox,
'gt_poly': [],
'difficult': difficult
}
if len(objs) != 0:
records.append(voc_rec)
ct += 1
return records

'''
record格式:
{'im_file': 'Car2024\\Images\\block1.jpg', 'im_id': array([0]), 'h': 240.0, 'w': 320.0, 'is_crowd': array([0, 0, 0]), 'gt_class': array([11, 8, 8]), 'gt_bbox': array([[110.5, 21.5, 36. , 30. ],
[ 99.5, 70. , 32. , 41. ],
[266. , 164.5, 49. , 70. ]], dtype=float32), 'gt_poly': [], 'difficult': array([0, 0, 0])}
'''

# E.g
label_list = {'spy': 0, 'safety': 1, 'bridge': 2, 'danger': 3, 'tumble': 4, 'thief': 5, 'evil': 6, 'bomb': 7, 'cone': 8, 'crosswalk': 9, 'prop': 10, 'block': 11, 'patient': 12}
records = get_annotations(label_list, train_dir, Annotations = 'Annotations', Images = 'Images')

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
import cv2
import numpy as np
# 引用 paddle inference 预测库
import paddle.inference as paddle_infer
from PIL import Image

# 创建 config
config = paddle_infer.Config("./models/mobilenet_ssd/mobilenet-ssd-model",
"./models/mobilenet_ssd/mobilenet-ssd-params")

# 根据 config 创建 predictor
predictor = paddle_infer.create_predictor(config)

# 获取输入 Tensor
input_names = predictor.get_input_names()
input_tensor = predictor.get_input_handle(input_names[0])

print(input_names)
print(input_tensor)

# 从 CPU 获取数据,设置到 Tensor 内部
imgPath = './frame/15.jpg'

cap = cv2.VideoCapture('./models/mobilenet_ssd/sample.mp4')
frame = []
while True:
ret, frame = cap.read()
if ret == False:
break
# cv2.imwrite("./frame/frame.jpg", frame)
# imgPath = './frame/frame.jpg'
im = Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))# Image.open(imgPath)
im = im.resize((300, 300), Image.BICUBIC)

# img = cv2.cvtColor(numpy.asarray(im.resize((320, 240), Image.BICUBIC)), cv2.COLOR_RGB2BGR)#cv2.cvtColor(, cv2.COLOR_RGB2BGR) # 转换代码
# cv2.imshow('img', img) # opencv显示
# cv2.waitKey()

im = np.array(im, dtype=np.float32).transpose(2, 0, 1).reshape((1, 3, 300, 300))
mean = [121.636447, 125.696666, 124.807721]
# mean = [127.5, 127.5, 127.5]
scale = [0.007843,
0.007843,
0.007843]
std = [ 69.480526,
66.625320,
50.616609]

for ri in range(0, 300):
im[0][0][ri] = (im[0][0][ri] / 255)# - (scale[0] - mean[0] / 255)
for gi in range(0, 300):
im[0][1][gi] = (im[0][1][gi] / 255)# - (scale[1] - mean[1] / 255)
for bi in range(0, 300):
im[0][2][bi] = (im[0][2][bi] / 255)# - (scale[2] - mean[2] / 255)

fake_input = im

input_tensor1 = predictor.get_input_handle(input_names[0])
input_tensor1.copy_from_cpu(im)
#
# im = np.asarray([[320.0/240.0, 320.0/320.0]], dtype=np.float32)
# input_tensor2 = predictor.get_input_handle(input_names[1])
# input_tensor2.copy_from_cpu(im)
#
# im = np.asarray([[608, 608]], dtype=np.float32)
# input_tensor2 = predictor.get_input_handle(input_names[2])
# input_tensor2.copy_from_cpu(im)

# 执行预测
predictor.run()

# 获取输出 Tensor
output_names = predictor.get_output_names()
output_tensor = predictor.get_output_handle(output_names[0])

# 从 Tensor 中获取数据到 CPU
output_data = output_tensor.copy_to_cpu()

# 获取 Tensor 的维度信息
output_shape = output_tensor.shape()

# 获取 Tensor 的数据类型
output_type = output_tensor.type()

results = []
i = 0
img = frame
label_list = ["background", "cone", "bridge", "pig", "tractor", "corn", "bump", "crosswalk", " "]
label_list = ["background", "cone", "granary", "bridge", "tractor", "corn", "pig", "crosswalk", "bump"]
img = cv2.resize(img, dsize=(300, 300), fx=1, fy=1, interpolation=cv2.INTER_LINEAR)
if len(output_data) > 1:
for data in output_data:
tmp = {}
if data[1] > 0.9:
tmp['type'] = data[0]
tmp['score'] = data[1]
tmp['x'] = data[2] * 300
tmp['y'] = data[3] * 300
tmp['width'] = data[4] * 300 - tmp['x']
tmp['height'] = data[5] * 300 - tmp['y']
results.insert(i, tmp)
# print(tmp)
i = i + 1
for i in results:
x = int(i['x'])
xmax = int(i['x'] + i['width'])
y = int(i['y'])
ymax = int(i['y'] + i['height'])
# print((x, y), (xmax, ymax))
cv2.rectangle(img, (x, y), (xmax, ymax), (0, 0, 255), 2)
# cv2.rectangle(img, (x, ymax), (xmax, y), (255, 0, 0), 2)
cv2.putText(img,
str(label_list[int(i['type'])]),
(int(x), int(y)),
cv2.FONT_HERSHEY_SIMPLEX,
0.75,
(0, int(i['type']) * 30, 255),
2)
img = cv2.resize(img, dsize=(320, 240), fx=1, fy=1, interpolation=cv2.INTER_LINEAR)
cv2.imshow('src', img)
cv2.waitKey(1)

# 释放中间 Tensor
predictor.clear_intermediate_tensor()

# 释放内存池中的所有临时 Tensor
predictor.try_shrink_memory()

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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Midi可视化</title>

<script type="text/javascript" src="./js/Tone.js"></script>
<script type="text/javascript" src="./js/Midi.js"></script>
<script type="text/javascript" src="./js/pixi.js"></script>
</head>
<body>
<input type="file" id="file">
<input type="button" id="play" value="播放"/>

<script>
const Application = PIXI.Application; // 应用类,快速创建PIXI应用
const Sprite = PIXI.Sprite; // 精灵类
const Graphics = PIXI.Graphics; // 图形类
// 创建应用程序并挂载
const pixi = new Application({
width: 1000,
height: 600,
backgroundColor: 0x000000
})
// pixi.view 代表画布,是一个canvas元素
document.body.appendChild(pixi.view);

const config = {
speed: 1,
leftColor: 0xFF69B4,
rightColor: 0x00BFFF,
color1: 0x66A9C9,
color2: 0xF0C9CF,
color3: 0xE2C17C,
color4: 0x363433,
color5: 0xFF4500,
}
// 定义灯光类作为音符的可视化
class Light extends Graphics {
constructor(color, height, x) {
super();
this.beginFill(color);
this.drawRect(x, 600, 10, height);
this.endFill();
// pixijs的定时器,可以实现每帧执行一次,并且十分稳定
pixi.ticker.add(() => {
this.y -= config.speed * 5;
});
}
}
// pixi.stage 代表舞台,所有的物体必须挂载在舞台上才可以显示。

const input = document.querySelector('#file');
input.addEventListener('change', (e) => {
console.log(e.target.files[0]);
parseMidi(e.target.files[0]);
})

// 读取midi文件
function parseMidi(file) {
// 创建文件读取器
const reader = new FileReader();
// 读取文件
reader.readAsArrayBuffer(file);
// 文件读取完成后将文件转化为json对象
reader.addEventListener('load', (e) => {
currentMidi = new Midi(e.target.result);
console.log(currentMidi);
})
}

play.addEventListener('click', (e) => {
console.log(currentMidi);
// 如果未加载midi文件
if(!currentMidi) {
alert('未加载文件');
return;
}

const now = Tone.now() + 0.5; // 获取当前时间
const synths = []; // 存储合成器
// 遍历midi文件中的轨道
currentMidi.tracks.forEach(track => {
// 创建合成器作为音轨并连接至出口,音色使用Tonejs的默认音色
const synth = new Tone.PolySynth(Tone.Synth, {
envelope: {
// 声音的生命周期:按下按键 - 渐入 - 攻击阶段 - 衰减阶段 - 衰减结束 - 松开按键 - 声音消逝

<!-- // 旧 -->
<!-- attack: 0.02, // 渐入时间 -->
<!-- decay: 0.1, // 攻击阶段(最大音量)持续时间 -->
<!-- sustain: 0.3, // 衰减结束后的最小声音 -->
<!-- release: 1, // 从松开按键到声音彻底消失所需的时间 -->

// Piano
attack: 0.005, // 渐入时间
decay: 1.5, // 攻击阶段(最大音量)持续时间
sustain: 0.05, // 衰减结束后的最小声音
release: 0.005, // 从松开按键到声音彻底消失所需的时间
},
}).toDestination();
// 将合成器存储起来,为之后停止播放的功能留下接口。
synths.push(synth);

// 遍历轨道中的每个音符
track.notes.forEach(note => {
// 合成器发声
note.velocity = note.velocity/10;
synth.triggerAttackRelease(
note.name, // 音名
note.duration, // 持续时间
note.time + now, // 开始发声时间
note.velocity // 音量
);

// 在播放按钮的事件中,遍历音符时,创建音频调度,实现音画同步
Tone.Transport.schedule((time) => {
// 根据音调划分颜色,(其实应该根据轨道来划分的)
var color = config.color1;
if(note.midi < 15) {
color = config.color1;
} else if (note.midi < 30){
color = config.color2;
} else if (note.midi < 45){
color = config.color3;
} else if (note.midi < 60){
color = config.color4;
} else {
color = config.color5;
}
//color = '0x'+ Math.random().toString(16).substr(2,6);
pixi.stage.addChild(new Light(color, note.duration * 150 * config.speed, (note.midi - 20) * 10))

}, note.time + now);

// 在代码最外层设置音频调度的模式,并启动音频调度。
Tone.context.latencyHint = 'fastest';
Tone.Transport.start();

});
});
})



</script>
</body>
</html>