All Posts

独立成分分析(Independent Component Analysis)

ICA是一种用于在统计数据中寻找隐藏的因素或者成分的方法。ICA是一种广泛用于盲缘分离的(BBS)方法,用于揭示随机变量或者信号中隐藏的信息。ICA被用于从混合信号中提取独立的信号信息。ICA在20世纪80年代提出来,但是知道90年代中后期才开始逐渐流行起来。 ICA的起源可以来源于一个鸡尾酒会问题,我们假设三个观测点x1,x2,x3,放在房间里同时检测三个人说话,另三个人的原始信号为s1,s2,s3,则求解的过程可以如下图所示: 定义 假设n个随机变量x1,x2,….xn,由n个随机变量s1,s2,…sn组成,并且这n个随机变量是相互独立的,可以用下面的公示表达: 为了表达的方便,我们可以用向量的形式来表达: x = As 这个只不过是ICA最基本的定义,在很多实际问题中,应该包含了噪声。但是为了简化问题,我们这里忽略了噪声。因为如果模型中包含噪音,处理起来将会十分困难,而且大多数不包含噪音的模型已经能够解决很多问题,所以这里我们就将噪声先忽略。 ICA的限制条件 独立成分应该是相互之间独立的。这是ICA成立的基本原则,同时,基本上可以说只需要这个原则我们就可以估计这个模型。 独立成分必须是非高斯分布的。高斯分布的高阶累计量是0,但是高阶信息对于ICA的模型的估计却是十分必要的。 为了简化,我们假设未知的混合矩阵A是一个方阵。 白化 白化是一种比不相关性要稍微强一些的性质。对一个零均值的随即向量y进行白化处理,就是让它的组成成分不相关,并且让变量的方差相等。也就是说,变量y的协方差矩阵是单位矩阵: 为什么独立成分是非高斯的 ICA最基本的限制条件就是独立成分必须是非高斯分布的,这或许也是ICA早期没有流行起来的原因。我们假设变量x1和x2是高斯分布的,不相关的,且方差相等: 下面的图表示联合概率分布,可以看出,我们无法判断任何关于变量x1和x2的方向信息,这就是为什么混合矩阵A不能被估计出来的原因: 峭度 在这我们讲述一个利用峭度来进行ICA模型估计的方法,ICA的估计方法很多,这只是最基础的一个方法。 对于变量y峭度可以由下面的公式定义: 峭度是可正可负的,高斯分布变量的峭度是0,这也是为什么独立成分必须是非高斯分布的原因之一。峭度为负的变量分布称为次高斯分布,峭度为正的变量的分布则为超高斯分布,下图分别是拉普拉斯分布(超高斯分布)和均匀分布(次高斯分布): 基于峭度的梯度算法 我们经常利用峭度的绝对值或者平方来进行求解: 我们通过优化这个目标函数来估计ICA模型,z表示白化后的观察数据x。 实际上,我们是使峭度极大化。我们会从某个方向向量w开始,然后计算在什么方向峭度的增长最快,我们则将方向向量w向这个方向移动。 峭度绝对值的梯度可以如下计算: 下面是一个快速不动点算法基于峭度计算的流程图: ## ICA估计的主要方法 ## 通过极大化非高斯性来估计 通过极大似然性来估计 通过极小互信息来估计 通过张量的方法来估计 通过非线性分解和非线性PCA来估计 这里,我们只是讲了其中的一个基础方法之一,并不就是最好的方法。 ICA算法的思想可以用下面的公式来描述: ICA method = objective funtion + optimization algorithm 引用 [1]Hyvärinen A, Karhunen J, Oja E. Independent component analysis[M]. John Wiley & Sons, 2004. [2]Hyvärinen A, Oja E. Independent component analysis: algorithms and applications[J]. Neural networks, 2000, 13(4): 411-430. [3]Hyvärinen A, Oja E. A fast fixed-point algorithm for independent component analysis[J]. Neural computation, 1997, 9(7): 1483-1492. [4]王刚. 基于最大非高斯估计的独立分量分析理论研究 [D][D]. 国防科学技术大学, 2005.

CHEVP算法(CannyHough Estimation of Vanishing Points)

这个算法是汪悦在 Lane detection and tracking using B-spline中提出来的。他在这篇论文中主要用的是B-spline模型,这个模型的主要优点是鲁棒性好,可以针对不同的情景进行处理,而且他将检测道路两边的边缘的问题转化成求解道路中间线的问题。 下面主要描述一下CHEVP算法: 边缘像素提取 我们使用Canny边缘检测来获得边缘映射和边缘定位映射。选择方差σ = 1 并且模板的尺寸是9*1在X方向和Y方向上进行高斯卷积。边缘映射是通过一个合适的阈值处理得到的结果。在图表1中,图b是通过Canny边缘检测得到的边缘映射,图c则是边缘定位映射。 通过霍夫变化检测直线 检测到的边缘点将被用于对直线参数空间中可能的存在的线进行投票。图像被水平地分为几个部分,如图2a所示,为了适应因为道路弯曲从而导致道路消失点的变化。图像部分自下而上高度越来越小。每个图像分割部分都有它们自己的直线参数空间,每个图像分割部分中边缘点分别为可能的直线进行投票。通过对于规范化后的累加空间的阈值处理,直线分割最终能够在每一个图像分割部分中检测出来。 地平线和消失点检测 每一个图像分割部分中检测到的直线都是成对出现的,任意一队直线的相交部分会为另外一个霍夫空间中的消失点进行投票。投票的权重是根据最后一步产生的成对直线的规范化累加值决定的。这个过程在每个图像分割部分中分别重复,但是会在相同的霍夫空间中投票。 霍夫空间中对于每一列的投票会归总起来从来检测可能的消失点。获得投票最多的一行将会被选择座位地平线在图像平面中,如下图所示: 对于每个图像分割部分来说,它的消失点由地平线附近投票最多的点所决定。所有检测到的消失点可以再图4b中看到。注意一点,对于图像部分5,没有消失点存在,因为在这个图像分割部分并没有检测到直线。 根据检测的道路线估计道路中间线的参数k 对于消失点进行投票的直线被认为是每个图像分割部分中道路线。从图像最下面的图像分割部分往上,挑选出在各个图像分割部分中的左右两边挑选出最接近去中间一列的检测到的道路线。如果这两条道路线在这个图像分割部分中并不存在,这个过程就会在更高的图像分割部分中进行,知道获得需要的道路线。图6表示两条直线L1和L2在图像分割部分4中,因为没有直线存在图像分割部分5中。 然后连接图像分割部分4中的消失点和P-l4和P-r4的中点P-m4(直线L1和直线L2的相交的部分) 参数k可以通过以下公式进行估计: 对于图7中中间线的估计的例子如下所示: 从图像分割部分4开始,因为图像分割部分5中不存在消失点,我们假设这个部分的消失点跟在分割部分4中的消失点。延伸通过vp4和P-m4交于图像分割部分5的P-m5点。同样的,我们在图像分割部分3中我们也能够检测到消失点。直线(vp3-P-m3)交于图像分割部分2的底部的P-m2处。同样的道理,适用于以上的部分 通过构建道路中间线,通过参数k和道路中间线我们可以估计处道路的两条边缘线,图8给出了例子 计算道路模型的控制点来接近检测的道路中间线 可以利用很多方法来计算B-spline中的控制点通过中间线。因为B-spline后面的部分会准确地逼近道路边缘,这里我们只是粗略地使用B-spline来接近检测到的道路中间线。 我们是通过使用3个不同的控制点来构成两个部分的B-spline。为了让B-spline通过第一个和最后一个控制点,我们使用三倍的第一个和最后一个控制点。因此事实上一共有7个控制点,3个第一个控制点和3个最后一个控制点都是相同的。 我们首先选择P-m0和P-m5分别代表道路模型中的第一个控制点Q0和最后一个控制点Q2.节点P1的选择取决于图9中β1和β2的值。如果β1和β2的值不等于0,我们则选择P-m作为Q1。即P1=P-m,P-m是P-m1和P-m2的中点。如果β1为0,而β2不等于0.我们则选择P-m1作为P1(Q1).其他的情况,我们则选择P-m2作为P1(Q1).因此控制点Q1可以通过下面的公式计算: ![控制点初始化] (http://img.blog.csdn.net/20150418193033394)![道路模型初始化](http://img.blog.csdn.net/20150418193239246) 实验结果## 引用: Wang, Yue, Eam Khwang Teoh, and Dinggang Shen. “Lane detection and tracking using B-Snake.” Image and Vision computing 22.4 (2004): 269-280.

winform中进行post上传文件

winform中要上传文件到远程的服务器上面,我在本地用的是post方式传递数据,用的是HTTP协议,具体代码如下: 下面的代码就是一个上传的方法,参数需要路径和文件路径就可以了,我本地winform只需要提交post请求就可以了,止于对于post请求如何处理,那就是远程服务端的事情了。 private string uploadFile(string uriAddress, string uploadfilePath) { HxSpecCore.SpectrumSet ss = new SpectrumSet(); try { // 设置提交的相关参数 HttpWebRequest request = WebRequest.Create(uriAddress) as HttpWebRequest; Encoding myEncoding = Encoding.UTF8; request.Method = "POST"; WebHeaderCollection headers = request.Headers; //提交请求数据 FileInfo fi = new FileInfo(uploadfilePath); FileStream fs = new FileStream(uploadfilePath, FileMode.Open, FileAccess.Read); byte[] postData = new byte[(int)fs.Length]; request.Headers.Set("md5data", Convert.ToBase64String(GetMD5(Convert.ToBase64String(GetMD5(Encoding.Default.GetString(postData))) ))); fs.Read(postData, 0, Convert.ToInt32(fs.Length)); fs.Close(); System.IO.Stream outputStream = request.GetRequestStream(); outputStream.Write(postData, 0, postData.Length); outputStream.Close(); HttpWebResponse response; Stream responseStream; response = request.GetResponse() as HttpWebResponse; responseStream = response.GetResponseStream(); System.IO.StreamReader reader = new System.IO.StreamReader(responseStream, Encoding.GetEncoding("UTF-8")); string result = reader.ReadToEnd(); reader.Close(); return result; } catch (Exception ex) { return " "; } }

sqlite操作

导入excel到表格 本来想使用sqlite expert personal导入表格的,后来发现软件里面没有import/export菜单,后来问只有professional版本才有这个菜单的,我晕,穷人那只能敲命令行了。 注意导入的excel表格是要把表头给去掉的,然后按照sqlite表格里面标头的顺序进行导入,excel的表格用csv的格式来保存。 sqlite3 .separator ',' .import filename tablename 导入文件乱码 经常会出现导入的文件的中文出现乱码的情况,建议就是把文件用记事本打开,然后用UTF-8的格式另存为csv的文件。 datatime()函数时间出错 使用sqlite数据库时,使用datatime函数获取当前时间的时候,时间总是错误的,总是晚了好几个小时,结果在datatime()函数里面加上参数就好了,datetime(’now’,’localtime’)。 database is locked 读完数据库一定要关闭,无论是reader还是dataset,必须统统都要close

Iplimage versus Mat

我们可能经常面临这样的困惑,Iplimage和Mat这两种数据结构,我们应该用哪一种数据结构。 Iplimage一开始就存在opencv库之中,他来源于Intel的另外一个函数库Intel Image Processing Library(IPL),这是一种非常重要的数据结构。在经典书籍里面的sample用的基本都是Iplimage这个数据结构。但是这是一种C风格的数据结构,你必须为他分配以及释放内存。 Mat则是一种新的数据结构,越来越多的人也在使用这种数据结构了,因为它是面向对象的。所以我们不需要自己来为它管理内存。它是通过计数的方式来进行引用,如果它的引用计数为0的话,那么它就会自动释放内存。 老实说,用什么数据结构,我也不知道。因为我觉得有些方法,Mat数据结构还不具备,有的方法只有运用Iplimage才可以。 将Iplimage转化为Mat IplImage* ipl; Mat m = cvarrToMat(ipl);

道路识别demo

最近做的道路识别一开始终于弄懂了点东西,一开始在网上找到了一个简单的道路识别的opencvsharp的版本。我觉得opencvsharp真的是一个很好的东西,它封装了比opencv更多的数据结构和库,而且得益于.net平台的强大,使用起来也非常的便捷。唯一的缺点就是目前关于这方面的资料还是少之又少,后来我还是想一想把这个demo转换成cpp版本,也是一个非常简单的demo。 opencvsharp版本 using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; using OpenCvSharp; namespace LaneDetection { class Program { [STAThread] static void Main() { CvCapture cap = CvCapture.FromFile("test1.mp4"); CvWindow w = new CvWindow("Lane Detection"); CvWindow canny = new CvWindow("Canny"); IplImage src, gray, dstCanny, halfFrame, smallImg; CvMemStorage storage = new CvMemStorage(); CvSeq lines; while (CvWindow.WaitKey(10) < 0) { src = cap.QueryFrame(); halfFrame = new IplImage(new CvSize(src.Size.Width / 2, src.Size.Height / 2), BitDepth.U8, 3); Cv.PyrDown(src, halfFrame, CvFilter.Gaussian5x5); gray = new IplImage(src.Size, BitDepth.U8, 1); dstCanny = new IplImage(src.Size, BitDepth.U8, 1); storage.Clear(); // Crop off top half of image since we're only interested in the lower portion of the video int halfWidth = src.Width / 2; int halfHeight = src.Height / 2; int startX = halfWidth - (halfWidth / 2); src.SetROI(new CvRect(0, halfHeight - 0, src.Width - 1, src.Height - 1)); gray.SetROI(src.GetROI()); dstCanny.SetROI(src.GetROI()); src.CvtColor(gray, ColorConversion.BgrToGray); Cv.Smooth(gray, gray, SmoothType.Gaussian, 5, 5); Cv.Canny(gray, dstCanny, 50, 200, ApertureSize.Size3); canny.Image = dstCanny; storage.Clear(); lines = dstCanny.HoughLines2(storage, HoughLinesMethod.Probabilistic, 1, Math.PI / 180, 50, 50, 100); for (int i = 0; i < lines.Total; i++) { CvLineSegmentPoint elem = lines.GetSeqElem<CvLineSegmentPoint>(i).Value; int dx = elem.P2.X - elem.P1.X; int dy = elem.P2.Y - elem.P1.Y; double angle = Math.Atan2(dy, dx) * 180 / Math.PI; if (Math.Abs(angle) <= 10) continue; if (elem.P1.Y > elem.P2.Y + 50 || elem.P1.Y < elem.P2.Y -50 ) { src.Line(elem.P1, elem.P2, CvColor.Red, 2, LineType.AntiAlias, 0); } } src.ResetROI(); storage.Clear(); w.Image = src; } } } } opencv版本 #include "stdafx.h" #include <highgui.h> #include <cv.h> #include <math.h> using namespace cv; using namespace std; #define INF 99999999 CvCapture* g_capture = NULL; int g_slider_pos = 0 ; int frame_count = 0; CvSeq* lines; int main(int argc,char* argv[]) { cvNamedWindow( "show"); g_capture=cvCreateFileCapture( "D:\\road.avi"); IplImage* frame; while(1) { CvMemStorage* storage = cvCreateMemStorage(); frame=cvQueryFrame(g_capture); //set the ROI of the original image int x = 0,y = frame->height/2; int width = frame->width,height = frame->height/2; if(!frame) break; cvSetImageROI(frame,cvRect(x,y,width,height)); IplImage* gray = cvCreateImage(cvGetSize(frame),8,1); cvCvtColor(frame,gray,CV_BGR2GRAY); cvCanny(gray,gray,50,100); cvShowImage("canny",gray); cvSmooth(gray,gray,CV_GAUSSIAN,3,1,0); //Hough lines = cvHoughLines2(gray,storage,CV_HOUGH_PROBABILISTIC,1,CV_PI/180,50,90,50); //select approprivate lines acoording to the slope for (int i = 0;i < lines->total;i ++) { double k =INF; CvPoint* line = (CvPoint*)cvGetSeqElem(lines,i); int dx = line[1].x - line[0].x; int dy = line[1].x - line[0].y; double angle = atan2(dy,dx) * 180 /CV_PI; if (abs(angle) <= 10) continue; if (line[0].y > line[1].y + 50 || line[0].y < line[1].y - 50) { cvLine(frame,line[0],line[1],CV_RGB(255,0,0),2,CV_AA); } } cvResetImageROI(frame); cvShowImage( "show",frame); char c = cvWaitKey(33); if(c==27) break; } cvReleaseCapture(&g_capture); cvDestroyWindow( "show"); return 0; } 非常希望有弄这方面的人能和我讨论一下,若转载请注明出处,谢谢。

combox系列问题集

visual studio崩溃 你是不是经常会遇到一编辑combox,visual studio就会立马崩溃。一直都无法理解是什么原因,然后后来发现居然是因为有道的截屏翻译,关掉截屏翻译就好了。 combox绑定数据源 SqliteDataReader dr; if (dr.Read()) { this.comboBox1.Items.Add(dr[0]); } 自动补全的功能 我们希望在combox中实现输入的时候,有推荐的文本自动补全功能。我们主要只需要设置AutoCompleteMode和AutoCompleteSource这两个属性就可以了。 模糊查询 上面那个自动补全的功能只能实现从左到右进行匹配,而不能进行模糊匹配。假设我们的combobox里面有“张三“,如果输入”张“可以进行匹配,但是我们如果输入”三“的话就无法实现匹配,而combobox自身并没有这个属性,所以我们需要自己写一个方法来实现。 List<string> listOnit = new List<string>(); List<string> listNew = new List<string>(); //用于模糊查询 private void BindComboBox() { string str = "select License from tb_drug"; SQLiteDataReader sdr = sh.getcom(str); while (sdr.Read()) { if (sdr[0].ToString() != " " && sdr[0].ToString() != null) listOnit.Add(sdr[0].ToString()); } sdr.Close(); this.comboBox1.Items.AddRange(listOnit.ToArray()); } private void comboBox1_TextUpdate(object sender, EventArgs e) { this.comboBox1.Items.Clear(); listNew.Clear(); foreach (var item in listOnit) { if (item.Contains(this.comboBox1.Text)) { listNew.Add(item); } } this.comboBox1.Items.AddRange(listNew.ToArray()); this.comboBox1.SelectionStart = this.comboBox1.Text.Length; Cursor = Cursors.Default; this.comboBox1.DroppedDown = true; }

初识NuGet

因为想查一查opencvsharp的东西,然后发觉这个包可以再NuGet上面可以直接下载。我也经常在很多地方都可以看到NuGet,所以我想写下来,记录下来。 NuGet是一个免费的并且开源的包管理器在微软的开发平台上。NuGet发布在Visual Studio的拓展插件上。 NuGet现在已经移植到代码管理平台github了,链接地址为https://github.com/nuget/home。他们打算以后新的东西都在这个网址更新了。 资源 NuGet Gallery: http://nuget.org Documentation: http://docs.nuget.org Blog: http://blog.nuget.org Twitter: @nuget JabbR chat: https://jabbr.net/#rooms/nuget TeamCity continuous build server: http://build.nuget.org Latest successful VS Extension build: http://build.nuget.org/NuGet.Tools.vsix Latest successful NuGet.exe build: http://build.nuget.org/NuGet.exe NuGet貌似自从vs2012版本之后就默认在系统中了,所以不需要再安装了。如果想确保你的版本有没有安装NuGet,你可以看一下工具栏。你也可以在扩展和更新中可以进行NuGet的更新和管理。 只要你安装了,就可以非常方便的引用第三方的库,直接在引用里面添加就可以了。

回调函数

回调函数 在计算机程序设计中,回调函数,是指通过函数参数传递到其他代码的,某一块可执行代码的引用。这一设计允许了底层的代码调用高层的子程序。回调函数在.net平台中相当于委托。 回调函数的机制 定义一个回调函数。 提供函数实现的一方在初始化的时候,将回调函数的函数指针给调用者。 当特定的事件或条件发生的时候,调用者使用函数指针调用回调函数对事件进行处理。 为什么要使用回调函数 因为可以把调用者和被调用者分开,所以调用者不关心谁是被调用者。它只需要知道存在一个具有特定原型和限制条件的被调用函数。 代码实现 下面创建了一个sort.dll的动态链接库,它导出了一个名为CompareFunction的类型–typedef int (__stdcall CompareFunction)(const byte,const byte*),它就是回调函数的类型。另外,它也导出了两个方法:Bubblesort()和Quicksort(),这两个方法原型相同,但实现了不同的排序算法。 void DLLDIR __stdcall Bubblesort(byte* array,int size,int elem_size,CompareFunction cmpFunc); void DLLDIR __stdcall Quicksort(byte* array,int size,int elem_size,CompareFunction cmpFunc); 这两个函数接受以下参数: ·byte * array:指向元素数组的指针(任意类型)。 ·int size:数组中元素的个数。 ·int elem_size:数组中一个元素的大小,以字节为单位。 ·CompareFunction cmpFunc:带有上述原型的指向回调函数的指针。 回调函数实例 int __stdcall CompareInts(const byte* velem1,const byte* velem2) { int elem1 = *(int*)velem1; int elem2 = *(int*)velem2; if(elem1 < elem2) return -1; if(elem1 > elem2) return 1; return 0; } int __stdcall CompareStrings(const byte* velem1,const byte* velem2) { const char* elem1 = (char*)velem1; const char* elem2 = (char*)velem2; return strcmp(elem1,elem2); } int main(int argc,char* argv[])

opencv视频流的读取和处理

Opencv提供一个简单易用的框架以提取视频文件和USB摄像头中的图像帧,如果只是想读取某个视频,你只需要创建一个VideoCapture实例,然后在循环中提取每一帧。下面是一个简单的代码 #include<opencv2\core\core.hpp> #include<opencv2\imgproc\imgproc.hpp> #include<opencv2\highgui\highgui.hpp> #include<iostream> using namespace cv; using namespace std; int main() { VideoCapture capture("d:\\road.avi"); //检测视频是否读取成功 if (!capture.isOpened()) { cout << "No input image"; return 1; } //获取图像帧率 double rate = capture.get(CV_CAP_PROP_FPS); bool stop = false; Mat frame; namedWindow("Example"); int delay = 1000/rate; while (!stop) { if (!capture.read(frame)) break; imshow("Example",frame); if (waitKey(delay) >= 0) stop = true; } return 0; } 要正确地打开视频文件必须确保电脑具有相应的解码器。同时也应该注意文件路径的未知是否正确,路径为止错误经常也会提示错误warning: Error opening file (../../modules/highgui/src/cap_ffmpeg_impl.hpp:545)。这个错误一般都是文件路径错误而导致的。 处理视频帧 为了对视频中的每一帧进行处理,我们可以创建自己的类VideoProcessor,其中封装OopenCV的视频获取框架,该类允许我们制定每帧调用的处理函数。 首先,我们希望制定一个回调处理函数,(关于回调函数,另外一个帖子http://blog.csdn.net/neal1991/article/details/45009377有介绍)。这个喊出可以接受一个Mat对象然后输出处理之后的Mat对象。 void processFrame(Mat& img, Mat& out); // 对视频的每帧做Canny算子边缘检测 void canny(Mat& img, Mat& out) { // 先要把每帧图像转化为灰度图 cvtColor(img,out,CV_BGR2GRAY); // 调用Canny函数 Canny(out,out,100,200); // 对像素进行翻转 threshold(out,out,128,255,THRESH_BINARY_INV); } 定义好一个视频处理类,它将与一个回调函数相关联。使用该类,可以创建一个实例,制定输入的视频文件,绑定回调函数,然后开始对每一帧进行处理,要调用这个视频处理类,只需要在main函数添加就可以了: