第一篇:三级项目报告图像匹配算法的实现及分析
三级项目设计(论文)
图像匹配算法的实现及分析
摘要
图像匹配是计算机视觉和图像处理领域中非常重要的工作,当我们需要在一副图像中寻找是否存在一个物体或一个小场景,并确定其位置,这时候我们就应当将具有灰度相关的图像进行匹配,实现图像匹配算法,通过计算它们之间的相关系数,确定协方差,进而进行图像匹配,确定其存在与否,并定位。
关键词:灰度相关;图像匹配;相关系数;协方差
前言
随着科技的进步,图像匹配技术已经成为信息处理领域极为重要和基本的技术。在军事上,它普遍应用于导弹的地图/地形匹配制导,飞机的导航等;在民用上,它普遍应用于运载工具自动导航仪,仪表导航,环境导航,环境保护,材料检测,机器人,交通等。
图像匹配是指通过一定的匹配算法在两幅或多幅图像之间识别同名点,如二维图像匹配中通过比较目标区和搜索区中相同大小的窗口的相关系数,取搜索区中相关系数最大所对应的窗口中心点作为同名点。其实质是在基元相似性的条件下,运用匹配准则的最佳搜索问题。常见方法有:像素灰度相关匹配,图像特征匹配等等。图像匹配是数字图像处理重要的研究课题之一。
正文
一.图像匹配方法原理与实现步骤
本项目要求,要用一个较小的图像,即模板与目标图像进行比较,以确定在目标图像中是否存在与该模板相同或相似的区域,若该区域存在,还可确定其位置。下面介绍几种常见的匹配方法 1.基于图像特征的配准方法
需要对图像进行预处理,然后提取图像中保持不变的特征,如边缘点、闭区域的中心、线特征、2.基于模型的匹配方法
在计算机视觉领域中的应用非常广泛,它可以分为刚体形状匹配和变形模板匹配[4]两大类。Kass提出的Snake主动轮廓模型是比较典型的自由式变形模板模型。3.基于变换域的匹配的方法
有基于傅立叶变换、基于Gabor变换和基于小波变换的匹配,这些匹配方法对噪声不敏感,检测结果不受照度变化影响,可以较好的处理图像之间的旋转和尺度变化。
综合看来:选择变换域的匹配方法可以较好的进行图像匹配。
根据相关定理,若f(x,y)和g(x,y)为二维时域函数,那么,定义以下相关运算: f(x,y)g(x,y)f()g(x,y)dd
式中,符号表示相关运算。
*F'f(x,y)g(x,y)F(u,v)G(u,v)
式中,F'表示傅里叶变换,F(u,v)是f(x,y)的傅里叶变换;G(u,v)是g(x,y)的傅里叶变换;G*(u,v)是G(u,v)的共轭。
也就是说,由于相关定理表示两个物体的相关程度,相关程度越高,说明两个物体越相似。那么我们根据定理,利用傅里叶变换,对两个图像做相关,然后观察出现的峰值,若峰值越高,表明两个物体越相似,并确定最高峰值的位置,则可以确定模板图在目标图中的位置。根据所给的条件,具体实现步骤如下:
1、制作模板图和目标图。根据所给的模板,利用画图工具重新制作一个模板图和目标图,要求目标图中间与左上角位置有与模板同样的图形,其他位置在画出另外三个图形。(如下图1、2、3)
2、将模板图与目标图数字化。即将模板图与目标图分别读入Matlab中,并存入相关矩阵,为了减少计算量,可将两幅图的数据矩阵转换为二值图像数据矩阵。
3、做傅里叶变换。根据相关定理,时域的相关,等于频域的乘积。所以要将模板图与目标图分别做傅里叶变换,变换的频域中去。(如下图4、5)
4、相关。模板图与目标图经傅里叶变换后,两图所得矩阵数乘,其中目标图的矩阵要先取共轭,然后经过反傅里叶变换到频域中去,并利用fftshift函数将低频部分移到中间去,并将图形旋转180度,得到正确的坐标轴,然后观察出现的五个峰值。(如下图6)
5、定位。求出相应矩阵中的最大值,根据最大值设置一阈值,找出高于此阈值的坐标,即为模板图在目标图中的位置。(如下图7)二.实现过程举例
根据上面所述实现步骤,具体实现过程如下 第一步所对应图形:
模板图 目标图
第三步所对应图形:
图4 模板图的傅里叶变换频谱
图5 目标图的傅里叶变换频谱
第四步所对应的图形:
图6 模板图与目标图相关后的图形
第五步所对应的图形:
图7 模板图在目标图中的位置(最高峰值出现的位置)
三.程序实现 具体实现程序如下:
function y=imagePosition()%图像匹配
%在一目标图像中,检测特定模板图像,并确定其位置
templet=imread('mig25_2.tif');%将模板图中的数据读入templet矩阵中 level=graythresh(templet);%设置黑白转换阀值 bw=im2bw(templet,level);%转换为二值图像数据
F=fft2(bw);%对模板图做快速傅里叶变换
figure,mesh(fftshift(abs(F)));%绘制模板图经过傅里叶变换后的三维图 title('模板图的傅里叶变换频谱');%图像题目
target=imread('mig25_3.tif');%将目标图中的数据读入target矩阵中 level=graythresh(target);BW=im2bw(target,level);F2=fft2(BW);%对目标图做快速傅里叶变换 %打开新的图形窗口,并绘制目标图经过傅里叶变换后的三维图 figure,mesh(fftshift(abs(F2)));title('目标图的傅里叶变换频谱');%在频域内用F点乘F2的共轭,相当于在时域内模板图与目标图做相关运算 %然后在做反傅里叶变换到时域,用fftshift函数将傅里叶变换的零频率部分移到数组中间
R=fftshift(abs(ifft2(F.*conj(F2))));R=rot90(R,2);%将R矩阵逆时针旋转180度,得到正确的坐标图 figure,mesh(R)%打开新的图形窗口,并绘制相关后的三维图,观察五个峰值 title('两个图相关后的频谱');thresh=max(R(:));%求矩阵R中的最大值
%求矩阵中最大值的所在的数组下标,即图像中最大峰值的位置 [row col]=find(R>thresh-1);figure,imshow(BW);%显示原始目标图
hold on %在当前坐标图形里添加绘制图形
%以找到的峰值的坐标为圆心,在原图上画圆做标记,即在目标图上标记模板图 for i=1:1:length(row)angle=0:0.1:2*pi;%采用极坐标法,其中半径设为10 plot(10*cos(angle)+col(i),10*sin(angle)+row(i),'LineWidth',3);End 四.结果分析
根据结果显示在目标图像中,与模板图像相同的图形被圈上了蓝圆圈,在相似图像的位置上有傅里叶函数变换频谱的峰值,进以证明图像在此相似度高,图像匹配。同时定位了相似图像的位置。通过对图像的像素的灰度值计算,可以充分利用图像的所有信息来高精度地区分不同对象,但因此处理的信息量很大,计算复杂度很高。同时不能分辨目标图片旋转,拉伸或压缩后的图像匹配问题。五.扩展解决方案
现如今为解决计算复杂度很高的问题可以通过SSDA算法,它的匹配精度与理论值相同,相位相关法匹配时间介于SSDA算法和ABS算法二者中间,也存在一个像素的误差; 为解决不能分辨目标图片旋转,拉伸或压缩后的图像匹配问题可以使用基于图像特征的匹配算法,应用图像边缘特征和频域相关相结合的图像处理技术进行图像匹配,能够达到较高精确地定位,具有自动匹配的优点。在带有旋转误差的图像匹配中,具有较好的稳定性,极大的减少了人为因素带来的误差,缩短了匹配时间,匹配效果良好。
这些方法都是进一步不错的解决图像匹配问题的方法,在这里不做过多的描述。
结论
1.基于傅立叶变换的匹配,这些匹配方法对噪声不敏感,检测结果不受照度变化影响,可以较好的处理图像之间的旋转和尺度变化。所以采用此变换方式来进行研究。
2.此匹配方法的优点:对噪声不敏感,检测结果不受光照变化影响。有成熟的快速算法并且易于硬件实现。缺点:该方法仅符合存在平移量的剧像间的配准,然而在实际中,图像间不仅存在平移量的不同,而且还有旋转角度、缩放尺度等的不同。
3.经过此次三级项目的制作与学习,不仅使我们对图像匹配算法有了更深的了解和认识,还加强了我们组内成员之间的沟通协作能力,让我们最感兴趣的是大家在一起共同探究,集思广益,各抒己见,这种形式让大家的观点来得更直接、更朴素、更真实。在交流中得到启发,得到快乐。
参考文献:
1.西安电子科技大学硕士学位论文“图像匹配算法研究” 2.哈尔滨工程大学计算机科学与技术学院 “特定图像的检测与定位”
第二篇:C++ 八种排序算法总结及实现
八种排序算法总结之C++版本
五种简单排序算法
一、冒泡排序
【稳定的】
void BubbleSort(int* a,int Count)//实现从小到大的最终结果 { int temp;for(int i=1;i for(int j=Count-1;j>=i;j--) if(a[j] < a[j-1]) { temp = a[j]; a[j] = a[j-1]; a[j-1] = temp; } } 现在注意,我们给出O方法的定义: 若存在一常量K和起点n0,使当n>=n0时,有f(n)<=K*g(n),则f(n)= O(g(n))。(呵呵,不要说没学好数学呀,对于编程数学是非常重要的!!) 现在我们来看1/2*(n-1)*n,当K=1/2,n0=1,g(n)=n*n时,1/2*(n-1)*n<=1/2*n*n=K*g(n)。所以f(n)=O(g(n))=O(n*n)。所以我们程序循环的复杂度为O(n*n)。 二、交换排序 【稳定的】 void ExchangeSort(int *a,int Count){ int temp;for(int i=0;i for(int j=i+1;j if(a[j] < a[i]) { temp = a[j]; a[j] = a[i]; a[i] = temp; } } 时间复杂度为O(n*n)。 三、选择法 【不稳定的】 void SelectSort(int *a,int Count){ int temp;//一个存储值 int pos;//一个存储下标 for(int i=0;i temp = a[i]; pos = i; for(int j=i+1;j if(a[j] < temp)//选择排序法就是用第一个元素与最小的元素交换 { temp = a[j]; pos = j;//下标的交换赋值,记录当前最小元素的下标位置 } a[pos] = a[i]; a[i] = temp;} } 遗憾的是算法需要的循环次数依然是1/2*(n-1)*n。所以算法复杂度为O(n*n)。 我们来看他的交换。由于每次外层循环只产生一次交换(只有一个最小值)。所以f(n)<=n 所以我们有f(n)=O(n)。所以,在数据较乱的时候,可以减少一定的交换次数。 四、插入法 【稳定的】 void InsertSort(int *a,int Count){ int temp;//一个存储值 int pos;//一个存储下标 for(int i=1;i { temp = a[i];//当前要插入的元素 pos = i-1; while(pos>=0 && temp { a[pos+1] = a[pos];//将前一个元素后移一位 pos--; } a[pos+1] = temp;} } 其复杂度仍为O(n*n)。 最终,我个人认为,在简单排序算法中,直接插入排序是最好的。 五、希尔排序法 【不稳定的】 /* * 希尔排序,n为数组的个数 */ void ShellSort(int arr[], int n){ int temp,pos;int d = n;//增量初值 do{ d = d/3 + 1; for(int i= d;i { temp = arr[i]; pos = i-d; while(pos>=0 && temp < arr[pos]){ arr[ pos + d ] = arr[pos]; pos-= d; } arr[ pos + d ] = temp; } } while(d > 1);} //实现增量为d的插入排序 三种高级排序算法 一、快速排序 辅助空间复杂度为O(1) 【不稳定的】 void QuickSort(int *a,int left, int right){ int i,j,middle,temp;i = left;j = right;middle = a[(left+right)/2 ];do { while(a[i] i++; while(a[j]>middle && j>left)//从右扫描小于中值的数 j--; if(i<=j)//找到了一对值 { temp = a[i]; a[i] = a[j]; } a[j] = temp; i++; j--;} } while(i 注意,在扫描过程中,对于给定参考值,对于向右(左)扫描,如果扫描值大(小)于或等于参考值,就需要进行交换。最终得到的结果是,j左边的值都小于参考值,而i右边的值都大于参考值,j和i之间的值都等于参考值。对j左边和i右边的分别使用递归,就可以完成最终的排序。 这里我没有给出行为的分析,因为这个很简单,我们直接来分析算法:首先我们考虑最理想的情况 1.数组的大小是2的幂,这样分下去始终可以被2整除。假设为2的k次方,即k=log2(n)。 2.每次我们选择的值刚好是中间值,这样,数组才可以被等分。 第一层递归,循环n次,第二层循环2*(n/2)......所以共有n+2(n/2)+4(n/4)+...+n*(n/n)= n+n+n+...+n=k*n=log2(n)*n 所以算法复杂度为O(log2(n)*n) 其他的情况只会比这种情况差,最差的情况是每次选择到的middle都是最小值或最大值,那么他将变 成交换法(由于使用了递归,情况更糟),但是糟糕的情况只会持续一个流程,到下一个流程的时候就很可能已经避开了该中间的最大和最小值,因为数组下标变化了,于是中间值不在是那个最大或者最小值。但是你认为这种情况发生的几率有多大??呵呵,你完全不必担心这个问题。实践证明,大多数的情况,快速排序总是最好的。 如果你担心这个问题,你可以使用堆排序,这是一种稳定的O(log2(n)*n)算法,但是通常情况下速度要慢 于快速排序(因为要重组堆)。 二、归并排序(两种实现方法均要掌握) 【稳定的】 归并排序是一种极好的外部排序方法,即针对数据保存在磁盘上而不是高速内存中的问题。 //以下程序参考数据结构课本P286页的模板,为使用指针链表实现的 #include struct node{ //链表的节点数据 int value;node *next;}; node * divide_from(node * head){ node * position, * midpoint, * second_half;if((midpoint=head)== NULL)//List is empty return NULL;position = midpoint->next;while(position!= NULL)//Move position twice for midpoint's one move { position = position->next; if(position!= NULL) { midpoint = midpoint->next; position = position->next; } } second_half = midpoint->next;midpoint->next = NULL;//在这里将原链拆断,分为两段 return second_half;} node * merge(node * first, node * second){ node * last_sorted;//当前已经链接好的有序链中的最后一个节点 node combined;//哑节点 last_sorted = &combined;while(first!=NULL && second!=NULL){ if(first->value < second->value){ last_sorted->next = first; last_sorted = first; first = first->next; }else { last_sorted->next = second; last_sorted = second; second = second->next; } } if(first==NULL) last_sorted->next = second;else last_sorted->next = first;return combined.next;//返回哑节点的后继指针,即为合并后的链表的头指针 } //这里的参数必须是引用调用,需要这个指引去允许函数修改调用自变量 void MergeSort(node * &head){ if(head!= NULL && head->next!= NULL)//如果只有一个元素,则不需排序 { node * second_half = divide_from(head); MergeSort(head); MergeSort(second_half); head = merge(head, second_half);} } int main(){ node a,b,c,d;node *p1, *p2, *p3, *p4,*head;p1 = &a;p2 = &b;p3 = &c;p4 = &d;a.value = 2;b.value = 4;c.value = 3;d.value = 1;a.next = p2;b.next = p3;c.next = p4;d.next = NULL;//调用归并排序前的结果 head = p1;while(head!= NULL){ cout< head = head->next;} cout< head = p1;while(head!= NULL){ cout< head = head->next;} cout< //以下程序为使用数组实现的归并排序,辅助空间复杂度为O(n) #include void Merge(int data[], int left, int mid, int right){ int n1,n2,k,i,j;n1 = midmid;int *L = new int[n1];//两个指针指向两个动态数组的首地址 int *R = new int[n2];for(i=0,k=left;i L[i] = data[k];for(i=0,k=mid+1;i R[i] = data[k];for(k=left,i=0,j=0;i if(L[i] < R[j]){ //取小者放前面 data[k] = L[i]; i++; } else { data[k] = R[j]; j++; } } if(i for(j=i;j < n1;j++,k++) } /* * left:数组的开始下标,一般为0;right:数组的结束下标,一般为(n-1)*/ void MergeSort(int data[], int left, int right){ if(left < right){ int mid = left +(right-left)/ 2;//mid=(right+left)/2,防止溢出 MergeSort(data, left, mid); MergeSort(data , mid+1, right); Merge(data , left, mid , right);} } int main(){ int data[] = {9,8,7,2,5,6,3,55,1};//排序前的输出 for(int i=0;i<9;i++) cout< for(int i=0;i<9;i++) cout< 三、堆排序 【不稳定的】 /* * 向堆中插入current元素的函数 */ void insert_heap(int data[], const int ¤t, int low, int high) data[k] = L[j];else //if(j for(i=j;i data[k] = R[i];delete []L;//回收内存 delete []R;{ int large;//元素data[low]左右儿子中,大者的位置 large = 2*low + 1;while(large <= high){ if(large < high && data[large] < data[ large+1]) large++; if(current > data[ large ])//待插入元素的值比它的两个儿子都大 break; else { data[ low ] = data[ large ];//将其左右儿子的大者上移 low = large; large = 2 * large + 1; } } data[ low ] = current;} /* * 建立堆函数,num为数组data的元素个数 * 只有一个结点的<2-树>自动满足堆的属性,因此不必担心树中的任何树叶,即 * 不必担心表的后一半中的元素。如果从表的中间点开始并从后向前工作,就 * 能够使用函数insert_heap去将每个元素插入到包含了所有后面元素的部分堆 * 中,从而创建完整的堆。*/ void build_heap(int data[], int num){ int current;for(int low = num/2-1;low>=0;low--){ current = data[ low ]; insert_heap(data, current, low, num-1);} } /* * 堆排序主函数,num为数组data的元素个数 */ void heap_sort(int data[], int num){ int current, last_sorted;build_heap(data, num);//建立堆 for(last_sorted = num-1;last_sorted>0;last_sorted--){ //逐个元素处理 current = data[ last_sorted ];//data[0]在整个数组排序结束前,存储的是待排序元素中最大的元素 data[last_sorted] = data[0]; insert_heap(data, current, 0, last_sorted-1);} } int main(){ //用于排序算法的输入输出 int a[8] = {5,7,1,2,9,4,6,3,};for(int i=0;i< sizeof(a)/sizeof(int);i++) cout< for(int i=0;i< sizeof(a)/sizeof(int);i++) cout< 1,插值算法(3种): (1)最邻近插值(近邻取样法): 最邻近插值的的思想很简单,就是把这个非整数坐标作一个四舍五入,取最近的整数点坐标处的点的颜色。可见,最邻近插值简单且直观,速度也最快,但得到的图像质量不高。 最邻近插值法的MATLAB源代码为: A = imread('F:lena.jpg');%读取图像信息 imshow(A);%显示原图 title('原图128*128'); Row = size(A,1);Col = size(A,2);%图像行数和列数 nn=8;%放大倍数 m = round(nn*Row);%求出变换后的坐标的最大值 n = round(nn*Col); B = zeros(m,n,3);%定义变换后的图像 for i = 1 : m for j = 1 : n x = round(i/nn);y = round(j/nn);%最小临近法对图像进行插值 if x==0 x = 1;end if y==0 y = 1;end if x>Row x = Row;end if y>Col y = Col;end B(i,j,:)= A(x,y,:); end end B = uint8(B);%将矩阵转换成8位无符号整数 figure;imshow(B); title('最邻近插值法放大8倍1024*1024'); 运行程序后,原图如图1所示: 图1 用最邻近插值法放大4倍后的图如图2所示: 图2 (2)双线性内插值法: 在双线性内插值法中,对于一个目的像素,设置坐标通过反向变换得到的浮点坐标为(i+u,j+v),其中i、j均为非负整数,u、v为[0,1)区间的浮点数,则这个像素得值 f(i+u,j+v)可由原图像中坐标为(i,j)、(i+1,j)、(i,j+1)、(i+1,j+1)所对应的周围四个像素的值决定,即: f(i+u,j+v)=(1-u)(1-v)f(i,j)+(1-u)vf(i,j+1)+ u(1-v)f(i+1,j)+ uvf(i+1,j+1)其中f(i,j)表示源图像(i,j)处的的像素值,以此类推。 这就是双线性内插值法。双线性内插值法计算量大,但缩放后图像质量高,不会出现像素值不连续的的情况。由于双线性插值具有低通滤波器的性质,使高频分量受损,所以可能会使图像轮廓在一定程度上变得模糊。 在MATLAB中,可用其自带的函数imresize()来实现双线性内插值算法。 双线性内插值算法的MATLAB源代码为: A=imread('F:lena.jpg');imshow(A); title('原图128*128'); C=imresize(A,8,'bilinear');%双线性插值 figure;imshow(C); title('双线性内插值法放大8倍1024*1024'); 程序运行后,原图如图3所示: 图3 双线性内插值法放大8倍后的图如图4所示: 图4 (3)双三次插值法: 双三次插值法能够在很大程度上克服以上两种算法的不足,该算法计算精度高,但计算量大,它考虑一个浮点坐标(i+u,j+v)周围的16个邻点。 目的像素值f(i+u,j+v)可由如下插值公式得到:f(i+u,j+v)= [A] * [B] * [C] 其中[A]=[ S(u + 1)S(u + 0)S(u2)];[C]=[ S(v + 1)S(v + 0)S(v2)];而[B]是周围16个邻点组成的4*4的矩阵;S(x)是对 Sin(x*π)/x 的逼近。 在MATLAB中,可用其自带的函数imresize()来实现双三次插值算法。MATLAB源代码为: A=imread('F:lena.jpg');%读取原图像 D=imresize(A,8,'bicubic');%双三次插值放大8倍 figure; T imshow(D);title('三次卷积法放大8倍1024*1024'); MATLAB自带双三次插值法运行结果如图5所示: 图5 也可以自己编写双三次插值算法MATLAB代码如下: clc,clear; ff=imread('F:lena.jpg');%读取图像到ff k=8;%设置放大倍数 [m,n,color]=size(ff); f=zeros(m,n);%将彩色图像ff转换为黑白图像f for i=1:m for j=1:n f(i,j)=ff(i,j); end end a=f(1,:);c=f(m,:);%将待插值图像矩阵前后各扩展两行两列,共扩展四行四列 b=[f(1,1),f(1,1),f(:,1)',f(m,1),f(m,1)];d=[f(1,n),f(1,n),f(:,n)',f(m,n),f(m,n)];a1=[a;a;f;c;c];a1'; b1=[b;b;a1';d;d];f=b1';f1=double(f); for i=1:k*m %利用双三次插值公式对新图象所有像素赋值 u=rem(i,k)/k;i1=floor(i/k)+2;A=[sw(1+u)sw(u)sw(1-u)sw(2-u)]; for j=1:k*n v=rem(j,k)/k;j1=floor(j/k)+2;C=[sw(1+v);sw(v);sw(1-v);sw(2-v)]; B=[f1(i1-1,j1-1)f1(i1-1,j1)f1(i1-1,j1+1)f1(i1-1,j1+2)f1(i1,j1-1)f1(i1,j1)f1(i1,j1+1)f1(i1,j1+2)f1(i1,j1-1)f1(i1+1,j1)f1(i1+1,j1+1)f1(i1+1,j1+2)f1(i1+2,j1-1)f1(i1+2,j1)f1(i1+2,j1+1)f1(i1+2,j1+2)];g1(i,j)=(A*B*C); end end g=uint8(g1);%将矩阵转换成8位无符号整数 imshow(g); title('自编双三次插值法放大8倍图像'); 其中子函数sw代码如下: function A=sw(w1)w=abs(w1);if w<1&&w>=0 A=1-2*w^2+w^3;elseif w>=1&&w<2 A=4-8*w+5*w^2-w^3;else A=0;end 与MATLAB自带函数相比,以上手工编写的MATLAB代码只能完成黑白图像输出,且运行时间远比MATLAB自带函数的运行时间长。手工编写双三次插值算法MATLAB代码的运行结果如图6所示: 图6 2,其他算法简介: 传统的图像放大方法有重复放大线性放大和高次多项式插值放大。重复放大最简单,但会产生明显的方块效应线性放大消除了方块效应,但会造成图像的模糊 高次多项式插值放大效果较好,但运算复杂。由于传统方法的固有缺陷,诞生了新一代图像放大方法,主要有小波放大、邻域交换内插和分形放大等。 下面简单介绍一下增强系数小波放大算法: 算法示意图如图7所示: 图7 通过二维离散小波变换,经分析高通滤波器和分析低通滤波器,可将一幅分辨率为p的二维图像分解为分辨率为p/2的离散逼近信号A1和水平、垂直、对角三个细节信号H1、V1、D1。这四个分量都只有原图像大小的1/4。之后又可以对A1进行同样的分解如图7所示。这个过程可以一直重复下去。通过二维离散小波反变换,用相应的综合高通滤波器和综合低通滤波器可将各分量重构为原图像。 对于一个图像,低频成分包含了基本特征,即原图像的近似,高频成分反应其细节。基于此,我们将原图像作为低频成分A1,其他3个细节部分置0,进行小波重构,便可得到放大4倍的图像。但是由于能量守恒,放大后的图像能量分散会显得较暗。可以将原图像灰度值矩阵乘2,再进行上述变换,便可解决这一问题。小波分解重构是一种全局运算,不会造成重复放大中的方块效应,同时较好地保持图像边缘的清晰。 ××公司目标利润实现分析报告 2007年公司制订的目标利润值是××万元,为了达到此目标,采取了节约生产成本,加大宣传力度,制订合理的销售计划等措施,顺利完成了预期目标。详细的销售利润情况表(略)。 一、利润情况分析 由上表可以看出,目标销售收入为××万元,实际销售额约为××万元,超过目标销售额将近××万元。预计单位产品成本为××元,实际销售时的单位成本为××元,则可计算出。 (1)预期利润=(产品计划销售单价-预估单位产品成本)×产品计划销售量,约为××万元。 (2)实际利润=(产品实际销售单价-实际销售单位成本)×产品实际销售量,约为××万元。由此可以看出,虽然实际销售收入大于目标销售额,但实际销售利润仅比目标销售利润高出××万元,这说明在产品销售工作上投入成本较高,没有实现更高的利润收入。 二、对问题提出解决建议 针对利润分析得出的问题,提出以下几点建议。 (1)产品销售前进行详细的市场调研,根据调研信息制订切实可行的销售策略。 (2)加强成本核算管理,严格控制成本投入。 (3)加强费用管理,严格控制费用支出。 综上所述,当前市场表现良好,但仍有改进空间,请相关部门参考。 ×××公司财务部 ××年×月×日 程序: #include lfsr(int a,int b,int c,int d,int T[]);void main(){ int A[19]={1,0,1,1,0,0,1,1,0,0,0,0,1,0,1,0,1,0,1}; int B[22]={0,0,1,0,0,0,1,1,1,0,0,1,0,0,1,0,1,0,1,0,1,1};int C[23]={1,0,0,0,1,0,1,1,0,1,0,0,1,0,0,0,1,0,1,0,1,0,1};for(int i=0;i { printf(“%d”,A[18]^B[21]^C[22]); lfsr(13,16,17,18,A); lfsr(12,16,20,21,B); lfsr(17,18,21,22,C);} else if(j==1) { printf(“%d”,A[18]^B[21]^C[22]); if(A[9]==0) lfsr(13,16,17,18,A); if(B[11]==0) lfsr(12,16,20,21,B); if(C[11]==0) lfsr(17,18,21,22,C);} else if(j==2) { printf(“%d”,A[18]^B[21]^C[22]); if(A[9]==1) lfsr(13,16,17,18,A); if(B[11]==1) lfsr(12,16,20,21,B); if(C[11]==1) lfsr(17,18,21,22,C);} else if(j==3) { printf(“%d”,A[18]^B[21]^C[22]); lfsr(13,16,17,18,A); lfsr(12,16,20,21,B); lfsr(17,18,21,22,C); } } printf(“n n”);} lfsr(int a,int b,int c,int d,int T[]){ int i; for(i=d;i>0;i--) { T[i]=T[i-1]; } T[0]=T[a]^T[b]^T[c]^T[d]; return(T[0]);} 密钥流: A[19]={1,0,1,1,0,0,1,1,0,0,0,0,1,0,1,0,1,0,1}; B[22]={0,0,1,0,0,0,1,1,1,0,0,1,0,0,1,0,1,0,1,0,1,1};C[23]={1,0,0,0,1,0,1,1,0,1,0,0,1,0,0,0,1,0,1,0,1,0,1};密钥流序列: 1111 1111 1101 1010 1101 0101 0111 0001 1110 0000 1010 1000 0101 1100 0100 0000第三篇:图像放大算法总结及MATLAB源程序
第四篇:利润实现分析报告
第五篇:A5算法C语言实现报告(写写帮推荐)