-
Notifications
You must be signed in to change notification settings - Fork 241
/
Copy pathOpenCV图像处理篇之采样金字塔.html
211 lines (197 loc) · 12.1 KB
/
OpenCV图像处理篇之采样金字塔.html
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
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta name="generator" content="pandoc" />
<title></title>
<style type="text/css">code{white-space: pre;}</style>
<style type="text/css">
table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
margin: 0; padding: 0; vertical-align: baseline; border: none; }
table.sourceCode { width: 100%; line-height: 100%; }
td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
td.sourceCode { padding-left: 5px; }
code > span.kw { color: #007020; font-weight: bold; }
code > span.dt { color: #902000; }
code > span.dv { color: #40a070; }
code > span.bn { color: #40a070; }
code > span.fl { color: #40a070; }
code > span.ch { color: #4070a0; }
code > span.st { color: #4070a0; }
code > span.co { color: #60a0b0; font-style: italic; }
code > span.ot { color: #007020; }
code > span.al { color: #ff0000; font-weight: bold; }
code > span.fu { color: #06287e; }
code > span.er { color: #ff0000; font-weight: bold; }
</style>
<link rel="stylesheet" href="../stylesheets/Github.css" type="text/css" />
<title>OpenCV图像处理篇之采样金字塔</title>
</head>
<body>
<div id="header"><center>
<p class="header_titleline">
<a href="../index.html" target="_self" title="主页">主页 </a><a href="../Search.html" target="_self" title="站内搜索">站内搜索 </a><a href="../Projects.html" target="_self" title="项目研究">项目研究 </a><a href="../Archives.html" target="_self" title="文章存档">文章存档 </a><a href="../README.html" target="_self" title="分类目录">分类目录 </a><a href="../AboutMe.html" target="_self" title="关于我">关于我 </a>
</p>
</center></div>
<h1>OpenCV图像处理篇之采样金字塔</h1>
<h4>2014-09-20 / xiahouzuoxin</h4>
<h4>Tags: OpenCV</h4>
转载请注明出处: <a href="http://xiahouzuoxin.github.io/notes/">http://xiahouzuoxin.github.io/notes/</a>
<div id="TOC">
<ul>
<li><a href="#图像金字塔">图像金字塔</a></li>
<li><a href="#程序分析">程序分析</a></li>
<li><a href="#结果显示">结果显示</a></li>
</ul>
</div>
<!---title:OpenCV图像处理篇之采样金字塔-->
<!---keywords:OpenCV-->
<!---date:2014-09-20-->
<h2 id="图像金字塔">图像金字塔</h2>
<p>图像金字塔是通过将原始图像经过平滑、下采样所生成一系列具有不同分辨率的图像的集合。金字塔结构(Pyramid)适于多分辨率处理的一种图像存储数据结构。</p>
<p>最常用的生成图像金字塔的方法是采用高斯函数平滑图像,每次将分辨率降低为原来的一半,由此得到一个图像序列{ML,ML-1,……,M0},图像金字塔的存储量为<code>N^2*(1+1/4+1/16+...)=(4*N^2)/3</code>。</p>
<div class="figure">
<img src="../images/OpenCV图像处理篇之采样金字塔/example.png" alt="example" /><p class="caption">example</p>
</div>
<p>如上图:最右边为原始图像,从右到左依次为使用高斯平滑1次、2次和3次后的图像,这些图像共同组成了图像金字塔。</p>
<p>图像金字塔这种结构在图像处理中有广泛的用途。最著名的特征匹配算子SIFT就是通过构造图像金字塔来完成的。有关图像金字塔在SIFT特征提取算法中的应用可参见Rachel Zhang的博文<a href="http://blog.csdn.net/abcjennifer/article/details/7639681">"SIFT特征提取分析"</a>。</p>
<h2 id="程序分析">程序分析</h2>
<pre class="sourceCode c"><code class="sourceCode c"><span class="co">/*</span>
<span class="co"> * FileName : pyramids.cpp</span>
<span class="co"> * Author : xiahouzuoxin @163.com</span>
<span class="co"> * Version : v1.0</span>
<span class="co"> * Date : Sat 20 Sep 2014 07:04:29 PM CST</span>
<span class="co"> * Brief : </span>
<span class="co"> * </span>
<span class="co"> * Copyright (C) MICL,USTB</span>
<span class="co"> */</span>
<span class="ot">#include <iostream></span>
<span class="ot">#include "cv.h" </span>
<span class="ot">#include "highgui.h"</span>
<span class="ot">#include "opencv2/imgproc/imgproc.hpp"</span>
using namespace std;
using namespace cv;
<span class="dt">const</span> <span class="dt">char</span> *wn = <span class="st">"Pyramids Demo"</span>;
<span class="dt">int</span> main(<span class="dt">int</span> argc, <span class="dt">char</span> *argv[])
{
<span class="kw">if</span> (argc < <span class="dv">2</span>) {
cout<<<span class="st">"Usage: ./pyramids [file name]"</span><<endl;
<span class="kw">return</span> -<span class="dv">1</span>;
}
Mat src = imread(argv[<span class="dv">1</span>]);
<span class="kw">if</span> (!src.data) {
cout<<<span class="st">"Error: read image error."</span><<endl;
<span class="kw">return</span> -<span class="dv">1</span>;
}
<span class="co">/* Size of input image must be 2^n */</span>
<span class="kw">if</span> ( src.cols & (src.cols<span class="dv">-1</span>) ) { <span class="co">// src.cols > 0 first</span>
cout<<<span class="st">"Error: input image's column must be 2^n"</span><<endl;
<span class="kw">return</span> -<span class="dv">1</span>;
}
<span class="kw">if</span> ( src.rows & (src.rows<span class="dv">-1</span>) ) { <span class="co">// src.cols > 0 first</span>
cout<<<span class="st">"Error: input image's row must be 2^n"</span><<endl;
<span class="kw">return</span> -<span class="dv">1</span>;
}
cout<<<span class="st">"User Guide:"</span><<endl;
cout<<<span class="st">"---------------------"</span><<endl;
cout<<<span class="st">"u -> Zoom out"</span><<endl;
cout<<<span class="st">"d -> Zoom in"</span><<endl;
cout<<<span class="st">"ESC -> Exit program"</span><<endl;
namedWindow(wn, WINDOW_AUTOSIZE);
imshow(wn, src);
Mat cur = src;
Mat dst = cur;
<span class="dt">int</span> end_while = <span class="dv">0</span>;
<span class="kw">while</span>(!end_while) {
<span class="dt">char</span> c;
c = waitKey(<span class="dv">10</span>);
<span class="kw">switch</span> (c) {
<span class="kw">case</span> <span class="dv">27</span>: <span class="co">/* ESC */</span>
end_while = <span class="dv">1</span>;
<span class="kw">break</span>;
<span class="kw">case</span> 'u':
pyrUp(cur, dst, Size(cur.cols*<span class="dv">2</span>, cur.rows*<span class="dv">2</span>));
imshow(wn, dst);
cur = dst;
<span class="kw">break</span>;
<span class="kw">case</span> 'd':
pyrDown(cur, dst, Size(cur.cols/<span class="dv">2</span>, cur.rows/<span class="dv">2</span>));
imshow(wn, dst);
cur = dst;
<span class="kw">break</span>;
<span class="kw">default</span>:
<span class="kw">break</span>;
}
}
}</code></pre>
<ol style="list-style-type: decimal">
<li><p>使用高斯图像金字塔进行降采样和插值的函数分别是<code>pyrDown</code>和<code>pyrUp</code>,参数依次为原图像、采样结果图像、采样后的图像尺寸。</p></li>
<li><p>上述程序中的降采样操作因为都是按2为倍数进行的,因此要求输入图像的长宽都必须是2<sup>n。<code>if ( src.cols & (src.cols-1) )</code>是用来判断原图像的列是否为2</sup>n的语句。请仔细体会这种判断某个数是否是2^n的方法——x*(x-1)返回0表示x是2^n,否则不是。</p></li>
</ol>
<h2 id="结果显示">结果显示</h2>
<p>下面一系列图片展现的是先将原图像通过图像金字塔降采样(会存在数据丢失),再通过金字塔插值恢复图像过程中图像的变化过程。由于降采样过程中存在数据丢失,所以可以看到恢复到原图像大小后的图像比原图像模糊。</p>
<div class="figure">
<img src="../images/OpenCV图像处理篇之采样金字塔/origin.png" alt="origin" /><p class="caption">origin</p>
</div>
<p><strong>图注</strong> 原图像</p>
<div class="figure">
<img src="../images/OpenCV图像处理篇之采样金字塔/div2.png" alt="div2" /><p class="caption">div2</p>
</div>
<p><strong>图注</strong> 1次降采样后的图像</p>
<div class="figure">
<img src="../images/OpenCV图像处理篇之采样金字塔/div4.png" alt="div4" /><p class="caption">div4</p>
</div>
<p><strong>图注</strong> 2次降采样后的图像</p>
<div class="figure">
<img src="../images/OpenCV图像处理篇之采样金字塔/MUL2.png" alt="MUL2" /><p class="caption">MUL2</p>
</div>
<p><strong>图注</strong> 2次降采样后,再经过1次图像金字塔插值操作后的图像,大小与1次降采样后图像相同,但变得模糊</p>
<div class="figure">
<img src="../images/OpenCV图像处理篇之采样金字塔/MUL4.png" alt="MUL4" /><p class="caption">MUL4</p>
</div>
<p><strong>图注</strong> 2次降采样后,再经过2次图像金字塔插值操作后的图像,大小与原图相同,但变得模糊</p>
<div class="ds-thread" data-thread-key="OpenCV图像处理篇之采样金字塔" data-title="OpenCV图像处理篇之采样金字塔" data-url="xiahouzuoxin.github.io/notes/html/OpenCV图像处理篇之采样金字塔.html"></div>
<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"slide":{"type":"slide","bdImg":"5","bdPos":"right","bdTop":"300"},"image":{"viewList":["qzone","tsina","tqq","renren","weixin"],"viewText":"分享到:","viewSize":"16"},"selectShare":{"bdContainerClass":null,"bdSelectMiniList":["qzone","tsina","tqq","renren","weixin"]}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
<!-- 多说公共JS代码 start (一个网页只需插入一次) -->
<script type="text/javascript">
var duoshuoQuery = {short_name:"xiahouzuoxin"};
(function() {
var ds = document.createElement('script');
ds.type = 'text/javascript';ds.async = true;
ds.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') + '//static.duoshuo.com/embed.js';
ds.charset = 'UTF-8';
(document.getElementsByTagName('head')[0]
|| document.getElementsByTagName('body')[0]).appendChild(ds);
})();
</script>
<!-- 多说公共JS代码 end -->
<div id="footer">
<p class="footer_subline">联系邮箱: [email protected]</p>
<p class="footer_subline">声明: 本站所有文章如非特别说明均为原创,转载请注明出处!
<script type="text/javascript">var cnzz_protocol = (("https:" == document.location.protocol) ? " https://" : " http://");document.write(unescape("%3Cspan id='cnzz_stat_icon_1253219218'%3E%3C/span%3E%3Cscript src='" + cnzz_protocol + "s4.cnzz.com/z_stat.php%3Fid%3D1253219218%26show%3Dpic' type='text/javascript'%3E%3C/script%3E"));</script>
</p>
</div>
<!-- 回到顶部 -->
<script>
lastScrollY=0;
function heartBeat(){
var diffY;
if (document.documentElement && document.documentElement.scrollTop)
diffY = document.documentElement.scrollTop;
else if (document.body)
diffY = document.body.scrollTop
else
{/*Netscape stuff*/}
percent=.1*(diffY-lastScrollY);
if(percent>0)percent=Math.ceil(percent);
else percent=Math.floor(percent);
document.getElementById("full").style.top=parseInt(document.getElementById("full").style.top)+percent+"px";
lastScrollY=lastScrollY+percent;
}
suspendcode="<div id=\"full\" style='right:1px;POSITION:absolute;TOP:600px;z-index:100'><a onclick='window.scrollTo(0,0);'><img src='../images/top.png'></a><br></div>"
document.write(suspendcode);
window.setInterval("heartBeat()",1);
</script>
</body>
</html>