-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathatom.xml
More file actions
243 lines (141 loc) · 234 KB
/
atom.xml
File metadata and controls
243 lines (141 loc) · 234 KB
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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Yao's station</title>
<subtitle>Get your hands dirty.</subtitle>
<link href="/atom.xml" rel="self"/>
<link href="http://yaoyirong.cn/"/>
<updated>2018-03-19T15:15:27.000Z</updated>
<id>http://yaoyirong.cn/</id>
<author>
<name>Sixdes</name>
</author>
<generator uri="http://hexo.io/">Hexo</generator>
<entry>
<title>caffe Feature extraction</title>
<link href="http://yaoyirong.cn/2018/01/03/Feature_extraction_caffe/"/>
<id>http://yaoyirong.cn/2018/01/03/Feature_extraction_caffe/</id>
<published>2018-01-03T05:42:00.000Z</published>
<updated>2018-03-19T15:15:27.000Z</updated>
<content type="html"><![CDATA[<p>caffe 官方示例</p><a id="more"></a><h1 id="Feature-extraction-caffe示例1"><a href="#Feature-extraction-caffe示例1" class="headerlink" title="Feature_extraction(caffe示例1)"></a>Feature_extraction(caffe示例1)</h1><p>尝试使用caffe, TensorFlow等框架来实现图像特征提取</p><p>使用Caffe官方提供的深度模型——CaffeNet来演示图像识别与分类。</p><p>使用预先训练的模型进行即时识别,并通过网络界面逐层浏览特征和参数。</p><h2 id="下载CaffeNet模型"><a href="#下载CaffeNet模型" class="headerlink" title="下载CaffeNet模型"></a>下载CaffeNet模型</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</div><div class="line">%matplotlib inline</div><div class="line"></div><div class="line"><span class="comment">#设置默认显示参数</span></div><div class="line">plt.rcParams[<span class="string">'figure.figsize'</span>] = (<span class="number">10</span>, <span class="number">10</span>) <span class="comment"># 图像显示大小</span></div><div class="line">plt.rcParams[<span class="string">'image.interpolation'</span>] = <span class="string">'nearest'</span> <span class="comment"># 最近邻差值: 像素为正方形</span></div><div class="line">plt.rcParams[<span class="string">'image.cmap'</span>] = <span class="string">'gray'</span> <span class="comment"># 使用灰度输出而不是彩色输出</span></div><div class="line"></div><div class="line"><span class="comment"># 这里我们将把caffe 模块添加到Python路径下.</span></div><div class="line"><span class="keyword">import</span> sys</div><div class="line"></div><div class="line">caffe_root = <span class="string">'/usr/local/Cellar/caffe/'</span> <span class="comment"># caffe根目录,此处为相对路径,如果失灵,可换成绝对路径</span></div><div class="line"></div><div class="line"><span class="comment"># sys.path是一个列表,insert()函数插入一行,也可以使用sys.path.append('模块地址')</span></div><div class="line"><span class="comment"># sys.path.insert(0, caffe_root + 'python') # 加载caffe的python模块</span></div><div class="line"><span class="keyword">import</span> caffe</div><div class="line"><span class="keyword">import</span> os</div><div class="line"></div><div class="line"><span class="keyword">if</span> os.path.isfile(caffe_root + <span class="string">'models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel'</span>):</div><div class="line"> print(<span class="string">'caffenet fount'</span>)</div><div class="line"><span class="keyword">else</span>:</div><div class="line"> print(<span class="string">'Downloading pre-trained CaffeNet model...'</span>)</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">caffenet fount</div></pre></td></tr></table></figure><h2 id="加载-net-以及输入图像预处理"><a href="#加载-net-以及输入图像预处理" class="headerlink" title="加载 net 以及输入图像预处理"></a>加载 net 以及输入图像预处理</h2><ul><li>Set Caffe to CPU mode and load the net from disk.</li></ul><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">caffe.set_mode_cpu()</div><div class="line"></div><div class="line">model_def = caffe_root + <span class="string">'models/bvlc_reference_caffenet/deploy.prototxt'</span></div><div class="line">model_weights = caffe_root + <span class="string">'models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel'</span></div><div class="line"></div><div class="line">net = caffe.Net(model_def, <span class="comment"># 定义模型结构</span></div><div class="line"> model_weights, <span class="comment"># 包含了模型的训练权值</span></div><div class="line"> caffe.TEST) <span class="comment"># 使用测试模式(不执行dropout)</span></div></pre></td></tr></table></figure><ul><li>设置输入预处理(我们将使用 <code>caffe.io.Transformer</code> 来进行预处理.由于该步骤与caffe的其它模块相互独立,所以任何预处理代码应该都是可行的)</li></ul><p>CaffeNet模型默认的输入图像格式是BGR格式, 其像素值位于[0,255]之间, 同时每个像素值都减去了ImageNet图像的平均值. 此外, 通道的维数等于第一维(outermost最外面的)大小</p><p>由于matplotlib加载的图像的值位于[0,1]之间,并且格式是RGB格式,通道的维数等于innermost(最里面的)维数,所以需要做相应变换:</p><h3 id="图像变换"><a href="#图像变换" class="headerlink" title="图像变换"></a>图像变换</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># 加载ImageNet训练集(同caffe一起发布)的图像均值,预处理需要减去均值</span></div><div class="line"><span class="comment"># 加载均值文件</span></div><div class="line">mu = np.load(caffe_root + <span class="string">'python/caffe/imagenet/ilsvrc_2012_mean.npy'</span>) </div><div class="line"><span class="comment"># mu.shape (3, 256, 256)</span></div><div class="line"><span class="comment"># 对所有像素值取平均以此获取BGR的均值像素值</span></div><div class="line">mu = mu.mean(<span class="number">1</span>).mean(<span class="number">1</span>)</div><div class="line">print(<span class="string">'mean-subtracted values: '</span>, list(zip(<span class="string">'BGR'</span>, mu)))</div><div class="line"></div><div class="line"><span class="comment"># 对输入数据进行变换</span></div><div class="line"><span class="comment"># caffe.io.transformer是一个类,实体化的时候构造函数__init__(self, inputs)给一个初值</span></div><div class="line"><span class="comment"># 其中net.blobs本身是一个字典,每一个key对应每一层的名字</span></div><div class="line"><span class="comment"># net.blobs['data'].data.shape计算结果为(10, 3, 227, 227)</span></div><div class="line"><span class="comment"># print(net.blobs['data'].data.shape)</span></div><div class="line">transformer = caffe.io.Transformer({<span class="string">'data'</span>: net.blobs[<span class="string">'data'</span>].data.shape})</div><div class="line"></div><div class="line"><span class="comment"># 以下都是caffe.io.transformer类的函数方法</span></div><div class="line"><span class="comment"># caffe.io.transformer的类定义放在io.py文件中,也可用help函数查看说明</span></div><div class="line"></div><div class="line"><span class="comment"># 将图像通道数设置为outermost的维数</span></div><div class="line">transformer.set_transpose(<span class="string">'data'</span>, (<span class="number">2</span>, <span class="number">0</span>, <span class="number">1</span>)) </div><div class="line"><span class="comment"># 每个通道都减去BGR的均值像素值</span></div><div class="line">transformer.set_mean(<span class="string">'data'</span>, mu)</div><div class="line"><span class="comment"># 像素值从[0,1]变换为[0,255]</span></div><div class="line">transformer.set_raw_scale(<span class="string">'data'</span>, <span class="number">255</span>)</div><div class="line"><span class="comment"># 交换通道,RGB->BGR</span></div><div class="line">transformer.set_channel_swap(<span class="string">'data'</span>, (<span class="number">2</span>, <span class="number">1</span>, <span class="number">0</span>))</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">mean-subtracted values: [('B', 104.0069879317889), ('G', 116.66876761696767), ('R', 122.6789143406786)]</div></pre></td></tr></table></figure><h3 id="CPU-分类"><a href="#CPU-分类" class="headerlink" title="CPU 分类"></a>CPU 分类</h3><h4 id="设置输入图像大小-可跳"><a href="#设置输入图像大小-可跳" class="headerlink" title="设置输入图像大小(可跳)"></a>设置输入图像大小(可跳)</h4><p>现在我们开始进行分类. 尽管我们只对一张图像进行分类, 不过我们将batch的大小设置为50以此来演示batching(一批).</p><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># 设置输入图像大小(可跳, 以后也可以改)</span></div><div class="line">net.blobs[<span class="string">'data'</span>].reshape(<span class="number">50</span>, <span class="comment"># batch size</span></div><div class="line"> <span class="number">3</span>, <span class="comment"># 3-channel (BGR) images</span></div><div class="line"> <span class="number">227</span>, <span class="number">227</span>) <span class="comment"># # image size is 227x227</span></div></pre></td></tr></table></figure><h4 id="加载图像-caffe自带的-并进行预处理"><a href="#加载图像-caffe自带的-并进行预处理" class="headerlink" title="加载图像(caffe自带的)并进行预处理"></a>加载图像(caffe自带的)并进行预处理</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># image RGB 0-1 innermost</span></div><div class="line"></div><div class="line">image = caffe.io.load_image(caffe_root + <span class="string">'examples/images/cat.jpg'</span>)</div><div class="line">print(image.shape)</div><div class="line"><span class="comment"># transformed_image BGR 0-255 outermost</span></div><div class="line">transformed_image = transformer.preprocess(<span class="string">'data'</span>, image)</div><div class="line">print(transformed_image.shape)</div><div class="line">plt.imshow(image)</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">(360, 480, 3)</div><div class="line">(3, 227, 227)</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><matplotlib.image.AxesImage at 0x147e865f8></div></pre></td></tr></table></figure><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/images/Feature_extraction_caffe/output_10_2.png" alt="output_10_2" title=""> </div> <div class="image-caption">output_10_2</div> </figure><h4 id="开始分类"><a href="#开始分类" class="headerlink" title="开始分类"></a>开始分类</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># 将图像数据拷贝到为net分配的内存中</span></div><div class="line"><span class="comment"># type(net.blobs['data'] -- <class 'caffe._caffe.Blob'></span></div><div class="line">net.blobs[<span class="string">'data'</span>].data[...] = transformed_image</div><div class="line"></div><div class="line"><span class="comment"># 执行分类</span></div><div class="line"><span class="comment"># 前向传播,进行分类, 跑一遍网络,默认结果为最后一层的blob(也可以指定某一中间层),赋给output</span></div><div class="line">output = net.forward()</div><div class="line"></div><div class="line"><span class="comment"># output['prob']矩阵的维度是(50, 1000)</span></div><div class="line"><span class="comment"># 取batch中第一张图像的概率值 (1000,)</span></div><div class="line">output_prob = output[<span class="string">'prob'</span>][<span class="number">0</span>]</div><div class="line"><span class="comment"># 打印概率最大的类别代号,argmax()函数是求取矩阵中最大元素的索引</span></div><div class="line">print(<span class="string">'predicted class is:'</span>, output_prob.argmax())</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">predicted class is: 281</div></pre></td></tr></table></figure><h4 id="验证结果是否正确"><a href="#验证结果是否正确" class="headerlink" title="验证结果是否正确"></a>验证结果是否正确</h4><p>net 输出是一个概率向量,最可能的类别是第281个类别. 但是结果是否正确呢,需要查看一下ImageNet的标签…</p><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># 加载ImageNet标签,如果不存在,则会自动下载</span></div><div class="line">labels_file = caffe_root + <span class="string">'data/ilsvrc12/synset_words.txt'</span></div><div class="line"><span class="keyword">if</span> <span class="keyword">not</span> os.path.exists(labels_file):</div><div class="line"> <span class="comment"># !../data/ilsvrc12/get_ilsvrc_aux.sh</span></div><div class="line"> print(<span class="string">'not found'</span>)</div><div class="line"></div><div class="line"><span class="comment"># 读取纯文本数据,三个参数分别是文件地址、数据类型和数据分隔符,保存为字典格式 </span></div><div class="line">labels = np.loadtxt(labels_file, str, delimiter=<span class="string">'\t'</span>)</div><div class="line"></div><div class="line">print(<span class="string">'output label:'</span>, labels[output_prob.argmax()])</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">output label: n02123045 tabby, tabby cat</div></pre></td></tr></table></figure><p>“Tabby cat”是正确的,我们再来看下其它几个置信的较高的结果。</p><h4 id="其他结果"><a href="#其他结果" class="headerlink" title="其他结果"></a>其他结果</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># 从softmax output可查看置信度最高的五个结果</span></div><div class="line"><span class="comment"># reverse逆序排列,取前五个最大值</span></div><div class="line">top_inds = output_prob.argsort()[::<span class="number">-1</span>][:<span class="number">5</span>]</div><div class="line"></div><div class="line">print(<span class="string">'probabilites and labels: '</span>)</div><div class="line"><span class="keyword">for</span> prob, label <span class="keyword">in</span> zip(output_prob[top_inds], labels[top_inds]):</div><div class="line"> print(prob, label)</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">probabilites and labels: </div><div class="line">0.312447 n02123045 tabby, tabby cat</div><div class="line">0.23797 n02123159 tiger cat</div><div class="line">0.123878 n02124075 Egyptian cat</div><div class="line">0.100752 n02119022 red fox, Vulpes vulpes</div><div class="line">0.0709571 n02127052 lynx, catamount</div></pre></td></tr></table></figure><p>我们可以看出,较低置信度的结构也是合理的</p><h4 id="GPU-模式加速-Mac无"><a href="#GPU-模式加速-Mac无" class="headerlink" title="GPU 模式加速(Mac无)"></a>GPU 模式加速(Mac无)</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">%timeit net.forward()</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">1.39 s ± 63.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)</div></pre></td></tr></table></figure><p>Mac 没有NVIDA的GPU, 故而不进行GPU加速, 加速的的确快</p><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="string">'''</span></div><div class="line"># gpu模式下跑一次</div><div class="line"># 使用第一块显卡</div><div class="line">caffe.set_device(0)</div><div class="line"># 设为gpu模式</div><div class="line">caffe.set_mode_gpu()</div><div class="line">net.forward()</div><div class="line">&timeit net.forward()</div><div class="line">'''</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">'\n# gpu模式下跑一次\n# 使用第一块显卡\ncaffe.set_device(0)\n# 设为gpu模式\ncaffe.set_mode_gpu()\nnet.forward()\n&timeit net.forward()\n'</div></pre></td></tr></table></figure><h3 id="测试中间输出结果"><a href="#测试中间输出结果" class="headerlink" title="测试中间输出结果"></a>测试中间输出结果</h3><ul><li>网络net不单单是一个黑盒子。我们接下来看看该模型的一些参数和一些中间输出。</li></ul><h3 id="中间层的可视化"><a href="#中间层的可视化" class="headerlink" title="中间层的可视化"></a>中间层的可视化</h3><p>首先,我们来看下如何读取网络的结构(每层的名字以及相应层的参数)</p><p>每一层的结构四部分(batch_size, channel_dim, height, width)</p><p>net.blobs 类型是 OrderedDict</p><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># 对于每一层,显示输出维度</span></div><div class="line"><span class="comment"># type(net.blobs) <class 'collections.OrderedDict'></span></div><div class="line"><span class="keyword">for</span> layer_name, blob <span class="keyword">in</span> net.blobs.items():</div><div class="line"> print(layer_name, <span class="string">'\t'</span>, str(blob.data.shape))</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div></pre></td><td class="code"><pre><div class="line">data (50, 3, 227, 227)</div><div class="line">conv1 (50, 96, 55, 55)</div><div class="line">pool1 (50, 96, 27, 27)</div><div class="line">norm1 (50, 96, 27, 27)</div><div class="line">conv2 (50, 256, 27, 27)</div><div class="line">pool2 (50, 256, 13, 13)</div><div class="line">norm2 (50, 256, 13, 13)</div><div class="line">conv3 (50, 384, 13, 13)</div><div class="line">conv4 (50, 384, 13, 13)</div><div class="line">conv5 (50, 256, 13, 13)</div><div class="line">pool5 (50, 256, 6, 6)</div><div class="line">fc6 (50, 4096)</div><div class="line">fc7 (50, 4096)</div><div class="line">fc8 (50, 1000)</div><div class="line">prob (50, 1000)</div></pre></td></tr></table></figure><h3 id="参数的维数"><a href="#参数的维数" class="headerlink" title="参数的维数"></a>参数的维数</h3><p>我们来看下参数的维数. 参数是OrderdDict类型,我们根据索引来访问参数, net.params[0]:权值表示weights,net.params[1]:表示偏移量biases</p><p>权值参数的维度表示是(output_channels, input_channels, filter_height, filter_width)<br>偏移量参数的维度表示(output_channels,) 一维</p><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># 循环打印参数名称,权值参数和偏移量参数的维度</span></div><div class="line"><span class="keyword">for</span> layer_name, param <span class="keyword">in</span> net.params.items():</div><div class="line"> print(layer_name, <span class="string">'\t'</span>, str(param[<span class="number">0</span>].data.shape), str(param[<span class="number">1</span>].data.shape))</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">conv1 (96, 3, 11, 11) (96,)</div><div class="line">conv2 (256, 48, 5, 5) (256,)</div><div class="line">conv3 (384, 256, 3, 3) (384,)</div><div class="line">conv4 (384, 192, 3, 3) (384,)</div><div class="line">conv5 (256, 192, 3, 3) (256,)</div><div class="line">fc6 (4096, 9216) (4096,)</div><div class="line">fc7 (4096, 4096) (4096,)</div><div class="line">fc8 (1000, 4096) (1000,)</div></pre></td></tr></table></figure><h4 id="辅助函数-helper"><a href="#辅助函数-helper" class="headerlink" title="辅助函数 helper"></a>辅助函数 helper</h4><p>这里要将四维数据进行特征可视化,需要一个定义辅助函数:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">def</span> <span class="title">vis_square</span><span class="params">(data)</span>:</span></div><div class="line"> <span class="string">'''</span></div><div class="line"> 输入一个形如:(n, height, width) or (n, height, width, 3)的数组,</div><div class="line"> 并对每一个形如(height,width)的特征进行可视化到一个大小近似的网格中sqrt(n) by sqrt(n)</div><div class="line"> '''</div><div class="line"> <span class="comment"># 数据正则化</span></div><div class="line"> data = (data - data.min()) / (data.max() - data.min())</div><div class="line"> </div><div class="line"> <span class="string">'''</span></div><div class="line"> 将滤波器的核转变为正方形</div><div class="line"> 此处目的是将一个个滤波器按照正方形的样子排列,</div><div class="line"> 先对shape[0]也就是滤波器数量取平方根,然后取大于等于该结果的正整数</div><div class="line"> ceil 向上取整</div><div class="line"> 比如40个卷积核,则需要7*7的正方形格子(虽然填不满)</div><div class="line"> '''</div><div class="line"> n = int(np.ceil(np.sqrt(data.shape[<span class="number">0</span>])))</div><div class="line"> padding = (</div><div class="line"> ((<span class="number">0</span>, n**<span class="number">2</span> - data.shape[<span class="number">0</span>]), (<span class="number">0</span>, <span class="number">1</span>), (<span class="number">0</span>, <span class="number">1</span>)) <span class="comment"># 在相邻的卷积核之间加入空白</span></div><div class="line"> + ((<span class="number">0</span>, <span class="number">0</span>),) *(data.ndim - <span class="number">3</span>) <span class="comment"># 不填充最后一维</span></div><div class="line"> )</div><div class="line"> <span class="comment"># 每张小图片向周围扩展一个白色像素</span></div><div class="line"> data = np.pad(data, padding, mode=<span class="string">'constant'</span>, constant_values=<span class="number">1</span>) </div><div class="line"> <span class="string">'''</span></div><div class="line"> pad函数声明:pad(array, pad_width, mode, **kwargs),作用是把list在原维度上进行扩展;</div><div class="line"> pad_width是扩充参数,例如参数((3,2),(2,3));</div><div class="line"> 其中(3,2)为水平方向上,上面加3行,下面加2行;</div><div class="line"> (2,3)为垂直方向上,上面加2行,下面加3行;</div><div class="line"> (1, 1)相当于常数, 各个方向都填充</div><div class="line"> constant是常数填充的意思。</div><div class="line"> '''</div><div class="line"> </div><div class="line"> <span class="comment"># 将卷积核平铺成图片</span></div><div class="line"> data = data.reshape((n, n) + data.shape[<span class="number">1</span>:]).transpose((<span class="number">0</span>, <span class="number">2</span>, <span class="number">1</span>, <span class="number">3</span>) + tuple(range(<span class="number">4</span>, data.ndim+<span class="number">1</span>)))</div><div class="line"> data = data.reshape((n * data.shape[<span class="number">1</span>], n * data.shape[<span class="number">3</span>]) + data.shape[<span class="number">4</span>:])</div><div class="line"> </div><div class="line"> plt.imshow(data)</div><div class="line"> plt.axis(<span class="string">'off'</span>)</div></pre></td></tr></table></figure><h4 id="卷积层-conv1-的输出特征"><a href="#卷积层-conv1-的输出特征" class="headerlink" title="卷积层(conv1)的输出特征"></a>卷积层(conv1)的输出特征</h4><p> 首先,我们来看下第一个卷积层(conv1)的输出特征</p><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># 参数为一个[weights, biases]的列表</span></div><div class="line">filters = net.params[<span class="string">'conv1'</span>][<span class="number">0</span>].data</div><div class="line">vis_square(np.transpose(filters, (<span class="number">0</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">1</span>)))</div></pre></td></tr></table></figure><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/images/Feature_extraction_caffe/output_28_0.png" alt="output_28_0" title=""> </div> <div class="image-caption">output_28_0</div> </figure><p>The first layer output, conv1 (rectified responses of the filters above, first 36 only)</p><h4 id="conv1-的blob数据"><a href="#conv1-的blob数据" class="headerlink" title="conv1 的blob数据"></a>conv1 的blob数据</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># 选取‘conv1’的blob数据,只选择前面36张图片</span></div><div class="line">feat = net.blobs[<span class="string">'conv1'</span>].data[<span class="number">0</span>, :<span class="number">36</span>]</div><div class="line">vis_square(feat)</div></pre></td></tr></table></figure><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/images/Feature_extraction_caffe/output_30_0.png" alt="output_30_0" title=""> </div> <div class="image-caption">output_30_0</div> </figure><h4 id="pool5"><a href="#pool5" class="headerlink" title="pool5"></a>pool5</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">feat = net.blobs[<span class="string">'pool5'</span>].data[<span class="number">0</span>]</div><div class="line">vis_square(feat)</div></pre></td></tr></table></figure><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/images/Feature_extraction_caffe/output_32_0.png" alt="output_32_0" title=""> </div> <div class="image-caption">output_32_0</div> </figure><h4 id="fc6"><a href="#fc6" class="headerlink" title="fc6"></a>fc6</h4><p>第一个完全连接层,fc6;<br>接下来,我们将显示输出结果(>0的值)及直方图.</p><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># 选取fc6的输出数据,这是一个4096维的向量</span></div><div class="line">feat = net.blobs[<span class="string">'fc6'</span>].data[<span class="number">0</span>] </div><div class="line"><span class="comment"># 创建2行1列的子图,现在是第1个子图</span></div><div class="line">plt.subplot(<span class="number">2</span>, <span class="number">1</span>, <span class="number">1</span>)</div><div class="line"><span class="comment"># 平铺向量,图像显示其每一个值</span></div><div class="line">plt.plot(feat.flat)</div><div class="line">plt.subplot(<span class="number">2</span>, <span class="number">1</span>, <span class="number">2</span>)</div><div class="line"><span class="comment"># 做直方图,总共100根条形</span></div><div class="line">_ = plt.hist(feat.flat[feat.flat > <span class="number">0</span>], bins=<span class="number">100</span>)</div></pre></td></tr></table></figure><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/images/Feature_extraction_caffe/output_34_0.png" alt="output_34_0" title=""> </div> <div class="image-caption">output_34_0</div> </figure><h4 id="最终的概率输出-prob"><a href="#最终的概率输出-prob" class="headerlink" title="最终的概率输出 prob"></a>最终的概率输出 prob</h4><p>注意强大的预测集群; 标签按照语义排序。 如上所示,顶部峰值对应于顶部预测标签。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">feat = net.blobs[<span class="string">'prob'</span>].data[<span class="number">0</span>]</div><div class="line">plt.figure(figsize=(<span class="number">15</span>, <span class="number">3</span>))</div><div class="line">plt.plot(feat.flat)</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">[<matplotlib.lines.Line2D at 0x148b944e0>]</div></pre></td></tr></table></figure><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/images/Feature_extraction_caffe/output_36_1.png" alt="output_36_1" title=""> </div> <div class="image-caption">output_36_1</div> </figure><h3 id="测试自己的图片"><a href="#测试自己的图片" class="headerlink" title="测试自己的图片"></a>测试自己的图片</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div></pre></td><td class="code"><pre><div class="line"><span class="string">'''</span></div><div class="line"># 下载图像</div><div class="line"># 图像URL地址</div><div class="line">my_image_url = ""</div><div class="line"># 在线下载图片</div><div class="line">!wget -O image.jpg $my_image_url </div><div class="line">'''</div><div class="line"><span class="comment"># 变换图像并将其拷贝到网络</span></div><div class="line">image = caffe.io.load_image(<span class="string">'../images.jpeg'</span>)</div><div class="line">net.blobs[<span class="string">'data'</span>].data[...] = transformer.preprocess(<span class="string">'data'</span>, image) </div><div class="line"></div><div class="line"><span class="comment"># 预测分类结果</span></div><div class="line">net.forward()</div><div class="line"></div><div class="line"><span class="comment"># 获取输出概率值</span></div><div class="line">output_prob = net.blobs[<span class="string">'prob'</span>].data[<span class="number">0</span>]</div><div class="line"></div><div class="line"><span class="comment"># 将softmax的输出结果按照从大到小排序,并取前5名</span></div><div class="line">top_inds = output_prob.argsort()[::<span class="number">-1</span>][:<span class="number">5</span>]</div><div class="line"></div><div class="line">plt.imshow(image)</div><div class="line">print(<span class="string">'probabilities and labels:'</span>)</div><div class="line"><span class="keyword">for</span> prob, label <span class="keyword">in</span> zip(output_prob[top_inds], labels[top_inds]):</div><div class="line"> print(prob, <span class="string">'\t'</span>, label)</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">probabilities and labels:</div><div class="line">0.936924 n02099712 Labrador retriever</div><div class="line">0.0573292 n02099601 golden retriever</div><div class="line">0.00213249 n02088364 beagle</div><div class="line">0.00084234 n02104029 kuvasz</div><div class="line">0.000632635 n02111500 Great Pyrenees</div></pre></td></tr></table></figure><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/images/Feature_extraction_caffe/output_38_1.png" alt="output_38_1" title=""> </div> <div class="image-caption">output_38_1</div> </figure>]]></content>
<summary type="html">
<p>caffe 官方示例</p>
</summary>
<category term="Feature extraction" scheme="http://yaoyirong.cn/categories/Feature-extraction/"/>
<category term="Image processing" scheme="http://yaoyirong.cn/tags/Image-processing/"/>
</entry>
<entry>
<title>Image processing - Feature extraction</title>
<link href="http://yaoyirong.cn/2017/12/26/%E5%9B%BE%E5%83%8F%E7%89%B9%E5%BE%81%E8%AF%86%E5%88%AB%E6%96%87%E5%AD%97%E6%80%A7%E6%8F%8F%E8%BF%B0/"/>
<id>http://yaoyirong.cn/2017/12/26/图像特征识别文字性描述/</id>
<published>2017-12-26T07:47:00.000Z</published>
<updated>2017-12-26T07:48:17.000Z</updated>
<content type="html"><![CDATA[<p>纯文字描述</p><a id="more"></a><p>[TOC]</p><h1 id="图像特征识别"><a href="#图像特征识别" class="headerlink" title="图像特征识别"></a>图像特征识别</h1><blockquote><p>调研 针对图像, 视频, 音频特征提取的工具和算法(方法)</p></blockquote><h2 id="图像特征概述"><a href="#图像特征概述" class="headerlink" title="图像特征概述"></a>图像特征概述</h2><p>属于图像分析的范畴, 也是图像识别的开始。如何从图像中提取有用的数据或信息,得到图像的“非图像” 的表示或描述,如数值、向量和符号等(特征提取).<br> “非图像”的表示或描述就是特征(数值或向量形式)。</p><p><strong>图像特征</strong><br>对于图像而言, 每一幅图像都具有能够区别于其他类图像的自身特征,有些是可以直观地感受到的自然特征,如亮度、边缘、纹理和色彩等;有些则是需要通过变换或处理才能得到的, 如矩、直方图以及主成份等.</p><p><strong>特征向量</strong><br>将某一类对象的多个或多种特性组合在一起, 形成一个特征向量来代表该类对象,如果只有单个数值特征,则特征向量为一个一维向量,如果是n个特性的组合,则为一个n维特征向量。该类特征向量常常作为识别系统的输入。</p><p>一个n维特征就是位于n维空间中的点,而识别分类的任务就是找到对这个n维空间的一种划分。 </p><p><strong>特征提取的一般原则</strong><br>图像识别实际上是一个<strong>分类</strong>的过程,要求选取的特征不仅要能够很好地描述图像,更重要的是还要能够很好地区分不同类别的图像。</p><p>在同类图像之间差异较小(较小的类内距),在不同类别的图像之间差异较大(较大的类间距)的图像特征 —- 最具有区分能力(most discriminative)的特征。在特征提取中先验知识扮演着重要的角色, 如何依靠先验知识来帮助我们选择特征也是后面将持续关注的问题。</p><p><strong>特征的评价标准</strong><br>特征提取应具体问题具体分析, 还是有一些可供遵循的普遍原则:</p><ul><li>特征应当容易提取</li><li>选取的特征应对噪声和不相关转换不敏感.<ul><li>比如: 需要得到对几何失真变形等转换不敏感的描绘子, 从而得到旋转不变, 或是投影失真不变的特征</li></ul></li><li>应试图寻找最具区分能力的特征.</li></ul><h2 id="基本统计特征"><a href="#基本统计特征" class="headerlink" title="基本统计特征"></a>基本统计特征</h2><blockquote><p>常用的基本统计特征,包括一些简单的<strong>区域描绘子</strong>, <strong>直方图</strong>及其<strong>统计特征</strong>以及<strong>灰度共现矩阵</strong>等</p></blockquote><h3 id="简单的区域描绘子及其Matlab实现"><a href="#简单的区域描绘子及其Matlab实现" class="headerlink" title="简单的区域描绘子及其Matlab实现"></a>简单的区域描绘子及其Matlab实现</h3><p>在经过图像分割得到各种我们感兴趣的区域之后<code>patch_tree = img[7:150, 300:450]</code>, 利用一些简单区域描绘子作为代表该区域的特征。通常将这些<strong>区域特征</strong>组合成<strong>特征向量</strong>以供分类使用。</p><p>常用的简单区域描绘子如下:</p><ul><li>周长: 区域边界的长度, 即位于区域边界上的像素数目</li><li>面积: 区域中的像素总数.</li><li>致密性: (周长) 2/面积.</li><li>区域的质心</li><li>灰度均值: 区域中所有像素的平均值.</li><li>灰度中值: 区域中所有像素的排序中值.</li><li>包含区域的最小矩形.</li><li>最小或最大灰度级</li><li>大于或小于均值的像素数</li><li>欧拉数: 区域中的对象数减去这些对象的孔洞数</li></ul><p>MATLAB 使用 <code>regionprops</code> 计算区域描绘子, 其原型 <code>D = regionprops(L,properties)</code> L是一个标记矩阵, properties可以是一个用逗号分割的字符串列表,常用取值如下:</p><ul><li>‘Area’ : 区域中的像素总数.</li><li>‘BoundingBox’: 包含区域的最小矩形. 1x4向量(矩形左上角x坐标, 矩形左上角y坐标, x方向长度, y方向长度)</li><li>Centroid: 区域的质心. 1x2向量: [质心x坐标, 质心y坐标]</li><li>ConvexHull: 含区域的最小凸多边形. Px2矩阵: 每一行包含多边形p个顶点之一的x和y坐标</li><li>EquivDiameter: 和区域有着相同面积的圆的直径</li><li>EulerNumber: 欧拉数, 区域中的对象数减去这些对象的孔洞数</li></ul><h3 id="直方图及其统计特征-一维"><a href="#直方图及其统计特征-一维" class="headerlink" title="直方图及其统计特征 (一维)"></a>直方图及其统计特征 (一维)</h3><p>纹理是图像固有的特征之一,是灰度(对彩色图像而言是颜色)<strong>在空间以一定的形式变换</strong>而产生的图案(模式),有时具有一定的周期性。直方图正是<strong>描述图像中像素灰度级分布</strong>的有力工具,可以用<strong>直方图或其统计特征</strong>作为图像纹理特征。</p><p>直方图本身就是一个向量,向量的维数是直方图统计的灰度级数,因此可以直接以此向量作为代表图像纹理的样本特征向量,从而交给分类器处理,对于LBP直方图就常常这样处理);另一种思路是进一步从直方图中提取出能够很好地描述<strong>直方图的统计特征</strong>,将直方图的这些统计特征组合成为样本特征向量, 这样做可以<strong>大大降低特征向量的维数</strong>。</p><p><strong>直方图的常用统计特征</strong>:<br>均值, 标准方差, 平滑度, 三阶矩, 一致性, 熵<br>一个由均值、标准差、平滑度和熵组合而成的特征向量如:v = (m,a, R, e)。 </p><p><strong>依靠直方图及其统计特征来作为分类特征时需要特别注意</strong><br>应认识到直方图及其统计特征是一种区分能力相对较弱的特征,这主要因为直方图属于一阶统计特征,而它们的一阶统计特征是无法反映纹理结构的变化的。直方图与纹理的对应关系并不是一对一的:首先,不同的纹理可能具有相同或相似的直方图; 其次,即便是两个不同的直方m.也可能具有相同的统计特 征如均值、标准差等。</p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/images/图像特征识别文字描述/直方图常用统计特征.png" alt="直方图常用统计特征" title=""> </div> <div class="image-caption">直方图常用统计特征</div> </figure><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/images/图像特征识别文字描述/直方图常用统计特征接上.png" alt="直方图常用统计特征接上" title=""> </div> <div class="image-caption">直方图常用统计特征接上</div> </figure><h3 id="灰度共现矩阵-二维"><a href="#灰度共现矩阵-二维" class="headerlink" title="灰度共现矩阵 (二维)"></a>灰度共现矩阵 (二维)</h3><p>灰度直方图是一种描述单个像素灰度分布的一阶统计量;而灰度共现矩阵描述的则是<strong>具有某种空间位置关系的两个像素的联合分布</strong>, 可以看成是两个像素灰度对的联合直方图,是种二阶统计量。</p><p>纹理是由灰度分布在空间位置上反复交替变化得来的, 因此在图像中具有某种空间位置关系的两个像素之间会存在一定的灰度关系, 这种关系被称为图像灰度的空间相关特性.<br>灰度共现矩阵可以比较好的表现灰度的空间相关性</p><p>x y 单位 灰度级是L 则为L x L 方阵, 其中每个元素 Pd(i, j)<br>Pd(i, j) 为具有空间位置关系 d = (Dx, Dy), 并且灰度分别为 i 和 j 的两个像素出现的次数或者是概率(归一化)</p><p>常用的空间位置关系: 水平(±Dx,0), 竖直(0, ±Dy) 正45°(Dx,-Dy), (-Dx, Dy)负45°(Dx, Dy), (-Dx, -Dy)</p><p>当灰度级L比较大时它将是一个庞大的方阵。如对于一般的256灰度图,凡就是一个256X256的矩阵,共2^16个元素。如此庞大的矩阵将使后续的计算量剧增。因此普通灰度图像通常要经过<strong>处理以减少灰度级数</strong>,而后再计算灰度共现矩阵。可以通过分析纹理图像的直方图,在尽量不影响纹理质量的情况下.通过适当的灰度变换来达到灰度级压缩的目的。</p><h3 id="特征降维"><a href="#特征降维" class="headerlink" title="特征降维"></a>特征降维</h3><h4 id="维度灾难"><a href="#维度灾难" class="headerlink" title="维度灾难"></a>维度灾难</h4><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/images/图像特征识别文字描述/维度灾难.png" alt="维度灾难" title=""> </div> <div class="image-caption">维度灾难</div> </figure><p>最大值时,分类器的性能不是得到改善,而是退化。<br>在低维空间中计算和分类都将变 得简单很多,训练(教授分类器如何区分不同类样本的过程,详见第11章)所需的样本数目也会大大降低。通过选择好的特征,摒弃坏的特征(10.3.2特征选择),将有助于分类器性能的提升;在通过组合特征降维时,在绝大多数情况下,丢弃某些特征所损失的信息通过在低 维空间中更加精确的映射(10.3.3特征抽取)可以得到补偿。</p><p><strong>降维的两个方法</strong>:</p><ul><li>特征选择<ul><li>选择全部特征的一个子集作为特征向量</li></ul></li><li>特征抽取<ul><li>通过已有特征的组合建立一个新的特征子集</li><li>如主成份分析方法(principa1component analysis, PCA) 原特征的线性组合</li></ul></li></ul><h4 id="主成分分析-Princjpal-Component-Analysis-PCA"><a href="#主成分分析-Princjpal-Component-Analysis-PCA" class="headerlink" title="主成分分析(Princjpal Component Analysis, PCA)"></a>主成分分析(Princjpal Component Analysis, PCA)</h4><p>特征抽取是指通过已有特征的组合(变换)建立一个新的特征子集。在众多的组合方法当中,线性组合(变换)因其计算简单且便于解析分析的特点而显得颇具吸引力。<br>PCA的实质就是在尽可能好地代表原始数据的前提下,通过线性变换将高维空间中的样本数据投影到低维空间中.</p><h2 id="图片特征提取"><a href="#图片特征提取" class="headerlink" title="图片特征提取"></a>图片特征提取</h2><p>图像处理的基础就是要进行特征点的提取,feature(interest points) detect 的方法也在不断的进步,边检测,角点检测,直线检测,圆检测,SIFT特征点检测,同时描述符也在发展,为了匹配的高效,逐渐从高维特征向量到二进制向量…</p><h3 id="通过像素值提取特征"><a href="#通过像素值提取特征" class="headerlink" title="通过像素值提取特征"></a>通过像素值提取特征</h3><p>比如识别光学字符, 0-9; scikit-learn的digits数字集包括至少1700种0-9的手写数字图像。每个图像都有8x8像像素构成。每个像素的值是0-16,白色是0,黑色是16。<br>将8x8矩阵转换成64维向量来创建一个特征向量:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</div><div class="line"><span class="keyword">from</span> sklearn <span class="keyword">import</span> datasets</div><div class="line"></div><div class="line">digits = datasets.load_digits()</div><div class="line"><span class="comment"># reshape的返回值都是 narray, 如果参数只有-1, 就是一维, 后面还加了64, 就是二维(1, 64)</span></div><div class="line">print(digits.image[<span class="number">0</span>].reshape(<span class="number">-1</span>, <span class="number">64</span>)</div></pre></td></tr></table></figure><p>可以有效的处理一些基本任务,比如识别手写字母等。但是,记录每个像素的数值在大图像处理时不太好用。<br>特征向量的维度灾难; 放缩,旋转或变换之后可能不对,缺乏稳定性; 对图像的亮度也十分敏感.<br><strong>现代计算机视觉应用通常手工实现特征提取,或者用深度学习自动化解决无监督问题。</strong></p><h3 id="对感兴趣的点进行特征提取"><a href="#对感兴趣的点进行特征提取" class="headerlink" title="对感兴趣的点进行特征提取"></a>对感兴趣的点进行特征提取</h3><p>有信息量的属性,称为兴趣点(points of interest); 由丰富的纹理包围,基本可以重建图像。<br><strong>边缘(edges)</strong>和<strong>角点(corners)</strong>是两种常用的兴趣点类型。边是像素快速变化的分界线(boundary),<br>这种提取方式更紧凑,而且当图片的亮度发生统一变化时,这些兴趣点依然存在。</p><p>Harris角点检测<br>scikit-image(skimage)库抽取图片的兴趣点<br><code>corners = corner_peak(corner_harris(image), min_distance=2)</code><br><code>corner_x, corner_y = zip(*corners)</code></p><h3 id="SIFT-特征提取"><a href="#SIFT-特征提取" class="headerlink" title="SIFT 特征提取"></a>SIFT 特征提取</h3><p>主要的思想是每个检测到的特征点都伴随对应的尺度因子, 具有尺度,旋转,仿射,视角,光照不变性。<br>引入兴趣点提取方法,通过SIFT和SURF进行优化。</p><p>尺度不变特征转换(Scale-Invariant Feature Transform,SIFT), 相比前面使用的方法,SIFT对图像的尺寸,旋转,亮度变化更不敏感。<strong>每个SIFT特征都是一个描述图片上某个区域边缘和角点的向量</strong>. 和兴趣点不同,SIFT还可以获取每个兴趣点和它周围点的综合信息</p><h3 id="SURF-特征抽取"><a href="#SURF-特征抽取" class="headerlink" title="SURF 特征抽取"></a>SURF 特征抽取</h3><p>加速稳健特征(Speeded-Up Robust Features,SURF), 是另一个抽取图像兴趣点的方法,其特征向量对图像的尺寸,旋转,亮度变化是不变的。其特征向量对图像的尺寸,旋转,亮度变化是不变的。<br>和兴趣点抽取类似,抽取SURF只是机器学习中创建特征向量的第一步。训练集的每个实例都会抽取不同的SURF。第六章的,K-Means聚类,我们会介绍聚类方法抽取SURF来学习特征,可以作为一种图像分类方法.<br><code>mahotas</code>(计算机视觉和图像处理 Python 库)<br><strong>包含算法</strong>:</p><ul><li>分水岭。</li><li>凸点计算。</li><li>击中/击不中,细化算法。</li><li>泽尼克&Haralick,枸杞多糖,和TAS的功能。</li><li>基于freeimage的numpy图像加载(需要安装freeimage库)。</li><li>加速的鲁棒特征(SURF)等。</li><li>阈值。</li><li>卷积。</li><li>Sobel边缘检测。</li><li>多边形绘制</li><li>距离变换</li><li>特征计算</li><li>样条插值</li></ul><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> mahotas <span class="keyword">as</span> mh</div><div class="line"><span class="keyword">from</span> mahotas.features <span class="keyword">import</span> surf</div><div class="line"></div><div class="line">image = mh.imread(<span class="string">'mandrill.jpeg'</span>, as_grey=<span class="keyword">True</span>)</div><div class="line">print(<span class="string">'第一个SURF描述符: \n{}\n'</span>.format(surf.surf(image)[<span class="number">0</span>]))</div><div class="line">print(<span class="string">'抽取了%s个SURF描述符'</span> % len(surf.surf(image)))</div></pre></td></tr></table></figure><h3 id="数据标准化"><a href="#数据标准化" class="headerlink" title="数据标准化"></a>数据标准化</h3><p>确保解释变量的数据都是同一量级,均值为0的标准化数据。<br>许多评估方法在处理标准化数据集时可以获得更好的效果。<strong>标准化数据均值为0,单位方差</strong>(Unit Variance)。均值为0的解释变量是关于原点对称的,特征向量的单位方差表示其特征值全身统一单位,统一量级的数据。</p><blockquote><p>例如,假设特征向量由两个解释变量构成,第一个变量值范围[0,1],第二个变量值范围[0,1000000],这时就要把第二个变量的值调整为[0,1],这样才能保证数据是单位方差。<br>如果变量特征值的量级比其他特征值的方差还大,这个特征值就会主导学习算法的方向,导致其他变量的影响被忽略。<br>有些机器学习算法会在数据不标准时引入很小的优化参数值。</p></blockquote><p>解释变量的值可以通过正态分布进行标准化,减去均值后除以标准差。<br>scikit-learn的scale函数可以实现:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">from</span> sklearn <span class="keyword">import</span> preprocessing</div><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line">X = np.array([</div><div class="line"> [<span class="number">0.</span>, <span class="number">0.</span>, <span class="number">5.</span>, <span class="number">13.</span>, <span class="number">9.</span>, <span class="number">1.</span>],</div><div class="line"> [<span class="number">0.</span>, <span class="number">0.</span>, <span class="number">13.</span>, <span class="number">15.</span>, <span class="number">10.</span>, <span class="number">15.</span>],</div><div class="line"> [<span class="number">0.</span>, <span class="number">3.</span>, <span class="number">15.</span>, <span class="number">2.</span>, <span class="number">0.</span>, <span class="number">11.</span>]</div><div class="line">])</div><div class="line">print(preprocessing.scale(X))</div></pre></td></tr></table></figure>]]></content>
<summary type="html">
<p>纯文字描述</p>
</summary>
<category term="Feature extraction" scheme="http://yaoyirong.cn/categories/Feature-extraction/"/>
<category term="Image processing" scheme="http://yaoyirong.cn/tags/Image-processing/"/>
</entry>
<entry>
<title>Image Feature extraction example</title>
<link href="http://yaoyirong.cn/2017/12/26/%E5%9B%BE%E5%83%8F%E7%89%B9%E5%BE%81%E6%8F%90%E5%8F%96%E5%AE%9E%E4%BE%8B/"/>
<id>http://yaoyirong.cn/2017/12/26/图像特征提取实例/</id>
<published>2017-12-26T07:24:00.000Z</published>
<updated>2017-12-26T07:49:02.000Z</updated>
<content type="html"><![CDATA[<p>关于图像特征提取的几个小栗子: </p><a id="more"></a><h1 id="Feature-extraction-ex1"><a href="#Feature-extraction-ex1" class="headerlink" title="Feature_extraction_ex1"></a>Feature_extraction_ex1</h1><p>以下是几个关于图像特征提取的小栗子:</p><h2 id="识别手写数字"><a href="#识别手写数字" class="headerlink" title="识别手写数字"></a>识别手写数字</h2><p>关于的手写数字识别的OCR问题,通过图像的像素矩阵扁平化来学习手写数字特征。(非常耗费资源)<br>scikit-learn的digits数字集包括至少1700种0-9的手写数字图像。每个图像都有8x8像像素构成。每个像素的值是0-16,白色是0,黑色是16。如下图所示:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line">%matplotlib inline</div><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</div><div class="line"><span class="keyword">from</span> sklearn <span class="keyword">import</span> datasets</div><div class="line"></div><div class="line">digits = datasets.load_digits()</div><div class="line">print(<span class="string">'Digits: '</span>, digits.target[<span class="number">0</span>])</div><div class="line"><span class="comment"># 8x8像像素构成。每个像素的值是0-16</span></div><div class="line">print(digits.images[<span class="number">0</span>].reshape(<span class="number">-1</span>))</div><div class="line">plt.figure()</div><div class="line">plt.axis(<span class="string">'off'</span>)</div><div class="line">plt.imshow(digits.images[<span class="number">0</span>], cmap=plt.cm.gray_r, interpolation=<span class="string">'nearest'</span>)</div><div class="line">plt.show()</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">Digits: 0</div><div class="line">[ 0. 0. 5. 13. 9. 1. 0. 0. 0. 0. 13. 15. 10. 15. 5.</div><div class="line"> 0. 0. 3. 15. 2. 0. 11. 8. 0. 0. 4. 12. 0. 0. 8.</div><div class="line"> 8. 0. 0. 5. 8. 0. 0. 9. 8. 0. 0. 4. 11. 0. 1.</div><div class="line"> 12. 7. 0. 0. 2. 14. 5. 10. 12. 0. 0. 0. 0. 6. 13.</div><div class="line"> 10. 0. 0. 0.]</div></pre></td></tr></table></figure><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/images/Feature_extraction_ex/output_3_1.png" alt="output_3_1" title=""> </div> <div class="image-caption">output_3_1</div> </figure><h2 id="scikit-image库抽取下图的兴趣点:"><a href="#scikit-image库抽取下图的兴趣点:" class="headerlink" title="scikit-image库抽取下图的兴趣点:"></a>scikit-image库抽取下图的兴趣点:</h2><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">from</span> skimage.feature <span class="keyword">import</span> corner_harris, corner_peaks</div><div class="line"><span class="keyword">from</span> skimage.color <span class="keyword">import</span> rgb2gray</div><div class="line"><span class="keyword">import</span> skimage.io <span class="keyword">as</span> io</div><div class="line"><span class="keyword">from</span> skimage.exposure <span class="keyword">import</span> equalize_hist</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">def</span> <span class="title">show_corners</span><span class="params">(corners, image)</span>:</span></div><div class="line"> fig = plt.figure()</div><div class="line"> plt.gray()</div><div class="line"> plt.imshow(image)</div><div class="line"> y_corner, x_corner = zip(*corners)</div><div class="line"> plt.plot(x_corner, y_corner, <span class="string">'or'</span>)</div><div class="line"> plt.xlim(<span class="number">0</span>, image.shape[<span class="number">1</span>])</div><div class="line"> plt.ylim(image.shape[<span class="number">0</span>], <span class="number">0</span>)</div><div class="line"> fig.set_size_inches(np.array(fig.get_size_inches()) * <span class="number">1.5</span>)</div><div class="line"> plt.show()</div><div class="line"> </div><div class="line">mandrill = io.imread(<span class="string">'mandrill.jpeg'</span>)</div><div class="line"><span class="comment"># 直方图均衡化</span></div><div class="line">mandrill = equalize_hist(rgb2gray(mandrill))</div><div class="line"><span class="comment"># harris 角点检测</span></div><div class="line">corners = corner_peaks(corner_harris(mandrill), min_distance=<span class="number">2</span>)</div><div class="line">show_corners(corners, mandrill)</div></pre></td></tr></table></figure><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/images/Feature_extraction_ex/output_5_0.png" alt="output_5_0" title=""> </div> <div class="image-caption">output_5_0</div> </figure><h2 id="用mahotas库来应用SURF方法处理下面的图片"><a href="#用mahotas库来应用SURF方法处理下面的图片" class="headerlink" title="用mahotas库来应用SURF方法处理下面的图片"></a>用mahotas库来应用SURF方法处理下面的图片</h2><p>引入兴趣点提取方法,通过SIFT和SURF进行优化。<br>Mahotas 是计算机视觉和图像处理 Python 库。它包含大量图像处理算法,C++实现形式,提高了性能。完全基于 numpy 的数组作为它的数据类型,有一个非常干净的Python 算法接口。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> mahotas <span class="keyword">as</span> mh</div><div class="line"><span class="keyword">from</span> mahotas.features <span class="keyword">import</span> surf</div><div class="line"></div><div class="line">image = mh.imread(<span class="string">'mandrill.jpeg'</span>, as_grey=<span class="keyword">True</span>)</div><div class="line">print(<span class="string">'第一个SURF描述符: \n{}\n'</span>.format(surf.surf(image)[<span class="number">0</span>]) )</div><div class="line">print(<span class="string">'抽取了%s个SURF描述符'</span> % len(surf.surf(image)))</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div></pre></td><td class="code"><pre><div class="line">第一个SURF描述符: </div><div class="line">[ 4.88720413e+01 1.24800860e+02 1.93404140e+00 4.69215836e+02</div><div class="line"> 1.00000000e+00 -1.89817090e+00 -9.16485838e-04 4.15829239e-04</div><div class="line"> 1.62917514e-03 4.50508786e-03 2.16965117e-03 -1.54517486e-02</div><div class="line"> 1.19871085e-02 2.27849309e-02 -4.96764299e-03 -2.30153165e-03</div><div class="line"> 1.24213881e-02 9.73558091e-03 1.01124633e-03 9.33727930e-05</div><div class="line"> 1.50382252e-03 4.28077728e-04 4.12196201e-04 2.63136511e-03</div><div class="line"> 1.47364160e-02 2.57975865e-02 2.13572331e-01 1.36266382e-03</div><div class="line"> 3.25871891e-01 2.83610749e-01 3.01434634e-01 -8.35839666e-02</div><div class="line"> 4.67635391e-01 1.61936283e-01 6.27416198e-03 -4.75608140e-03</div><div class="line"> 6.38395923e-02 2.88552374e-02 4.36529968e-03 1.22763937e-02</div><div class="line"> 4.28753085e-02 2.97861362e-02 -1.65692866e-01 -3.00393938e-02</div><div class="line"> 3.07613402e-01 2.59695442e-01 -1.77392860e-01 -8.42926232e-02</div><div class="line"> 3.22241967e-01 2.68252184e-01 1.22916451e-02 -2.17223444e-03</div><div class="line"> 3.34867018e-02 7.92410354e-03 -3.77849533e-04 -3.75246341e-03</div><div class="line"> 5.13159418e-03 4.26743799e-03 2.47661732e-02 -9.75867100e-03</div><div class="line"> 3.38654071e-02 2.22350151e-02 1.25097158e-02 -5.13047076e-03</div><div class="line"> 6.62972574e-02 3.98549144e-02 7.56108237e-03 4.19496163e-04</div><div class="line"> 1.53695063e-02 5.35408794e-03]</div><div class="line"></div><div class="line">抽取了222个SURF描述符</div></pre></td></tr></table></figure><h2 id="数据标准化"><a href="#数据标准化" class="headerlink" title="数据标准化"></a>数据标准化</h2><p>scikit-learn的scale函数实现:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">from</span> sklearn <span class="keyword">import</span> preprocessing</div><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"></div><div class="line">X = np.array([</div><div class="line"> [<span class="number">0.</span>, <span class="number">0.</span>, <span class="number">5.</span>, <span class="number">13.</span>, <span class="number">9.</span>, <span class="number">1.</span>],</div><div class="line"> [<span class="number">0.</span>, <span class="number">0.</span>, <span class="number">13.</span>, <span class="number">15.</span>, <span class="number">10.</span>, <span class="number">15.</span>],</div><div class="line"> [<span class="number">0.</span>, <span class="number">3.</span>, <span class="number">15.</span>, <span class="number">2.</span>, <span class="number">0.</span>, <span class="number">11.</span>]</div><div class="line">])</div><div class="line">print(preprocessing.scale(X))</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">[[ 0. -0.70710678 -1.38873015 0.52489066 0.59299945 -1.35873244]</div><div class="line"> [ 0. -0.70710678 0.46291005 0.87481777 0.81537425 1.01904933]</div><div class="line"> [ 0. 1.41421356 0.9258201 -1.39970842 -1.4083737 0.33968311]]</div></pre></td></tr></table></figure><h2 id="OpenCV-SURF-特征提取"><a href="#OpenCV-SURF-特征提取" class="headerlink" title="OpenCV SURF() 特征提取"></a>OpenCV SURF() 特征提取</h2><p>KeyPoint 数据结构</p><ul><li>angle:角度,表示关键点的方向</li><li>class_id:当要对图片进行分类时,我们可以用class_id对每个特征点进行区分,未设定时为-1</li><li>octave:代表是从金字塔哪一层提取的得到的数据。</li><li>pt:关键点点的坐标 —-这次用到的</li><li>response:响应程度,代表该点强壮大小; response代表着该关键点how good,更确切的说,是该点角点的程度。</li><li>size:该点直径的大小</li></ul><p>注意一个问题:keypoint只是保存了opencv的sift库检测到的特征点的一些基本信息,也就上面所说的这些,但sift所提取出来的特征向量其实不是在这个里面,特征向量通过SiftDescriptorExtractor 提取,结果放在一个Mat的数据结构中。这个数据结构才真正保存了该特征点所对应的特征向量。具体见后文对SiftDescriptorExtractor 所生成的对象的详解。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> cv2</div><div class="line"></div><div class="line">image = cv2.imread(<span class="string">'surf_exm.jpg'</span>)</div><div class="line">image2 = image.copy()</div><div class="line"><span class="comment">#cv2.imshow('original', image)</span></div><div class="line"><span class="comment">#cv2.waitKey()</span></div><div class="line"></div><div class="line"><span class="comment"># 下采样</span></div><div class="line"><span class="comment"># 高斯图像金字塔</span></div><div class="line"><span class="comment">#im_lowers = cv2.pyrDown(image) </span></div><div class="line"><span class="comment">#cv2.imshow('imlowers', im_lowers)</span></div><div class="line"></div><div class="line"><span class="comment"># 检测特征点</span></div><div class="line"><span class="comment"># 调用SIFT</span></div><div class="line"><span class="comment"># opencv将SIFT等算法整合到xfeatures2d集合里面了。变更后写法如下:</span></div><div class="line">s = cv2.xfeatures2d.SIFT_create()</div><div class="line"></div><div class="line">keypoints = s.detect(image)</div><div class="line"><span class="comment"># type(keypoints) <class 'list'></span></div><div class="line"><span class="comment"># len(keypoints) 6212</span></div><div class="line"></div><div class="line"><span class="comment"># 显示特征点</span></div><div class="line"><span class="keyword">for</span> k <span class="keyword">in</span> keypoints:</div><div class="line"> cv2.circle(image, (int(k.pt[<span class="number">0</span>]), int(k.pt[<span class="number">1</span>])), <span class="number">1</span>, (<span class="number">0</span>, <span class="number">255</span>, <span class="number">0</span>), <span class="number">-1</span>)</div><div class="line"> </div><div class="line">s1 = cv2.xfeatures2d.SURF_create()</div><div class="line">keypoints2 = s1.detect(image)</div><div class="line"></div><div class="line"><span class="keyword">for</span> kk <span class="keyword">in</span> keypoints2:</div><div class="line"> <span class="comment"># circle 函数 (指针, 圆心坐标, 圆半径, 颜色, thickness正数表示组成圆的线条的粗细程度;否则,表示圆是否被填充</span></div><div class="line"> cv2.circle(image2, (int(kk.pt[<span class="number">0</span>]), int(kk.pt[<span class="number">1</span>])), <span class="number">1</span>, (<span class="number">0</span>, <span class="number">255</span>, <span class="number">0</span>), <span class="number">-1</span>)</div><div class="line"> <span class="comment">#cv2.circle(image2, (int(kk.pt[0]), int(kk.pt[1])), int(k.size), (0, 255, 0), -1)</span></div><div class="line"></div><div class="line">cv2.imwirte(<span class="string">'SIFT_features.jpg'</span>,image)</div><div class="line">cv2.imwrite(<span class="string">'SURF_features.jpg'</span>,image2)</div><div class="line">cv2.waitKey()</div></pre></td></tr></table></figure><p><strong>原图:</strong></p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/images/Feature_extraction_ex/surf_exm.jpg" alt="surf_exm" title=""> </div> <div class="image-caption">surf_exm</div> </figure><p><strong>SIFT:</strong></p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/images/Feature_extraction_ex/SIFT_features.jpg" alt="SIFT_features" title=""> </div> <div class="image-caption">SIFT_features</div> </figure><p><strong>SURF:</strong></p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/images/Feature_extraction_ex/SURF_features.jpg" alt="SURF_features" title=""> </div> <div class="image-caption">SURF_features</div> </figure>]]></content>
<summary type="html">
<p>关于图像特征提取的几个小栗子: </p>
</summary>
<category term="Feature extraction" scheme="http://yaoyirong.cn/categories/Feature-extraction/"/>
<category term="Image processing" scheme="http://yaoyirong.cn/tags/Image-processing/"/>
</entry>
<entry>
<title>OpenCV_python 使用</title>
<link href="http://yaoyirong.cn/2017/12/22/OpenCV_python%E4%BD%BF%E7%94%A8/"/>
<id>http://yaoyirong.cn/2017/12/22/OpenCV_python使用/</id>
<published>2017-12-22T04:30:13.000Z</published>
<updated>2018-03-19T15:19:14.000Z</updated>
<content type="html"><![CDATA[<p>python-OpenCV</p><a id="more"></a><h1 id="Python-OpenCV"><a href="#Python-OpenCV" class="headerlink" title="Python - OpenCV"></a>Python - OpenCV</h1><p>介绍和深度学习数据处理阶段最相关的基础使用,并完成4个有趣实用的小例子:</p><ul><li>延时摄影小程序</li><li>视频中截屏采样的小程序</li><li>图片数据增加(data augmentation)的小工具</li><li>物体检测框标注小工具</li></ul><h2 id="OpenCV-简介"><a href="#OpenCV-简介" class="headerlink" title="OpenCV 简介"></a>OpenCV 简介</h2><p>OpenCV是计算机视觉领域应用最广泛的开源工具包,基于C/C++,支持Linux/Windows/MacOS/Android/iOS,并提供了Python,Matlab和Java等语言的接口.</p><h3 id="OpenCV的结构"><a href="#OpenCV的结构" class="headerlink" title="OpenCV的结构"></a>OpenCV的结构</h3><blockquote><p>和Python一样,当前的OpenCV也有两个大版本,OpenCV2和OpenCV3。相比OpenCV2,OpenCV3提供了更强的功能和更多方便的特性。不过考虑到和深度学习框架的兼容性,以及上手安装的难度,这部分先以2为主进行介绍。从使用的角度来看,和OpenCV2相比,OpenCV3的主要变化是更多的功能和更细化的模块划分。</p></blockquote><p>根据功能和需求的不同,OpenCV中的函数接口大体可以分为如下部分:</p><ul><li>core:核心模块,主要包含了OpenCV中最基本的结构(矩阵,点线和形状等),以及相关的基础运算/操作。</li><li>imgproc:图像处理模块,包含和图像相关的基础功能(滤波,梯度,改变大小等),以及一些衍生的高级功能(图像分割,直方图,形态分析和边缘/直线提取等). </li><li>highgui:提供了用户界面和文件读取的基本函数,比如图像显示窗口的生成和控制,图像/视频文件的IO等。</li></ul><p>如果不考虑视频应用,以上三个就是最核心和常用的模块了. </p><p>针对<strong>视频和一些特别的视觉应用</strong>,OpenCV也提供了强劲的支持:</p><ul><li>video:用于视频分析的常用功能,比如光流法(Optical Flow)和目标跟踪等。</li><li>calib3d:三维重建,立体视觉和相机标定等的相关功能。</li><li>features2d:二维特征相关的功能,主要是一些不受专利保护的,商业友好的特征点检测和匹配等功能,比如ORB特征。</li><li>object:目标检测模块,包含级联分类和Latent SVM</li><li>ml:机器学习算法模块,包含一些视觉中最常用的传统机器学习算法。</li><li>flann:最近邻算法库,Fast Library for Approximate Nearest Neighbors,用于在多维空间进行聚类和检索,经常和关键点匹配搭配使用。</li><li>gpu:包含了一些gpu加速的接口,底层的加速是CUDA实现。</li><li>photo:计算摄像学(Computational Photography)相关的接口,当然这只是个名字,其实只有图像修复和降噪而已。</li><li>stitching:图像拼接模块,有了它可以自己生成全景照片。</li><li>nonfree:受到专利保护的一些算法,其实就是SIFT和SURF。</li><li>contrib:一些实验性质的算法,考虑在未来版本中加入的。</li><li>legacy:字面是遗产,意思就是废弃的一些接口,保留是考虑到向下兼容。</li><li>ocl:利用OpenCL并行加速的一些接口。</li><li>superres:超分辨率模块,其实就是BTV-L1(Biliteral Total Variation – L1 regularization)算法</li><li>viz:基础的3D渲染模块,其实底层就是著名的3D工具包VTK(Visualization Toolkit)。</li></ul><h4 id="基本使用"><a href="#基本使用" class="headerlink" title="基本使用"></a>基本使用</h4><p>图像就是一个矩阵,在OpenCV for Python中,图像就是NumPy中的数组, 图像使用NumPy数组的属性来表示图像的尺寸和通道信息</p><h5 id="读取图像"><a href="#读取图像" class="headerlink" title="读取图像"></a>读取图像</h5><p>读图像用<code>cv2.imread()</code>,可以按照不同模式读取,一般最常用到的是读取单通道灰度图,或者直接默认读取多通道。存图像用<code>cv2.imwrite()</code>,注意存的时候是没有单通道这一说的, 根据保存文件名的后缀和当前的array维度,OpenCV自动判断存的通道,另外压缩格式还可以指定存储质量.</p><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># -----------------------------</span></div><div class="line"><span class="comment"># 读取图像</span></div><div class="line"><span class="comment"># -----------------------------</span></div><div class="line"></div><div class="line"><span class="keyword">import</span> cv2</div><div class="line"></div><div class="line">img = cv2.imread(<span class="string">'little_white_dog.jpeg'</span>)</div><div class="line">cv2.namedWindow(<span class="string">'Image'</span>)</div><div class="line">cv2.imshow(<span class="string">'Image'</span>, img)</div><div class="line">cv2.waitKey(<span class="number">0</span>)</div><div class="line">cv2.destroyAllWindows()</div><div class="line">print(img.shape)</div></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> cv2</div><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"></div><div class="line">img = cv2.imread(<span class="string">'figure.jpg'</span>)</div><div class="line">px = img[<span class="number">100</span>,<span class="number">100</span>] </div><div class="line"><span class="comment"># [128 122 153]</span></div><div class="line">print( px) </div><div class="line">blue = img[<span class="number">100</span>,<span class="number">100</span>,<span class="number">0</span>] </div><div class="line">print(blue)</div><div class="line"></div><div class="line"><span class="comment"># 以上这种读取像素值的方式非常缓慢。推荐使用Numpy的函数——array.item()和array.itemset()来访问</span></div><div class="line"><span class="comment"># accessing red value </span></div><div class="line">red = img.item(<span class="number">100</span>, <span class="number">100</span>, <span class="number">2</span>)</div><div class="line">print(red)</div><div class="line"></div><div class="line"><span class="comment"># modifying RED value </span></div><div class="line">img.itemset((<span class="number">100</span>,<span class="number">100</span>,<span class="number">2</span>), <span class="number">10</span>)</div><div class="line">img.item(<span class="number">100</span>, <span class="number">100</span>, <span class="number">2</span>)</div><div class="line"></div><div class="line"><span class="comment"># 获取图像的属性——行数、列数、通道数、图像的数据类型以及像素点的数量等</span></div><div class="line">img.shape</div><div class="line"><span class="comment"># 获得像素点的数量</span></div><div class="line">img.size</div><div class="line">img.dtype</div></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> cv2</div><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"></div><div class="line">color_img = cv2.imread(<span class="string">'test_400x600.jpeg'</span>)</div><div class="line">print(color_img.shape)</div><div class="line"></div><div class="line"><span class="comment"># 直接读取单通道</span></div><div class="line">gray_img = cv2.imread(<span class="string">'test_400x600.jpeg'</span>, cv2.IMREAD_GRAYSCALE)</div><div class="line">print(gray_img.shape)</div><div class="line"></div><div class="line"><span class="comment"># 把单通道图片保存后,再读取,仍然是3通道,相当于把单通道值复制到3个通道保存</span></div><div class="line">cv2.imwrite(<span class="string">'test_grayscale.jpeg'</span>, gray_img)</div><div class="line">reload_grascale = cv2.imread(<span class="string">'test_grayscale.jpeg'</span>)</div><div class="line">print(reload_grascale.shape)</div><div class="line"></div><div class="line"><span class="comment"># cv2.IMWRITE_JPEG_QUALITY指定jpg质量,范围0到100,默认95,越高画质越好,文件越大</span></div><div class="line">cv2.imwrite(<span class="string">'test_imwrite.jpeg'</span>, color_img, (int(cv2.IMWRITE_JPEG_QUALITY), <span class="number">80</span>))</div><div class="line"></div><div class="line">cv2.imwrite(<span class="string">'test_imwrite.png'</span>, color_img, (int(cv2.IMWRITE_PNG_COMPRESSION), <span class="number">5</span>))</div></pre></td></tr></table></figure><h5 id="创建-复制图像"><a href="#创建-复制图像" class="headerlink" title="创建/复制图像"></a>创建/复制图像</h5><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># -----------------------------</span></div><div class="line"><span class="comment"># 创建/复制图像</span></div><div class="line"><span class="comment"># 图像就是一个矩阵,在OpenCV for Python中,图像就是NumPy中的数组</span></div><div class="line"><span class="comment"># 如果要创建图像,需要使用numpy的函数, 图像使用NumPy数组的属性来表示图像的尺寸和通道信息</span></div><div class="line"><span class="comment"># -----------------------------</span></div><div class="line"><span class="keyword">import</span> cv2</div><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"></div><div class="line">img = cv2.imread(<span class="string">'little_white_dog.jpeg'</span>)</div><div class="line">emptyImage = np.zeros(img.shape, np.uint8)</div><div class="line"></div><div class="line">emptyImage2 = img.copy()</div><div class="line"></div><div class="line">emptyImage3 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)</div><div class="line"><span class="comment"># emptyImage3[...] = 0</span></div><div class="line"></div><div class="line">cv2.imshow(<span class="string">'EmptyImage'</span>, emptyImage)</div><div class="line">cv2.imshow(<span class="string">'Image'</span>, img)</div><div class="line">cv2.imshow(<span class="string">'EmptyImage2'</span>, emptyImage2)</div><div class="line">cv2.imshow(<span class="string">'EmptyImage3'</span>, emptyImage3)</div><div class="line"></div><div class="line"><span class="comment"># 第三个参数针对特定的格式: 对于JPEG,其表示的是图像的质量,</span></div><div class="line"><span class="comment"># 用0-100的整数表示,默认为95。 注意,cv2.IMWRITE_JPEG_QUALITY类型为Long,必须转换成int。下面是以不同质量存储的两幅图:</span></div><div class="line"></div><div class="line">cv2.imwrite(<span class="string">'little_white_dog2.jpg'</span>, img, [int(cv2.IMWRITE_JPEG_QUALITY), <span class="number">5</span>])</div><div class="line">cv2.imwrite(<span class="string">'little_white_dog3.jpg'</span>, img, [int(cv2.IMWRITE_JPEG_QUALITY), <span class="number">100</span>])</div><div class="line"></div><div class="line"><span class="comment"># 对于PNG,第三个参数表示的是压缩级别。cv2.IMWRITE_PNG_COMPRESSION,从0到9,压缩级别越高,图像尺寸越小。默认级别为3:</span></div><div class="line"></div><div class="line">cv2.imwrite(<span class="string">'little_white_dog2.png'</span>, img, [int(cv2.IMWRITE_PNG_COMPRESSION), <span class="number">0</span>])</div><div class="line">cv2.imwrite(<span class="string">'little_white_dog3.png'</span>, img, [int(cv2.IMWRITE_PNG_COMPRESSION), <span class="number">9</span>])</div><div class="line"></div><div class="line">cv2.waitKey(<span class="number">0</span>)</div><div class="line">cv2.destroyAllWindows()</div></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># numpy 全复制 不是镜像</span></div><div class="line"><span class="keyword">import</span> cv2</div><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"></div><div class="line">img = cv2.imread(<span class="string">'little_white_dog.jpeg'</span>)</div><div class="line">c = np.zeros(img.shape, dtype=img.dtype)</div><div class="line">c[:, :, :] = img[:, :, :]</div><div class="line">c <span class="keyword">is</span> img <span class="comment"># false</span></div><div class="line">c.base <span class="keyword">is</span> img <span class="comment"># false</span></div></pre></td></tr></table></figure><h5 id="图像元素的访问"><a href="#图像元素的访问" class="headerlink" title="图像元素的访问"></a>图像元素的访问</h5><p><strong>与C++不同,在Python中灰度图的img.ndim = 2,而C++中灰度图图像的通道数img.channel() =1</strong></p><p>这里使用了numpy的随机数,Python自身也有一个随机数生成函数。这里只是一种习惯,np.random模块中拥有更多的方法,而Python自带的random只是一个轻量级的模块。不过需要注意的是np.random.seed()不是线程安全的,而<strong>Python自带的random.seed()是线程安全</strong>的。如果使用随机数时需要用到多线程,建议使用Python自带的random()和random.seed(),或者构建一个本地的np.random.Random类的实例。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># -----------------------------</span></div><div class="line"><span class="comment"># 图像元素的访问</span></div><div class="line"><span class="comment"># 像素的访问和访问numpy中ndarray的方法完全一样</span></div><div class="line"><span class="comment"># 下面通过对图像添加人工的椒盐现象来进一步说明OpenCV Python中需要注意的一些问题</span></div><div class="line"><span class="comment"># -----------------------------</span></div><div class="line"></div><div class="line"><span class="keyword">import</span> cv2</div><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">def</span> <span class="title">salt</span><span class="params">(img, n)</span>:</span></div><div class="line"> <span class="keyword">for</span> k <span class="keyword">in</span> range(n):</div><div class="line"> j = int(np.random.random() * img.shape[<span class="number">0</span>])</div><div class="line"> i = int(np.random.random() * img.shape[<span class="number">1</span>])</div><div class="line"> <span class="keyword">if</span> img.ndim == <span class="number">2</span>:</div><div class="line"> img[j, i] = <span class="number">255</span></div><div class="line"> <span class="keyword">elif</span> img.ndim ==<span class="number">3</span>:</div><div class="line"> img[j, i, <span class="number">0</span>] = <span class="number">255</span></div><div class="line"> img[j, i, <span class="number">1</span>] = <span class="number">255</span></div><div class="line"> img[j, i, <span class="number">2</span>] = <span class="number">255</span></div><div class="line"> <span class="keyword">return</span> img</div><div class="line"> </div><div class="line"><span class="keyword">if</span> __name__ == <span class="string">'__main__'</span>:</div><div class="line"> img = cv2.imread(<span class="string">'iPhone.png'</span>)</div><div class="line"> saltImage = salt(img, <span class="number">500</span>)</div><div class="line"> cv2.imshow(<span class="string">'Salt'</span>, saltImage)</div><div class="line"> cv2.waitKey(<span class="number">0</span>)</div><div class="line"> cv2.destoryAllWindows()</div></pre></td></tr></table></figure><h5 id="缩放,裁剪和补边"><a href="#缩放,裁剪和补边" class="headerlink" title="缩放,裁剪和补边"></a>缩放,裁剪和补边</h5><p>缩放通过<code>cv2.resize()</code>实现(<strong>指定大小的格式是(宽度,高度)</strong>),裁剪则是利用array自身的下标截取实现,此外OpenCV还可以给图像补边,这样能对一幅图像的形状和感兴趣区域实现各种操作。</p><p>下面的例子中读取一幅400×600分辨率的图片,并执行一些基础的操作:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div></pre></td><td class="code"><pre><div class="line"></div><div class="line"><span class="comment"># 读取一张600x375分辨率的图像</span></div><div class="line">img = cv2.imread(<span class="string">'figure.jpg'</span>)</div><div class="line"><span class="comment"># 缩放成200x200的方形图像</span></div><div class="line">img_200x200 = cv2.resize(img, (<span class="number">200</span>, <span class="number">200</span>))</div><div class="line"></div><div class="line"><span class="comment"># 不直接指定缩放后大小,通过fx和fy指定缩放比例,0.5则长宽都为原来一半</span></div><div class="line"><span class="comment"># 等效于img_200x300 = cv2.resize(img, (300, 200)),注意指定大小的格式是(宽度,高度)</span></div><div class="line"></div><div class="line"><span class="comment"># 插值方法默认是cv2.INTER_LINEAR,这里指定为最近邻插值</span></div><div class="line"><span class="comment"># fx、fy是沿x轴和y轴的缩放系数 和 dsize不能同时为0</span></div><div class="line"><span class="string">'''</span></div><div class="line">最优一个参数interpolation表示插值方式,有以下几种:</div><div class="line">INTER_NEAREST - 最近邻插值</div><div class="line">INTER_LINEAR - 线性插值(默认)</div><div class="line">INTER_AREA - 区域插值</div><div class="line">INTER_CUBIC - 三次样条插值</div><div class="line">INTER_LANCZOS4 - Lanczos插值</div><div class="line">'''</div><div class="line">img_200x300 = cv2.resize(img, (<span class="number">200</span>, <span class="number">300</span>), fx=<span class="number">0.5</span>, fy=<span class="number">0.5</span>, interpolation=cv2.INTER_NEAREST)</div><div class="line"></div><div class="line"><span class="comment"># 在上张图片的基础上,上下各贴50像素的黑边,生成300x300的图像</span></div><div class="line">img_300x300 = cv2.copyMakeBorder(img, <span class="number">50</span>, <span class="number">50</span>, <span class="number">0</span>, <span class="number">0</span>, cv2.BORDER_CONSTANT, value=(<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>))</div><div class="line"></div><div class="line"><span class="comment"># 对照片中人脸的部分进行剪裁 高度区间和宽度区间 </span></div><div class="line"><span class="comment"># patch_tree = img[20:150, -300:-10]</span></div><div class="line">patch_tree = img[<span class="number">7</span>:<span class="number">150</span>, <span class="number">300</span>:<span class="number">450</span>]</div><div class="line"></div><div class="line">cv2.imwrite(<span class="string">'cropped_tree.jpg'</span>, patch_tree)</div><div class="line">cv2.imwrite(<span class="string">'resize_200x300.jpg'</span>, img_200x300)</div><div class="line">cv2.imwrite(<span class="string">'bordered_300x300.jpg'</span>, img_300x300)</div><div class="line">cv2.imwrite(<span class="string">'resize_200x200.jpg'</span>, img_200x200)</div></pre></td></tr></table></figure><p><strong>补边:</strong></p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/images/OpenCV_python使用/bordered_300x300.jpg" alt="bordered_300x300" title=""> </div> <div class="image-caption">bordered_300x300</div> </figure><p><strong>裁剪:</strong></p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/images/OpenCV_python使用/cropped_tree.jpg" alt="cropped_tree" title=""> </div> <div class="image-caption">cropped_tree</div> </figure><h5 id="色调,明暗,直方图和Gamma曲线"><a href="#色调,明暗,直方图和Gamma曲线" class="headerlink" title="色调,明暗,直方图和Gamma曲线"></a>色调,明暗,直方图和Gamma曲线</h5><p>除了区域,图像本身的属性操作也非常多,比如可以通过HSV空间对色调和明暗进行调节。(HSV分别是色调(Hue), 饱和度(Saturation)和明度(Value)。在HSV空间中进行调节就避免了直接在RGB空间中调节是还需要考虑三个通道的相关性. OpenCV中H的取值是[0, 180),其他两个通道的取值都是[0, 256). </p><p>下面例子接着上面例子代码,通过HSV空间对图像进行调整:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> cv2</div><div class="line"></div><div class="line">img = cv2.imread(<span class="string">'figure.jpg'</span>)</div><div class="line"></div><div class="line"><span class="comment"># 通过cv2.cvtColor把图像从BGR转换到HSV</span></div><div class="line">img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)</div><div class="line"></div><div class="line">turn_green = img_hsv.copy()</div><div class="line">colorless_hsv = img_hsv.copy()</div><div class="line">darker_hsv = img_hsv.copy()</div><div class="line"></div><div class="line"><span class="comment"># H空间中,绿色比黄色的值高一点,所以给每个像素+15,黄色的树叶就会变绿</span></div><div class="line">turn_green[:, :, <span class="number">0</span>] = (turn_green[:, :, <span class="number">0</span>]+<span class="number">15</span>) % <span class="number">180</span></div><div class="line">turn_green_img = cv2.cvtColor(turn_green, cv2.COLOR_HSV2BGR)</div><div class="line">cv2.imwrite(<span class="string">'trun_green.jpg'</span>, turn_green_img)</div><div class="line"></div><div class="line"><span class="comment"># 减小饱和度会让图像损失鲜艳,变得更灰</span></div><div class="line">colorless_hsv[:, :, <span class="number">1</span>] = <span class="number">0.5</span> * colorless_hsv[:, :, <span class="number">1</span>]</div><div class="line">colorless_img = cv2.cvtColor(colorless_hsv, cv2.COLOR_HSV2BGR)</div><div class="line">cv2.imwrite(<span class="string">'colorless.jpg'</span>, colorless_img)</div><div class="line"></div><div class="line"><span class="comment"># 减小明度为原来一半</span></div><div class="line">darker_hsv[:, :, <span class="number">2</span>] = <span class="number">0.5</span> * darker_hsv[:, :, <span class="number">2</span>]</div><div class="line">darker_img = cv2.cvtColor(darker_hsv, cv2.COLOR_HSV2BGR)</div><div class="line">cv2.imwrite(<span class="string">'darker.jpg'</span>, darker_img)</div></pre></td></tr></table></figure><ol><li><p>更改色调</p><p><img src="/images/OpenCV_python使用/trun_green.jpg" alt="trun_green"></p></li><li><p>更改饱和度</p><p><img src="/images/OpenCV_python使用/colorless.jpg" alt="colorless"></p></li><li><p>更改亮度</p><p><img src="/images/OpenCV_python使用/darker.jpg" alt="darker"></p></li></ol><p><strong>直方图</strong></p><p>无论是HSV还是RGB,我们都较难一眼就对像素中值的分布有细致的了解,这时候就需要直方图。如果直方图中的成分过于靠近0或者255,可能就出现了<strong>暗部细节不足或者亮部细节丢失</strong>的情况。</p><p>这个时候,一个常用方法是考虑用Gamma变换来提升暗部细节。Gamma变换是矫正相机直接成像和人眼感受图像差别的一种常用手段,</p><p>简单来说就是通过非线性变换让图像从对曝光强度的线性响应变得更接近人眼感受到的响应。</p><p><strong>矫正前:</strong></p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/images/OpenCV_python使用/darker.jpg" alt="darker" title=""> </div> <div class="image-caption">darker</div> </figure><p><strong>矫正后:</strong></p><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/images/OpenCV_python使用/img_corrected.jpg" alt="img_corrected" title=""> </div> <div class="image-caption">img_corrected</div> </figure><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div><div class="line">57</div><div class="line">58</div><div class="line">59</div><div class="line">60</div><div class="line">61</div><div class="line">62</div><div class="line">63</div><div class="line">64</div><div class="line">65</div><div class="line">66</div><div class="line">67</div><div class="line">68</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"><span class="keyword">import</span> cv2</div><div class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</div><div class="line"><span class="keyword">from</span> mpl_toolkits.mplot3d <span class="keyword">import</span> Axes3D</div><div class="line"></div><div class="line"><span class="string">'''</span></div><div class="line">cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate ]]) 返回hist</div><div class="line">其中第一个参数必须用方括号括起来。</div><div class="line">第二个参数是用于计算直方图的通道</div><div class="line">第三个参数是Mask,这里没有使用,所以用None。</div><div class="line">第四个参数是histSize,表示这个直方图分成多少份(即多少个直方柱)</div><div class="line">第五个参数是表示直方图中各个像素的值, [0.0, 256.0]表示直方图能表示像素值从0.0到256的像素。</div><div class="line">最后是两个可选参数,由于直方图作为函数结果返回了,所以第六个hist就没有意义了(待确定)</div><div class="line">最后一个accumulate是一个布尔值,用来表示直方图是否叠加。</div><div class="line">'''</div><div class="line">img = cv2.imread(<span class="string">'darker.jpg'</span>)</div><div class="line"></div><div class="line"><span class="comment"># 直方图 <class 'numpy.ndarray'> (256, 1)</span></div><div class="line">hist_b = cv2.calcHist([img], [<span class="number">0</span>], <span class="keyword">None</span>, [<span class="number">256</span>], [<span class="number">0</span>, <span class="number">256</span>])</div><div class="line">hist_g = cv2.calcHist([img], [<span class="number">1</span>], <span class="keyword">None</span>, [<span class="number">256</span>], [<span class="number">0</span>, <span class="number">256</span>])</div><div class="line">hist_r = cv2.calcHist([img], [<span class="number">2</span>], <span class="keyword">None</span>, [<span class="number">256</span>], [<span class="number">0</span>, <span class="number">256</span>])</div><div class="line"></div><div class="line"><span class="comment"># 定义Gamma矫正的函数</span></div><div class="line"><span class="function"><span class="keyword">def</span> <span class="title">gamma_trans</span><span class="params">(img, gamma)</span>:</span></div><div class="line"> <span class="comment"># 具体做法是先归一化到1,然后gamma作为指数值求出新的像素值再还原</span></div><div class="line"> gamma_table = [np.power(x/<span class="number">255.0</span>, gamma)*<span class="number">255.0</span> <span class="keyword">for</span> x <span class="keyword">in</span> range(<span class="number">256</span>)]</div><div class="line"> gamma_table = np.round(np.array(gamma_table)).astype(np.uint8)</div><div class="line"> </div><div class="line"> <span class="comment"># 实现这个映射用的是OpenCV的查找表函数</span></div><div class="line"> <span class="keyword">return</span> cv2.LUT(img, gamma_table)</div><div class="line"></div><div class="line"><span class="comment"># 执行Gamma矫正,小于1的值让暗部细节大量提升,同时亮部细节少量提升</span></div><div class="line">img_corrected = gamma_trans(img, <span class="number">0.5</span>)</div><div class="line">cv2.imwrite(<span class="string">'img_corrected.jpg'</span>,img_corrected)</div><div class="line"></div><div class="line"><span class="comment"># 分通道计算Gamma矫正后的直方图 256行一列</span></div><div class="line">hist_b_corrected = cv2.calcHist([img_corrected], [<span class="number">0</span>], <span class="keyword">None</span>, [<span class="number">256</span>], [<span class="number">0</span>, <span class="number">256</span>])</div><div class="line">hist_g_corrected = cv2.calcHist([img_corrected], [<span class="number">1</span>], <span class="keyword">None</span>, [<span class="number">256</span>], [<span class="number">0</span>, <span class="number">256</span>])</div><div class="line">hist_r_corrected = cv2.calcHist([img_corrected], [<span class="number">2</span>], <span class="keyword">None</span>, [<span class="number">256</span>], [<span class="number">0</span>, <span class="number">256</span>])</div><div class="line"></div><div class="line"><span class="comment"># 这样就会变成一行</span></div><div class="line"><span class="comment"># -------------------------------</span></div><div class="line"><span class="comment"># print(hist_b_corrected.reshape(-1))</span></div><div class="line"></div><div class="line">fig = plt.figure(figsize=(<span class="number">12</span>, <span class="number">6</span>))</div><div class="line"></div><div class="line">pix_hists = [</div><div class="line"> [hist_b.reshape(<span class="number">-1</span>), hist_g.reshape(<span class="number">-1</span>), hist_r.reshape(<span class="number">-1</span>)],</div><div class="line"> [hist_b_corrected.reshape(<span class="number">-1</span>), hist_g_corrected.reshape(<span class="number">-1</span>), hist_r_corrected.reshape(<span class="number">-1</span>)]</div><div class="line">]</div><div class="line"></div><div class="line">pix_vals = range(<span class="number">256</span>)</div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"><span class="keyword">for</span> sub_plt, pix_hist <span class="keyword">in</span> zip([<span class="number">121</span>, <span class="number">122</span>], pix_hists):</div><div class="line"> ax = fig.add_subplot(sub_plt, projection=<span class="string">'3d'</span>)</div><div class="line"> <span class="keyword">for</span> c, z, channel_hist <span class="keyword">in</span> zip([<span class="string">'b'</span>, <span class="string">'g'</span>, <span class="string">'r'</span>], [<span class="number">20</span>, <span class="number">10</span>, <span class="number">0</span>], pix_hist):</div><div class="line"> cs = [c] * <span class="number">256</span></div><div class="line"> <span class="comment"># 传入的 XYZ应该是一维数组, 不能是二维, 应该是一行</span></div><div class="line"> ax.bar(pix_vals, channel_hist, zs=z, zdir=<span class="string">'y'</span>, color=cs, alpha=<span class="number">0.618</span>, edgecolor=<span class="string">'none'</span>, lw=<span class="number">0</span>)</div><div class="line"></div><div class="line"> ax.set_xlabel(<span class="string">'Pixel Values'</span>)</div><div class="line"> ax.set_xlim([<span class="number">0</span>, <span class="number">256</span>])</div><div class="line"> ax.set_ylabel(<span class="string">'Channels'</span>)</div><div class="line"> ax.set_zlabel(<span class="string">'Counts'</span>)</div><div class="line"></div><div class="line">plt.show()</div></pre></td></tr></table></figure><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/images/OpenCV_python使用/output_14_0.png" alt="output_14_0" title=""> </div> <div class="image-caption">output_14_0</div> </figure><p>接上图 可以看到,Gamma变换后的暗部细节比起原图清楚了很多,并且从直方图来看,像素值也从集中在0附近变得散开了一些。</p><h5 id="分离通道"><a href="#分离通道" class="headerlink" title="分离通道"></a>分离通道</h5><p>由于OpenCV Python和NumPy结合的很紧, 所以即可以使用OpenCV自带的split函数,也可以直接操作numpy数组来分离通道。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># -----------------------------</span></div><div class="line"><span class="comment"># 分离、合并通道</span></div><div class="line"><span class="comment"># 即可以使用OpenCV自带的split函数,也可以直接操作numpy数组来分离通道。</span></div><div class="line"><span class="comment"># </span></div><div class="line"><span class="comment"># -----------------------------</span></div><div class="line"><span class="keyword">import</span> cv2</div><div class="line"></div><div class="line">img = cv2.imread(<span class="string">'little_white_dog.jpeg'</span>)</div><div class="line">b, g, r = cv2.split(img)</div><div class="line">cv2.imshow(<span class="string">'Blue'</span>, b)</div><div class="line">cv2.imshow(<span class="string">'Green'</span>, g)</div><div class="line">cv2.imshow(<span class="string">'Red'</span>, r)</div><div class="line"></div><div class="line">cv2.waitKey(<span class="number">0</span>)</div><div class="line">cv2.destroyAllWindows() </div><div class="line"></div><div class="line"><span class="comment"># split返回RGB三个通道,如果只想返回其中一个通道, 最后的索引指出所需要的通道。</span></div><div class="line">b2 = cv2.split(img)[<span class="number">0</span>]</div></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># 也可以直接操作NumPy数组来达到这一目的:</span></div><div class="line"></div><div class="line"><span class="keyword">import</span> cv2</div><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"></div><div class="line">img = cv2.imread(<span class="string">'little_white_dog.jpeg'</span>)</div><div class="line">b = np.zeros((img.shape[<span class="number">0</span>], img.shape[<span class="number">1</span>]), dtype=img.dtype)</div><div class="line">g = np.zeros((img.shape[<span class="number">0</span>], img.shape[<span class="number">1</span>]), dtype=img.dtype)</div><div class="line">r = np.zeros((img.shape[<span class="number">0</span>], img.shape[<span class="number">1</span>]), dtype=img.dtype)</div><div class="line"></div><div class="line">b[:, :] = img[:, :, <span class="number">0</span>]</div><div class="line">g[:, :] = img[:, :, <span class="number">1</span>]</div><div class="line">r[:, :] = img[:, :, <span class="number">2</span>]</div><div class="line"></div><div class="line">cv2.imshow(<span class="string">'Blue'</span>, b)</div><div class="line">cv2.imshow(<span class="string">'green'</span>, g)</div><div class="line">cv2.imshow(<span class="string">'red'</span>, r)</div><div class="line"></div><div class="line">cv2.waitKey(<span class="number">0</span>)</div><div class="line">cv2.destoryAllWindows()</div></pre></td></tr></table></figure><h5 id="通道合并"><a href="#通道合并" class="headerlink" title="通道合并"></a>通道合并</h5><p><strong>????????注意:这里只是演示,实际使用时请用OpenCV自带的merge函数!用NumPy组合的结果不能在OpenCV中其他函数使用,因为其组合方式与OpenCV自带的不一样,如下:</strong></p><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> cv2</div><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"></div><div class="line">img = cv2.imread(<span class="string">'little_white_dog.jpeg'</span>)</div><div class="line">b = np.zeros((img.shape[<span class="number">0</span>], img.shape[<span class="number">1</span>]), dtype=img.dtype)</div><div class="line">g = np.zeros((img.shape[<span class="number">0</span>], img.shape[<span class="number">1</span>]), dtype=img.dtype)</div><div class="line">r = np.zeros((img.shape[<span class="number">0</span>], img.shape[<span class="number">1</span>]), dtype=img.dtype)</div><div class="line"></div><div class="line">b[:, :] = img[:, :, <span class="number">0</span>]</div><div class="line">g[:, :] = img[:, :, <span class="number">1</span>]</div><div class="line">r[:, :] = img[:, :, <span class="number">2</span>]</div><div class="line"></div><div class="line"></div><div class="line"><span class="comment"># openCV 方法 merge</span></div><div class="line">merged = cv2.merge([b, g, r])</div><div class="line">print(<span class="string">'merge by opencv'</span>)</div><div class="line"><span class="comment"># 在每个维数上以字节计算的步长</span></div><div class="line">print(merged.strides)</div><div class="line"><span class="comment"># numpy 方法 dstack</span></div><div class="line">mergedByNp = np.dstack([b, g, r])</div><div class="line">print(<span class="string">'merge by numpy'</span>)</div><div class="line">print(mergedByNp.strides)</div></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># 关于stride</span></div><div class="line"><span class="comment"># 在每个维数上以字节计算的步长</span></div><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"></div><div class="line"><span class="comment"># a数组中每个元素都是NumPy中的整数类型,占8个字节,所以第一维中相邻元素之间的步长为8(个字节)。</span></div><div class="line">a = np.arange(<span class="number">6</span>)</div><div class="line"><span class="comment"># (8,)</span></div><div class="line">print(a.strides)</div><div class="line">print(a.dtype) <span class="comment"># int64</span></div><div class="line"></div><div class="line"><span class="comment"># 从里面开始看,里面是一个4个元素的一维整数数组,所以步长应该为8。外面是一个含有3个元素,每个元素的长度是8×4=32。所以步长为32。</span></div><div class="line">b = np.arange(<span class="number">12</span>).reshape(<span class="number">3</span>, <span class="number">4</span>)</div><div class="line">b.strides</div><div class="line"></div><div class="line"><span class="comment"># (160, 40, 8)</span></div><div class="line">c = np.arange(<span class="number">60</span>).reshape(<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>) <span class="comment"># 三维, 行 , 列</span></div><div class="line">c.strides</div></pre></td></tr></table></figure><h2 id="Python-OpenCV基础"><a href="#Python-OpenCV基础" class="headerlink" title="Python-OpenCV基础"></a>Python-OpenCV基础</h2><h3 id="图像的表示"><a href="#图像的表示" class="headerlink" title="图像的表示"></a>图像的表示</h3><p>单通道的灰度图像在计算机中的表示,就是一个8位无符号整形的矩阵。</p><p><strong>在OpenCV中,默认的图像的表示确实反过来的,也就是BGR</strong>, 比如在Python中,图像都是用numpy的array表示,但是同样的array在OpenCV中的显示效果和matplotlib中的显示效果就会不一样。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> cv2</div><div class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</div><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"></div><div class="line">img = np.array([</div><div class="line"> [[<span class="number">255</span>, <span class="number">0</span>, <span class="number">0</span>], [<span class="number">0</span>, <span class="number">255</span>, <span class="number">0</span>], [<span class="number">0</span>, <span class="number">0</span>, <span class="number">255</span>]],</div><div class="line"> [[<span class="number">255</span>, <span class="number">255</span>, <span class="number">0</span>], [<span class="number">255</span>, <span class="number">0</span>, <span class="number">255</span>], [<span class="number">0</span>, <span class="number">255</span>, <span class="number">255</span>]],</div><div class="line"> [[<span class="number">255</span>, <span class="number">255</span>, <span class="number">255</span>], [<span class="number">128</span>, <span class="number">128</span>, <span class="number">128</span>], [<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>]],</div><div class="line">], dtype=np.uint8)</div><div class="line"></div><div class="line">plt.figure(<span class="string">'matplotlib & OpenCV'</span>, figsize=(<span class="number">8</span>, <span class="number">4</span>))</div><div class="line"><span class="comment"># 用matplotlib存储</span></div><div class="line">plt.imsave(<span class="string">'img_pyplot.jpg'</span>, img)</div><div class="line"></div><div class="line"><span class="comment"># 用OpenCV存储</span></div><div class="line">cv2.imwrite(<span class="string">'img_cv2.jpg'</span>, img)</div></pre></td></tr></table></figure><p><strong>不管是RGB还是BGR,都是高度×宽度×通道数,H×W×C的表达方式,而在深度学习中,因为要对不同通道应用卷积,所以用的是另一种方式:C×H×W,就是把每个通道都单独表达成一个二维矩阵.</strong><br>np.reshape() 😂 好像就是 CHW (不知道能否这么表述)</p><p><strong>像素点太小了, 截图展示</strong></p><p><strong>用matplotlib存储:</strong> <strong>用OpenCV存储:</strong></p><p><img src="/images/OpenCV_python使用/img_pyplot截图.png" alt="img_pyplot截图"> <img src="/images/OpenCV_python使用/img_cv2截图.png" alt="img_cv2截图"></p>]]></content>
<summary type="html">
<p>python-OpenCV</p>
</summary>
<category term="Foundation" scheme="http://yaoyirong.cn/categories/Foundation/"/>
<category term="Image processing" scheme="http://yaoyirong.cn/tags/Image-processing/"/>
<category term="python" scheme="http://yaoyirong.cn/tags/python/"/>
<category term="OpenCV" scheme="http://yaoyirong.cn/tags/OpenCV/"/>
</entry>
<entry>
<title>matplotlib 使用</title>
<link href="http://yaoyirong.cn/2017/12/22/matplotlib%E4%BD%BF%E7%94%A8/"/>
<id>http://yaoyirong.cn/2017/12/22/matplotlib使用/</id>
<published>2017-12-22T03:30:13.000Z</published>
<updated>2018-03-19T15:18:13.000Z</updated>
<content type="html"><![CDATA[<p>python-matplotlib</p><a id="more"></a><h1 id="python-matplotlib-jupyter"><a href="#python-matplotlib-jupyter" class="headerlink" title="python matplotlib jupyter"></a>python matplotlib jupyter</h1><p>matplotlib 是 python 的 著名数据可视化工具包</p><h2 id="2D图表"><a href="#2D图表" class="headerlink" title="2D图表"></a>2D图表</h2><p>Matplotlib中最基础的模块是pyplot。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">%matplotlib inline</div></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># 有一组数据,还有一个拟合模型,通过下面的代码图来可视化</span></div><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"><span class="keyword">import</span> matplotlib <span class="keyword">as</span> mpl</div><div class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</div><div class="line"></div><div class="line"><span class="comment"># 通过rcParams设置全局横纵轴字体大小</span></div><div class="line">mpl.rcParams[<span class="string">'xtick.labelsize'</span>] = <span class="number">24</span></div><div class="line">mpl.rcParams[<span class="string">'ytick.labelsize'</span>] = <span class="number">24</span></div><div class="line"></div><div class="line">np.random.seed(<span class="number">42</span>)</div><div class="line"><span class="comment"># x 轴的采样点</span></div><div class="line">x = np.linspace(<span class="number">0</span>, <span class="number">5</span>, <span class="number">100</span>)</div><div class="line"><span class="comment"># 通过下面曲线加上噪声生成数据,所以拟合模型就用y了……</span></div><div class="line">y = <span class="number">2</span>*np.sin(x) + <span class="number">0.3</span>*x**<span class="number">2</span></div><div class="line">y_data = y + np.random.normal(scale=<span class="number">0.3</span>, size=<span class="number">100</span>)</div><div class="line"></div><div class="line"><span class="comment"># figure() 指定图表名称</span></div><div class="line">plt.figure(<span class="string">'data'</span>)</div><div class="line"></div><div class="line"><span class="comment"># '.'标明画散点图,每个散点的形状是个圆</span></div><div class="line">plt.plot(x, y_data, <span class="string">'.'</span>)</div><div class="line"></div><div class="line"><span class="comment"># 画模型的图,plot函数默认画连线图</span></div><div class="line">plt.figure(<span class="string">'model'</span>)</div><div class="line">plt.plot(x, y)</div><div class="line"></div><div class="line"><span class="comment"># 两个图画一起</span></div><div class="line">plt.figure(<span class="string">'data & model'</span>)</div><div class="line"></div><div class="line"><span class="comment"># 通过'k'指定线的颜色,lw指定线的宽度</span></div><div class="line"><span class="comment"># 第三个参数除了颜色也可以指定线形,比如'r--'表示红色虚线</span></div><div class="line"><span class="comment"># 更多属性可以参考官网:http://matplotlib.org/api/pyplot_api.html</span></div><div class="line">plt.plot(x, y, <span class="string">'k'</span>, lw=<span class="number">3</span>)</div><div class="line"></div><div class="line"><span class="comment"># scatter可以更容易地生成散点图</span></div><div class="line">plt.scatter(x, y_data)</div><div class="line"></div><div class="line"><span class="comment"># 将当前figure的图保存到文件result.png</span></div><div class="line">plt.savefig(<span class="string">'result.png'</span>)</div><div class="line"></div><div class="line">plt.show()</div></pre></td></tr></table></figure><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/images/matplotlib使用/output_3_0.png" alt="output_3_0" title=""> </div> <div class="image-caption">output_3_0</div> </figure><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/images/matplotlib使用/output_3_1.png" alt="output_3_0" title=""> </div> <div class="image-caption">output_3_0</div> </figure><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/images/matplotlib使用/output_3_2.png" alt="output_3_2" title=""> </div> <div class="image-caption">output_3_2</div> </figure><p>点和线图表只是最基本的用法,有的时候我们获取了分组数据要做对比,柱状或饼状类型的图</p><p>平时画图蹦出的一个窗口,这叫一个figure。Figure相当于一个大的画布,在每个figure中,又可以存在多个子图,这种子图叫做axes。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div><div class="line">57</div><div class="line">58</div><div class="line">59</div><div class="line">60</div><div class="line">61</div><div class="line">62</div><div class="line">63</div><div class="line">64</div><div class="line">65</div><div class="line">66</div><div class="line">67</div><div class="line">68</div><div class="line">69</div><div class="line">70</div><div class="line">71</div><div class="line">72</div><div class="line">73</div><div class="line">74</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> matplotlib <span class="keyword">as</span> mpl</div><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</div><div class="line"></div><div class="line"><span class="comment"># 全都是设置字的大小</span></div><div class="line">mpl.rcParams[<span class="string">'axes.titlesize'</span>] = <span class="number">13</span></div><div class="line">mpl.rcParams[<span class="string">'xtick.labelsize'</span>] = <span class="number">10</span></div><div class="line">mpl.rcParams[<span class="string">'ytick.labelsize'</span>] = <span class="number">10</span></div><div class="line">mpl.rcParams[<span class="string">'axes.labelsize'</span>] = <span class="number">10</span></div><div class="line">mpl.rcParams[<span class="string">'xtick.major.size'</span>] = <span class="number">0</span></div><div class="line">mpl.rcParams[<span class="string">'ytick.major.size'</span>] = <span class="number">0</span></div><div class="line"></div><div class="line"><span class="comment"># 包含了狗,猫和猎豹的最高奔跑速度,还有对应的可视化颜色</span></div><div class="line">speed_map = {</div><div class="line"> <span class="string">'dog'</span>: (<span class="number">48</span>, <span class="string">'#7199cf'</span>),</div><div class="line"> <span class="string">'cat'</span>: (<span class="number">45</span>, <span class="string">'#4fc4aa'</span>),</div><div class="line"> <span class="string">'cheetah'</span>: (<span class="number">120</span>, <span class="string">'#e1a7a2'</span>)</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment"># 整体图的标题</span></div><div class="line">fig = plt.figure(<span class="string">'Bar chart & Pie chart'</span>, figsize=(<span class="number">12</span>,<span class="number">6</span>))</div><div class="line"></div><div class="line"><span class="comment"># 在整张图上加入一个子图,121的意思是在一个1行2列的子图中的第一张</span></div><div class="line">ax = fig.add_subplot(<span class="number">121</span>)</div><div class="line">ax.set_title(<span class="string">'Running speed - bar chart'</span>)</div><div class="line"></div><div class="line"><span class="comment"># 生成x轴每个元素的位置</span></div><div class="line">xticks = np.arange(<span class="number">3</span>)</div><div class="line"></div><div class="line"><span class="comment"># 定义柱状图每个柱的宽度</span></div><div class="line">bar_width = <span class="number">0.5</span></div><div class="line"></div><div class="line"><span class="comment"># 动物名称</span></div><div class="line">animals = speed_map.keys()</div><div class="line"></div><div class="line"><span class="comment"># 奔跑速度</span></div><div class="line">speeds = [x[<span class="number">0</span>] <span class="keyword">for</span> x <span class="keyword">in</span> speed_map.values()]</div><div class="line"></div><div class="line"><span class="comment"># 对应颜色</span></div><div class="line">colors = [x[<span class="number">1</span>] <span class="keyword">for</span> x <span class="keyword">in</span> speed_map.values()]</div><div class="line"></div><div class="line"><span class="comment"># 画柱状图,横轴是动物标签的位置,纵轴是速度,定义柱的宽度,同时设置柱的边缘为透明</span></div><div class="line">bars = ax.bar(xticks, speeds, width=bar_width, edgecolor=<span class="string">'none'</span>)</div><div class="line"></div><div class="line"><span class="comment"># 设置y轴的标题</span></div><div class="line">ax.set_ylabel(<span class="string">'Speed(km/h)'</span>)</div><div class="line"></div><div class="line"><span class="comment"># x轴每个标签的具体位置,设置为每个柱的中央</span></div><div class="line">ax.set_xticks(xticks)</div><div class="line"></div><div class="line"><span class="comment"># 设置每个标签的名字</span></div><div class="line">ax.set_xticklabels(animals)</div><div class="line"></div><div class="line"><span class="comment"># 设置x轴的范围 ---轴不变, 在轴上显示多少, 直接决定柱子好不好看</span></div><div class="line">ax.set_xlim([bar_width/<span class="number">2</span><span class="number">-1</span>, <span class="number">3</span>-bar_width/<span class="number">2</span>])</div><div class="line"></div><div class="line"><span class="comment"># 设置y轴的范围</span></div><div class="line">ax.set_ylim([<span class="number">0</span>, <span class="number">125</span>])</div><div class="line"></div><div class="line"><span class="comment"># 给每个bar分配指定的颜色</span></div><div class="line"><span class="keyword">for</span> bar, color <span class="keyword">in</span> zip(bars, colors):</div><div class="line"> bar.set_color(color)</div><div class="line"> </div><div class="line"><span class="comment"># 在122位置加入新的图</span></div><div class="line">ax = fig.add_subplot(<span class="number">122</span>)</div><div class="line">ax.set_title(<span class="string">'Running speed - pie chart'</span>)</div><div class="line"></div><div class="line"><span class="comment"># 生成同时包含名称和速度的标签</span></div><div class="line">labels = [<span class="string">'{}\n{} km/h'</span>.format(animal, speed) <span class="keyword">for</span> animal, speed <span class="keyword">in</span> zip(animals, speeds)]</div><div class="line"></div><div class="line"><span class="comment"># 画饼状图,并指定标签和对应颜色</span></div><div class="line">ax.pie(speeds, labels=labels, colors=colors)</div><div class="line"></div><div class="line">plt.show()</div></pre></td></tr></table></figure><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/images/matplotlib使用/output_5_0.png" alt="output_5_0" title=""> </div> <div class="image-caption">output_5_0</div> </figure><h2 id="3D-图表"><a href="#3D-图表" class="headerlink" title="3D 图表"></a>3D 图表</h2><p>Matplotlib中也能支持一些基础的3D图表,比如曲面图,散点图和柱状图。这些3D图表需要使用mpl_toolkits模块</p><blockquote><p>python2 python3 原来1/2(两个整数相除)结果是0,现在是0.5了<br>python 2.2+ 以上都可以使用 from <strong>future</strong> import division 实现改特性, 同时注意 // 取代了之前的 / 运算</p></blockquote><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</div><div class="line"></div><div class="line"><span class="comment"># 3D图标必须的模块,project='3d'的定义</span></div><div class="line"><span class="keyword">from</span> mpl_toolkits.mplot3d <span class="keyword">import</span> Axes3D</div><div class="line"></div><div class="line">np.random.seed(<span class="number">42</span>)</div><div class="line">n_grids = <span class="number">51</span> <span class="comment"># x-y平面的格点数 </span></div><div class="line">c = n_grids//<span class="number">2</span> <span class="comment"># 中心位置</span></div><div class="line">nf = <span class="number">2</span> <span class="comment"># 低频成分的个数</span></div><div class="line"></div><div class="line"><span class="comment"># 生成格点</span></div><div class="line">x = np.linspace(<span class="number">0</span>, <span class="number">1</span>, n_grids)</div><div class="line">y = np.linspace(<span class="number">0</span>, <span class="number">1</span>, n_grids)</div><div class="line"></div><div class="line"><span class="comment"># x和y是长度为n_grids的array</span></div><div class="line"><span class="comment"># meshgrid会把x和y组合成n_grids*n_grids的array,X和Y对应位置就是所有格点的坐标</span></div><div class="line">X, Y = np.meshgrid(x, y)</div><div class="line"></div><div class="line"><span class="comment"># 生成一个0值的傅里叶谱</span></div><div class="line">spectrum = np.zeros((n_grids, n_grids), dtype=np.complex)</div><div class="line"></div><div class="line"><span class="comment"># 生成一段噪音,长度是(2*nf+1)**2/2</span></div><div class="line"><span class="comment">#noise = [np.complex(x, y) for x, y in np.random.uniform(-1, 1, ((2*nf+1)**2/2, 2))]</span></div><div class="line">noise = [np.complex(x, y) <span class="keyword">for</span> x, y <span class="keyword">in</span> np.random.uniform(<span class="number">-1</span>,<span class="number">1</span>,((<span class="number">2</span>*nf+<span class="number">1</span>)**<span class="number">2</span>//<span class="number">2</span>, <span class="number">2</span>))]</div><div class="line"></div><div class="line"><span class="comment"># 傅里叶频谱的每一项和其共轭关于中心对称</span></div><div class="line">noise_block = np.concatenate((noise, [<span class="number">0j</span>], np.conjugate(noise[::<span class="number">-1</span>])))</div><div class="line"></div><div class="line"><span class="comment"># 将生成的频谱作为低频成分</span></div><div class="line">spectrum[c-nf:(c+nf+<span class="number">1</span>), c-nf:c+nf+<span class="number">1</span>] = noise_block.reshape((<span class="number">2</span>*nf+<span class="number">1</span>, <span class="number">2</span>*nf+<span class="number">1</span>))</div><div class="line"></div><div class="line"><span class="comment"># 进行反傅里叶变换</span></div><div class="line">Z = np.real(np.fft.ifft2(np.fft.ifftshift(spectrum)))</div><div class="line"></div><div class="line"><span class="comment"># 创建图表</span></div><div class="line">fig = plt.figure(<span class="string">'3D surface & wire'</span>, figsize=(<span class="number">12</span>, <span class="number">6</span>))</div><div class="line"></div><div class="line"><span class="comment"># 第一个子图,surface图</span></div><div class="line">ax = fig.add_subplot(<span class="number">121</span>, projection=<span class="string">'3d'</span>)</div><div class="line"></div><div class="line"><span class="comment"># alpha定义透明度,cmap是color map</span></div><div class="line"><span class="comment"># rstride和cstride是两个方向上的采样,越小越精细,lw是线宽</span></div><div class="line">ax.plot_surface(X, Y, Z, alpha=<span class="number">0.7</span>, cmap=<span class="string">'jet'</span>, rstride=<span class="number">1</span>, cstride=<span class="number">1</span>, lw=<span class="number">0</span>)</div><div class="line"></div><div class="line"><span class="comment"># 第二个子图,网线图</span></div><div class="line">ax = fig.add_subplot(<span class="number">122</span>, projection=<span class="string">'3d'</span>)</div><div class="line">ax.plot_wireframe(X, Y, Z, rstride=<span class="number">3</span>, cstride=<span class="number">3</span>, lw=<span class="number">0.5</span>)</div><div class="line"></div><div class="line">plt.show()</div></pre></td></tr></table></figure><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/images/matplotlib使用/output_7_0.png" alt="output_7_0" title=""> </div> <div class="image-caption">output_7_0</div> </figure><p><strong>3D的散点图</strong></p><p>也是常常用来查看空间样本分布的一种手段,并且画起来比表面图和网线图更加简单</p><p>这个例子中,为了方便,直接先采样了一堆3维的正态分布样本,保证方向上的均匀性。然后归一化,让每个样本到原点的距离为1,相当于得到了一个均匀分布在球面上的样本。再接着把每个样本都乘上一个均匀分布随机数的开3次方,这样就得到了在球体内均匀分布的样本,最后根据判别平面3x+2y-z-1=0对平面两侧样本用不同的形状和颜色画出,图像如下:</p><blockquote><p>shape[0] 看行数, 即第一维数</p></blockquote><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</div><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"></div><div class="line"><span class="keyword">from</span> mpl_toolkits.mplot3d <span class="keyword">import</span> Axes3D</div><div class="line"></div><div class="line">np.random.seed(<span class="number">42</span>)</div><div class="line"></div><div class="line"><span class="comment"># 采样个数500</span></div><div class="line">n_samples = <span class="number">500</span></div><div class="line">dim = <span class="number">3</span></div><div class="line"></div><div class="line"><span class="comment"># 先生成一组3维正态分布数据,数据方向完全随机</span></div><div class="line">samples = np.random.multivariate_normal(</div><div class="line"> np.zeros(dim),</div><div class="line"> np.eye(dim),</div><div class="line"> n_samples</div><div class="line">)</div><div class="line"></div><div class="line"><span class="comment"># 通过把每个样本到原点距离和均匀分布吻合得到球体内均匀分布的样本</span></div><div class="line"><span class="comment"># samples[i] / np.linalg.norm(samples[i]) 归一化 (二范数是向量长度)</span></div><div class="line"><span class="comment"># r 一个均匀分布随机数的开3次方</span></div><div class="line"><span class="keyword">for</span> i <span class="keyword">in</span> range(samples.shape[<span class="number">0</span>]):</div><div class="line"> r = np.power(np.random.random(), <span class="number">1.0</span>/<span class="number">3.0</span>)</div><div class="line"> samples[i] *= r / np.linalg.norm(samples[i])</div><div class="line"></div><div class="line">upper_samples = []</div><div class="line">lower_samples = []</div><div class="line"></div><div class="line"><span class="keyword">for</span> x, y, z <span class="keyword">in</span> samples:</div><div class="line"> <span class="comment"># 3x+2y-z=1作为判别平面</span></div><div class="line"> <span class="keyword">if</span> z > <span class="number">3</span>*x + <span class="number">2</span>*y - <span class="number">1</span>:</div><div class="line"> upper_samples.append((x, y, z))</div><div class="line"> <span class="keyword">else</span>:</div><div class="line"> lower_samples.append((x, y, z))</div><div class="line"> </div><div class="line">fig = plt.figure(<span class="string">'3D scatter plot'</span>)</div><div class="line">ax = fig.add_subplot(<span class="number">111</span>, projection=<span class="string">'3d'</span>)</div><div class="line">uppers = np.array(upper_samples)</div><div class="line">lowers = np.array(lower_samples)</div><div class="line"></div><div class="line"><span class="comment"># 用不同颜色不同形状的图标表示平面上下的样本</span></div><div class="line"><span class="comment"># 判别平面上半部分为红色圆点,下半部分为绿色三角</span></div><div class="line">ax.scatter(uppers[:, <span class="number">0</span>], uppers[:, <span class="number">1</span>], uppers[:, <span class="number">2</span>], c=<span class="string">'r'</span>, marker=<span class="string">'o'</span>)</div><div class="line">ax.scatter(lowers[:, <span class="number">0</span>], lowers[:, <span class="number">1</span>], lowers[:, <span class="number">2</span>], c=<span class="string">'g'</span>, marker=<span class="string">'^'</span>)</div><div class="line"></div><div class="line">plt.show()</div></pre></td></tr></table></figure><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/images/matplotlib使用/output_9_0.png" alt="output_9_0" title=""> </div> <div class="image-caption">output_9_0</div> </figure><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">x = np.linspace(<span class="number">0</span>, <span class="number">1</span>, <span class="number">10</span>)</div><div class="line">y = np.linspace(<span class="number">2</span>, <span class="number">3</span>, <span class="number">10</span>)</div><div class="line">X, Y = np.meshgrid(x, y)</div><div class="line">X.shape[<span class="number">1</span>]</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">10</div></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># 展示画一个3d图</span></div><div class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</div><div class="line"><span class="comment"># 导入3D 包</span></div><div class="line"><span class="keyword">from</span> mpl_toolkits.mplot3d <span class="keyword">import</span> Axes3D</div><div class="line"></div><div class="line"><span class="comment"># 将会话框进行对象化</span></div><div class="line">fig = plt.figure()</div><div class="line"><span class="comment"># 将对话框划分为一个子图, 并指定为3d图</span></div><div class="line">ax = fig.add_subplot(<span class="number">111</span>, projection=<span class="string">'3d'</span>)</div><div class="line"></div><div class="line"><span class="comment"># 定义 x, y, z 三个坐标轴的数据集</span></div><div class="line">U = [<span class="number">1</span>, <span class="number">1</span>, <span class="number">2</span>, <span class="number">2</span>]</div><div class="line">V = [<span class="number">3</span>, <span class="number">4</span>, <span class="number">4</span>, <span class="number">3</span>]</div><div class="line">W = [<span class="number">1</span>, <span class="number">100</span>, <span class="number">1</span>, <span class="number">1</span>]</div><div class="line"></div><div class="line"><span class="comment"># 用函数填满 4个点组成的三角形空间</span></div><div class="line">ax.plot_trisurf(U, V, W)</div><div class="line">plt.show()</div></pre></td></tr></table></figure><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/images/matplotlib使用/output_11_0.png" alt="output_11_0" title=""> </div> <div class="image-caption">output_11_0</div> </figure><h2 id="图像显示"><a href="#图像显示" class="headerlink" title="图像显示"></a>图像显示</h2><p>Matplotlib也支持图像的存取和显示,并且和OpenCV一类的接口比起来,对于一般的二维矩阵的可视化要方便很多:</p><p>这段代码中第一个例子是读取一个本地图片并显示,第二个例子中直接把上小节中反傅里叶变换生成的矩阵作为图像拿过来,原图和经过乘以3再加4变换的图直接绘制了两个形状一样,但是值的范围不一样的图案。显示的时候imshow会自动进行归一化,把最亮的值显示为纯白,最暗的值显示为纯黑。这是一种非常方便的设定,尤其是查看深度学习中某个卷积层的响应图时。得到图像如下:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</div><div class="line"></div><div class="line"><span class="comment"># 读取一张手机的照片并显示</span></div><div class="line">plt.figure(<span class="string">'A little White iPhone'</span>)</div><div class="line">little_iPhone_img = plt.imread(<span class="string">'iPhone.png'</span>)</div><div class="line">plt.imshow(little_iPhone_img)</div><div class="line"></div><div class="line"><span class="comment"># Z是上小节生成的随机图案,img0就是Z,img1是Z做了个简单的变换</span></div><div class="line">img0 = Z</div><div class="line">img1 = <span class="number">3</span>*Z + <span class="number">4</span></div><div class="line"></div><div class="line"><span class="comment"># cmap指定为'gray'用来显示灰度图</span></div><div class="line">fig = plt.figure(<span class="string">'Auto Normalized Visualization'</span>)</div><div class="line">ax0 = fig.add_subplot(<span class="number">121</span>)</div><div class="line">ax0.imshow(img0, cmap=<span class="string">'gray'</span>)</div><div class="line"></div><div class="line">ax1 = fig.add_subplot(<span class="number">122</span>)</div><div class="line">ax1.imshow(img1, cmap=<span class="string">'gray'</span>)</div><div class="line"></div><div class="line">plt.show()</div></pre></td></tr></table></figure><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/images/matplotlib使用/output_13_0.png" alt="output_13_0" title=""> </div> <div class="image-caption">output_13_0</div> </figure><figure class="image-bubble"> <div class="img-lightbox"> <div class="overlay"></div> <img src="/images/matplotlib使用/output_13_1.png" alt="output_13_1" title=""> </div> <div class="image-caption">output_13_1</div> </figure>]]></content>
<summary type="html">
<p>python-matplotlib</p>
</summary>
<category term="Foundation" scheme="http://yaoyirong.cn/categories/Foundation/"/>
<category term="Data mining" scheme="http://yaoyirong.cn/tags/Data-mining/"/>
<category term="python" scheme="http://yaoyirong.cn/tags/python/"/>
<category term="matplotlib" scheme="http://yaoyirong.cn/tags/matplotlib/"/>
</entry>
<entry>
<title>numpy 使用</title>
<link href="http://yaoyirong.cn/2017/12/22/numpy%E4%BD%BF%E7%94%A8/"/>
<id>http://yaoyirong.cn/2017/12/22/numpy使用/</id>
<published>2017-12-22T02:30:13.000Z</published>
<updated>2018-03-19T15:18:27.000Z</updated>
<content type="html"><![CDATA[<p>python-numpy 基础</p><a id="more"></a><h1 id="入门-numpy-篇"><a href="#入门-numpy-篇" class="headerlink" title="入门 numpy 篇"></a>入门 numpy 篇</h1><h2 id="numpy-篇"><a href="#numpy-篇" class="headerlink" title="numpy 篇"></a>numpy 篇</h2><p>array,也就是数组,是numpy中最基础的数据结构, 最关键的属性是<strong>维度</strong>和<strong>元素类型</strong>, 在numpy中,可以非常方便地创建各种不同类型的多维数组,并且执行一些基本基本操作</p><blockquote><p>array 维度 元素类型</p></blockquote><h3 id="基本类型(array"><a href="#基本类型(array" class="headerlink" title="基本类型(array)"></a>基本类型(array)</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">%matplotlib inline</div></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="comment">#%load douban.py</span></div><div class="line"><span class="comment"># run douban.py</span></div></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">!python --version</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">Python 2.7.10</div></pre></td></tr></table></figure><h4 id="创建数组-获取数组的属性"><a href="#创建数组-获取数组的属性" class="headerlink" title="创建数组, 获取数组的属性"></a>创建数组, 获取数组的属性</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> matplotlib.pyplot <span class="keyword">as</span> plt</div><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"></div><div class="line">np.arange(<span class="number">15</span>).reshape(<span class="number">3</span>,<span class="number">5</span>)</div><div class="line"><span class="comment"># 在从1到3中产生9个数:(等差数列)</span></div><div class="line">np.linspace(<span class="number">1</span>, <span class="number">3</span>, <span class="number">9</span>)</div><div class="line"></div><div class="line"><span class="comment"># 创建矩阵</span></div><div class="line">np.zeros((<span class="number">3</span>, <span class="number">4</span>))</div><div class="line"><span class="comment"># 2x2x3的无符号8位整型3维数组,并且初始化所有元素值为0</span></div><div class="line">g = np.zeros((<span class="number">2</span>, <span class="number">2</span>, <span class="number">3</span>), dtype=np.uint8)</div><div class="line">print(g)</div><div class="line"> <span class="comment"># 用另一种类型表示</span></div><div class="line">g.astype(np.float)</div><div class="line"></div><div class="line">np.ones((<span class="number">3</span>, <span class="number">4</span>))</div><div class="line"></div><div class="line">np.eye(<span class="number">3</span>)</div><div class="line"></div><div class="line"><span class="comment"># 创建一个一维数组,元素值是把3重复4次,array([3, 3, 3, 3])</span></div><div class="line">np.repeat(<span class="number">3</span>, <span class="number">4</span>)</div><div class="line"></div><div class="line"><span class="comment"># 三维数组</span></div><div class="line">a = np.zeros((<span class="number">2</span>,<span class="number">2</span>,<span class="number">2</span>))</div><div class="line"><span class="comment"># 数组的维数</span></div><div class="line">a.ndim</div><div class="line"><span class="comment"># 数组每一维的大小</span></div><div class="line">a.shape</div><div class="line"><span class="comment"># 数组的元素数</span></div><div class="line">a.size</div><div class="line"><span class="comment"># 元素类型 dtype('float64')</span></div><div class="line">a.dtype</div><div class="line"><span class="comment"># 每个元素所占的字节数 8</span></div><div class="line">a.itemsize</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">[[[0 0 0]</div><div class="line"> [0 0 0]]</div><div class="line"></div><div class="line"> [[0 0 0]</div><div class="line"> [0 0 0]]]</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">8</div></pre></td></tr></table></figure><p>load()和save()用Numpy专用的二进制格式保存数据,它们会自动处理元素类型和形状等信息。savez()提供了将多个数组存储至一个文件的能力,调用load()方法返回的对象,可以使用数组名对各个数组进行读取。默认数组名arr_0,arr_1,arr_2……</p><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># 关于文件</span></div><div class="line"><span class="comment"># 保存到文件</span></div><div class="line"><span class="comment"># 保存为二进制 第二个参数为要存的数组</span></div><div class="line">np.save(<span class="string">'p.npy'</span>, a)</div><div class="line"><span class="comment"># 保存为txt</span></div><div class="line">np.savetxt(<span class="string">'001'</span>, (<span class="number">11</span>, <span class="number">12</span>, <span class="number">13</span>))</div><div class="line"></div><div class="line"><span class="comment"># 读取数据</span></div><div class="line">q = np.load(<span class="string">'p.npy'</span>)</div><div class="line">qq = np.loadtxt(<span class="string">'001'</span>)</div><div class="line">print(q)</div><div class="line">print(qq)</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">[ 11. 12. 13.]</div></pre></td></tr></table></figure><h4 id="数组索引,切片,赋值"><a href="#数组索引,切片,赋值" class="headerlink" title="数组索引,切片,赋值"></a>数组索引,切片,赋值</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># 切片不能直接print</span></div><div class="line">a = np.array([[<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>], [<span class="number">5</span>,<span class="number">6</span>,<span class="number">7</span>]])</div><div class="line">print(a)</div><div class="line"><span class="comment"># 索引, 行列</span></div><div class="line">b = a[<span class="number">1</span>, <span class="number">2</span>]</div><div class="line">print(b)</div><div class="line"><span class="comment"># 切片, 得到数组</span></div><div class="line">b = a[<span class="number">1</span>,:]</div><div class="line">print(b)</div><div class="line"><span class="comment"># 切片, 得到数组</span></div><div class="line">b = a[<span class="number">1</span>, <span class="number">1</span>:<span class="number">2</span>]</div><div class="line">print(b)</div><div class="line">a[<span class="number">1</span>,:] = [<span class="number">8</span>, <span class="number">9</span>, <span class="number">10</span>]</div><div class="line">print(a)</div><div class="line"></div><div class="line"><span class="comment"># 平均分成3份</span></div><div class="line">g = np.split(np.arange(<span class="number">9</span>), <span class="number">3</span>)</div><div class="line">print(g)</div><div class="line"></div><div class="line"><span class="comment"># 按照下标位置进行划分</span></div><div class="line">h = np.split(np.arange(<span class="number">9</span>), [<span class="number">2</span>, <span class="number">-3</span>])</div><div class="line"></div><div class="line"><span class="comment"># 使用 for 操作元素</span></div><div class="line"><span class="keyword">for</span> x <span class="keyword">in</span> np.linspace(<span class="number">1</span>, <span class="number">3</span>, <span class="number">3</span>):</div><div class="line"> print(x)</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line">[[2 3 4]</div><div class="line"> [5 6 7]]</div><div class="line">7</div><div class="line">[5 6 7]</div><div class="line">[6]</div><div class="line">[[ 2 3 4]</div><div class="line"> [ 8 9 10]]</div><div class="line">[array([0, 1, 2]), array([3, 4, 5]), array([6, 7, 8])]</div><div class="line">1.0</div><div class="line">2.0</div><div class="line">3.0</div></pre></td></tr></table></figure><h4 id="基本的数组运算"><a href="#基本的数组运算" class="headerlink" title="基本的数组运算"></a>基本的数组运算</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line">a = np.ones((<span class="number">2</span>, <span class="number">2</span>))</div><div class="line">b = np.eye(<span class="number">2</span>)</div><div class="line">print(a><span class="number">2</span>)</div><div class="line">print(a+b)</div><div class="line">print(a-b)</div><div class="line">print(b*<span class="number">2</span>)</div><div class="line">print((a*<span class="number">2</span>)*(b*<span class="number">2</span>))</div><div class="line">print(b/(a*<span class="number">2</span>))</div><div class="line">print((a*<span class="number">2</span>)**<span class="number">4</span>)</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div></pre></td><td class="code"><pre><div class="line">[[False False]</div><div class="line"> [False False]]</div><div class="line">[[ 2. 1.]</div><div class="line"> [ 1. 2.]]</div><div class="line">[[ 0. 1.]</div><div class="line"> [ 1. 0.]]</div><div class="line">[[ 2. 0.]</div><div class="line"> [ 0. 2.]]</div><div class="line">[[ 4. 0.]</div><div class="line"> [ 0. 4.]]</div><div class="line">[[ 0.5 0. ]</div><div class="line"> [ 0. 0.5]]</div><div class="line">[[ 16. 16.]</div><div class="line"> [ 16. 16.]]</div></pre></td></tr></table></figure><p>numerical python,基础数学运算也是强大的: </p><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line">np.abs(<span class="number">-1</span>) </div><div class="line">np.sin(np.pi/<span class="number">2</span>) </div><div class="line">np.arctanh(<span class="number">0.462118</span>)</div><div class="line">d = np.exp(<span class="number">3</span>)</div><div class="line">f = np.power(<span class="number">2</span>, <span class="number">3</span>)</div><div class="line">g = np.dot([<span class="number">1</span>, <span class="number">2</span>], [<span class="number">3</span>, <span class="number">4</span>])</div><div class="line">h = np.sqrt(<span class="number">25</span>)</div><div class="line">l = np.sum([<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>])</div><div class="line">m = np.mean([<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>])</div><div class="line"><span class="comment"># 标准差</span></div><div class="line">p = np.std([<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">2</span>, <span class="number">1</span>, <span class="number">3</span>, <span class="number">2</span>, <span class="number">0</span>])</div></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># 使用数组对象自带的方法</span></div><div class="line">print(a.sum())</div><div class="line"><span class="comment"># 计算每一列的和(二维数组中类似于矩阵的列)的和</span></div><div class="line">print(a.sum(axis=<span class="number">0</span>))</div><div class="line"></div><div class="line">a.min()</div><div class="line">a.max()</div><div class="line">a.mean()</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">3.0</div><div class="line">[ 2. 1.]</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">0.75</div></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># 使用numpy下的方法:</span></div><div class="line">print(np.sin(a))</div><div class="line">print(np.max(a))</div><div class="line"><span class="comment"># 向下取整, 取不大于x的整数</span></div><div class="line">print(np.floor(a))</div><div class="line">print(np.exp(a))</div><div class="line"></div><div class="line"><span class="comment"># 矩阵乘法</span></div><div class="line">print(np.dot(a, a))</div><div class="line">print(<span class="string">'-----'</span>)</div><div class="line">print(a)</div><div class="line">print(b)</div><div class="line"><span class="comment"># 合并数组</span></div><div class="line"><span class="comment"># 使用numpy下的vstack和hstack函数:</span></div><div class="line"><span class="comment"># 只能同行同列</span></div><div class="line"></div><div class="line"><span class="string">'''</span></div><div class="line">vstack是指沿着纵轴拼接两个array,vertical</div><div class="line">hstack是指沿着横轴拼接两个array,horizontal</div><div class="line">更广义的拼接用concatenate实现,horizontal后的两句依次等效于vstack和hstack</div><div class="line">stack不是拼接而是在输入array的基础上增加一个新的维度</div><div class="line">'''</div><div class="line">r = np.concatenate((a, b), axis=<span class="number">-1</span>)</div><div class="line"></div><div class="line">c = np.vstack((a, b))</div><div class="line">print(c)</div><div class="line">d = np.hstack((a, b))</div><div class="line">print(d)</div><div class="line"></div><div class="line"><span class="comment"># 深拷贝</span></div><div class="line"><span class="comment"># 即更改 a b 数, c不会发生改变</span></div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div></pre></td><td class="code"><pre><div class="line">[[ 0.84147098 0.84147098]</div><div class="line"> [ 0.84147098 0. ]]</div><div class="line">1.0</div><div class="line">[[ 1. 1.]</div><div class="line"> [ 1. 0.]]</div><div class="line">[[ 2.71828183 2.71828183]</div><div class="line"> [ 2.71828183 1. ]]</div><div class="line">[[ 2. 1.]</div><div class="line"> [ 1. 1.]]</div><div class="line">-----</div><div class="line">[[ 1. 1.]</div><div class="line"> [ 1. 0.]]</div><div class="line">[[ 1. 1.]</div><div class="line"> [ 1. 0.]]</div><div class="line">[[ 1. 1.]</div><div class="line"> [ 1. 0.]</div><div class="line"> [ 1. 1.]</div><div class="line"> [ 1. 0.]]</div><div class="line">[[ 1. 1. 1. 1.]</div><div class="line"> [ 1. 0. 1. 0.]]</div></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># 数组对象自带了浅拷贝和深拷贝的方法,但是一般用深拷贝多一些</span></div><div class="line"><span class="comment"># 浅拷贝</span></div><div class="line">a = np.ones((<span class="number">2</span>, <span class="number">2</span>))</div><div class="line">b = a</div><div class="line">a[<span class="number">1</span>,<span class="number">1</span>] = <span class="number">4</span></div><div class="line">print(b <span class="keyword">is</span> a)</div><div class="line">print(b)</div><div class="line"></div><div class="line"><span class="comment"># 深拷贝</span></div><div class="line">c = a.copy()</div><div class="line">a[<span class="number">1</span>, <span class="number">1</span>] = <span class="number">0</span></div><div class="line">print(c)</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">True</div><div class="line">[[ 1. 1.]</div><div class="line"> [ 1. 4.]]</div><div class="line">[[ 1. 1.]</div><div class="line"> [ 1. 4.]]</div></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># 转置</span></div><div class="line">e = np.array([[<span class="number">2</span>, <span class="number">3</span>], [<span class="number">5</span>, <span class="number">6</span>]])</div><div class="line">print(e)</div><div class="line">print(e.transpose())</div><div class="line"><span class="comment"># 按指定轴进行转置</span></div><div class="line">t = e.transpose((<span class="number">2</span>, <span class="number">0</span>, <span class="number">1</span>))</div><div class="line"><span class="comment"># 逆时针旋转90度,第二个参数是旋转次数</span></div><div class="line">v = np.rot90(e, <span class="number">3</span>)</div><div class="line"><span class="comment"># 沿纵轴左右翻转</span></div><div class="line">w = np.fliplr(e)</div><div class="line"><span class="comment"># 沿水平轴上下翻转</span></div><div class="line">x = np.flipud(e)</div><div class="line"><span class="comment"># 按照一维顺序滚动位移</span></div><div class="line">y = np.roll(e, <span class="number">1</span>)</div><div class="line"><span class="comment"># 按照指定轴滚动位移</span></div><div class="line">z = np.roll(e, <span class="number">1</span>, axis=<span class="number">1</span>)</div><div class="line"><span class="comment"># 迹</span></div><div class="line">np.trace(a)</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">[[2 3]</div><div class="line"> [5 6]]</div><div class="line">[[2 5]</div><div class="line"> [3 6]]</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">1.0</div></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># numpy.linalg模块中有很多关于矩阵运算的方法:</span></div><div class="line"><span class="keyword">import</span> numpy.linalg <span class="keyword">as</span> nplg</div><div class="line"></div><div class="line"><span class="comment"># 特征值 特征向量</span></div><div class="line">nplg.eig(a)</div><div class="line"></div><div class="line">print(a)</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">[[ 1. 1.]</div><div class="line"> [ 1. 0.]]</div></pre></td></tr></table></figure><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line">c = np.array([[<span class="number">1</span>,<span class="number">2</span>], [<span class="number">3</span>,<span class="number">4</span>]])</div><div class="line"><span class="comment"># 每一列的最大值</span></div><div class="line">c.max(axis=<span class="number">1</span>)</div><div class="line"><span class="comment"># 每一行的均值</span></div><div class="line">c.mean(axis=<span class="number">0</span>) </div><div class="line"></div><div class="line"><span class="comment"># 展开一个numpy数组为1维数组,array([1, 2, 3, 4])</span></div><div class="line">c.flatten()</div><div class="line"><span class="comment"># 展开一个可以解析的结构为1维数组,array([1, 2, 3, 4]) </span></div><div class="line">np.ravel(c)</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">array([1, 2, 3, 4])</div></pre></td></tr></table></figure><h3 id="线性代数模块-linalg"><a href="#线性代数模块-linalg" class="headerlink" title="线性代数模块 (linalg)"></a>线性代数模块 (linalg)</h3><p>在深度学习相关的数据处理和运算中,线性代数模块(linalg)是最常用的之一. 结合numpy提供的基本函数,可以对向量,矩阵,或是说多维张量进行一些基本的运算. </p><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div><div class="line">57</div><div class="line">58</div><div class="line">59</div><div class="line">60</div><div class="line">61</div><div class="line">62</div><div class="line">63</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"></div><div class="line">a = np.array([<span class="number">3</span>, <span class="number">4</span>])</div><div class="line"></div><div class="line"><span class="comment"># norm则表示范数,首先需要注意的是范数是对向量(或者矩阵)的度量,是一个标量(scalar):</span></div><div class="line">np.linalg.norm(a)</div><div class="line"></div><div class="line">b = np.array([</div><div class="line"> [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>],</div><div class="line"> [<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>],</div><div class="line"> [<span class="number">7</span>, <span class="number">8</span>, <span class="number">9</span>]</div><div class="line">])</div><div class="line"></div><div class="line">c = np.array([<span class="number">1</span>, <span class="number">0</span>, <span class="number">1</span>])</div><div class="line"></div><div class="line"><span class="comment"># 矩阵和向量之间的乘法 ???</span></div><div class="line">np.dot(b, c)</div><div class="line">np.dot(c, b.T)</div><div class="line"></div><div class="line"><span class="comment"># 求矩阵的迹,15(一个n×n矩阵A的主对角线(从左上方至右下方的对角线)</span></div><div class="line"><span class="comment"># 上各个元素的总和被称为矩阵A的迹)</span></div><div class="line">np.trace(b)</div><div class="line"><span class="comment"># 求矩阵的行列式值,0</span></div><div class="line">np.linalg.det(b)</div><div class="line"><span class="comment"># 求矩阵的秩,2,不满秩,因为行与行之间等差</span></div><div class="line">np.linalg.matrix_rank(b)</div><div class="line"></div><div class="line">d = np.array([</div><div class="line"> [<span class="number">2</span>, <span class="number">1</span>],</div><div class="line"> [<span class="number">1</span>, <span class="number">2</span>]</div><div class="line">])</div><div class="line"><span class="string">'''</span></div><div class="line">对正定矩阵求本征值和本征向量</div><div class="line">本征值为u,array([ 3., 1.])</div><div class="line">本征向量构成的二维array为v,</div><div class="line">array([[ 0.70710678, -0.70710678],</div><div class="line"> [ 0.70710678, 0.70710678]])</div><div class="line">是沿着45°方向</div><div class="line">eig()是一般情况的本征值分解,对于更常见的对称实数矩阵,</div><div class="line">eigh()更快且更稳定,不过输出的值的顺序和eig()是相反的</div><div class="line">'''</div><div class="line"></div><div class="line">u, v = np.linalg.eig(d)</div><div class="line">print(u, v)</div><div class="line"></div><div class="line"><span class="comment"># Cholesky分解并重建</span></div><div class="line"><span class="comment"># 把一个对称正定的矩阵表示成一个下三角矩阵L和其转置的乘积的分解</span></div><div class="line">l = np.linalg.cholesky(d)</div><div class="line">np.dot(l, l.T)</div><div class="line"></div><div class="line">e = np.array([</div><div class="line"> [<span class="number">1</span>, <span class="number">2</span>],</div><div class="line"> [<span class="number">3</span>, <span class="number">4</span>]</div><div class="line">])</div><div class="line"></div><div class="line"><span class="comment"># 对不镇定矩阵,进行SVD分解(奇异值分解)并重建</span></div><div class="line">U, s, V = np.linalg.svd(e)</div><div class="line"></div><div class="line">S = np.array([</div><div class="line"> [s[<span class="number">0</span>], <span class="number">0</span>],</div><div class="line"> [<span class="number">0</span>, s[<span class="number">1</span>]]</div><div class="line">])</div><div class="line">np.dot(U, np.dot(S, V))</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">[ 3. 1.] [[ 0.70710678 -0.70710678]</div><div class="line"> [ 0.70710678 0.70710678]]</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">array([[ 1., 2.],</div><div class="line"> [ 3., 4.]])</div></pre></td></tr></table></figure><h3 id="随机模块(random)"><a href="#随机模块(random)" class="headerlink" title="随机模块(random)"></a>随机模块(random)</h3><p>包含了随机数产生和统计分布相关的基本函数, Python本身也有随机模块random,不过功能更丰富</p><p><strong>注意: 方法参数中都是规定产生随机数的数量(一维, 二维a*b)</strong>, 并非是产生的大小</p><h4 id="随机数产生"><a href="#随机数产生" class="headerlink" title="随机数产生"></a>随机数产生</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</div><div class="line"><span class="keyword">import</span> numpy.random <span class="keyword">as</span> random</div><div class="line"></div><div class="line"><span class="comment"># 设置随机数种子</span></div><div class="line">random.seed(<span class="number">42</span>)</div><div class="line"><span class="comment"># 产生一个1x3 数组,[0,1)之间的浮点型随机数</span></div><div class="line">random.rand(<span class="number">1</span>, <span class="number">3</span>)</div><div class="line"><span class="comment"># 产生一个[0,1)之间的浮点型随机数</span></div><div class="line">random.random()</div><div class="line"></div><div class="line"><span class="comment"># 下边4个没有区别,都是按照指定大小产生[0,1)之间的浮点型随机数array,不Pythonic…</span></div><div class="line">random.random((<span class="number">3</span>, <span class="number">3</span>))</div><div class="line">random.sample((<span class="number">3</span>, <span class="number">3</span>))</div><div class="line">random.random_sample((<span class="number">3</span>, <span class="number">3</span>))</div><div class="line">random.ranf((<span class="number">3</span>, <span class="number">3</span>))</div><div class="line"></div><div class="line"><span class="comment"># 产生10个[1,6)之间的浮点型随机数</span></div><div class="line"><span class="number">5</span>*random.random(<span class="number">10</span>) + <span class="number">1</span></div><div class="line"><span class="comment"># (3, 3)生成二维</span></div><div class="line">random.uniform(<span class="number">1</span>, <span class="number">6</span>, <span class="number">10</span>) </div><div class="line"></div><div class="line"><span class="comment"># 产生10个[1,6)之间的整型随机数</span></div><div class="line">random.randint(<span class="number">1</span>, <span class="number">6</span>, <span class="number">10</span>)</div><div class="line"></div><div class="line"><span class="comment"># 产生2x5的标准正态分布样本</span></div><div class="line">random.normal(size=(<span class="number">5</span>, <span class="number">2</span>))</div><div class="line"></div><div class="line"><span class="comment"># 产生5个,n=5,p=0.5的二项分布样本</span></div><div class="line"></div><div class="line">random.binomial(n=<span class="number">5</span>, p=<span class="number">0.5</span>, size=<span class="number">5</span>)</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">array([3, 4, 4, 2, 1])</div></pre></td></tr></table></figure><h4 id="统计分布"><a href="#统计分布" class="headerlink" title="统计分布"></a>统计分布</h4><p>对具体的样本数据进行与统计分布相关操作</p><blockquote><p>in-place操作,意思是所有的操作都是”就地“操作,不允许进行移动,或者称作 <strong>原位操作</strong>,即不允许使用临时变量。</p></blockquote><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div></pre></td><td class="code"><pre><div class="line">a = np.arange(<span class="number">10</span>)</div><div class="line"></div><div class="line"><span class="comment"># 从a中有回放的随机采样7个</span></div><div class="line">random.choice(a, <span class="number">7</span>)</div><div class="line"></div><div class="line"><span class="comment"># 从a中无回放的随机采样7个</span></div><div class="line">random.choice(a, <span class="number">7</span>, replace=<span class="keyword">False</span>)</div><div class="line"></div><div class="line"><span class="comment"># 对a进行乱序并返回一个新的array</span></div><div class="line">random.permutation(a)</div><div class="line"></div><div class="line"><span class="comment"># 对a进行in-place乱序</span></div><div class="line">random.shuffle(a)</div><div class="line">print(a)</div><div class="line"></div><div class="line"><span class="comment"># 生成一个长度为9的随机bytes序列并作为str返回</span></div><div class="line">random.bytes(<span class="number">9</span>)</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">[1 8 4 2 9 6 5 7 0 3]</div></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">b'[4&`a}0\x94A'</div></pre></td></tr></table></figure>]]></content>
<summary type="html">
<p>python-numpy 基础</p>
</summary>
<category term="Foundation" scheme="http://yaoyirong.cn/categories/Foundation/"/>
<category term="Data mining" scheme="http://yaoyirong.cn/tags/Data-mining/"/>
<category term="python" scheme="http://yaoyirong.cn/tags/python/"/>
<category term="numpy" scheme="http://yaoyirong.cn/tags/numpy/"/>
</entry>
<entry>
<title>LeetCode1541</title>
<link href="http://yaoyirong.cn/2017/03/15/LeetCode%E7%AE%97%E6%B3%95%E5%88%B7%E9%A2%98%E8%BF%87%E7%A8%8B/"/>
<id>http://yaoyirong.cn/2017/03/15/LeetCode算法刷题过程/</id>
<published>2017-03-15T07:03:02.000Z</published>
<updated>2018-03-19T15:16:30.000Z</updated>
<content type="html"><![CDATA[<a id="more"></a><h1 id="LeetCode-一"><a href="#LeetCode-一" class="headerlink" title="LeetCode(一)"></a><strong>LeetCode(一)</strong></h1><h3 id="Tag-Arrays-和Hash-1-15"><a href="#Tag-Arrays-和Hash-1-15" class="headerlink" title="Tag: Arrays 和Hash (1,15)"></a><strong>Tag: <code>Arrays</code> 和<code>Hash</code> (1,15)</strong></h3><h4 id="1-twoSum-返回目标值索引"><a href="#1-twoSum-返回目标值索引" class="headerlink" title="1. twoSum 返回目标值索引"></a><strong>1. twoSum 返回目标值索引</strong></h4><blockquote><p>本题学习过程帮助我了解vector, unordered_map和map</p></blockquote><p>我的思路: 先对vector<int>num进行sort排序, 进而头尾相加, 小于target则头指针加一; 大于则只尾指针减一; 等于跳出循环</int></p><figure class="highlight c++"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div></pre></td><td class="code"><pre><div class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iostream></span></span></div><div class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><algorithm></span></span></div><div class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><vector></span></span></div><div class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</div><div class="line"></div><div class="line"><span class="built_in">vector</span><<span class="keyword">int</span>> twoSum(<span class="built_in">vector</span><<span class="keyword">int</span>>& nums, <span class="keyword">int</span> target) {</div><div class="line"> <span class="built_in">vector</span><<span class="keyword">int</span>>vec(nums);</div><div class="line"> <span class="built_in">vector</span><<span class="keyword">int</span>> result ;</div><div class="line"> sort(nums.begin(), nums.end());</div><div class="line"> <span class="keyword">int</span> a,b,c=<span class="number">0</span>;</div><div class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>,j=nums.size()<span class="number">-1</span>; i<=j; i++,j--)</div><div class="line"> {</div><div class="line"> <span class="keyword">int</span> temp = nums.at(i) + nums.at(j);</div><div class="line"> <span class="keyword">if</span>(temp < target) {j++;}</div><div class="line"> <span class="keyword">else</span> <span class="keyword">if</span>(temp > target){i--;}</div><div class="line"> <span class="keyword">else</span> {a=nums.at(i); b=nums.at(j);<span class="keyword">break</span>;}</div><div class="line"> }</div><div class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> k=<span class="number">0</span>;k<vec.size();k++){</div><div class="line"> <span class="keyword">if</span>(c==<span class="number">2</span>) <span class="keyword">break</span>;</div><div class="line"> <span class="keyword">if</span>(vec.at(k) == a) {result.push_back(k);c++;</div><div class="line"> <span class="keyword">continue</span>;}</div><div class="line"> <span class="keyword">if</span>(vec.at(k) == b) {result.push_back(k);c++;</div><div class="line"> <span class="keyword">continue</span>;}</div><div class="line"> }</div><div class="line"> <span class="keyword">return</span> result;</div><div class="line">}</div></pre></td></tr></table></figure><p><em>网上解答</em></p><p>Solution/*将n方复杂度的转换为linear, 主要是使用map追踪正确需要的数, 把需要的值存进map</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line"><span class="built_in">vector</span><<span class="keyword">int</span>> twoSum(<span class="built_in">vector</span><<span class="keyword">int</span>> &nums, <span class="keyword">int</span> target){</div><div class="line"> <span class="built_in">unordered_map</span><<span class="keyword">int</span>, <span class="keyword">int</span>> hash;</div><div class="line"> <span class="built_in">vector</span><<span class="keyword">int</span>> result;</div><div class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>; i<nums.size(); i++){</div><div class="line"> <span class="keyword">int</span> numToFind = target - nums[i];</div><div class="line"> <span class="keyword">if</span>(hash.find(numsToFind) != hash.end()){</div><div class="line"> result.push_back(hash[numsToFind]);</div><div class="line"> result.push_back(i);</div><div class="line"> <span class="keyword">return</span> result;</div><div class="line"> }</div><div class="line"> hash[nums[i]] = i;</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure><p>####<strong>3. 15. 3Sum</strong></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">报错</div><div class="line">Runtime Error Message: reference binding to null pointer of type 'struct value_type'</div><div class="line">原因: 没有验证输入是否为空数组(向量)</div><div class="line">解决:方法里加入if判断</div></pre></td></tr></table></figure><p>我的思路: 参照第一题, 先外层遍历i, target=0-nums[i], 在按照第一题的方法去做</p><p><strong>问题</strong>: 内层时需要考虑不中间返回, 以及去重问题, 耽误了我的时间复杂度, 😭😭😭</p><p>开始 <strong>但是,超时了</strong>妈个叽</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">class</span> Solution {</div><div class="line"><span class="keyword">public</span>:</div><div class="line"> <span class="built_in">vector</span><<span class="built_in">vector</span><<span class="keyword">int</span>>> threeSum(<span class="built_in">vector</span><<span class="keyword">int</span>>& nums) {</div><div class="line"> <span class="built_in">set</span><<span class="keyword">int</span>> hash; <span class="comment">//便于追踪正确值, 两个的情况</span></div><div class="line"> <span class="built_in">set</span><<span class="keyword">int</span>> skip; <span class="comment">//存放已测试的num[i],用于跳过</span></div><div class="line"> <span class="built_in">vector</span><<span class="built_in">vector</span><<span class="keyword">int</span>>> result;</div><div class="line"> <span class="built_in">vector</span><<span class="keyword">int</span>> tmp;</div><div class="line"> <span class="built_in">set</span><<span class="keyword">int</span>> repeat;</div><div class="line"> <span class="keyword">if</span> (nums.size() < <span class="number">3</span>){</div><div class="line"> <span class="keyword">return</span> result;</div><div class="line"> }</div><div class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < nums.size()<span class="number">-2</span>; i++) {</div><div class="line"> <span class="keyword">if</span> (skip.find(nums[i]) != skip.end()) <span class="keyword">continue</span>;</div><div class="line"> <span class="keyword">int</span> target = <span class="number">0</span> - nums[i];</div><div class="line"> hash.clear();</div><div class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> j = i + <span class="number">1</span>; j < nums.size(); j++) {</div><div class="line"> <span class="keyword">int</span> numToFind = target - nums[j];</div><div class="line"> <span class="keyword">if</span> (skip.find(nums[j]) != skip.end() || skip.find(numToFind) != skip.end()) <span class="keyword">continue</span>;</div><div class="line"> <span class="keyword">if</span>(hash.find(nums[j]) != hash.end()){</div><div class="line"> <span class="keyword">if</span>(numToFind != nums[j]) <span class="keyword">continue</span>;</div><div class="line"> <span class="keyword">if</span>(repeat.find(numToFind) != repeat.end()) <span class="keyword">continue</span>;</div><div class="line"> repeat.insert(numToFind);</div><div class="line"> }</div><div class="line"> <span class="keyword">if</span> (hash.find(numToFind) != hash.end()) {</div><div class="line"> tmp.push_back(numToFind);</div><div class="line"> tmp.push_back(nums[j]);</div><div class="line"> tmp.push_back(nums[i]);</div><div class="line"> result.push_back(tmp);</div><div class="line"> tmp.clear();</div><div class="line"> }</div><div class="line"> hash.insert(nums[j]);</div><div class="line"> }</div><div class="line"> skip.insert(nums[i]);</div><div class="line"> }</div><div class="line"> <span class="keyword">return</span> result;</div><div class="line"> }</div><div class="line">};</div></pre></td></tr></table></figure><figure class="highlight c++"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div></pre></td><td class="code"><pre><div class="line"><span class="comment">//改成能accepted, 然而复杂度不忍直视😂</span></div><div class="line"> <span class="built_in">vector</span><<span class="built_in">vector</span><<span class="keyword">int</span>>> threeSum(<span class="built_in">vector</span><<span class="keyword">int</span>>& nums) {</div><div class="line"> <span class="built_in">set</span><<span class="keyword">int</span>> hash; <span class="comment">//便于追踪正确值, 两个的情况</span></div><div class="line"> <span class="built_in">vector</span><<span class="built_in">vector</span><<span class="keyword">int</span>>> result;</div><div class="line"> <span class="built_in">vector</span><<span class="keyword">int</span>> tmp; </div><div class="line"> <span class="keyword">if</span> (nums.size() < <span class="number">3</span>) {</div><div class="line"> <span class="keyword">return</span> result;</div><div class="line"> }</div><div class="line"> sort(nums.begin(), nums.end());</div><div class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < nums.size() - <span class="number">2</span>; i++) {</div><div class="line"> <span class="keyword">if</span> ((i > <span class="number">0</span> && nums[i] != nums[i - <span class="number">1</span>]) || i == <span class="number">0</span>) {</div><div class="line"> <span class="keyword">int</span> target = <span class="number">0</span> - nums[i];</div><div class="line"> hash.clear();</div><div class="line"> <span class="keyword">int</span> j = i + <span class="number">1</span>;</div><div class="line"> <span class="keyword">while</span>(j < nums.size()) {</div><div class="line"> <span class="keyword">int</span> numToFind = target - nums[j];</div><div class="line"> <span class="keyword">if</span>(hash.find(numToFind) != hash.end()){</div><div class="line"> tmp.push_back(numToFind);</div><div class="line"> tmp.push_back(nums[j]);</div><div class="line"> tmp.push_back(nums[i]);</div><div class="line"> result.push_back(tmp);</div><div class="line"> tmp.clear();</div><div class="line"> <span class="keyword">while</span>(j < nums.size()<span class="number">-1</span> && nums[j] == nums[j+<span class="number">1</span>]) j++;</div><div class="line"> j++;</div><div class="line"> }</div><div class="line"> <span class="keyword">else</span> hash.insert(nums[j++]);</div><div class="line"> }</div><div class="line"> <span class="comment">// for(it = hash.begin(); it!=hash.end(); it++){cout<<*it<<" ";}</span></div><div class="line"> }</div><div class="line"> <span class="comment">// cout<<endl;</span></div><div class="line"> }</div><div class="line"> <span class="keyword">return</span> result;</div><div class="line"> }</div></pre></td></tr></table></figure><p>参照网上的答案更改过后:</p><p><strong>问题明白两点</strong> </p><ul><li>排序,先对给定数组进行排序 </li><li>有时, while循环比for循环更好用 优势在于更好的控制每一次 i+1</li></ul><figure class="highlight c++"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div></pre></td><td class="code"><pre><div class="line"><span class="built_in">vector</span><<span class="built_in">vector</span><<span class="keyword">int</span>>> threeSum2(<span class="built_in">vector</span><<span class="keyword">int</span>> &nums) {</div><div class="line"> sort(nums.begin(), nums.end());</div><div class="line"> <span class="built_in">vector</span><<span class="keyword">int</span>> tmp;</div><div class="line"> <span class="built_in">vector</span><<span class="built_in">vector</span><<span class="keyword">int</span>>> res;</div><div class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i < nums.size(); i++){</div><div class="line"> <span class="keyword">if</span>(i == <span class="number">0</span> || (i > <span class="number">0</span> && nums[i] != nums[i<span class="number">-1</span>])){</div><div class="line"> <span class="keyword">int</span> lo = i + <span class="number">1</span>, hi= nums.size() - <span class="number">1</span>, sum = <span class="number">0</span> - nums[i];</div><div class="line"> <span class="keyword">while</span> (lo < hi){</div><div class="line"> <span class="comment">//第一次允许, 以后通过排序直接跳过可能的重复</span></div><div class="line"> <span class="keyword">if</span> (nums[lo] + nums[hi] == sum){</div><div class="line"> tmp.push_back(nums[i]);</div><div class="line"> tmp.push_back(nums[lo]);</div><div class="line"> tmp.push_back(nums[hi]);</div><div class="line"> res.push_back(tmp);</div><div class="line"> tmp.clear();</div><div class="line"> <span class="keyword">while</span> (lo < hi && nums[lo] == nums[lo + <span class="number">1</span>]) lo++;</div><div class="line"> <span class="keyword">while</span> (lo < hi && nums[hi] == nums[hi - <span class="number">1</span>]) hi--;</div><div class="line"> lo++; hi--;</div><div class="line"> }</div><div class="line"> <span class="keyword">else</span> <span class="keyword">if</span>(nums[lo] + nums[hi] < sum) lo++;</div><div class="line"> <span class="keyword">else</span> hi--;</div><div class="line"> }</div><div class="line"> }</div><div class="line"> }</div><div class="line"> <span class="keyword">return</span> res;</div><div class="line">}</div></pre></td></tr></table></figure><p>char<em> p = “test”; 这个声明,声明了一个指针,而这个指针指向的是<em>*全局的const内存区</em></em>,const内存区当然不会让你想改就改的。</p><h4 id="541-Reverse-String-II"><a href="#541-Reverse-String-II" class="headerlink" title="541.Reverse String II"></a><strong>541.Reverse String II</strong></h4><p>问题描述:一串小写字符,分<k, k<s<2k,="" s="">2k几种情况,每2k个字符第k个逆转到开头,k范围[1, 10000]</k,></p><p><strong>小问题</strong>(是我理解的问题还是)</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">class</span> Solution{</div><div class="line"><span class="keyword">public</span>:</div><div class="line"> <span class="function"><span class="built_in">string</span> <span class="title">reverseStr</span><span class="params">(String str, <span class="keyword">int</span> k)</span></span>{</div><div class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> left=<span class="number">0</span>; left<str.size; left+= <span class="number">2</span>*k)</div><div class="line"> {</div><div class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=left,j=min(left+k<span class="number">-1</span>, <span class="keyword">int</span>(s.size()<span class="number">-1</span>)); i<j; i++,j--)</div><div class="line"> {</div><div class="line"> swap(s[i], s[j]);</div><div class="line"> }</div><div class="line"> }</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure>]]></content>
<summary type="html">
<a id="more"></a>
<h1 id="LeetCode-一"><a href="#LeetCode-一" class="headerlink" title="LeetCode(一)"></a><strong>LeetCode(一)</strong></h1><h3
</summary>
<category term="Algorithm" scheme="http://yaoyirong.cn/categories/Algorithm/"/>
<category term="LeetCode" scheme="http://yaoyirong.cn/tags/LeetCode/"/>
<category term="arrays" scheme="http://yaoyirong.cn/tags/arrays/"/>
<category term="hash" scheme="http://yaoyirong.cn/tags/hash/"/>
</entry>
<entry>
<title>范数</title>
<link href="http://yaoyirong.cn/2017/03/01/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0%E7%AC%AC%E4%B8%80%E5%91%A8%E4%B9%8B%E8%8C%83%E6%95%B0/"/>
<id>http://yaoyirong.cn/2017/03/01/机器学习第一周之范数/</id>
<published>2017-03-01T02:20:13.000Z</published>
<updated>2018-03-19T15:20:04.000Z</updated>
<content type="html"><![CDATA[<p>机器学习?(ノへ ̄、)</p><a id="more"></a><h4 id="向量范数"><a href="#向量范数" class="headerlink" title="向量范数"></a><strong>向量范数</strong></h4><p>min∑(f(x)-y)^2+正则表达(范数解决过拟合问题)</p><ol><li><p>L0 特征选择, 非0元素稀疏, 缺点是难优化</p></li><li><p>L1 可以直接使得元素值为0从而容易稀疏</p></li><li><p>L2 岭回归 最小化L2范数,可以使得x的元素值都很小, 但都不是0</p><p>最小二乘L2范数优化, 凸优化方法</p><blockquote><p>优点: </p><p> 1) 改善”过拟合”overfitting—新样本表现很差(长发问题)</p><p>2) 利于优化 机器学习中有时候损失函数是非凸的, 例如: 神经网络, 梯度下降之类的方法遇见</p></blockquote></li></ol><h4 id="矩阵范数"><a href="#矩阵范数" class="headerlink" title="矩阵范数"></a><strong>矩阵范数</strong></h4><ol><li><p>1-范数 列范数最大 变成向量</p></li><li><p>2-范数 谱范数 难优化 求特征值</p></li><li><p>F-范数: (∑i=1,m∑j1,n aij^2)^1/2</p><p>最小化矩阵的f范数,会使得矩阵的每个元素都很小,近0</p><p>||A-B||F A,B矩阵尽可能相同 应用字典学习</p></li><li><p>核范数—-矩阵奇异值的和 </p><p>最小化可以导致矩阵低秩 </p><p>矩阵的秩—-矩阵线性不相关的行数 去除冗余</p><p>不好求所以 近似 是核范数 </p><p>应用 推荐系统,低秩 奇异值分解 /鲁棒PCA 重构为低秩+噪声, 不在原始图像上降维</p></li><li><p>2,1范数 按列求2范数(平方开根)再求1范数, 整列(列向量)稀疏(全0)</p><p>Lasso 找出关键词 Group Lasso使一组为0,找出关键句子 Hierarchical Lasso找出关键段</p><p>应用:文本分类</p></li><li><p>1,2范数 按列1(每一列可能有好多0)再2(不稀疏保证了每一列不为0,进而保证了每一列中的每一行不可全为0,平方和开根不为0), 使得行内元素互斥, 行内有0元素但不可能全0</p></li></ol>]]></content>
<summary type="html">
<p>机器学习?(ノへ ̄、)</p>
</summary>
<category term="Foundation" scheme="http://yaoyirong.cn/categories/Foundation/"/>
<category term="Machine learning" scheme="http://yaoyirong.cn/tags/Machine-learning/"/>
<category term="norm" scheme="http://yaoyirong.cn/tags/norm/"/>
</entry>
<entry>
<title>Mac Linux文件系统</title>
<link href="http://yaoyirong.cn/2016/07/15/mac%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F/"/>
<id>http://yaoyirong.cn/2016/07/15/mac文件系统/</id>
<published>2016-07-15T01:18:35.000Z</published>
<updated>2018-03-19T15:16:50.000Z</updated>
<content type="html"><![CDATA[<h3 id="mac-文件系统"><a href="#mac-文件系统" class="headerlink" title="mac 文件系统"></a><strong>mac 文件系统</strong></h3><p>隐藏<br>cmd中ls /</p><h4 id="符合unix传统的目录"><a href="#符合unix传统的目录" class="headerlink" title="符合unix传统的目录"></a><strong>符合unix传统的目录</strong></h4><p>/bin 传统unix命令的存放目录,如ls,rm,mv等。<br>/sbin 传统unix管理类命令存放目录,如fdisk,ifconfig等等。<br>/usr 第三方程序安装目录。<br>/usr/bin, /usr/sbin, /usr/lib,其中/usr/lib目录中存放了共享库(动态链接库).<br>/etc. 标准unix系统配置文件存放目录,如用户密码文件/etc/passwd。此目录实际为指向/private/etc的链接。<br>/dev 设备文件存放目录,如何代表硬盘的/dev/disk0。<br>/tmp 临时文件存放目录,其权限为所有人任意读写。此目录实际为指向/private/tmp的链接。<br>/var 存放经常变化的文件,如日志文件。此目录实际为指向/private/var的链接。</p><h4 id="os-x特有的目录"><a href="#os-x特有的目录" class="headerlink" title="os x特有的目录"></a><strong>os x特有的目录</strong></h4><p>/Applications 应用程序目录,默认所有的GUI应用程序都安装在这里;<br>/Library 系统的数据文件、帮助文件、文档等等;<br>/Network 网络节点存放目录;<br>/System 他只包含一个名为Library的目录,这个子目录中存放了系统的绝大部分组件,如各种framework,以及内核模块,字体文件等等。<br>/Users 存放用户的个人资料和配置。每个用户有自己的单独目录。<br>/Volumes 文件系统挂载点存放目录。<br>/cores 内核转储文件存放目录。当一个进程崩溃时,如果系统允许则会产生转储文件。<br>/private 里面的子目录存放了/tmp, /var, /etc等链接目录的目标目录。</p><p>OS X发生崩溃和不能启动的概率实在是太低了,就算是系统出现问题,由于用户目录和系统目录是彼此独立的,所以也容易找回。<br>所以通常情况下,用户直接把资料存放在自己的用户目录中</p><h3 id="Linux-文件系统"><a href="#Linux-文件系统" class="headerlink" title="Linux 文件系统"></a>Linux 文件系统</h3><p>形式表现上一体——所有数据目录均为根目录下的子目录<br>实质——多个不同的<strong>【逻辑主体】</strong>(为了实现不同的逻辑功能)组合在一起</p><h4 id="文件系统结构标准"><a href="#文件系统结构标准" class="headerlink" title="文件系统结构标准"></a><strong>文件系统结构标准</strong></h4><h5 id="LINUX系统的数据文件分类——双重标准"><a href="#LINUX系统的数据文件分类——双重标准" class="headerlink" title="LINUX系统的数据文件分类——双重标准"></a><strong>LINUX系统的数据文件分类——双重标准</strong></h5><p>共享的与独享的(shareable vs. unshareable)<br>数据与平台不相关,如/usr (共享) 数据是平台相关的,如配置数据/etc。变化的和静态的(variable vs. static)<br>相对非管理员用户而言的,没有更变的权限 (静态)</p><h5 id="Linux根文件系统逻辑组成"><a href="#Linux根文件系统逻辑组成" class="headerlink" title="Linux根文件系统逻辑组成"></a><strong>Linux根文件系统逻辑组成</strong></h5><p>(以具体目录表现逻辑功能)/ ——根目录(专用的静态的“根本所在”)/usr ——(共享的静态的)/var——(动态的共享的)/opt/home</p><h5 id="根目录必选组成目录"><a href="#根目录必选组成目录" class="headerlink" title="根目录必选组成目录"></a><strong>根目录必选组成目录</strong></h5><blockquote><p>/bin 基本工具或命令<br>/sbin 系统管理工具或命令<br>/etc 主机相关(Host-specific)的配置数据<br>/lib 基本共享库和内核模块<br>/dev 设备文件<br>/boot 引导程序<br>/root 管理员的工作目录<br>/mnt 系统管理员的临时挂接点<br>/tmp 系统级临时文件<br>/media 移动设备挂接点</p></blockquote><h5 id="usr-目录"><a href="#usr-目录" class="headerlink" title="/usr 目录"></a><strong>/usr 目录</strong></h5><p>/usr 目录是系统的一大组成部分,共享的静态的</p><p>静态:普通用户不可更改/usr下数据<br>共享:/usr下数据与主机平台不相关,代码独立于运行主机<br>/usr必选组成目录/usr/bin Most user commands<br>/usr/include Header files included by C programs<br>/usr/blib Libraries<br>/usr/local Local hierarchy (empty after main installation)<br>/usr/sbin Non-vital system binaries<br>/usr/share Architecture-independent data</p><h5 id="var目录"><a href="#var目录" class="headerlink" title="/var目录"></a><strong>/var目录</strong></h5><p>/var基本上是动态的和共享的(少量是主机相关的,如/var/log)。<br>/var保存大部分是程序运行期的动态生成数据</p>]]></content>
<summary type="html">
<h3 id="mac-文件系统"><a href="#mac-文件系统" class="headerlink" title="mac 文件系统"></a><strong>mac 文件系统</strong></h3><p>隐藏<br>cmd中ls /</p>
<h4 id="符合
</summary>
<category term="System" scheme="http://yaoyirong.cn/categories/System/"/>
<category term="os" scheme="http://yaoyirong.cn/tags/os/"/>
</entry>
</feed>