Python - 随机数获取示例

import random

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# [0.0, 1.0)
random.random()

# [a, b]
random.randint(a, b)

# 返回float类型,b不一定被包含
random.uniform(a, b)

# [start, stop)
random.randrange(start, stop[, step])

# 返回一个随机元素
random.choice(seq)

# 洗牌
random.shuffle(x[, random])

# 不放回采样k个不同元素(如需有放回采样,重复做choice即可)
random.sample(population, k)

Python - FFT代码示例

FFT变换、反变换、画图

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

import numpy as np
from scipy.fftpack import fft, ifft
import matplotlib.pyplot as plt

if __name__ == '__main__':

"""
首先,连续/离散 v.s. 周期性/非周期性,在时域与频域中是相互决定的。
时域连续,频域非周期性;时域离散,频域周期性;
时域周期性,频域离散;时域非周期性,频域连续。
"""
"""
其次,奈奎斯特采样定理:为了不失真地恢复模拟信号,采样频率应该不小于模拟信号频谱中最高频率的2倍。
(第一个对称中心是采样频率的一半,因为极限场景中,频谱右半部分+频谱左半部分 = 2 * f_max = fs)
"""

# #----------FFT Demo----------
# # 采样时长
# ts = 6.0
# # 采样点数
# n = 500
# # 采样频率
# fs = ts / n
# # 时域
# x = np.linspace(0.0, ts, n, endpoint=False)
# # 时域信号
# freq_sampling1 = 10
# freq_sampling2 = 20
# amplitude1 = 2
# amplitude2 = 4
# y = amplitude1 * np.sin(2 * np.pi * freq_sampling1 * x) + amplitude2 * np.sin(2 * np.pi * freq_sampling2 * x)
# plt.figure(figsize=(10, 4))
# plt.plot(x, y, 'k', lw=0.8)
# plt.show()
#
# yf = fft(y)
# xf = np.linspace(0.0, 1.0 / 2.0 * fs, n // 2, endpoint=False)
# yf1 = 2.0 / n * np.abs(yf[: n // 2])
# plt.figure(figsize=(10, 6))
# plt.plot(xf, yf1)
# plt.show()
# exit(0)


# 采样时长ts = 288s。
ts = 288.0
# 采样点数n = 288。
n = 288
# 采样频率fs = 1Hz,即1s采1个点。
fs = n / ts

# 时域
x = np.linspace(0.0, ts, n, endpoint=False)
# 时域信号
# 周期性噪声
cycle = [1, 0, 0, 0, 0, 0]
y1 = np.array(cycle * (n // len(cycle)) + cycle[0 : n % len(cycle)])
# 混入一些非周期信号
y2 = np.zeros(n)
y2[3] = 5
y2[13] = 8
y2[34] = 6
y = y1 + y2
#y = np.sin(2 * np.pi * 10 * x) + 2 * np.sin(2 * np.pi * 20 * x)
#y = 1 + 2 * np.cos(2 * np.pi * 50 * x - np.pi * 30 / 180) + 3 * np.cos(2 * np.pi * 100 * x + np.pi * 60 / 180)

plt.figure(figsize=(15, 6))
plt.subplot(231)
plt.plot(x[0:50], y[0:50])
plt.title('Original Signal (Periodic + Aperiodic)', fontsize=9)
plt.ylim((-1, 10))
print("Original Signal")
print(y)

yf = fft(y)
yf1 = fft(y1)
yf2 = fft(y2)

xf = np.linspace(0.0, 1.0 * fs, n, endpoint=False)

# 归一化处理
yf_n = 2.0 / n * np.abs(yf)
xf_n = xf
yf1_n = 2.0 / n * np.abs(yf1)
xf1_n = xf
print("FFT Periodic")
print(yf1_n)
yf2_n = 2.0 / n * np.abs(yf2)
xf2_n = xf
print("FFT Aperiodic")
print(yf2_n)
plt.subplot(232)
plt.plot(xf1_n, yf1_n, 'g')
plt.title('FFT Transform Normalization (Periodic)', fontsize=9, color='g')
plt.xlim((-0.01, max(xf_n) + 0.01))
plt.ylim((0, 1))
plt.subplot(233)
plt.plot(xf2_n, yf2_n, 'g')
plt.title('FFT Transform Normalization (Aperiodic)', fontsize=9, color='g')
plt.xlim((-0.01, max(xf_n) + 0.01))
plt.ylim((0, 1))
plt.subplot(234)
plt.plot(xf_n, yf_n, 'g')
plt.title('FFT Transform Normalization (Periodic + Aperiodic)', fontsize=9, color='g')
plt.xlim((-0.01, max(xf_n) + 0.01))
plt.ylim((0, 1))

# 滤除毛刺
thr = 1. / len(cycle)
plt.hlines(thr, min(xf_n), max(xf_n), linestyles="dashed")
idx = np.where(2.0 / n * np.abs(yf) > thr)
yf.real[idx] = 0
yf.imag[idx] = 0

# 归一化处理
yf_n = 2.0 / n * np.abs(yf)
xf_n = xf
plt.subplot(235)
plt.plot(xf_n, yf_n, 'r')
plt.title('FFT Transform Normalization (After Filtering)', fontsize=9, color='r')
plt.xlim((-0.01, max(xf_n) + 0.01))
plt.ylim((0, 1))

# 还原时域
filtered_y = ifft(yf).real
plt.subplot(236)
plt.plot(x[0:50], filtered_y[0:50], 'b')
plt.title('Filtered Signal', fontsize=9, color='b')
plt.ylim((-1, 10))
print("Filtered Signal")
print(filtered_y)

plt.show()

Python - ConfigParser配置模块

配置读取模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import ConfigParser
import os


class Config:
def __init__(self, config_path=os.path.join(os.path.dirname(os.path.realpath(__file__)), "argogo.config")):
self.config_path = config_path

def read_config(self):
config = ConfigParser.ConfigParser()
config.read(self.config_path)
return config

def get_value(self, section, key):
config = ConfigParser.ConfigParser()
config.read(self.config_path)
return config.get(section, key)

配置文件

1
2
3
4
5
6
7
# config file

[section1]
key1 = value1

[section2]
key2 = value 2

使用标准config file格式,注意=周围的空格会被忽略。

使用

1
2
3
4
5
6
7
8
import config.config_parser
conf = config.config_parser.Config().read_config()

import config.global_config as gc
gc.key1 = conf.get("section1", "key1")
gc.key2 = config.config_parser.Config().get_value("section2", "key2")
log.info("key1 = " + gc.key1)
log.info("key2 = " + gc.key2)

Python - logging日志模块

1. 日志配置直接写在代码中

日志模块

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

import logging
import logging.config
import sys
import os

"""
Python中,类实例化的过程是先执行Singleton.__new__生成instance,
然后执行instance.__init__进行初始化的。
所以通过重写__new__可以达到所有调用Singleton()的地方都返回同一个对象。
"""
class Singleton(object):
_instance = None
def __new__(class_, *args, **kwargs):
if not isinstance(class_._instance, class_):
class_._instance = object.__new__(class_, *args, **kwargs)
return class_._instance

"""
单例模式,以适配场景:程序中有多个模块有main入口,都会import本模块;而当这些模块相互import时,logger只应进行一次配置。
"""
class Logger(Singleton):
def __init__(self):
import detector_info as di
self.logger = logging.getLogger(di.name)
# 进入handler的日志级别
self.logger.setLevel(logging.DEBUG)

stream_handler = logging.StreamHandler(sys.stdout)
stream_handler.setLevel(logging.DEBUG)
formatter = logging.Formatter("%(message)s")
stream_handler.setFormatter(formatter)
self.logger.addHandler(stream_handler)

log_dir = os.path.dirname(os.path.realpath(__file__))
log_file_path = os.path.join(log_dir, "argogo.log")
file_handler = logging.FileHandler(log_file_path)
file_handler.setLevel(logging.DEBUG)
formatter = logging.Formatter(fmt="%(asctime)s | %(levelname)s | %(message)s", datefmt="%Y/%m/%d %H:%M:%S")
file_handler.setFormatter(formatter)
self.logger.addHandler(file_handler)

初始化

在主模块中

1
2
import log.detector_log
log = log.detector_log.Logger().logger

引入

其他模块中

1
2
import detector_info as di
log = logging.getLogger(di.name)

2. 日志配置写在配置文件中

配置文件

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
#--------------------------------------------------

[loggers]
keys = root, dlog

[logger_root]
level = DEBUG
handlers = console_handler

[logger_dlog]
level = DEBUG
handlers = console_handler, file_handler
# to avoid duplicated log with root logger
propagate = 0
qualname = %(logger_name)s

#--------------------------------------------------

[handlers]
keys = console_handler, file_handler

[handler_console_handler]
class = StreamHandler
level = DEBUG
formatter = simple_format
args = (sys.stdout,)

[handler_file_handler]
class = FileHandler
level = DEBUG
formatter = detailed_format
args = (r"%(log_file_path)s",)

#--------------------------------------------------

[formatters]
keys = detailed_format, simple_format

[formatter_detailed_format]
format = %(asctime)s | %(levelname)s | %(message)s
datefmt = %Y/%m/%d %H:%M:%S

[formatter_simple_format]
format = %(message)s

#--------------------------------------------------

使用标准config file格式,注意=周围的空格会被忽略。

日志模块

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

import logging
import logging.config
import sys
import os

"""
Python中,类实例化的过程是先执行Singleton.__new__生成instance,
然后执行instance.__init__进行初始化的。
所以通过重写__new__可以达到所有调用Singleton()的地方都返回同一个对象。
"""
class Singleton(object):
_instance = None
def __new__(class_, *args, **kwargs):
if not isinstance(class_._instance, class_):
class_._instance = object.__new__(class_, *args, **kwargs)
return class_._instance

"""
单例模式,以适配场景:程序中有多个模块有main入口,都会import本模块;而当这些模块相互import时,logger只应进行一次配置。
"""
class Logger(Singleton):
def __init__(self):
log_dir = os.path.dirname(__file__)
log_config_path = os.path.join(log_dir, "log.config")
log_file_path = os.path.join(log_dir, "argogo.log")
import detector_info as di
logging.config.fileConfig(log_config_path, defaults={"logger_name": di.name, "log_file_path": log_file_path})
self.logger = logging.getLogger(di.name)

初始化及引入方式不变

高光谱相关背景知识

光谱

在电磁学里,电磁波谱包括电磁辐射所有可能的频率。
电磁波谱频率从低到高分别列为无线电波、微波、红外线、可见光、紫外线、X射线和伽马射线。

  • 人类眼睛可以观测到波长大约在400纳米和700纳米之间的电磁辐射,称为可见光。
  • 可见光只是电磁波谱中一个很小的部分
$$\begin{aligned} f=\frac{c}{\lambda} \end{aligned}$$

波长$\lambda$与频率$f$成反比:波长越长,频率越低;波长越短,频率越高。其乘积是一个常数即光速$c$。


高光谱图像

高光谱影像是收集及处理整个跨电磁波谱的信息。
通过搭载在不同空间平台上的高光谱传感器,即成像光谱仪,在电磁波谱的紫外、可见光、近红外和中红外区域,以数十至数百个连续且细分的光谱波段对目标区域同时成像。