行业资讯「汽车」 IndustryResearch(Automotive)

新格局下,全球化扩张和回潮的天平逐渐向后者倾斜。而中国正在加快构建以国内大循环为主体,以国内国际双循环相互促进的新发展格局。在此过程中汽车行业率先作为,但产业供给侧改革仍然处在浅水区,难以满足消费者定制化需求。上游供给侧不确定性逐渐上升,产业分工逻辑转向安全和韧性;下游用户对汽车消费需求和审美理解存在不同程度提升,更加要求车辆的定制化和个性化程度,迫使车企从围绕成本向围绕用户转变。同时,我国智慧交通体系的变局正在酝酿,主机厂也将不同程度的成为变革的助推者。在此趋势下,在不确定性加剧的环境中获取确定性的生存空间和可持续性的竞争力成为汽车行业的必修课,一场深入而持久的数字化变革展开。
——[艾瑞咨询—2023中国汽车行业数字化转型解决方案白皮书]

联邦学习 Federated Learning

联邦学习背景:

近年来人工智能可谓风风火火,掀起一波又一波浪潮,从人脸识别、活体检验发现刑事案件报警到阿尔法狗大战人类围棋手李世石、再到无人驾驶、以及已被普遍应用的精准营销,AI逐步进入人们生活的方方面面。当然也不免出现部分过度吹捧,导致对AI的误解–AI无所不能,既然这么好用,为啥我不能拿来用一下?在追逐AI的同时却忽略了一点,AI是靠数据来喂的,而且是大量优质数据。

现实生活中,除了少数巨头公司能够满足,绝大多数企业都存在数据量少,数据质量差的问题,不足以支撑人工智能技术的实现;同时国内外监管环境也在逐步加强数据保护,陆续出台相关政策,如欧盟最近引入 的新法案《通用数据保护条例》(GDPR),我国国家互联网信息办公室起草的《数据安全管理办法(征求意见稿)》,因此数据在安全合规的前提下自由流动,成了大势所趋;在用户和企业角度下,商业公司所拥有的数据往往都有巨大的潜在价值。两个公司甚至公司间的部门都要考虑利益的交换,往往这些机构不会提供各自数据与其他公司做与单的聚合,导致即使在同一个公司内,数据也往往以孤岛形式出现。

基于以上不足以支撑实现、不允许粗暴交换、不愿意贡献价值三点,导致了现在大量存在的数据孤岛,以及隐私保护问题,联邦学习应运而生。

数据结构和算法-树与树算法 Tree

树与树算法

树的概念

树(英语:tree)是一种抽象数据类型(ADT)或是实作这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合。它是由n(n>=1)个有限节点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:

  • 每个节点有零个或多个子节点;
  • 没有父节点的节点称为根节点;
  • 每一个非根节点有且只有一个父节点;
  • 除了根节点外,每个子节点可以分为多个不相交的子树;

数据结构和算法-栈 Stack

栈(stack),有些地方称为堆栈,是一种容器,可存入数据元素、访问元素、删除元素,它的特点在于只能允许在容器的一端(称为栈顶端指标,英语:top)进行加入数据(英语:push)和输出数据(英语:pop)的运算。没有了位置概念,保证任何时候可以访问、删除的元素都是此前最后存入的那个元素,确定了一种默认的访问顺序。
由于栈数据结构只允许在一端进行操作,因而按照后进先出(LIFO, Last In First Out)的原理运作。

数据结构和算法-排序与搜索 Sort&Search

排序

排序算法(英语:Sorting algorithm)是一种能将一串数据依照特定顺序进行排列的一种算法。

排序算法的稳定性

  • 稳定性:稳定排序算法会让原本有相等键值的纪录维持相对次序。也就是如果一个排序算法是稳定的,当有两个相等键值的纪录R和S,且在原本的列表中R出现在S之前,在排序过的列表中R也将会是在S之前。
    当相等的元素是无法分辨的,比如像是整数,稳定性并不是一个问题。然而,假设以下的数对将要以他们的第一个数字来排序。

数据结构和算法-队列 Queue

队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。
队列是一种先进先出的(First In First Out)的线性表,简称FIFO。允许插入的一端为队尾,允许删除的一端为队头。队列不允许在中间部位进行操作!假设队列是q=(a1,a2,……,an),那么a1就是队头元素,而an是队尾元素。这样我们就可以删除时,总是从a1开始,而插入时,总是在队列最后。这也比较符合我们通常生活中的习惯,排在第一个的优先出列,最后来的当然排在队伍最后。

数据结构和算法-链表 LinkedList

为什么需要链表

顺序表的构建需要预先知道数据大小来申请连续的存储空间,而在进行扩充时又需要进行数据的搬迁,所以使用起来并不是很灵活。
链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。

链表的定义

链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是不像顺序表一样连续存储数据,而是在每一个节点(数据存储单元)里存放下一个节点的位置信息(即地址)

数据结构和算法-顺序表 SequenatialList

在程序中,经常需要将一组(通常是同为某个类型的)数据元素作为整体管理和使用,需要创建这种元素组,用变量记录它们,传进传出函数等。一组数据中包含的元素个数可能发生变化(可以增加或删除元素)。
对于这种需求,最简单的解决方案便是将这样一组元素看成一个序列,用元素在序列里的位置和顺序,表示实际应用中的某种有意义的信息,或者表示数据之间的某种关系。
这样的一组序列元素的组织形式,我们可以将其抽象为线性表。一个线性表是某类元素的一个集合,还记录着元素之间的一种顺序关系。线性表是最基本的数据结构之一,在实际程序中应用非常广泛,它还经常被用作更复杂的数据结构的实现基础。
根据线性表的实际存储方式,分为两种实现模型:

  • 顺序表,将元素顺序地存放在一块连续的存储区里,元素间的顺序关系由它们的存储顺序自然表示。
  • 链表,将元素存放在通过链接构造起来的一系列存储块中。

数据挖掘 DataMining

一个优秀的数据分析师不仅要掌握基本的统计、数据库、数据分析方法、思维、数据分析工具和技能,
还要掌握一些数据挖掘的思路,帮助我们挖掘出有价值的数据,这也是数据分析专家和一般数据分析师的差距之一

AWS使用笔记 Athena

AWS 全称Amazon web service(亚马逊网络服务),是亚马逊公司旗下云计算服务平台,为全世界各个国家和地区的客户提供一整套基础设施和云解决方案。
AWS面向用户提供包括弹性计算、存储、数据库、物联网在内的一整套云计算服务,帮助企业降低IT投入和维护成本,轻松上云
从概念是来看,AWS提供了一系列的托管产品,帮助我们在没有物理服务器的情况下,照样可以正常完成软件开发中的各种需求,也就是我们常说的云服务。

AWS使用笔记 S3

AWS 全称Amazon web service(亚马逊网络服务),是亚马逊公司旗下云计算服务平台,为全世界各个国家和地区的客户提供一整套基础设施和云解决方案。
AWS面向用户提供包括弹性计算、存储、数据库、物联网在内的一整套云计算服务,帮助企业降低IT投入和维护成本,轻松上云
从概念是来看,AWS提供了一系列的托管产品,帮助我们在没有物理服务器的情况下,照样可以正常完成软件开发中的各种需求,也就是我们常说的云服务。

AWS使用笔记 Sagemaker


AWS 全称Amazon web service(亚马逊网络服务),是亚马逊公司旗下云计算服务平台,为全世界各个国家和地区的客户提供一整套基础设施和云解决方案。
AWS面向用户提供包括弹性计算、存储、数据库、物联网在内的一整套云计算服务,帮助企业降低IT投入和维护成本,轻松上云
从概念是来看,AWS提供了一系列的托管产品,帮助我们在没有物理服务器的情况下,照样可以正常完成软件开发中的各种需求,也就是我们常说的云服务。

图片数据增强 Data Augmentation

YoloV5训练图片增强 python代码

Generate More Label – 生成配套的Label

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
#!/usr/bin/python
# -*- coding=utf-8 -*-
from xml.etree.ElementTree import ElementTree, Element
import xml.etree.ElementTree as ET
import os
from tqdm import tqdm


def change_box(update_path, save_path, filename, box_n, new_value):
update_tree = ET.parse(update_path + filename)
root = update_tree.getroot()
size = root.find('size')
object = root.find('object')
bndbox = object.find("bndbox")
_box_n = bndbox.find(box_n)
_box_n.text = new_value
update_tree.write(save_path + filename, encoding='utf-8')


def change_name(update_path, save_path, filename, new_name):
update_tree = ET.parse(update_path + filename)
root = update_tree.getroot()
size = root.find('size')
object = root.find('object')
filename = root.find("filename")
filename.text = new_name
update_tree.write(save_path + new_name, encoding='utf-8')


def rotate_90(update_path, save_path, filename, new_name):
"""generate rotate 90° new label"""
update_tree = ET.parse(update_path + filename)
root = update_tree.getroot()
size = root.find('size')
object = root.find('object')
bndbox = root.find('object').find("bndbox")
width = int(size.find('width').text)
height = int(size.find('height').text)
xmin, ymin, xmax, ymax = bndbox.find("xmin"), bndbox.find("ymin"), bndbox.find(
"xmax"), bndbox.find("ymax")
_xmin, _ymin, _xmax, _ymax = int(xmin.text), int(ymin.text), int(xmax.text), int(ymax.text)
xmin.text = str(_ymin)
ymin.text = str(width - _xmax)
xmax.text = str(_ymax)
ymax.text = str(height - _xmin)
update_tree.write(save_path + new_name, encoding='utf-8')


def rotate_180(update_path, save_path, filename, new_name):
"""generate rotate 180° new label"""
update_tree = ET.parse(update_path + filename)
root = update_tree.getroot()
size = root.find('size')
bndbox = root.find('object').find("bndbox")
width = int(size.find('width').text)
height = int(size.find('height').text)
xmin, ymin, xmax, ymax = bndbox.find("xmin"), bndbox.find("ymin"), bndbox.find(
"xmax"), bndbox.find("ymax")
_xmin, _ymin, _xmax, _ymax = int(xmin.text), int(ymin.text), int(xmax.text), int(ymax.text)
xmin.text = str(height - _xmax)
ymin.text = str(width - _ymax)
xmax.text = str(height - _xmin)
ymax.text = str(width - _ymin)
update_tree.write(save_path + new_name, encoding='utf-8')


def gen_fli_label(update_path, save_path, filename, new_name):
"""generate fli new label"""
update_tree = ET.parse(update_path + filename)
root = update_tree.getroot()
size = root.find('size')
bndbox = root.find('object').find("bndbox")
width = int(size.find('width').text)
height = int(size.find('height').text)
xmin, ymin, xmax, ymax = bndbox.find("xmin"), bndbox.find("ymin"), bndbox.find("xmax"), bndbox.find("ymax")
_xmin, _ymin, _xmax, _ymax = int(xmin.text), int(ymin.text), int(xmax.text), int(ymax.text)
xmin.text = str(width - _xmax)
ymin.text = str(_ymin)
xmax.text = str(height - _xmin)
ymax.text = str(_ymax)
update_tree.write(save_path + new_name, encoding='utf-8')


def modify_quality(update_path, save_path, filename, new_name):
"""generate rotate 180° new label"""
change_name(update_path, save_path, filename, new_name)


def gen_label_square(update_path, save_path, filename):
update_tree = ET.parse(update_path + filename)
root = update_tree.getroot()
bndbox = root.find('object').find("bndbox")
width = root.find('size').find('width')
height = root.find('size').find('height')
xmin, ymin, xmax, ymax = bndbox.find("xmin"), bndbox.find("ymin"), bndbox.find("xmax"), bndbox.find("ymax")
_xmin, _ymin, _xmax, _ymax = int(xmin.text), int(ymin.text), int(xmax.text), int(ymax.text)
_width, _height = int(width.text), int(height.text)
max_w = max(_width, _height)
width.text, height.text = str(max_w), str(max_w)
if _height > _width:
xmin.text = str(_xmin + (_height - _width) // 2)
xmax.text = str(_xmax + (_height - _width) // 2)
elif _width > _height:
ymin.text = str(_ymin + (_width - _height) // 2)
ymax.text = str(_ymax + (_width - _height) // 2)
update_tree.write(save_path + filename, encoding='utf-8')


def gen_rotate_label(update_path, save_path, filename):
new_name_90 = filename.split('.')[0] + "_r90" + ".xml"
new_name_180 = filename.split('.')[0] + "_r180" + ".xml"
modify_fli = filename.split('.')[0] + "_fli" + ".xml"
rotate_90(update_path, save_path, filename, new_name=new_name_90)
rotate_180(update_path, save_path, filename, new_name=new_name_180)
gen_fli_label(update_path, save_path, filename, new_name=modify_fli)


def gen_modify_label(update_path, save_path, filename):
modify_blur = filename.split('.')[0] + "_blur" + ".xml"
modify_brighter = filename.split('.')[0] + "_brighter" + ".xml"
modify_darker = filename.split('.')[0] + "_darker" + ".xml"
modify_nosie = filename.split('.')[0] + "_nosie" + ".xml"
modify_quality(update_path, save_path, filename, new_name=modify_blur)
modify_quality(update_path, save_path, filename, new_name=modify_brighter)
modify_quality(update_path, save_path, filename, new_name=modify_darker)
modify_quality(update_path, save_path, filename, new_name=modify_nosie)


if __name__ == "__main__":
update_path = "../data/picture/label/"
# save_path = "../yolov5/data/VOCdevkit/VOC2007/pic_train20221110/label/"
for label_name in tqdm(os.listdir(update_path)):
update_tree = ET.parse(update_path + label_name)
root = update_tree.getroot()
bndbox = root.find('object').find("bndbox")
width = root.find('size').find('width')
height = root.find('size').find('height')
_width, _height = int(width.text), int(height.text)
if _width != _height:
gen_label_square(update_path, update_path, label_name)
for label_name in tqdm(os.listdir(update_path)):
gen_rotate_label(update_path, update_path, label_name)
for label_name in tqdm(os.listdir(update_path)):
gen_modify_label(update_path, update_path, label_name)

Generate More Picture – 生成增强图片

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
# -*- coding: utf-8 -*-

import cv2
import numpy as np
import os.path
import copy
from tqdm import tqdm
import xml.etree.ElementTree as ET

from PIL import Image


def trans_square(image, save_name):
r"""Open the image using PIL."""
image = image.convert('RGB')
w, h = image.size
background = Image.new('RGB', size=(max(w, h), max(w, h)), color=(255, 255, 255)) # 创建背景图,颜色值为127
length = int(abs(w - h) // 2) # 一侧需要填充的长度
box = (length, 0) if w < h else (0, length) # 粘贴的位置
background.paste(image, box)
print(save_name)
background.save(save_name, quality=95)
return background


def salt_and_pepper(src, percetage):
"""椒盐噪声"""
SP_NoiseImg = src.copy()
SP_NoiseNum = int(percetage * src.shape[0] * src.shape[1])
for i in range(SP_NoiseNum):
randR = np.random.randint(0, src.shape[0] - 1)
randG = np.random.randint(0, src.shape[1] - 1)
randB = np.random.randint(0, 3)
if np.random.randint(0, 1) == 0:
SP_NoiseImg[randR, randG, randB] = 0
else:
SP_NoiseImg[randR, randG, randB] = 255
return SP_NoiseImg


def addGaussianNoise(image, percetage):
"""给图片增加高斯噪声"""
G_Noiseimg = image.copy()
w = image.shape[1]
h = image.shape[0]
G_NoiseNum = int(percetage * image.shape[0] * image.shape[1])
for i in range(G_NoiseNum):
temp_x = np.random.randint(0, h)
temp_y = np.random.randint(0, w)
G_Noiseimg[temp_x][temp_y][np.random.randint(3)] = np.random.randn(1)[0]
return G_Noiseimg


def darker(image, percetage=0.9):
"""降低图片亮度"""
image_copy = image.copy()
w = image.shape[1]
h = image.shape[0]
# get darker
for xi in range(0, w):
for xj in range(0, h):
image_copy[xj, xi, 0] = int(image[xj, xi, 0] * percetage)
image_copy[xj, xi, 1] = int(image[xj, xi, 1] * percetage)
image_copy[xj, xi, 2] = int(image[xj, xi, 2] * percetage)
return image_copy


def brighter(image, percetage=1.5):
"""增加图片亮度"""
image_copy = image.copy()
w = image.shape[1]
h = image.shape[0]
# get brighter
for xi in range(0, w):
for xj in range(0, h):
image_copy[xj, xi, 0] = np.clip(int(image[xj, xi, 0] * percetage), a_max=255, a_min=0)
image_copy[xj, xi, 1] = np.clip(int(image[xj, xi, 1] * percetage), a_max=255, a_min=0)
image_copy[xj, xi, 2] = np.clip(int(image[xj, xi, 2] * percetage), a_max=255, a_min=0)
return image_copy


def rotate(image, angle, center=None, scale=1.0):
"""生成旋转图片"""
(h, w) = image.shape[:2]
# If no rotation center is specified, the center of the image is set as the rotation center
if center is None:
center = (w / 2, h / 2)
m = cv2.getRotationMatrix2D(center, angle, scale)
rotated = cv2.warpAffine(image, m, (w, h))
return rotated


def flip(image):
"""生成翻转图片"""
flipped_image = np.fliplr(image)
return flipped_image


def run(file_dir):
# # 图片文件夹路径
# file_dir = '../data/meishigewen-img/'

for img_name in tqdm(os.listdir(file_dir)):
image = Image.open(file_dir + img_name)
if image.size[0] != image.size[1]:
trans_square(image, file_dir + img_name)

for img_name in tqdm(os.listdir(file_dir)):
img_path = file_dir + img_name
img = cv2.imread(img_path)
rotated_90 = rotate(img, 90)
cv2.imwrite(file_dir + img_name[0:-4] + '_r90.jpg', rotated_90)

rotated_180 = rotate(img, 180)
cv2.imwrite(file_dir + img_name[0:-4] + '_r180.jpg', rotated_180)

flipped_img = flip(img)
cv2.imwrite(file_dir + img_name[0:-4] + '_fli.jpg', flipped_img)

for img_name in tqdm(os.listdir(file_dir)):
img_path = file_dir + img_name
img = cv2.imread(img_path)

img_gauss = addGaussianNoise(img, 0.3)
cv2.imwrite(file_dir + img_name[0:-4] + '_noise.jpg', img_gauss)

img_darker = darker(img)
cv2.imwrite(file_dir + img_name[0:-4] + '_darker.jpg', img_darker)

img_brighter = brighter(img)
cv2.imwrite(file_dir + img_name[0:-4] + '_brighter.jpg', img_brighter)

blur = cv2.GaussianBlur(img, (7, 7), 1.5)
cv2.imwrite(file_dir + img_name[0:-4] + '_blur.jpg', blur)


if __name__ == '__main__':
run(file_dir='../data/picture/img/')

目标检测 ObjectDetection

计算机视觉-目标检测

什么是目标检测

目标检测(Object Detection)的任务是找出图像中所有感兴趣的目标(物体),确定它们的类别和位置,是计算机视觉领域的核心问题之一。由于各类物体有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具有挑战性的问题。
计算机视觉中关于图像识别有四大类任务:
(1)分类-Classification:解决“是什么?”的问题,即给定一张图片或一段视频判断里面包含什么类别的目标。
(2)定位-Location:解决“在哪里?”的问题,即定位出这个目标的的位置。
(3)检测-Detection:解决“在哪里?是什么?”的问题,即定位出这个目标的位置并且知道目标物是什么。
(4)分割-Segmentation:分为实例的分割(Instance-level)和场景分割(Scene-level),解决“每一个像素属于哪个目标物或场景”的问题。
所以,目标检测是一个分类、回归问题的叠加。


Powered by Hexo and Hexo-theme-hiker

Copyright © 2013 - 2024 HELLO WORLD All Rights Reserved.

UV : | PV :