﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-Amigo</title><link>http://www.cppblog.com/Amigo/</link><description>Labor vanquishes all,
not inconstant, spasmodic, ill-directed labor
but faithful, unremitting, daily effort towad a well-directed purpose .
Just as truly as eternal vigilance is the price of liberty ,
so is eternal industry the price of noble and enduring success !
</description><language>zh-cn</language><lastBuildDate>Thu, 23 Apr 2026 10:10:36 GMT</lastBuildDate><pubDate>Thu, 23 Apr 2026 10:10:36 GMT</pubDate><ttl>60</ttl><item><title>视频原理</title><link>http://www.cppblog.com/Amigo/archive/2009/02/20/74369.html</link><dc:creator>Amigo</dc:creator><author>Amigo</author><pubDate>Fri, 20 Feb 2009 02:15:00 GMT</pubDate><guid>http://www.cppblog.com/Amigo/archive/2009/02/20/74369.html</guid><wfw:comment>http://www.cppblog.com/Amigo/comments/74369.html</wfw:comment><comments>http://www.cppblog.com/Amigo/archive/2009/02/20/74369.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Amigo/comments/commentRss/74369.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Amigo/services/trackbacks/74369.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 21世纪进入了信息化时代。随着信息技术的数字化、网络化、宽带化和综合化，使视频技术得到了长足的发展。在进入多媒体时代的今天，到处都可以见到各式各样的图像和视频产品，它们使我们的生活变得丰富多彩。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 图象与视频是两个既有联系又有区别的概念：静止的图片称为图象（Image），运动的图象称为视频（Video）。图象的输入要靠扫描仪、数字照相机或摄象机等；而视频的输入只能是摄象机、录象机、影碟机以及电视接收机等可以输出连续图象信号的设备。<br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 本文将针对视频图像这一领域作一个概括的介绍，希望对大家进一步了解视频技术方面的知识有所帮助。下面先对一些视频技术名词作一下简单解释。<br><br><strong>视频信号的分类和基本概念</strong><br><br><strong>一、模拟视频信号<br><br></strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 根据三基色原理，在视频领域利用R（红）、G（绿）、B（蓝）三色不同比例的混合来表现丰富多采的现实世界。首先，通过摄像机的光敏器件像CCD（电荷耦合器件），将光信号转换成RGB三路电信号；其次，在电视机或监视器内部也使用RGB信号分别控制三支电子枪轰击荧光屏以产生影象。这样，由于摄像机中原始信号和电视机、监视器中的最终信号都是RGB信号，因此直接使用RGB信号作为视频信号的传输和记录方式会获得极高的信号质量。但这样做会极大地加宽视频带宽从而增加设备成本，且这也与现行黑白电视不兼容，因此，在实际应用中不这样做，而是按亮度方程Y=0.39R+0.5G+0.11B（PAL制）RGB信号转换成亮度信号Y和两个色差信号U（B-Y）、V（R-Y），形成YUV分量信号。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 此种信号利用人眼对亮度细节分辨率高而对色度细节分辨率低的特点，对U、V信号带宽压缩。U、V信号还可进一步合成一个色度信号C，进而形成Y/C记录方式。由于记录时对C信号采取降频处理，因此也称彩色降频方式。Y和C又可进一步形成复合视频（Composite），即彩色全电视信号，这种方式便于传输和电视信号的发射。将RGB信号转换成YUV信号、Y/C信号直至composite信号的过程称为编码，逆过程则为解码。由此可看出，由于转换步骤的多少，视频输出质量由YUV端口到Y/C端口到Composite端口依次降低。因此，在视频捕捉或输出时选择合适的输入、输出端口可提高视频质量。另外，还应提供同步信号以保证传送图象稳定再现。 <br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 视频影像是由一系列被称为帧的单个静止画面组成。一般帧率在24-30帧/秒时，视频运动非常平滑，而低于15帧/秒时就会有停顿感。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NTSC：国家电视标准委员会(National Television Standards Commitee)的缩写。是中北美洲及日本通用的电视制式，与欧洲的PAL制式和法国的SECAM只是相对。他的垂直分辨率有525线，帧速为30(29.97)FPS。 <br><br>　　PAL：逐行倒相(Phase Alteration Line)的缩写，是中国及欧洲大多数国家通用的电视制式。具有更高的垂直分辨率(625线)，但是帧速相对慢于NTSC(25FPS)。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 分量视频信号(Separate Video) ：将画面按三个颜色通道(RGB)分成红、绿和蓝(附加亮度信号)三个单独信号通道。产生的画面质量较高，一般在广播级视频设备中被采用。 <br>　　复合视频信号(Composite Video) ：将彩色信号、亮度信号和同步信号混合在一个信号通道内，在家用视频设备中被大量采用。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; S-Video：是一种信号质量更高的视频接口，它取消了信号叠加的方法，可有效避免一些无谓的质量损失。它的功能是将RGB三原色和亮度进行分离处理。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; YUV色彩系统： YUV（亦称YCrCb）是被欧洲电视系统所采用的一种颜色编码方法（属于PAL）。YUV主要用于优化彩色视频信号的传输，使其向后兼容老式黑白电视。与RGB视频信号传输相比，它最大的优点在于只需占用极少的带宽（RGB要求三个独立的视频信号同时传输）。其中&#8220;Y&#8221;表示明亮度（1uminance或 Luma），也就是灰阶值；而&#8220;U&#8221;和&#8220;V&#8221;表示的则是色度(Chrominance Chroma)，作用是描述影像色彩及饱和度，用于指定像素的颜色。&#8220;亮度&#8221;是通过RGB输入信号来创建的，方法是将RGB信号的特定部分叠加到一起。&#8220;色度&#8221;则定义了颜色的两个方面—-色调与饱和度，分别用Cr和Cb来表示。其中，Cr反映了Cb输入信号红色部分与RGB信号亮度值之间的差异。而Cb反映的是RGB输入信号蓝色部分与RGB信号亮度值之间的差异。<br><br><strong>二、数字视频信号</strong> <br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 数字视频就是先用摄像机之类的视频捕捉设备，将外界影像的颜色和亮度信息转变为电信号，再记录到储存介质（如录像带）。如果用示波器来观看未投影的模拟电信号，看起来就像脑电波的扫描图像，由一些连续锯齿状的山峰和山谷组成。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 为了存储视觉信息，模拟视频信号的山峰和山谷必须通过数字/模拟（D/A）转换器来转变为数字的&#8220;0&#8221;或&#8220;1&#8221;。这个转变过程就是我们所说的视频捕捉（或采集过程）。如果要在电视机上观看数字视频，则需要一个从数字到模拟的转换器将二进制信息解码成模拟信号，才能进行播放。<br><br><strong>1、LVDS&nbsp;</strong><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;低压差分信号传输 (LVDS) 是一种满足当今高性能数据传输应用的新型技术。 由于其可使系统供电电压低至 2V，因此它还能满足未来应用的需要。 此技术基于 ANSI/TIA/EIA-644 LVDS 接口标准。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LVDS 技术拥有 330mV 的低压差分信号 (250mV MIN abd 450mV MAX) 和快速过渡时间。 这可以让产品达到自 100 Mbps 至超过 1 Gbps 的高数据速率。 此外，这种低压摆幅可以降低功耗消散，同时具备差分传输的优点。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LVDS 技术用于简单的线路驱动器和接收器物理层器件以及比较复杂的接口通信芯片组。 通道链路芯片组多路复用和解多路复用慢速 TTL 信号线路以提供窄式高速低功耗 LVDS 接口。 这些芯片组可以大幅节省系统的电缆和连接器成本，并且可以减少连接器所占面积所需的物理空间。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LVDS 解决方案为设计人员解决高速 I/O 接口问题提供了新选择。 LVDS 为当今和未来的高带宽数据传输应用提供毫瓦每千兆位的方案。<br><br><strong>2、Camera Link</strong><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Camera Link 的标准是由数家工业摄影机及影像卡大厂共同制定出来的, 标准的本身是基于Channel Link 的特性, 并定义出标准的接头也就是讯号线也标准化了, 让Camera及影像卡的讯号传输更简单化了, 同时定义出基本架构(Base Configuration), 中阶架构(Medium 　　Configuration), 及完整架构(Full Configuration) 的讯号接脚规范以及传输数据量。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 它是连接摄像头和图像采集卡的新标准，提供了超高的图像传送速度，并且同时提供4根摄像头的控制线。由于Camera Link的高性能、低成本以及其连接的便利性，迅速得到大多摄像头及图像采集卡的生产商的支持。是连接摄像头和图像采集卡的新标准，提供了超高的图像传送速度，并且同时提供4根摄像头的控制线。<br><br><strong>3、1394 <br>4、USB<br><br>5、千兆网<br><br></strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 视频信号的产生从摄影机端开始，透过一个影像传输系统至中央控制室。在闭路电视系统中，信号称为合成视频，而这合成视频信号振幅之峰值为1伏特 (1V)。下列为视频信号结构之组成部份：<br><br>视频信号:<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 当影像的光源落在CCD摄影机之晶片上时，其像素即产生电量作用，而这 作用与落在晶片上的光线多少有相对关系，越多的光将会产生越大的电流，此电流可从晶片上读出并转变成视频信号。而晶片读取资料的方式是依晶片 种 类 的不同而有所差异。像素光线数量越大，视频信号的峰值将相对增大，在合成视频信号中，最大峰值是 0.7 伏特。换句话说，白色或 明亮的图片部分将有 0.7伏特的信号强度，而黑色或者黑暗的部分则有0伏特的信号 。<br><br>&nbsp;水平（行）同步信号 :<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一个影像图框是由线组成的，在NTSC的标准中，每图框为525条线，而PAL标准为每图框有625条线。而在线上的每一个点，都反映视频信号的强度。在每一条线的末端，加入了一个水平同步脉波，通知摄影机和其他闭路电视的电子装 置，准 备结束此一图框或图场并让他们准备起始下一个图框或图场。脉波的持续时程决定于电子装置收到下一条图线的时间，而这个脉波的峰值为0.3伏特。<br><br>垂直（场）同步信号:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 视频图像是由图框所组成，NTSC的标准为每秒30个图框，而 PAL彩色电视系统的标准为 每秒25个图框。闭路电 视系统为避免画面闪动现象，将这个视频图框分成2个不同图场，称为奇图场和偶图场；这两个图场在摄影机点分离后，会在监视器端结合，通称图场结合或交错扫瞄 。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在每一个图框或图场的终端，增加了一个垂直同步脉波，藉以通知摄影机和其他闭路电视的电子装置，准备结束此一图框或图场，并让他们准备起始下一个图框或者图场。脉波的持续时程决定于电子装置收到下一个图场的时间，而这个脉波的峰值为 0.3伏特。当此峰值加上视频信号之峰值时，其总峰值为 1伏特。<br><br><br>
<img src ="http://www.cppblog.com/Amigo/aggbug/74369.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Amigo/" target="_blank">Amigo</a> 2009-02-20 10:15 <a href="http://www.cppblog.com/Amigo/archive/2009/02/20/74369.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>博弈论初步</title><link>http://www.cppblog.com/Amigo/archive/2008/10/25/65006.html</link><dc:creator>Amigo</dc:creator><author>Amigo</author><pubDate>Sat, 25 Oct 2008 07:46:00 GMT</pubDate><guid>http://www.cppblog.com/Amigo/archive/2008/10/25/65006.html</guid><wfw:comment>http://www.cppblog.com/Amigo/comments/65006.html</wfw:comment><comments>http://www.cppblog.com/Amigo/archive/2008/10/25/65006.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/Amigo/comments/commentRss/65006.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Amigo/services/trackbacks/65006.html</trackback:ping><description><![CDATA[<p><font style="BACKGROUND-COLOR: #d0e3ff">P-position 先手必败<br>N-position 先手必胜<br><br>1.无法进行任何移动的局面是P-position.<br>2.可以移动到P-position的局面是N-position.<br>3.所有移动都导致N-position的局面是P-position.<br></font></p>
<img src ="http://www.cppblog.com/Amigo/aggbug/65006.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Amigo/" target="_blank">Amigo</a> 2008-10-25 15:46 <a href="http://www.cppblog.com/Amigo/archive/2008/10/25/65006.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C#获取系统时间</title><link>http://www.cppblog.com/Amigo/archive/2008/10/24/64927.html</link><dc:creator>Amigo</dc:creator><author>Amigo</author><pubDate>Fri, 24 Oct 2008 05:18:00 GMT</pubDate><guid>http://www.cppblog.com/Amigo/archive/2008/10/24/64927.html</guid><wfw:comment>http://www.cppblog.com/Amigo/comments/64927.html</wfw:comment><comments>http://www.cppblog.com/Amigo/archive/2008/10/24/64927.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Amigo/comments/commentRss/64927.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Amigo/services/trackbacks/64927.html</trackback:ping><description><![CDATA[<p style="COLOR: #0000ff">－－DateTime 数字型 <br>System.DateTime currentTime=new System.DateTime(); <br>1.1 取当前年月日时分秒 <br>currentTime=System.DateTime.Now; <br>1.2 取当前年 <br>int 年=currentTime.Year; <br>1.3 取当前月 <br>int 月=currentTime.Month; <br>1.4 取当前日 <br>int 日=currentTime.Day; <br>1.5 取当前时 <br>int 时=currentTime.Hour; <br>1.6 取当前分 <br>int 分=currentTime.Minute; <br>1.7 取当前秒 <br>int 秒=currentTime.Second; <br>1.8 取当前毫秒 <br>int 毫秒=currentTime.Millisecond; <br>（变量可用中文）</p>
<br>
<p style="COLOR: #0000ff">1.9 取中文日期显示——年月日时分 <br>string strY=currentTime.ToString("f"); //不显示秒</p>
<br>
<p style="COLOR: #0000ff">1.10 取中文日期显示_年月 <br>string strYM=currentTime.ToString("y");</p>
<br>
<p style="COLOR: #0000ff">1.11 取中文日期显示_月日 <br>string strMD=currentTime.ToString("m");</p>
<br>
<p style="COLOR: #0000ff">1.12 取当前年月日，格式为：2003-9-23 <br>string strYMD=currentTime.ToString("d");</p>
<br>
<p style="COLOR: #0000ff">1.13 取当前时分，格式为：14：24 <br>string strT=currentTime.ToString("t");</p>
<img src ="http://www.cppblog.com/Amigo/aggbug/64927.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Amigo/" target="_blank">Amigo</a> 2008-10-24 13:18 <a href="http://www.cppblog.com/Amigo/archive/2008/10/24/64927.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C#生成随机数</title><link>http://www.cppblog.com/Amigo/archive/2008/10/20/64536.html</link><dc:creator>Amigo</dc:creator><author>Amigo</author><pubDate>Mon, 20 Oct 2008 13:58:00 GMT</pubDate><guid>http://www.cppblog.com/Amigo/archive/2008/10/20/64536.html</guid><wfw:comment>http://www.cppblog.com/Amigo/comments/64536.html</wfw:comment><comments>http://www.cppblog.com/Amigo/archive/2008/10/20/64536.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/Amigo/comments/commentRss/64536.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Amigo/services/trackbacks/64536.html</trackback:ping><description><![CDATA[<div class=articleContent id=articleBody>blog1:<span id=dgfiList__ctl3_Body><br>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>我们在做能自动生成试卷的考试系统时，常常需要随机生成一组不重复的题目，在.net&nbsp;<wbr>Framework中提供了一个专门用来产生随机数的类System.Random。<br>　　对于随机数，大家都知道，计算机不可能产生完全随机的数字，所谓的随机数发生器都是通过一定的算法对事先选定的随机种子做复杂的运算，用产生的结果来近似的模拟完全随机数，这种随机数被称&nbsp;<wbr>作伪随机数。伪随机数是以相同的概率从一组有限的数字中选取的。所选数字并不具有完全的随机性，但是从实用的角度而言，其随机程度已足够了。伪随机数的选&nbsp;<wbr>择是从随机种子开始的，所以为了保证每次得到的伪随机数都足够地&#8220;随机&#8221;，随机种子的选择就显得非常重要。如果随机种子一样，那么同一个随机数发生器产生&nbsp;<wbr>的随机数也会一样。一般地，我们使用同系统时间有关的参数作为随机种子，这也是.net&nbsp;<wbr>Framework中的随机数发生器默认采用的方法。<br>　　我们可以使用两种方式初始化一个随机数发生器：<br>　　第一种方法不指定随机种子，系统自动选取当前时间作为随机种子：<br>　　Random&nbsp;<wbr>ro&nbsp;<wbr>=&nbsp;<wbr>new&nbsp;<wbr>Random();<br>　　第二种方法可以指定一个int型参数作为随机种子：<br>　　int&nbsp;<wbr>iSeed=10;<br>　　Random&nbsp;<wbr>ro&nbsp;<wbr>=&nbsp;<wbr>new&nbsp;<wbr>Random(10);<br>　　long&nbsp;<wbr>tick&nbsp;<wbr>=&nbsp;<wbr>DateTime.Now.Ticks;<br>　　Random&nbsp;<wbr>ran&nbsp;<wbr>=&nbsp;<wbr>new&nbsp;<wbr>Random((int)(tick&nbsp;<wbr>&amp;&nbsp;<wbr>0xffffffffL)&nbsp;<wbr>|&nbsp;<wbr>(int)&nbsp;<wbr>(tick&nbsp;<wbr>&gt;&gt;&nbsp;<wbr>32));<br>　　这样可以保证99%不是一样。<br>　　之后，我们就可以使用这个Random类的对象来产生随机数，这时候要用到Random.Next()方法。这个方法使用相当灵活，你甚至可以指定产生的随机数的上下限。<br>　　不指定上下限的使用如下：<br>　　int&nbsp;<wbr>iResult;<br>　　iResult=ro.Next();<br>　　下面的代码指定返回小于100的随机数：<br>　　int&nbsp;<wbr>iResult;<br>　　int&nbsp;<wbr>iUp=100;<br>　　iResult=ro.Next(iUp);<br>　　而下面这段代码则指定返回值必须在50-100的范围之内：<br>　　int&nbsp;<wbr>iResult;<br>　　int&nbsp;<wbr>iUp=100;<br>　　int&nbsp;<wbr>iDown=50;<br>　　iResult=ro.Next(iDown,iUp);<br>　　除了Random.Next()方法之外，Random类还提供了Random.NextDouble()方法产生一个范围在0.0-1.0之间的随机的双精度浮点数：<br>　　double&nbsp;<wbr>dResult;<br>　　dResult=ro.NextDouble();<br>　　但是用Random类生成题号，会出现重复，特别是在数量较小的题目中要生成不重复的的题目是很难的，参考了网上的一些方法，包括两类，一类是通过随机种子入手，使每一次的随机种子不同，来保证不重复；第二类是使用一些数据结构和算法。下面主要就第二类介绍几个方法。<br>　&nbsp;<wbr>　<br>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>方法1：思想是用一个数组来保存索引号，先随机生成一个数组位置，然后把这个位置的索引号取出来，并把最后一个索引号复制到当前的数组位置，然后使随机&nbsp;<wbr>数的上限减一，具体如：先把这100个数放在一个数组内，每次随机取一个位置（第一次是1-100，第二次是1-99，...），将该位置的数用最后的数&nbsp;<wbr>代替。<br><br>&nbsp;<wbr>　　int[]&nbsp;<wbr>index&nbsp;<wbr>=&nbsp;<wbr>new&nbsp;<wbr>int[15];<br>　　for&nbsp;<wbr>(int&nbsp;<wbr>i&nbsp;<wbr>=&nbsp;<wbr>0;&nbsp;<wbr>i&nbsp;<wbr>&lt;&nbsp;<wbr>15;&nbsp;<wbr>i++)<br>　　　　index&nbsp;<wbr>=&nbsp;<wbr>i;<br>　　Random&nbsp;<wbr>r&nbsp;<wbr>=&nbsp;<wbr>new&nbsp;<wbr>Random();<br>　　//用来保存随机生成的不重复的10个数<br>　　int[]&nbsp;<wbr>result&nbsp;<wbr>=&nbsp;<wbr>new&nbsp;<wbr>int[10];<br>　　int&nbsp;<wbr>site&nbsp;<wbr>=&nbsp;<wbr>15;//设置下限<br>　　int&nbsp;<wbr>id;<br>　　for&nbsp;<wbr>(int&nbsp;<wbr>j&nbsp;<wbr>=&nbsp;<wbr>0;&nbsp;<wbr>j&nbsp;<wbr>&lt;&nbsp;<wbr>10;&nbsp;<wbr>j++)<br>　　{<br>　　　　id&nbsp;<wbr>=&nbsp;<wbr>r.Next(1,&nbsp;<wbr>site&nbsp;<wbr>-&nbsp;<wbr>1);<br>　　　　//在随机位置取出一个数，保存到结果数组<br>　　　　result[j]&nbsp;<wbr>=&nbsp;<wbr>index[id];<br>　　　　//最后一个数复制到当前位置<br>　　　　index[id]&nbsp;<wbr>=&nbsp;<wbr>index[site&nbsp;<wbr>-&nbsp;<wbr>1];<br>　　　　//位置的下限减少一<br>　　　　site--;<br>　　}&nbsp;<wbr><br><br><br>　　方法2：利用Hashtable。[NextPage]<br><br>&nbsp;<wbr>　　Hashtable&nbsp;<wbr>hashtable&nbsp;<wbr>=&nbsp;<wbr>new&nbsp;<wbr>Hashtable();<br>　　Random&nbsp;<wbr>rm&nbsp;<wbr>=&nbsp;<wbr>new&nbsp;<wbr>Random();<br>　　int&nbsp;<wbr>RmNum&nbsp;<wbr>=&nbsp;<wbr>10;<br>　　for&nbsp;<wbr>(int&nbsp;<wbr>i&nbsp;<wbr>=&nbsp;<wbr>0;&nbsp;<wbr>hashtable.Count&nbsp;<wbr>&lt;&nbsp;<wbr>RmNum;&nbsp;<wbr>i++)<br>　　{<br>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>　　&nbsp;<wbr>int&nbsp;<wbr>nValue&nbsp;<wbr>=&nbsp;<wbr>rm.Next(100);<br>&nbsp;<wbr>&nbsp;<wbr>　　&nbsp;<wbr>&nbsp;<wbr>if&nbsp;<wbr>(!hashtable.ContainsValue(nValue)&nbsp;<wbr>&amp;&amp;&nbsp;<wbr>nValue&nbsp;<wbr>!=&nbsp;<wbr>0)<br>&nbsp;<wbr>&nbsp;<wbr>　　&nbsp;<wbr>&nbsp;<wbr>{<br>&nbsp;<wbr>&nbsp;<wbr>　　&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>hashtable.Add(nValue,&nbsp;<wbr>nValue);<br>&nbsp;<wbr>&nbsp;<wbr>　　&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>Console.WriteLine(nValue.ToString());<br>&nbsp;<wbr>&nbsp;<wbr>　　&nbsp;<wbr>&nbsp;<wbr>}<br>　　}&nbsp;<wbr><br><br><br>　　方法3：递归，用它来检测生成的随机数是否有重复，如果取出来的数字和已取得的数字有重复就重新随机获取。<br><br>&nbsp;<wbr>　Random&nbsp;<wbr>ra=new&nbsp;<wbr>Random(unchecked((int)DateTime.Now.Ticks));<br>　　int[]&nbsp;<wbr>arrNum=new&nbsp;<wbr>int[10];<br>　　int&nbsp;<wbr>tmp=0;<br>　　int&nbsp;<wbr>minValue=1;<br>　　int&nbsp;<wbr>maxValue=10;<br>　　for&nbsp;<wbr>(int&nbsp;<wbr>i=0;i&lt;10;i++)<br>　　{<br>　　　　tmp=ra.Next(minValue,maxValue);&nbsp;<wbr>//随机取数<br>　　　　arrNum=getNum(arrNum,tmp,minValue,maxValue,ra);&nbsp;<wbr>//取出值赋到数组中<br>　　}<br>　　.........<br>　　.........<br>　　public&nbsp;<wbr>int&nbsp;<wbr>getNum(int[]&nbsp;<wbr>arrNum,int&nbsp;<wbr>tmp,int&nbsp;<wbr>minValue,int&nbsp;<wbr>maxValue,Random&nbsp;<wbr>ra)<br>　　{<br>　　　　int&nbsp;<wbr>n=0;<br>　　　　while&nbsp;<wbr>(n&lt;=arrNum.Length-1)<br>　　　　{<br>　　　　　　if&nbsp;<wbr>(arrNum[n]==tmp)&nbsp;<wbr>//利用循环判断是否有重复<br>　　　　　　{<br>　　　　　　　　tmp=ra.Next(minValue,maxValue);&nbsp;<wbr>//重新随机获取。<br>　　　　　　　　getNum(arrNum,tmp,minValue,maxValue,ra);//递归:如果取出来的数字和已取得的数字有重复就重新随机获取。<br>　　　　　　}<br>　　　　n++;<br>　　　　}<br>　　　　return&nbsp;<wbr>tmp;<br>　　}&nbsp;<wbr><br></span></div>
blog2:<br>&nbsp;/// &lt;summary&gt;<br>&nbsp;&nbsp;/// 功能描述：返回不重复随机数数组<br>&nbsp;&nbsp;/// 作者：&nbsp;&nbsp;&nbsp; 杨艳峰<br>&nbsp;&nbsp;/// 创建日期：2006-4-30<br>&nbsp;&nbsp;/// &lt;/summary&gt;<br>&nbsp;&nbsp;/// &lt;param name="Num"&gt;随机数个数&lt;/param&gt;<br>&nbsp;&nbsp;/// &lt;param name="minNum"&gt;随机数下限&lt;/param&gt;<br>&nbsp;&nbsp;/// &lt;param name="maxNum"&gt;随机数上限&lt;/param&gt;<br>&nbsp;&nbsp;/// &lt;returns&gt;&lt;/returns&gt;<br>&nbsp;&nbsp;public int[] GetRandomArray(int Number,int minNum,int maxNum)<br>&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;int j;<br>&nbsp;&nbsp;&nbsp;int[] b=new int[Number];<br>&nbsp;&nbsp;&nbsp;Random r=new Random();<br>&nbsp;&nbsp;&nbsp;for(j=0;j&lt;Number;j++)<br>&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;int i=r.Next(minNum,maxNum+1);<br>&nbsp;&nbsp;&nbsp;&nbsp;int num=0;<br>&nbsp;&nbsp;&nbsp;&nbsp;for(int k=0;k&lt;j;k++)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(b[k]==i)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;num=num+1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;if(num==0 )<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b[j]=i;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;else<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;j=j-1;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;return b;<br>&nbsp;&nbsp;} <br><br><br>blog3:<br>
<p>public static string GetRandomPassword(int length)<br>{<br>byte[] random = new Byte[length/2];<br>RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();<br>rng.GetNonZeroBytes(random);</p>
<p>StringBuilder sb = new StringBuilder(length);<br>int i;<br>for (i = 0; i &lt; random.Length; i++) <br>{<br>sb.Append(String.Format("{0:X2}",random[i]));<br>}<br>return sb.ToString();<br>}</p>
<rdf:rdf xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskill.com/public/xml/rss/module/trackback/"><rdf:description rdf:about="http://www.bullog.cn/blogs/virushuo/archives/37237.aspx" dc:identifier="http://www.bullog.cn/blogs/virushuo/archives/37237.aspx" dc:title="C#随机数生成" trackback:ping="http://www.bullog.cn/blogs/virushuo/trackbacks/37237.aspx"><br><br>blog4:<br>Random &nbsp; newRandom=new &nbsp; Random(); &nbsp; <br>&nbsp; string &nbsp; tempRandom=""; &nbsp; <br>&nbsp; for(int &nbsp; i=0;i&lt;4;i++) &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; { &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; string &nbsp; t=Convert.ToInt16(9*a.NextDouble()).ToString(); &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tempRandom+=t; &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; }<br><br>生成9位 &nbsp; <br>&nbsp; Random &nbsp; newRandom=new &nbsp; Random(); &nbsp; <br>&nbsp; string &nbsp; tempRandom=""; &nbsp; <br>&nbsp; for(int &nbsp; i=0;i&lt;9;i++) &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; { &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; string &nbsp; t=Convert.ToInt16(9*a.NextDouble()).ToString(); &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tempRandom+=t; &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; <br>&nbsp; 随机生成&#8220;0&#8221;或&#8220;1&#8221;字符 &nbsp; <br>&nbsp; &nbsp; <br>&nbsp; Random &nbsp; newRandom=new &nbsp; Random(); &nbsp; <br>&nbsp; string &nbsp; tempRandom=""; &nbsp; <br>&nbsp; for(int &nbsp; i=0;i&lt;1;i++) &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; { &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; string &nbsp; t=Convert.ToInt16(1*a.NextDouble()).ToString(); &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tempRandom+=t; &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; <br>&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp; <br>更正.请把 &nbsp; &nbsp; Random &nbsp; newRandom=new &nbsp; Random(); &nbsp; &nbsp; 换成 &nbsp; &nbsp; &nbsp; Random &nbsp; a=new &nbsp; Random();<br><br>public &nbsp; string &nbsp; GetRandom(int &nbsp; length) &nbsp; <br>&nbsp; { &nbsp; <br>&nbsp; string &nbsp; radstr &nbsp; = &nbsp; ""; &nbsp; <br>&nbsp; Random &nbsp; random &nbsp; = &nbsp; new &nbsp; Random(); &nbsp; <br>&nbsp; for &nbsp; (int &nbsp; i=0;i&lt;length;i++) &nbsp; <br>&nbsp; { &nbsp; <br>&nbsp; int &nbsp; a &nbsp; = &nbsp; random.Next(10); &nbsp; <br>&nbsp; radstr+=a.ToString(); &nbsp; <br>&nbsp; } &nbsp; <br>&nbsp; return &nbsp; radstr; &nbsp; <br>&nbsp; }<br><br>blog5:<br>
<h1 class=ContentTitle><strong>C#生成随机数小结</strong></h1>
<h2 class=ContentAuthor>作者:dnawo 日期:2008-05-22</h2>
<div class=Content-Info>
<div class=InfoOther>字体大小: <a accessKey=1 href="javascript:SetFont('12px')"><u><font color=#0000ff>小</font></u></a> <a accessKey=2 href="javascript:SetFont('14px')"><u><font color=#0000ff>中</font></u></a> <a accessKey=3 href="javascript:SetFont('16px')"><u><font color=#0000ff>大</font></u></a></div>
<div class=InfoAuthor><u><font color=#0000ff><img style="MARGIN: 0px 2px -6px 0px" alt="" src="http://www.mzwu.com/images/weather/hn2_sunny.gif"><img alt="" src="http://www.mzwu.com/images/weather/hn2_t_sunny.gif"></font></u> <img style="MARGIN: 0px 2px -1px 0px" alt="" src="http://www.mzwu.com/images/level3.gif"> </div>
</div>
<div class=Content-body id=logPanel>C#的Random类的实例方法Next可以生成一串伪随机数，Next有三个重载函数：<br><br>
<div class=UBBPanel>
<div class=UBBTitle><img style="MARGIN: 0px 2px -3px 0px" alt=程序代码 src="http://www.mzwu.com/images/code.gif"> 程序代码</div>
<div class=UBBContent>public virtual int Next();<br>public virtual int Next(int maxValue);<br>public virtual int Next(int minValue, int maxValue);</div>
</div>
<br><br><strong>1.public virtual int Next()</strong><br>说明：返回大于或等于零且小于 System.Int32.MaxValue 的 32 位带符号整数。<br>
<div class=UBBPanel>
<div class=UBBTitle><img style="MARGIN: 0px 2px -3px 0px" alt=程序代码 src="http://www.mzwu.com/images/code.gif"> 程序代码</div>
<div class=UBBContent>Random rand = new Random();<br>Response.Write(rand.Next());</div>
</div>
<br><strong>2.public virtual int Next(int maxValue)</strong><br>说明：返回大于或等于零且小于 maxValue 的 32 位带符号整数。<br>
<div class=UBBPanel>
<div class=UBBTitle><img style="MARGIN: 0px 2px -3px 0px" alt=程序代码 src="http://www.mzwu.com/images/code.gif"> 程序代码</div>
<div class=UBBContent>Random rand = new Random();<br>Response.Write(rand.Next(100));</div>
</div>
<br><strong>3.public virtual int Next(int minValue, int maxValue)</strong><br>说明：返回一个大于或等于 minValue 且小于 maxValue 的 32 位带符号整数。<br>
<div class=UBBPanel>
<div class=UBBTitle><img style="MARGIN: 0px 2px -3px 0px" alt=程序代码 src="http://www.mzwu.com/images/code.gif"> 程序代码</div>
<div class=UBBContent>Random rand = new Random();<br>Response.Write(rand.Next(1000,2000));</div>
</div>
<br>和Random类相似的还有一个类Guid，可以用它的静态方法NewGuid来返回一个全局唯一标识符：<br><br>
<div class=UBBPanel>
<div class=UBBTitle><img style="MARGIN: 0px 2px -3px 0px" alt=程序代码 src="http://www.mzwu.com/images/code.gif"> 程序代码</div>
<div class=UBBContent>Response.Write(Guid.NewGuid().ToString());</div>
</div>
<br><br>blog6:<br>
<table style="TABLE-LAYOUT: fixed">
    <tbody>
        <tr>
            <td>
            <div class=cnt id=blog_text>
            <p># regular<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /// &lt;summary&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /// 返回大于或等于零且小于 System.Int32.MaxValue 的 32 位带符号整数。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /// &lt;/summary&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /// &lt;returns&gt;&lt;/returns&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static void Next1()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Random rand = new Random();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(rand.Next());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /// &lt;summary&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /// 返回大于或等于零且小于 maxValue 的 32 位带符号整数<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /// &lt;/summary&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /// &lt;param name="maxValue"&gt;&lt;/param&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /// &lt;returns&gt;&lt;/returns&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static void Next2(int maxValue)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Random rand = new Random();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(rand.Next(100));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /// &lt;summary&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /// 返回一个大于或等于 minValue 且小于 maxValue 的 32 位带符号整数。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /// &lt;/summary&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /// &lt;param name="minValue"&gt;&lt;/param&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /// &lt;param name="maxValue"&gt;&lt;/param&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /// &lt;returns&gt;&lt;/returns&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public static void Next3(int minValue, int maxValue)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Random rand = new Random();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(rand.Next(1000, 2000));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
            <p>/// &lt;summary&gt;<br>/// C#中随机生成指定长度的密码<br>/// &lt;/summary&gt;</p>
            <p>private static string MakePassword(int pwdLength)<br>&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp; //声明要返回的字符串<br>&nbsp;&nbsp;&nbsp; string tmpstr = "";<br>&nbsp;&nbsp;&nbsp; //密码中包含的字符数组<br>&nbsp;&nbsp;&nbsp; string pwdchars="abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";<br>&nbsp;&nbsp;&nbsp; //数组索引随机数<br>&nbsp;&nbsp;&nbsp; int iRandNum;<br>&nbsp;&nbsp;&nbsp; //随机数生成器<br>&nbsp;&nbsp;&nbsp; Random rnd = new Random();<br>&nbsp;&nbsp;&nbsp; for(int i=0;i&lt;pwdLength;i++)<br>&nbsp;&nbsp;&nbsp; {<br>&nbsp;&nbsp;&nbsp;&nbsp; //Random类的Next方法生成一个指定范围的随机数<br>&nbsp;&nbsp;&nbsp;&nbsp; iRandNum = rnd.Next(pwdchars.Length);<br>&nbsp;&nbsp;&nbsp;&nbsp; //tmpstr随机添加一个字符<br>&nbsp;&nbsp;&nbsp;&nbsp; tmpstr += pwdchars[iRandNum];<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; return tmpstr;<br>&nbsp;&nbsp; }<br>#endregular</p>
            </div>
            </td>
        </tr>
    </tbody>
</table>
<br><br><br></rdf:description></rdf:rdf></div>
<img src ="http://www.cppblog.com/Amigo/aggbug/64536.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Amigo/" target="_blank">Amigo</a> 2008-10-20 21:58 <a href="http://www.cppblog.com/Amigo/archive/2008/10/20/64536.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>matlab 二值图像的形态学变换</title><link>http://www.cppblog.com/Amigo/archive/2008/06/28/54857.html</link><dc:creator>Amigo</dc:creator><author>Amigo</author><pubDate>Fri, 27 Jun 2008 20:32:00 GMT</pubDate><guid>http://www.cppblog.com/Amigo/archive/2008/06/28/54857.html</guid><wfw:comment>http://www.cppblog.com/Amigo/comments/54857.html</wfw:comment><comments>http://www.cppblog.com/Amigo/archive/2008/06/28/54857.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/Amigo/comments/commentRss/54857.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Amigo/services/trackbacks/54857.html</trackback:ping><description><![CDATA[<div class=cnt id=blog_text style="COLOR: #0000ff">1、dilate函数 <br>该函数能够实现二值图像的膨胀操作，有以下形式： <br>BW2=dilate(BW1，SE) <br>BW2=dilate(BW1，SE，&#8230;，n) <br>其中：BW2=dilate(BW1，SE)表示使用二值结构要素矩阵SE队图像数据矩阵BW1执行膨胀操作。输入图像BW1的类型为double或unit8，输出图像BW2的类型为unit8。BW2=dilate(BW1，SE，&#8230;，n)表示执行膨胀操作n次。 <br>2、erode 函数 <br>该函数能够实现二值图像的腐蚀操作，有以下形式： <br>BW2= erode(BW1，SE) <br>BW2= erode(BW1，SE，&#8230;，n) <br>其中：BW2= erode(BW1，SE)表示使用二值结构要素矩阵SE队图像数据矩阵BW1执行腐蚀操作。输入图像BW1的类型为double或unit8，输出图像BW2的类型为unit8。BW2= erode(BW1，SE，&#8230;，n)表示执行腐蚀操作n次。 <br>3、bwmorph函数 <br>该函数的功能是能实现二值图像形态学运算。它的格式如下： <br>① BW2=bwmorph(BW1，operation) <br>② BW2=bwmorph(BW1，operation，n) <br>其中：对于格式①，bwmorph函数可对二值图像BW1采用指定的形态学运算；对于格式②，bwmorph函数可对二值图像BW1采用指定的形态学运算n次。operation为下列字符串之一： <br>&#8216;clean&#8217;：除去孤立的像素(被0包围的1) <br>&#8216;close&#8217;：计算二值闭合 <br>&#8216;dilate&#8217;：用结构元素计算图像膨胀 <br>&#8216;erode&#8217;：用结构元素计算图像侵蚀 <br>4、imclose函数 <br>该函数功能是对灰度图像执行形态学闭运算，即使用同样的结构元素先对图像进行膨胀操作后进行腐蚀操作。调用格式为： <br>IM2=imclose(IM,SE) <br>IM2=imclose(IM,NHOOD) <br>5、imopen函数 <br>该函数功能是对灰度图像执行形态学开运算，即使用同样的结构元素先对图像进行腐蚀操作后进行膨胀操作。调用格式为： <br>IM2=imopen(IM,SE) <br>IM2=imopen(IM,NHOOD) <br>3用MATLAB编程实现图像去噪 <br>3.1 二值形态学消除图像噪声 <br>用二值形态学方法对图像中的噪声进行滤除的基本思想[4]是：使用具有一定形态的结构元素去度量和提取图像中的对应形状，以达到消除图像噪声的目的。下面是二值形态学消除图像噪声的一个实例。 <br>首先将tire.tif图像加入椒盐噪声，这种噪声前面已经介绍过，它在亮的图像区域内是暗点，而在暗的图像区域内是亮点，再对有噪声图像进行二值化操作，再对有噪声图像进行开启操作，由于这里的结构元素矩阵比噪声的尺寸要大，因而开启的结果是将背景上的噪声点去除了，最后对前一步得到的图像进行闭合操作，将轮胎上的噪声点去掉了。 <br>下面是算法实现的程序代码： <br>I1=imread('tire.tif'); %读灰度图tire.tif <br>I2=imnoise(I1,'salt &amp; pepper'); %在图像上加入椒盐噪声 <br>figure,imshow(I2) %显示加椒盐噪声后的灰度图像 <br>I3=im2bw(I1); %把加椒盐噪声后的灰度图像二值化 <br>figure,imshow(I3) %显示二值化后的图像 <br>I4=bwmorph(I3,'open'); %对二值噪声图像进行二值形态学开运算 <br>figure,imshow(I4) %显示开运算后的图像 <br>I5=bwmorph(I4,'close'); %对上述图像进行形态学闭运算 <br>figure,imshow(I5) %显示最终处理后的图像<br><br>转自:http://hi.baidu.com/%D2%B9%CB%AE%BE%A7%CD%F5%BD%A8%C7%E0/blog/item/160ea634225dfb385bb5f58b.html<br></div>
<img src ="http://www.cppblog.com/Amigo/aggbug/54857.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Amigo/" target="_blank">Amigo</a> 2008-06-28 04:32 <a href="http://www.cppblog.com/Amigo/archive/2008/06/28/54857.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>matlab读txt文件</title><link>http://www.cppblog.com/Amigo/archive/2008/06/04/52183.html</link><dc:creator>Amigo</dc:creator><author>Amigo</author><pubDate>Wed, 04 Jun 2008 10:13:00 GMT</pubDate><guid>http://www.cppblog.com/Amigo/archive/2008/06/04/52183.html</guid><wfw:comment>http://www.cppblog.com/Amigo/comments/52183.html</wfw:comment><comments>http://www.cppblog.com/Amigo/archive/2008/06/04/52183.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/Amigo/comments/commentRss/52183.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Amigo/services/trackbacks/52183.html</trackback:ping><description><![CDATA[<span style="COLOR: #0000ff">法一：<br>fid1=fopen('fx.txt','r');％得到文件号<br>[f,count]=fscanf(fid,'%f %f',[12,90]);<br>％把文件号1的数据读到f中。其中f是[12 90]的矩阵<br>％这里'%f %f'表示读取数据的形势，他是按原始数据型读出<br>fclose(fid);％关闭文件<br><br>法二：<br>load data.txt <br>data<br><br>法三：<br>a=importdata('data.txt');<br></span>
<img src ="http://www.cppblog.com/Amigo/aggbug/52183.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Amigo/" target="_blank">Amigo</a> 2008-06-04 18:13 <a href="http://www.cppblog.com/Amigo/archive/2008/06/04/52183.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在VC中创建DLL文件的方法步骤</title><link>http://www.cppblog.com/Amigo/archive/2008/05/14/49874.html</link><dc:creator>Amigo</dc:creator><author>Amigo</author><pubDate>Wed, 14 May 2008 13:59:00 GMT</pubDate><guid>http://www.cppblog.com/Amigo/archive/2008/05/14/49874.html</guid><wfw:comment>http://www.cppblog.com/Amigo/comments/49874.html</wfw:comment><comments>http://www.cppblog.com/Amigo/archive/2008/05/14/49874.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Amigo/comments/commentRss/49874.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Amigo/services/trackbacks/49874.html</trackback:ping><description><![CDATA[<p>　　<strong>一.Win32动态链接库</strong></p>
<p>　　<strong><font color=#e66b1a>1.<nobr oncontextmenu="return false;" onmousemove=kwM(0); id=key0 onmouseover="kwE(event,0, this);" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">制作</nobr>的步骤：</font></strong></p>
<p>　　(1)新建WIN32 Dynamic-link Library工程，工程名为MyDll，选择A simple DLL project类型。</p>
<p>　　(2)MyDll.h的内容如下：</p>
<p>
<table cellSpacing=0 cellPadding=6 width="95%" align=center border=0>
    <tbody>
        <tr>
            <td bgColor=#f3f3f3><font size=+0>以下是引用片段：</font><br>　　extern&nbsp;"C"&nbsp;_declspec(dllexport)&nbsp;int&nbsp;sum(int&nbsp;a,int&nbsp;b);//本文所有的例子只有一个sum即加法函数。</td>
        </tr>
    </tbody>
</table>
</p>
<p>　　(3)MyDll.cpp的内容如下:</p>
<p>
<table cellSpacing=0 cellPadding=6 width="95%" align=center border=0>
    <tbody>
        <tr>
            <td bgColor=#f3f3f3><font size=+0>以下是引用片段：</font><br>　　#include&nbsp;"stdafx.h" <br>　　#include&nbsp;"windows.h" <br>　　#include&nbsp;"MyDll.h" <br>　　BOOL&nbsp;APIENTRY&nbsp;DllMain( <br>　　HANDLE&nbsp;hModule, <br>　　DWORD&nbsp;ul_reason_for_call, <br>　　LPVOID&nbsp;lpReserved <br>　　) <br>　　{ <br>　　return&nbsp;TRUE; <br>　　} <br>　　extern&nbsp;"C"&nbsp;_declspec(dllexport)int&nbsp;sum(int&nbsp;a,&nbsp;int&nbsp;b) <br>　　{ <br>　　return&nbsp;a+b; <br>　　}</td>
        </tr>
    </tbody>
</table>
</p>
<p>　　(4)编译之后产生了MyDll.lib与MyDll.dll两个文件。</p>
<p>　　<strong><font color=#e66b1a>2.使用方法：</font></strong></p>
<p>　　(1).隐式调用法： 将MyDll.lib和MyDll.h拷贝到需要<nobr oncontextmenu="return false;" onmousemove=kwM(3); id=key3 onmouseover="kwE(event,3, this);" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">应用</nobr>该DLL的工程的目录下，将MyDll.dll拷贝到产生的应用<nobr oncontextmenu="return false;" onmousemove=kwM(1); id=key1 onmouseover="kwE(event,1, this);" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">程序</nobr>的目录下，并在需要应用该DLL中的函数的CPP文件中添加如下几行：</p>
<p>
<table cellSpacing=0 cellPadding=6 width="95%" align=center border=0>
    <tbody>
        <tr>
            <td bgColor=#f3f3f3><font size=+0>以下是引用片段：</font><br>　　#include&nbsp;"MyDll.h" <br>　　#pragma&nbsp;comment(lib,"MyDll");</td>
        </tr>
    </tbody>
</table>
</p>
<p>　　(2).显示调用法：将MyDll.lib和MyDll.h拷贝到需要应用该DLL的工程的目录下，将MyDll.dll拷贝到产生的应用程序的目录下，并在需要应用该DLL中的函数的CPP文件中包含头文件，如：</p>
<p>
<table cellSpacing=0 cellPadding=6 width="95%" align=center border=0>
    <tbody>
        <tr>
            <td bgColor=#f3f3f3><font size=+0>以下是引用片段：</font><br>　　#include&nbsp;"MyDll.h"</td>
        </tr>
    </tbody>
</table>
</p>
<p>　　同时还需要在Project-&gt;Setting-&gt;Link-&gt;Object/library modules的框中增加MyDll.lib这个库。</p>
<p>　　<strong>二.MFC动态链接库</strong></p>
<p>　　<strong><font color=#e66b1a>1.制作的步骤：</font></strong></p>
<p>　　(1)新建MFC AppWizard(dll)工程，工程名为MFCDll，选择Regular DLL using shared MFC DLL类型。</p>
<p>　　(2)在生成的MFCDll.cpp文件后面增加下面几行：</p>
<p>
<table cellSpacing=0 cellPadding=6 width="95%" align=center border=0>
    <tbody>
        <tr>
            <td bgColor=#f3f3f3><font size=+0>以下是引用片段：</font><br>　　int&nbsp;sum(int&nbsp;a,&nbsp;int&nbsp;b) <br>　　{ <br>　　return&nbsp;a+b; <br>　　}</td>
        </tr>
    </tbody>
</table>
</p>
<p>　　(3)在生成的MFCDll.def文件后面增加如下：</p>
<p>
<table cellSpacing=0 cellPadding=6 width="95%" align=center border=0>
    <tbody>
        <tr>
            <td bgColor=#f3f3f3><font size=+0>以下是引用片段：</font><br>　　sum&nbsp;@1&nbsp;;表示第一个函数是sum</td>
        </tr>
    </tbody>
</table>
</p>
<p>　　(4)编译后会产生两个文件MFCDll.lib,MFCDll.dll</p>
<p>　　<strong><font color=#e66b1a>2.使用方法</font></strong></p>
<p>　　(1)隐式调用法： 将MFCDll.lib拷贝到需要应用该DLL的工程的目录下，将MyDll.dll拷贝到产生的应用程序的目录下，并在需要应用该DLL中的函数的CPP文件中添加如下几行：</p>
<p>　　//注意这里没有在MFCDll.h中声明函数，所以不能直接包含MFCDll.h来声明函数。</p>
<p>
<table cellSpacing=0 cellPadding=6 width="95%" align=center border=0>
    <tbody>
        <tr>
            <td bgColor=#f3f3f3><font size=+0>以下是引用片段：</font><br>　　#pragma&nbsp;comment(lib,"MFCDll"); <br>　　int&nbsp;sum(int&nbsp;a,&nbsp;int&nbsp;b);</td>
        </tr>
    </tbody>
</table>
</p>
<p>　　//当然如果你的DLL中有很多函数，那可以另外写个MFCDll.h，包含所有的函数声明，然后直接将头文件包含进去</p>
<p>　　(2)显示调用法：与Win32的调用方法一样，不需要#pragma comment(lib,"MFCDll");，但是需要在Project-&gt;Setting-&gt;Link-&gt;Object/library modules的框中增加MFCDll.lib这个库。<br><br>作者：<span><font color=#666666>佚名</font></span> 来源:中国自学编程网</p>
<img src ="http://www.cppblog.com/Amigo/aggbug/49874.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Amigo/" target="_blank">Amigo</a> 2008-05-14 21:59 <a href="http://www.cppblog.com/Amigo/archive/2008/05/14/49874.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Matlab的一个小动画(带源文件)</title><link>http://www.cppblog.com/Amigo/archive/2008/04/05/46285.html</link><dc:creator>Amigo</dc:creator><author>Amigo</author><pubDate>Fri, 04 Apr 2008 18:59:00 GMT</pubDate><guid>http://www.cppblog.com/Amigo/archive/2008/04/05/46285.html</guid><wfw:comment>http://www.cppblog.com/Amigo/comments/46285.html</wfw:comment><comments>http://www.cppblog.com/Amigo/archive/2008/04/05/46285.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cppblog.com/Amigo/comments/commentRss/46285.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Amigo/services/trackbacks/46285.html</trackback:ping><description><![CDATA[<p><span style="COLOR: #0000ff"><img height=290 alt="" src="http://www.cppblog.com/images/cppblog_com/amigo/a1.jpg" width=532 border=0><br><br>应同学之托第一次尝试用matlab做动画，弄了一下午加一晚上终于弱弱地搞定了。<br>先做了个GUI界面，点击Debug —run就会跳出个对话框，然后输入参数，如果参数是负数的话就跳出警告窗口。如下图：<br><img height=472 alt="" src="http://www.cppblog.com/images/cppblog_com/amigo/a2.jpg" width=566 border=0><br><br><img height=474 alt="" src="http://www.cppblog.com/images/cppblog_com/amigo/a3.jpg" width=566 border=0><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 然后就开始动画了：<br><img height=473 alt="" src="http://www.cppblog.com/images/cppblog_com/amigo/a4.jpg" width=564 border=0><br><br>下边是源文件：<br>function varargout = mmmove(varargin)<br>% MMMOVE M-file for mmmove.fig<br>%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MMMOVE, by itself, creates a new MMMOVE or raises the existing<br>%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; singleton*.<br>%<br>%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; H = MMMOVE returns the handle to a new MMMOVE or the handle to<br>%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; the existing singleton*.<br>%<br>%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MMMOVE('CALLBACK',hObject,eventData,handles,...) calls the local<br>%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; function named CALLBACK in MMMOVE.M with the given input arguments.<br>%<br>%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MMMOVE('Property','Value',...) creates a new MMMOVE or raises the<br>%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; existing singleton*.&nbsp; Starting from the left, property value pairs are<br>%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; applied to the GUI before mmmove_OpeningFunction gets called.&nbsp; An<br>%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unrecognized property name or invalid value makes property application<br>%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stop.&nbsp; All inputs are passed to mmmove_OpeningFcn via varargin.<br>%<br>%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *See GUI Options on GUIDE's Tools menu.&nbsp; Choose "GUI allows only one<br>%&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; instance to run (singleton)".<br>%<br>% See also: GUIDE, GUIDATA, GUIHANDLES</span></p>
<p><span style="COLOR: #0000ff">% Edit the above text to modify the response to help mmmove</span></p>
<p><span style="COLOR: #0000ff">% Last Modified by GUIDE v2.5 04-Apr-2008 21:41:08</span></p>
<p><span style="COLOR: #0000ff">% Begin initialization code - DO NOT EDIT<br>gui_Singleton = 1;<br>gui_State = struct('gui_Name',&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mfilename, ...<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'gui_Singleton',&nbsp; gui_Singleton, ...<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'gui_OpeningFcn', @mmmove_OpeningFcn, ...<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'gui_OutputFcn',&nbsp; @mmmove_OutputFcn, ...<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'gui_LayoutFcn',&nbsp; [] , ...<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'gui_Callback',&nbsp;&nbsp; []);<br>if nargin &amp;&amp; ischar(varargin{1})<br>&nbsp;&nbsp;&nbsp; gui_State.gui_Callback = str2func(varargin{1});<br>end</span></p>
<p><span style="COLOR: #0000ff">if nargout<br>&nbsp;&nbsp;&nbsp; [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});<br>else<br>&nbsp;&nbsp;&nbsp; gui_mainfcn(gui_State, varargin{:});<br>end<br>% End initialization code - DO NOT EDIT</span></p>
<span style="COLOR: #0000ff">
<p><br>% --- Executes just before mmmove is made visible.<br>function mmmove_OpeningFcn(hObject, eventdata, handles, varargin)<br>% This function has no output args, see OutputFcn.<br>% hObject&nbsp;&nbsp;&nbsp; handle to figure<br>% eventdata&nbsp; reserved - to be defined in a future version of MATLAB<br>% handles&nbsp;&nbsp;&nbsp; structure with handles and user data (see GUIDATA)<br>% varargin&nbsp;&nbsp; command line arguments to mmmove (see VARARGIN)</p>
<p>% Choose default command line output for mmmove<br>handles.output = hObject;</p>
<p>% Update handles structure<br>guidata(hObject, handles);</p>
<p>% UIWAIT makes mmmove wait for user response (see UIRESUME)<br>% uiwait(handles.figure1);</p>
<p><br>% --- Outputs from this function are returned to the command line.<br>function varargout = mmmove_OutputFcn(hObject, eventdata, handles) <br>% varargout&nbsp; cell array for returning output args (see VARARGOUT);<br>% hObject&nbsp;&nbsp;&nbsp; handle to figure<br>% eventdata&nbsp; reserved - to be defined in a future version of MATLAB<br>% handles&nbsp;&nbsp;&nbsp; structure with handles and user data (see GUIDATA)</p>
<p>% Get default command line output from handles structure<br>varargout{1} = handles.output;</p>
<p><br>% --------------------------------------------------------------------<br>function Debug_Callback(hObject, eventdata, handles)<br>% hObject&nbsp;&nbsp;&nbsp; handle to Debug (see GCBO)<br>% eventdata&nbsp; reserved - to be defined in a future version of MATLAB<br>% handles&nbsp;&nbsp;&nbsp; structure with handles and user data (see GUIDATA)</p>
<p><br>% --------------------------------------------------------------------<br>function run_Callback(h, eventdata, handles)<br>% hObject&nbsp;&nbsp;&nbsp; handle to run (see GCBO)<br>% eventdata&nbsp; reserved - to be defined in a future version of MATLAB<br>% handles&nbsp;&nbsp;&nbsp; structure with handles and user data (see GUIDATA)<br>prompt={'请输入速度v:','请输入长度L:','请输入半径r:'};<br>defans={'5','10','2'};<br>v=5;L=10;r=2;<br>p=inputdlg(prompt,'Input',1,defans);<br>v=str2double(p(1));<br>L=str2double(p(2));<br>r=str2double(p(3));<br>%guidata(h,handles)<br>if v&lt;=0|L&lt;=0|r&lt;=0<br>&nbsp;&nbsp;&nbsp; warndlg('非法输入','警告')<br>else<br>ox1=r;oy1=r;ox2=r+L;oy2=r;<br>x1=r:0.015*v:r+L;<br>y1=2*r*ones(size(x1));<br>thita=0:0.015*v/r:pi;<br>x2=sin(thita)*r+ox2;<br>y2=cos(thita)*r+oy2;<br>x3=r+L:-0.015*v:r;<br>y3=zeros(size(x3));<br>x4=-sin(thita)*r+ox1;<br>y4=-cos(thita)*r+oy1;<br>x=[x1 x2 x3 x4 x1(1)];<br>y=[y1 y2 y3 y4 y1(1)];<br>plot(x,y);<br>axis([0,2*r+L,-1,2*r+1]);<br>h_text=text(0,-2,['L = ' num2str(L) ' , ' 'r = ' num2str(r) ' , ' 'v = ' num2str(v)]);<br>set(h_text,'fontSize',13);<br>axis equal<br>set(gca,'Visible','off')<br>hm=line(r,2*r,'color','red','marker','.','markersize',37,'erasemode','xor');<br>while 1<br>&nbsp;&nbsp;&nbsp; for i=1:length(x)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set(hm,'xdata',x(i),'ydata',y(i));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pause(0.0003)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; drawnow<br>&nbsp;&nbsp;&nbsp; end<br>end<br>end<br><br>为了能让小球不停的循环运动，我加了while 1的语句。<br>这样在关闭窗口的时候，matlab的命令窗里就会跳出一堆错误，大概是因为for循环里涉及到的hm随着figure的关闭删除了，但是程序仍然在运行，所以跳出东西说hm是invalid的。是不是可以放个停止程序的函数放figure或者axis的deleteFcn里头，不过没找到那样的函数。<br>期待好心大牛指教。。。<br>还有就是速度控制问题，用计算的的速度控制，运行明显偏慢，大概是程序自己运行也耗时吧，这个也不知道怎么办。不过后来看到篇文章说用timer对象来产生动画的，很不错的样子。<br>先引用下来：<br></p>
<h3 class="post-title entry-title"><a href="http://liuxqsmile.blogspot.com/2007/04/matlab-gui.html"><u>MATLAB GUI中利用定时器制作动画</u></a> </h3>
<div class="post-body entry-content">
<p>（本文为Liuxqsmile原创，转载请保留<a href="http://liuxqsmile.blogspot.com/2007/04/matlab-gui.html"><u><font color=#de7008>原文链接</font></u></a>）<br>MATLAB中提供了一些动态显示图形的例子，例如vibes、truss等，但他们的程序结构都和由GUIDE产生的M文件的结构不同。truss中用while循环来更新图形窗口，pause函数来控制更新的速度。这样的结构是不适合放在某一个子函数中来执行的，否则程序在执行该子函数时无法响应用户的其它操作，只能一开始就设置终止条件，等待动画的自然结束。<br>MATLAB中的定时器timer可以定时触发，周期性地执行指定的函数，我们可以据此来实现绘图的自动更新，而不会影响整个GUI对用户其它操作的响应。<br>比如我们要让一个曲面随时间周期性地变形，类似vibes中的情形，按下&#8220;开始&#8221;按钮后，曲面开始周期振动，同时我们可以调整振幅大小、周期的长短。所不同的是我们一切都在子函数中完成。<br>在GUIDE中建立界面元素后，在&#8220;开始&#8221;按钮的callback中建立一个定时器timer对象object<br>handles.timer = timer('Period',0.05,'ExecutionMode','FixedRate',<br>... 'TimerFcn',{@PlotUpdate,handles});<br>Period是触发的周期，这里设置为0.05s，ExecutionMode是执行的方式，可以有三种选择，对于不需要精确控制时序的动画的影响不大，TimerFcn指定触发时所执行函数的句柄，在这里我们建立一个函数PlotUpdate来执行绘图命令，handles作为参数传递到PlotUpdate中去。<br>注意PlotUpdate的定义：<br>function PlotUpdate(obj,events,handles)<br>前两个参数是必不可少的，最后的handles才是用户传递的数据。在这个函数中你基本上可以无视前两个参数，按照曲面的运动趋势产生新的顶点坐标，然后用set命令将新的坐标赋给曲面(面片patch)对象的Vertices属性。drawnow更新就可以了。你可以用曲面对象的UserData属性存放当前振动的幅值相位等参数。<br>然后在&#8220;停止&#8221;按钮的callback中stop(handles.timer)停止定时器，就可以停止自动绘图了。<br>在&#8220;增大振幅&#8221;按钮的callback中对振幅参数作修改。<br>排除了一些小问题后，你的曲面终于可以动起来了，按&#8220;增大振幅&#8221;等也没有影响图形的运动，真的是&#8220;一点影响都没有&#8221;啊！<br>问题出在哪里呢？原来，当定时器第一次触发时，用户指定的参数被传递到响应函数中执行，以后每一次触发，都是使用的这同一组参数，并不会随着程序的运行而更新。好了，现在可以在<br>&#8220;增大振幅&#8221;中重新赋一次参数<br>set(handles.timer,'TimerFcn',{@PlotUpdate,handles})；<br>怎么样，达到你的要求了吧！想知道更多？MATLAB Help的index中输入timer，够多了吧。</p>
</div>
<br><br><a title=动画下载 href="http://www.cppblog.com/Files/Amigo/move.rar">动画下载</a>：<span style="COLOR: red">下载后，用matlab7.0以上的版本可运行。</span></span> <br>
<img src ="http://www.cppblog.com/Amigo/aggbug/46285.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Amigo/" target="_blank">Amigo</a> 2008-04-05 02:59 <a href="http://www.cppblog.com/Amigo/archive/2008/04/05/46285.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>卡尔曼滤波 – Kalman Filtering</title><link>http://www.cppblog.com/Amigo/archive/2008/04/01/45914.html</link><dc:creator>Amigo</dc:creator><author>Amigo</author><pubDate>Tue, 01 Apr 2008 06:24:00 GMT</pubDate><guid>http://www.cppblog.com/Amigo/archive/2008/04/01/45914.html</guid><wfw:comment>http://www.cppblog.com/Amigo/comments/45914.html</wfw:comment><comments>http://www.cppblog.com/Amigo/archive/2008/04/01/45914.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/Amigo/comments/commentRss/45914.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Amigo/services/trackbacks/45914.html</trackback:ping><description><![CDATA[<span style="COLOR: #0000ff">1．&nbsp;&nbsp;&nbsp;&nbsp;什么是卡尔曼滤波器<br>（What is the Kalman Filter?）<br><br>在学习卡尔曼滤波器之前，首先看看为什么叫&#8220;卡尔曼&#8221;。跟其他著名的理论（例如傅立叶变换，泰勒级数等等）一样，卡尔曼也是一个人的名字，而跟他们不同的是，他是个现代人！<br><br>卡尔曼全名Rudolf Emil Kalman，匈牙利数学家，1930年出生于匈牙利首都布达佩斯。1953，1954年于麻省理工学院分别获得电机工程学士及硕士学位。1957年于哥伦比亚大学获得博士学位。我们现在要学习的卡尔曼滤波器，正是源于他的博士论文和1960年发表的论文《A New Approach to Linear Filtering and Prediction Problems》（线性滤波与预测问题的新方法）。如果对这编论文有兴趣，可以到这里的地址下载：</span> <a href="http://www.cs.unc.edu/~welch/media/pdf/Kalman1960.pdf%20。" target=_blank><span style="COLOR: #0000ff">http://www.cs.unc.edu/~welch/media/pdf/Kalman1960.pdf 。</span></a><span style="COLOR: #0000ff"> <br><br>简单来说，卡尔曼滤波器是一个&#8220;optimal recursive data processing algorithm（最优化自回归数据处理算法）&#8221;。对于解决很大部分的问题，他是最优，效率最高甚至是最有用的。他的广泛应用已经超过30年，包括机器人导航，控制，传感器数据融合甚至在军事方面的雷达</span><a href="http://www.china-vision.net/Article/sd/Index.html" target=_blank><span style="COLOR: #0000ff">系统</span></a><span style="COLOR: #0000ff">以及导弹追踪等等。近年来更被应用于计算机图像处理，例如头脸识别，图像分割，图像边缘检测等等。<br><br>2．卡尔曼滤波器的介绍<br>（Introduction to the Kalman Filter）<br><br>为了可以更加容易的理解卡尔曼滤波器，这里会应用形象的描述方法来讲解，而不是像大多数参考书那样罗列一大堆的数学公式和数学符号。但是，他的5条公式是其核心内容。结合现代的计算机，其实卡尔曼的程序相当的简单，只要你理解了他的那5条公式。<br><br>在介绍他的5条公式之前，先让我们来根据下面的例子一步一步的探索。<br><br>假设我们要研究的对象是一个房间的温度。根据你的经验判断，这个房间的温度是恒定的，也就是下一分钟的温度等于现在这一分钟的温度（假设我们用一分钟来做时间单位）。假设你对你的经验不是100%的相信，可能会有上下偏差几度。我们把这些偏差看成是高斯白噪声（White Gaussian Noise），也就是这些偏差跟前后时间是没有关系的而且符合高斯分配（Gaussian Distribution）。另外，我们在房间里放一个温度计，但是这个温度计也不准确的，测量值会比实际值偏差。我们也把这些偏差看成是高斯白噪声。<br><br>好了，现在对于某一分钟我们有两个有关于该房间的温度值：你根据经验的预测值（</span><a href="http://www.china-vision.net/Article/sd/Index.html" target=_blank><span style="COLOR: #0000ff">系统</span></a><span style="COLOR: #0000ff">的预测值）和温度计的值（测量值）。下面我们要用这两个值结合他们各自的噪声来估算出房间的实际温度值。<br><br>假如我们要估算k时刻的是实际温度值。首先你要根据k-1时刻的温度值，来预测k时刻的温度。因为你相信温度是恒定的，所以你会得到k时刻的温度预测值是跟k-1时刻一样的，假设是23度，同时该值的高斯噪声的偏差是5度（5是这样得到的：如果k-1时刻估算出的最优温度值的偏差是3，你对自己预测的不确定度是4度，他们平方相加再开方，就是5）。然后，你从温度计那里得到了k时刻的温度值，假设是25度，同时该值的偏差是4度。<br><br>由于我们用于估算k时刻的实际温度有两个温度值，分别是23度和25度。究竟实际温度是多少呢？相信自己还是相信温度计呢？究竟相信谁多一点，我们可以用他们的covariance来判断。因为Kg^2=5^2/(5^2+4^2)，所以Kg=0.78，我们可以估算出k时刻的实际温度值是：23+0.78*(25-23)=24.56度。可以看出，因为温度计的covariance比较小（比较相信温度计），所以估算出的最优温度值偏向温度计的值。<br><br>现在我们已经得到k时刻的最优温度值了，下一步就是要进入k+1时刻，进行新的最优估算。到现在为止，好像还没看到什么自回归的东西出现。对了，在进入k+1时刻之前，我们还要算出k时刻那个最优值（24.56度）的偏差。算法如下：((1-Kg)*5^2)^0.5=2.35。这里的5就是上面的k时刻你预测的那个23度温度值的偏差，得出的2.35就是进入k+1时刻以后k时刻估算出的最优温度值的偏差（对应于上面的3）。<br><br>就是这样，卡尔曼滤波器就不断的把covariance递归，从而估算出最优的温度值。他运行的很快，而且它只保留了上一时刻的covariance。上面的Kg，就是卡尔曼增益（Kalman Gain）。他可以随不同的时刻而改变他自己的值，是不是很神奇！<br><br>下面就要言归正传，讨论真正工程</span><a href="http://www.china-vision.net/Article/sd/Index.html" target=_blank><span style="COLOR: #0000ff">系统</span></a><span style="COLOR: #0000ff">上的卡尔曼。<br><br>3．&nbsp;&nbsp;&nbsp;&nbsp;卡尔曼滤波器算法<br>（The Kalman Filter Algorithm）<br><br>在这一部分，我们就来描述源于Dr Kalman 的卡尔曼滤波器。下面的描述，会涉及一些基本的概念知识，包括概率（Probability），随即变量（Random Variable），高斯或正态分配（Gaussian Distribution）还有State-space Model等等。但对于卡尔曼滤波器的详细证明，这里不能一一描述。<br><br>首先，我们先要引入一个离散控制过程的系统。该</span><a href="http://www.china-vision.net/Article/sd/Index.html" target=_blank><span style="COLOR: #0000ff">系统</span></a><span style="COLOR: #0000ff">可用一个线性随机微分方程（Linear Stochastic Difference equation）来描述：<br>X(k)=A X(k-1)+B U(k)+W(k) <br>再加上</span><a href="http://www.china-vision.net/Article/sd/Index.html" target=_blank><span style="COLOR: #0000ff">系统</span></a><span style="COLOR: #0000ff">的测量值：<br>Z(k)=H X(k)+V(k) <br>上两式子中，X(k)是k时刻的</span><a href="http://www.china-vision.net/Article/sd/Index.html" target=_blank><span style="COLOR: #0000ff">系统</span></a><span style="COLOR: #0000ff">状态，U(k)是k时刻对</span><a href="http://www.china-vision.net/Article/sd/Index.html" target=_blank><span style="COLOR: #0000ff">系统</span></a><span style="COLOR: #0000ff">的控制量。A和B是系统参数，对于多模型</span><a href="http://www.china-vision.net/Article/sd/Index.html" target=_blank><span style="COLOR: #0000ff">系统</span></a><span style="COLOR: #0000ff">，他们为矩阵。Z(k)是k时刻的测量值，H是测量系统的参数，对于多测量</span><a href="http://www.china-vision.net/Article/sd/Index.html" target=_blank><span style="COLOR: #0000ff">系统</span></a><span style="COLOR: #0000ff">，H为矩阵。W(k)和V(k)分别表示过程和测量的噪声。他们被假设成高斯白噪声(White Gaussian Noise)，他们的covariance 分别是Q，R（这里我们假设他们不随</span><a href="http://www.china-vision.net/Article/sd/Index.html" target=_blank><span style="COLOR: #0000ff">系统</span></a><span style="COLOR: #0000ff">状态变化而变化）。<br><br>对于满足上面的条件(线性随机微分</span><a href="http://www.china-vision.net/Article/sd/Index.html" target=_blank><span style="COLOR: #0000ff">系统</span></a>，<span style="COLOR: #0000ff">过程和测量都是高斯白噪声)，卡尔曼滤波器是最优的信息处理器。下面我们来用他们结合他们的covariances 来估算</span><a href="http://www.china-vision.net/Article/sd/Index.html" target=_blank><span style="COLOR: #0000ff">系统</span></a><span style="COLOR: #0000ff">的最优化输出（类似上一节那个温度的例子）。<br><br></span><span style="COLOR: #0000ff">首先我们要利用系统的过程模型，来预测下一状态的系统。假设现在的</span><a href="http://www.china-vision.net/Article/sd/Index.html" target=_blank><span style="COLOR: #0000ff">系统</span></a><span style="COLOR: #0000ff">状态是k，根据系统的模型，可以基于</span><a href="http://www.china-vision.net/Article/sd/Index.html" target=_blank><span style="COLOR: #0000ff">系统</span></a><span style="COLOR: #0000ff">的上一状态而预测出现在状态：<br>X(k|k-1)=A X(k-1|k-1)+B U(k) &#8230;&#8230;&#8230;.. (1)<br>式(1)中，X(k|k-1)是利用上一状态预测的结果，X(k-1|k-1)是上一状态最优的结果，U(k)为现在状态的控制量，如果没有控制量，它可以为0。<br><br>到现在为止，我们的</span><a href="http://www.china-vision.net/Article/sd/Index.html" target=_blank><span style="COLOR: #0000ff">系统</span></a><span style="COLOR: #0000ff">结果已经更新了，可是，对应于X(k|k-1)的covariance还没更新。我们用P表示covariance：<br>P(k|k-1)=A P(k-1|k-1) A&#8217;+Q &#8230;&#8230;&#8230; (2)<br>式(2)中，P(k|k-1)是X(k|k-1)对应的covariance，P(k-1|k-1)是X(k-1|k-1)对应的covariance，A&#8217;表示A的转置矩阵，Q是</span><a href="http://www.china-vision.net/Article/sd/Index.html" target=_blank><span style="COLOR: #0000ff">系统</span></a><span style="COLOR: #0000ff">过程的covariance。式子1，2就是卡尔曼滤波器5个公式当中的前两个，也就是对</span><a href="http://www.china-vision.net/Article/sd/Index.html" target=_blank><span style="COLOR: #0000ff">系统</span></a><span style="COLOR: #0000ff">的预测。<br><br>现在我们有了现在状态的预测结果，然后我们再收集现在状态的测量值。结合预测值和测量值，我们可以得到现在状态(k)的最优化估算值X(k|k)：<br>X(k|k)= X(k|k-1)+Kg(k) (Z(k)-H X(k|k-1)) &#8230;&#8230;&#8230; (3)<br>其中Kg为卡尔曼增益(Kalman Gain)：<br>Kg(k)= P(k|k-1) H&#8217; / (H P(k|k-1) H&#8217; + R) &#8230;&#8230;&#8230; (4)<br><br>到现在为止，我们已经得到了k状态下最优的估算值X(k|k)。但是为了要另卡尔曼滤波器不断的运行下去直到</span><a href="http://www.china-vision.net/Article/sd/Index.html" target=_blank><span style="COLOR: #0000ff">系统</span></a><span style="COLOR: #0000ff">过程结束，我们还要更新k状态下X(k|k)的covariance：<br>P(k|k)=（I-Kg(k) H）P(k|k-1) &#8230;&#8230;&#8230; (5)<br>其中I 为1的矩阵，对于单模型单测量，I=1。当</span><a href="http://www.china-vision.net/Article/sd/Index.html" target=_blank><span style="COLOR: #0000ff">系统</span></a><span style="COLOR: #0000ff">进入k+1状态时，P(k|k)就是式子(2)的P(k-1|k-1)。这样，算法就可以自回归的运算下去。<br><br>卡尔曼滤波器的原理基本描述了，式子1，2，3，4和5就是他的5 个基本公式。根据这5个公式，可以很容易的实现计算机的程序。<br><br>下面，我会用程序举一个实际运行的例子。。。<br>4．&nbsp;&nbsp;&nbsp;&nbsp;简单例子<br>（A Simple Example）<br><br>这里我们结合第二第三节，举一个非常简单的例子来说明卡尔曼滤波器的工作过程。所举的例子是进一步描述第二节的例子，而且还会配以程序模拟结果。<br><br>根据第二节的描述，把房间看成一个系统，然后对这个</span><a href="http://www.china-vision.net/Article/sd/Index.html" target=_blank><span style="COLOR: #0000ff">系统</span></a><span style="COLOR: #0000ff">建模。当然，我们见的模型不需要非常地精确。我们所知道的这个房间的温度是跟前一时刻的温度相同的，所以A=1。没有控制量，所以U(k)=0。因此得出：<br>X(k|k-1)=X(k-1|k-1) &#8230;&#8230;&#8230;.. (6)<br>式子（2）可以改成：<br>P(k|k-1)=P(k-1|k-1) +Q &#8230;&#8230;&#8230; (7)<br><br>因为测量的值是温度计的，跟温度直接对应，所以H=1。式子3，4，5可以改成以下：<br>X(k|k)= X(k|k-1)+Kg(k) (Z(k)-X(k|k-1)) &#8230;&#8230;&#8230; (8)<br>Kg(k)= P(k|k-1) / (P(k|k-1) + R) &#8230;&#8230;&#8230; (9)<br>P(k|k)=（1-Kg(k)）P(k|k-1) &#8230;&#8230;&#8230; (10)<br><br>现在我们模拟一组测量值作为输入。假设房间的真实温度为25度，我模拟了200个测量值，这些测量值的平均值为25度，但是加入了标准偏差为几度的高斯白噪声（在图中为蓝线）。<br><br>为了令卡尔曼滤波器开始工作，我们需要告诉卡尔曼两个零时刻的初始值，是X(0|0)和P(0|0)。他们的值不用太在意，随便给一个就可以了，因为随着卡尔曼的工作，X会逐渐的收敛。但是对于P，一般不要取0，因为这样可能会令卡尔曼完全相信你给定的X(0|0)是</span><a href="http://www.china-vision.net/Article/sd/Index.html" target=_blank><span style="COLOR: #0000ff">系统</span></a><span style="COLOR: #0000ff">最优的，从而使算法不能收敛。我选了X(0|0)=1度，P(0|0)=10。<br><br>该</span><a href="http://www.china-vision.net/Article/sd/Index.html" target=_blank><span style="COLOR: #0000ff">系统</span></a><span style="COLOR: #0000ff">的真实温度为25度，图中用黑线表示。图中红线是卡尔曼滤波器输出的最优化结果（该结果在算法中设置了Q=1e-6，R=1e-1）。<br><br><font style="COLOR: #0000ff" color=#000000><strong>作者</strong>：jearome</font></span>
<img src ="http://www.cppblog.com/Amigo/aggbug/45914.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Amigo/" target="_blank">Amigo</a> 2008-04-01 14:24 <a href="http://www.cppblog.com/Amigo/archive/2008/04/01/45914.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>原谅我的任性</title><link>http://www.cppblog.com/Amigo/archive/2008/03/16/44600.html</link><dc:creator>Amigo</dc:creator><author>Amigo</author><pubDate>Sun, 16 Mar 2008 04:29:00 GMT</pubDate><guid>http://www.cppblog.com/Amigo/archive/2008/03/16/44600.html</guid><wfw:comment>http://www.cppblog.com/Amigo/comments/44600.html</wfw:comment><comments>http://www.cppblog.com/Amigo/archive/2008/03/16/44600.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Amigo/comments/commentRss/44600.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Amigo/services/trackbacks/44600.html</trackback:ping><description><![CDATA[<span style="COLOR: #0000ff">渐渐明白<br>沉醉不一定是因为爱<br>渐渐明白<br>害怕对自己坦白<br>渐渐明白<br>不爱不一定放得开<br>渐渐明白<br>我越来越对你依赖<br><br>如何告白<br>不是爱让你守侯<br>如何告白<br>想念已成为我功课<br>如何告白<br>习惯有你的天空<br>如何告白<br>你是我最珍惜的朋友<br><br>我不敢靠近却更害怕失去<br>才会让暧昧飘扬漫溢<br>多少次决定不再见你<br>多少次任性地重新联系<br><br>我不敢靠近却更害怕失去<br>才会在你说想我时调转身去<br>我真的不是故意<br>有种温柔让寂寞的人难以抗拒<br><br>会否有天<br>你看清我玩的游戏<br>会否有天<br>我让你恨彻心底<br>会否有天<br>我无助地独自哭泣<br>会否有天<br>我终于长大找到自己<br><br>你说<br>我可以一个人不用再依赖着你<br>你说<br>这段路已是珍贵的回忆<br>原谅我<br>一直任性注定这悲伤的结局</span>&nbsp;<br><img height=584 alt="" src="http://www.cppblog.com/images/cppblog_com/amigo/20060801152.jpg" width=730 border=0>
<img src ="http://www.cppblog.com/Amigo/aggbug/44600.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Amigo/" target="_blank">Amigo</a> 2008-03-16 12:29 <a href="http://www.cppblog.com/Amigo/archive/2008/03/16/44600.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>