Frenet标架及曲率挠率计算
此文算法基于马国庆等论文“点云空间曲线的微分信息计算及匹配方法”,引用请注明出处,在此感谢 ###Code function [curveture,fT,fN,fB]=Frenet_Curveture(pt,k) %计算连续曲线点的frenet标架及点的曲率 %参考:点云空间曲线的微分信息计算及匹配方法 %pt:三维点集 %k:领域大小 ptNum=size(pt,1); curveture=zeros(ptNum,1); hs=floor(k/2); fT=zeros(ptNum,3); fN=zeros(ptNum,3); fB=zeros(ptNum,3); for i=hs+1:ptNum-hs Rx=pt(i,:); pj=pt(i-hs:i+hs,:); % frenet 标架计算 centerDis = sum((pj-repmat(Rx,k,1)).^2,2); scenterDis=sort(centerDis); h=scenterDis((max(floor(k/3),1)+1)); thetaj=...
开轮廓轮轮廓跟踪
function out = OpenBoundaryTrack(bw) % 单个边缘跟踪,pstart为联通区右下方的像素点 当边缘位于边界处,无法跟踪,需将 % 图像人为扩大2*2像素并置0,并将最后结果做边界处理 bw1=zeros(size(bw)+2); bw1(2:end-1,2:end-1)=bw; ba=BoundaryTrack(bw1); [row,col]=size(bw); ba=ba-1; ba(find(ba(:,1)==1 | ba(:,1) == col | ba(:,2)== 1 | ba(:,2)== row),:)=[]; % 寻找最大距离为开始点 [~,dex]=max(sum((ba(1:end-1,:)-ba(2:end,:)).^2,2)); out=[ba(dex+1:end,:);ba(1:dex,:)]; function pt =BoundaryTrack(bw,pstart,pend) % 单个边缘跟踪,pstart为联通区右下方的像素点 当边缘位于边界处,无法跟踪,需将 % 图像人为扩大2*2像素并置0,并将最后结果...
只有旋转和平移的变换矩阵推导
此处推导只针对二维情况,三维情况肯定也是合适的,暂时没有推导假设二维平面中有两条曲线,求一组变换矩阵,使得两条曲线的间距最小,自然而然大家第一个想到的就应该是最小二乘法,推导步骤如下所示 但是在求得theta后,因为有正负之分,可能会相差180°,此时,再需比较一下两次变换后的距离,即可求得所需旋转矩阵及平移量 ###code: sx1=sum(p1(:,1));sy1=sum(p1(:,2)); sx2=sum(p2(:,1));sy2=sum(p2(:,2)); sx1y2=sum(p1(:,1).*p2(:,2)); sy1x2=sum(p1(:,2).*p2(:,1)); sy1y2=sum(p1(:,2).*p2(:,2)); sx1x2=sum(p1(:,1).*p2(:,1)); theta =atan((sx1*sy2-len1*sx1y2-sy1*sx2+len1*sy1x2) /... (sy1*sy2-len1*sy1y2+sx1*sx2-len1*sx1x2)) M=[cos(theta) sin(theta) 0;-sin(theta) cos...
bwlabel之C++
最近因为需要,会用到二值图像连通域分析算法,网上找了一些算法,但是都存在问题,比较多的一个是利用等价表的方法剔除错误标签方法,但是在后续开发中,验证了这个算法也存在问题,参考这个链接,改为c++的代码,文中作者也提出了相应的改进算法,但是不是很明白,按此建议修改错误标签更正算法,其结果经验证与matlab bwlabel算法结果一直,算法速度上没有做进一步优化,日后会做进一步优化。 ###原始代码 /// 连通区域标记 void CalNumberOfRuns(const uchar *data, int height, int width, int &numRuns) { assert(data != NULL); int count = 0; for (int j = 0; j < width; j++) { if (data[j] != 0) { count++; } for (int i = 1; i...
svn file was locked ,can not commit
when you use svn,when one file was locked by another ,you can not update and commit ,you can relocked the file ,it can point out the one who locked the file ,of course if must be a mistake, reference solution: you can use the repo browser and “break lock” from the context menu,note the this item will only appear if the item is in face ,locked,as show in the follow picture,
c++野指针释放出错
动态申请指针数组时,最后都要释放内存,但是如果中间内存越界,即野指针,在释放的过程中,会出debbg错误,如下图所示, 例如, double *data = new double[5]; data[5] = 6; delete[] data; 这是常见的,也是比较容易发现的,但是在循环内部,还是需要多加注意的,特别是 data[index++] 这样的情况,要多加注意检测数组是否越界。
opencv3.0 vs2008 编译静态库
最近因工作需要,需要编译64位的opencv静态lib库,由于之前一直用dll文件,这次还是走了不少弯路,用多长时间,就不说了,不好意思,也主要自己对微软的东西不是很感冒,好久搞不明白,这里坐下备注,防止日后再用到找不到。先说环境吧,vs2008因为一直都在用,不像换新的,所以这次还是在vs2008平台下编译,opencv采用最新的opencv3.0 beta版本,cmake也是采用最新的cmake3.1.0-rc2, cmake编译源代码如下 ###cMake编译静态库,主要的一项就是BUILD_SHARED_LIBS,这个东西我觉得名字有点怪,选了它编译出来的是dll,反之是lib,让人不得其解,其他的诸如BUILD_EXAMPLE,BUILD_TEST,BUILD_PERF_TEST,都可以不编译,还有一项,BUILD_OPENCV_WORLD,这是很好玩的,之前添加lib库文件,需要添加一大堆,现在如果选择了这一项,一个lib可以替代之前的一大堆lib了,甚是方便,推荐使用,其他的可以根据自己需要选择或去除了,反正我也不懂,呵呵,就都默认了。最后加一句,在编译64位li...
最大子数组求解
在做股票投资时,当买进最低,抛出最高时,获取的盈利是最大的,分别求出当天相对于前天的差价,数学上讲,将差价定义为一个数组,求其一阶差分,求一个数组下标,使得其和最大。 为了解决这一问题,可以采用分治法解决,对于数组A,开始、中间和结束坐标索引为low,mid,hight,最大的子数组只可能存在[low,mid],[mid+1,hight]和跨越中点的最大子数组,函数FIND-MAX-CORSSING-SUBARRAY接受数组A及线标low,mid,high为输入,返回一个下标元祖划定跨越中点的最大子数组的边界,并返回最大子数组 分析可以知道,其复杂度为N,进而可以通过分治算法求得最终解如下所示:
归并排序
归并排序是将两个有序表合并成一个有序表的过程,即把待排序序列分割成多个排好序的子序列,再合并成一个有序序列。该方法是分治法一个典型应用,类似与从两个排好序的纸牌中选择小的排成一个大的有序列。例如有两个有序表:(7,10,13,15)和(4,8,19,20),归并后得到的有序表为:(4,7,8,10,13,15,19,20)。 归并过程为:比较a[i]和a[j]的大小,若a[i]≤a[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1;否则将第二个有序表中的元素a[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。 Merge(A,p,q,r) 1 n1=q-p+1 2 n2=r-q 3 L(1...n1+1) and R(1...n2+1) as new arrays 4 for i=1 to n1 5 L(i) = A[p+i-1] 6 for i = 1 to n2 7 R(i) = A[q + ...
插入排序
插入排序,将未整理好的牌按大小插在已经排好序的队列中。 INSERTION-SORT(A) 1 for j = 2 to A.length 2 key = A[j] 3 i = j - 1 4 while i > 0 and A[i] > key 5 A[i + 1] = A[i] 6 i -- 7 A[i + 1] = key
