‘壹’ 字符串匹配的传统算法
传统的匹配算法
串匹配算法虽然发展了几十年,然而非常实用的算法是近年才出现。串匹配问题的研究存在理论研究和实际应用的脱节。那些专门从事算法研究的学者关心的只是理论上看起来很美妙的算法——具有很好的时间复杂度。而开发人员只追求实际应用中尽可能快的算法。两者之间从不注意对方在干什么。将理论研究和实际应用结合的算法(如BNDM算法)只是近年才出现。在实际应用中常常很难找到适合需求的算法——这样的算法实际上是存在的,但是只有资深专家才比较了解。考虑如下情况,一位软件开发人员,或者一位计算生物学家,或者一位研究人员,又或者一位学生,对字符串匹配领域并没有深入了解,可是现在需要处理一个文本搜索问题。那些汗牛充栋的书籍使得阅读者淹没在各种匹配算法的海洋中,却没有足够的知识选择最适用的算法。最后,常常导致这样的局面:选择一种最简单的算法加以实现。这往往导致很差的性能,从而影响整个开发系统的质量。更糟糕的是,选择了一个理论上看起来很漂亮的算法,并且花费了大量精力去实现。结果,却发现实际效果和一个简单算法差不多,甚至还不如简单算法。因此,应该选用一种“实用”算法,即在实际应用中性能较好,并且一个普通程序员能在几小时内完成算法的实现代码。另外,在字符串匹配研究领域中,一个人所共知的事实是“算法的思想越简单,实际应用的效果越好”。
传统的串匹配算法可以概括为前缀搜索、后缀搜索、子串搜索。代表算法有KMP,Shift-And,Shift-Or,BM,Horspool,BNDM,BOM等。所用到的技术包括滑动窗口、位并行、自动机、后缀树等。
‘贰’ 解析一哈c语言中的kmp算法,bf算法,kr算法之间的联系与区别,尽量浅显易懂,谢谢!
三种算法联系:都是字符串匹配算法。
区别:
“KMP算法”:在匹配过程称,若发生不匹配的情况,如果next[j]>=0,则目标串的指针i不变,将模式串的指针j移动到next[j]的位置继续进行匹配;若next[j]=-1,则将i右移1位,并将j置0,继续进行比较。
“BF算法”是普通的模式匹配算法,BF算法的思想就是将目标串S的第一个字符与模式串P的第一个字符进行匹配,若相等,则继续比较S的第二个字符和P的第二个字符;若不相等,则比较S的第二个字符和P的第一个字符,依次比较下去,直到得出最后的匹配结果。
“KR算法”在每次比较时,用HASH算法计算文本串和模式串的HASH映射,通过比较映射值的大小来比较字符串是否匹配。但是考虑到HASH冲突,所以在映射值相同的时候,还需要近一步比较字符串是否相同。但是在每次比较时,需要计算HASH值,所以选择合适的HASH算法很重要。
略知一二!
‘叁’ 人类有多少种交匹配方式
原始社会是平均分配。
她长得非常漂亮,美得既诱惑又天真,非常惹人怜爱。但是她从来没有真正地投入过爱情。
她虽然美丽,但在潜意识里,并不认为自己值得被爱,她对自己打的分数很低。
和任何男人在一起,她都觉得对方不会对自己真心投入,她都担心对方会离开,她也一直自我保护从不过分陷入某段感情。
朴素的模式匹配算法:
算法思想:从目标串的的第一个字符起与模式串的第一个字符比较,若相等,则继续对字符进行后续的比较,否则目标串从第二个字符起与模式串的第一个字符重新比较,直至模式串中的每个字符依次和目标串中的一个连续的字符序列相等为止,此时称为匹配成功,否则匹配失败。
‘肆’ SGM半全局匹配算法求助
#include "stdafx.h"
#include <cstdio>
#include <cstring>
#include <iostream>
#include<cv.h>
#include<highgui.h>
#include <cmath>
using namespace std;
const int Width = 1024;
const int Height = 1024;
int Lvalue[Width][Width];
uchar C(int x, int y, int d, IplImage * matchImage, IplImage * baseImage)
{
uchar * pMatchPixel = NULL;
uchar * pBasePixel = NULL;
uchar matchPixel = 0;
uchar basePixel =0;
uchar matchMax = 0;
uchar matchMin = 0;
uchar tempMatch1 = 0;
uchar tempMatch2 = 0;
uchar difPixel = 0;
if (x+d <= matchImage->width && x+d >= 0)
{
pMatchPixel = (uchar *)matchImage->imageData + y*matchImage->widthStep + (x+d);
matchPixel = *pMatchPixel;
pBasePixel= (uchar *)baseImage->imageData + y*baseImage->widthStep + x;
basePixel = *pBasePixel;
//匹配影像上的像素点与其左、右像素点的平均值,线性插值的方法
tempMatch1 = (*pMatchPixel +(*(pMatchPixel -1)))/2;
tempMatch2 = (*pMatchPixel +(*(pMatchPixel +1)))/2;
matchMax = max(max(tempMatch1,tempMatch2),matchPixel);
matchMin = min(min(tempMatch1,tempMatch2),matchPixel);
//赋予视差d时的匹配代价C
//BT法
difPixel = max(max(basePixel - matchMax, matchMin - basePixel),0);
//AD法
//difPixel = abs(basePixel - matchPixel);
return difPixel;
}
else
return 255;
}
int main()
{
IplImage * leftImage = cvLoadImage("headL.png",0);
IplImage * rightImage = cvLoadImage("headR.png",0);
int imageWidth = leftImage->width;
int imageHeight =leftImage->height;
int minLvalue = 1000;
int minL1 = 1000;
int minL2 = 1000;
int P1 = 2;
int P2 = 5;
int disparity= 0;
int minDis = 0;
int maxDis = 21;
int scale = 12;
unsigned char * pPixel = NULL;
#pragma region 实现横向DP(以右影像为准,0度方向)
IplImage * MyDPImage_0 = cvCreateImage(cvGetSize(leftImage),leftImage->depth,1);
cvZero(MyDPImage_0);
int t3 = clock();
for (int i = 0; i < imageHeight;i++)
{
for (int j = 0; j<imageWidth ;j++)
{
disparity = 0;
minL1 = 1000;
minL2 = 1000;
for (int d = minDis; d <= maxDis; d++)
{
//初始化为代价函数的值
Lvalue[j][d] = C(j, i, d, leftImage, rightImage);
if (j > 0)
{
minL1 = min(minL1, Lvalue[j-1][d]);
}
}
for (int d = minDis; d <= maxDis; d++)
{
if (j > 0)
{
minL2 = min(minL2, Lvalue[j-1][d]);
minL2 = min(minL2, (Lvalue[j-1][d+1] + P1));
minL2 = min(minL2, (Lvalue[j-1][d-1] + P1));
minL2 = min(minL2, (minL1 + P2));
Lvalue[j][d] = Lvalue[j][d] + (minL2 - minL1);
}
}
int max=Lvalue[j][0];
for(int d=minDis;d<=maxDis;++d)
{
if(Lvalue[j][d]<max)
{
disparity=d;
max=Lvalue[j][d];
}
}
disparity=disparity*scale;
//生成视差图
pPixel = (uchar *)MyDPImage_0->imageData + i*MyDPImage_0->widthStep + j;
*pPixel =disparity;
}
}
int t4 = clock();
cout<<"横向DP共用时: "<<t4-t3<<"ms"<<endl;
cvNamedWindow("MyDPImage_0", 1);
cvShowImage("MyDPImage_0", MyDPImage_0);
cvSaveImage("MyDPImage_0.jpg", MyDPImage_0);
#pragma endregion
#pragma region 实现横向DP(以左影像为准,0度方向)
IplImage * MyDPImage_0_L = cvCreateImage(cvGetSize(leftImage),leftImage->depth,1);
cvZero(MyDPImage_0_L);
for (int i = 0; i < imageHeight;i++)
{
for (int j = 0; j<imageWidth;j++)
{
disparity = 0;
minL1 = 1000;
minL2 = 1000;
for (int d = minDis; d <= maxDis; d++)
{
//初始化为代价函数的值
Lvalue[j][d] = C(j, i, -d, rightImage, leftImage);
if (j > 0)
{
minL1 = min(minL1, Lvalue[j-1][d]);
}
}
for (int d = minDis; d <= maxDis; d++)
{
if (j > 0)
{
minL2 = min(minL2, Lvalue[j-1][d]);
minL2 = min(minL2, (Lvalue[j-1][d+1] + P1));
minL2 = min(minL2, (Lvalue[j-1][d-1] + P1));
minL2 = min(minL2, (minL1 + P2));
Lvalue[j][d] = Lvalue[j][d] + minL2 - minL1;
}
}
int max=Lvalue[j][0];
for(int d=0;d<=maxDis;++d)
{
if(Lvalue[j][d]<max)
{
disparity=d;
max=Lvalue[j][d];
}
}
disparity = disparity * scale;
//生成视差图
pPixel = (uchar *)MyDPImage_0_L->imageData + i*MyDPImage_0_L->widthStep + j;
*pPixel = disparity;
}
}
cvNamedWindow("MyDPImage_0_L", 1);
cvShowImage("MyDPImage_0_L", MyDPImage_0_L);
cvSaveImage("MyDPImage_0_L.jpg", MyDPImage_0_L);
#pragma endregion
#pragma region 一致性检查
uchar * pLeftDepthPixel = NULL;
uchar * pRightDepthPixel = NULL;
uchar leftDepthPixel = 0;
uchar rightDepthPixel =0;
uchar difDepthPixel = 0;
IplImage * CheckImage_0 = cvCloneImage(MyDPImage_0);
cvZero(CheckImage_0);
for (int i = 0; i < imageHeight; i++)
{
for(int j = 0; j < imageWidth; j++)
{
pRightDepthPixel = (uchar *)MyDPImage_0->imageData + i*MyDPImage_0->widthStep + j;
rightDepthPixel = *pRightDepthPixel;
if(j + rightDepthPixel/scale < imageWidth)
{
pLeftDepthPixel = (uchar *)MyDPImage_0_L->imageData + i*MyDPImage_0_L->widthStep + j + rightDepthPixel/scale;
leftDepthPixel = *pLeftDepthPixel;
}
else
leftDepthPixel = 0;
difDepthPixel = abs((leftDepthPixel - rightDepthPixel)/scale);
pPixel = (uchar *)CheckImage_0->imageData + i * CheckImage_0->widthStep +j;
if (difDepthPixel <= 1)
{
*pPixel = rightDepthPixel;
}
else
{
//否则,当前像素的视差值为零
*pPixel = 0;
}
}
}
int lp,rp;
int lx,rx;
for(int i=0;i<imageHeight;i++)
{
for(int j=0;j<imageWidth;j++)
{
int tem = *((uchar *)CheckImage_0->imageData+i*CheckImage_0->widthStep + j);
if(tem==0)
{
lp = rp = 0;
lx = j;
rx = j;
if(lx-1<0)
lp= *((uchar *)CheckImage_0->imageData+i*CheckImage_0->widthStep + lx);
while((lp==0)&&( lx-1 >= 0 ))
lp = *((uchar *)CheckImage_0->imageData+i*CheckImage_0->widthStep + (--lx));
if(rx+1>=imageWidth)
rp = *((uchar *)CheckImage_0->imageData+i*CheckImage_0->widthStep + rx);
while((rp==0)&&(rx+1<imageWidth))
rp = *((uchar *)CheckImage_0->imageData+i*CheckImage_0->widthStep +(++rx));
if (lp > rp)
{
*((uchar *)CheckImage_0->imageData+i*CheckImage_0->widthStep + j) = rp;
}
else
{
*((uchar *)CheckImage_0->imageData+i*CheckImage_0->widthStep + j) = lp;
}
}
}
}
cvSmooth(CheckImage_0,CheckImage_0,CV_MEDIAN,3,0,0);
cvNamedWindow("CheckImage_0", 1);
cvShowImage("CheckImage_0", CheckImage_0);
cvSaveImage("CheckImage_0.jpg", CheckImage_0);
#pragma endregion
cout << "完成!"<<endl;
cvWaitKey(0);
return 0;
}
‘伍’ 半全局块匹配(Semi-Global Block Matching)算法
最近在做双目视差估计算法,在OpenCV里有一些算法,其中半全局块匹配(Semi-Global Block Matching,SGBM)算法具有视差效果好速度快的特点,因此常常被广泛应用。本文主要讨论的就是SGBM算法。OpenCV的SGBM算法主要参考了《Stereo Processing by Semiglobal Matching and Mutual Information》这篇论文。
原论文使用的方法是利用互信息熵,而OpenCV使用的是Birchfield和Tomasi的方法(参照《Depth Discontinuities by Pixel-to-Pixel Stereo》)。这里我们分别介绍一下。
所谓的熵,是用来表示随机变量的不确定性,熵的值越大,信息的不确定性也越大。熵H和互信息MI的定义分别如下:
其中,P I 代表某个点i的概率分布,也就是灰度直方图为i的点出现的概率;对应地,P I 1 ,I 2 就是两个图对应点i 1 和i 2 的联合概率分布,也就是:
Kim等人将上式做了一个改进:利用泰勒展开把H I 1 ,I 2 的计算转化为求和问题(参见论文《Visual Correspondence Using Energy Minimization and Mutual Information》)。
其中圈中带叉表示卷积运算,g(i,k)为高斯卷积核。
相应地,边缘熵以及边缘概率的计算如下:
这样的话,互信息的定义为:
MI匹配代价C MI 为:
其中 q 是点 p 在视差为d的情况下的对应校正点。
原作者使用分层互信息(HMI)进行计算,每一层尺寸减少一半。单次计算的时间复杂度是O(WHD),即width×height×disparity range,所以上次迭代将会是当前迭代速度的1/8。
这里1/16 3 要乘3的原因是小尺寸的随机视差图不靠谱,需要迭代3次。我们可以看到,相比于后文的BT方法仅仅慢了14%
对于一个匹配序列M,其代价函数γ(M)表示匹配结果 不 准确的程度,其值越小越好。
其中,κ occ 表示未匹配的惩罚项(constant occlusion penalty),κ r 表示匹配的奖励项,N occ 和N r 分别表示未匹配和匹配的点数。
我们为视差设置一个能量函数E(D)
其中P 1 和P 2 分别表示视差差值为1和视差差值大于1的惩罚系数,一般P 1 <P 2 。添加两个正则化项一是为了保持视差图平滑,二是为了保持边缘。我们要做的是找到D使得能量函数E(D)最小,但是不幸的是,在二维图像的这个问题是一个NP-完全问题。为了解决这个问题,原文选择沿着一圈8个或者16个方向进行优化。
选取使代价聚合最小的视差值min d S[e mb ( q ,d),d]即可。
我们看一下stereoSGBM类的参数。
简单地试了一下:
‘陆’ D3群在三维实空间中的矩阵表示是怎么算的
MVS是一种从具有一定重叠度的多视图视角中恢复场景的稠密结构的技术,传统方法利用几何、光学一致性构造匹配代价,进行匹配代价累积,再估计深度值。虽然传统方法有较高的深度估计精度,但由于存在缺少纹理或者光照条件剧烈变化的场景中的错误匹配,传统方法的深度估计完整度还有很大的提升空间。近年来卷积神经网络已经成功被应用在特征匹配上,提升了立体匹配的精度。在这样的背景下,香港科技大学Yaoyao等人,在2018年提出了一种基于深度学习的端到端深度估计框架——MVSNet。
多视图立体匹配(Multi-view Stereo, MVS)是计算机领域中一个核心问题。重建多视图立体匹配,可以认为是拍摄既定场景的一个逆过程。相机映射下,三维场景变换为二维,而多视图立体匹配重建正好相反,其从这样子。不同视点拍摄图像,恢复出真实的三维场景。
传统的方法使用手工设计的相似性度量指标和正则化方法计算场景的稠密对应关系(比如使用归一化互相关Normalized Cross-Correlation和半全局匹配semi-global matching)。这些方法在非朗伯体表面、无弱纹理区域的场景可以达到很好的效果。但是在弱纹理区域,人工设计的相似性指标变得不可信,因此导致重建结果不完整。由MVS数据集的排行榜可知,这些方法具有很高的精度,然而在重建的完整度方法还有很大的空间可以提升。
卷积神经网络的研究的最新进展引发了人们完善立体匹配重建热情。从概念看,基于学习算法能够捕获全局的语义信息,比如基于高光和反射的先验条件,便于得到更加稳健的匹配。目前已经探求一些两视图立体匹配,用神经网络替换手工设计的相似性度量或正则化方法。这些方法展现出更好的结果,并且逐步超过立体匹配领域的传统方法。事实上,立体匹配任务完全适合使用CNN,因为图像对是已经过修正过的,因此立体匹配问题转化为水平方向上逐像素的视差估计。
与双目立体匹配不同的是,MVS的输入是任意数目的视图,这是深度学习方法需要解决的一个棘手的问题。而且只有很少的工作意识到该问题,比如SurfaceNet事先重建彩色体素立方体,将所有像素的颜色信息和相机参数构成一个3D代价体,所构成的3D代价体即为网络的输入。然而受限于3D代价体巨大的内存消耗,SurfaceNet网络的规模很难增大:SurfaceNet运用了一个启发式的“分而治之”的策略,对于大规模重建场景则需要花费很长的时间。
‘柒’ SGM半全局匹配算法求助
SGM半全局匹配算法用c++实现的代码如下,仅供参考(vs中编译通过)。
#include"stdafx.h"
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cv.h>
#include<highgui.h>
#include<cmath>
usingnamespacestd;
constintWidth=1024;
constintHeight=1024;
intLvalue[Width][Width];
ucharC(intx,inty,intd,IplImage*matchImage,IplImage*baseImage)
{
uchar*pMatchPixel=NULL;
uchar*pBasePixel=NULL;
ucharmatchPixel=0;
ucharbasePixel=0;
ucharmatchMax=0;
ucharmatchMin=0;
uchartempMatch1=0;
uchartempMatch2=0;
uchardifPixel=0;
if(x+d<=matchImage->width&&x+d>=0)
{
pMatchPixel=(uchar*)matchImage->imageData+y*matchImage->widthStep+(x+d);
matchPixel=*pMatchPixel;
pBasePixel=(uchar*)baseImage->imageData+y*baseImage->widthStep+x;
basePixel=*pBasePixel;
//匹配影像上的像素点与其左、右像素点的平均值,线性插值的方法
tempMatch1=(*pMatchPixel+(*(pMatchPixel-1)))/2;
tempMatch2=(*pMatchPixel+(*(pMatchPixel+1)))/2;
matchMax=max(max(tempMatch1,tempMatch2),matchPixel);
matchMin=min(min(tempMatch1,tempMatch2),matchPixel);
//赋予视差d时的匹配代价C
//BT法
difPixel=max(max(basePixel-matchMax,matchMin-basePixel),0);
//AD法
//difPixel=abs(basePixel-matchPixel);
returndifPixel;
}
else
return255;
}
intmain()
{
IplImage*leftImage=cvLoadImage("headL.png",0);
IplImage*rightImage=cvLoadImage("headR.png",0);
intimageWidth=leftImage->width;
intimageHeight=leftImage->height;
intminLvalue=1000;
intminL1=1000;
intminL2=1000;
intP1=2;
intP2=5;
intdisparity=0;
intminDis=0;
intmaxDis=21;
intscale=12;
unsignedchar*pPixel=NULL;
#pragmaregion实现横向DP(以右影像为准,0度方向)
IplImage*MyDPImage_0=cvCreateImage(cvGetSize(leftImage),leftImage->depth,1);
cvZero(MyDPImage_0);
intt3=clock();
for(inti=0;i<imageHeight;i++)
{
for(intj=0;j<imageWidth;j++)
{
disparity=0;
minL1=1000;
minL2=1000;
for(intd=minDis;d<=maxDis;d++)
{
//初始化为代价函数的值
Lvalue[j][d]=C(j,i,d,leftImage,rightImage);
if(j>0)
{
minL1=min(minL1,Lvalue[j-1][d]);
}
}
for(intd=minDis;d<=maxDis;d++)
{
if(j>0)
{
minL2=min(minL2,Lvalue[j-1][d]);
minL2=min(minL2,(Lvalue[j-1][d+1]+P1));
minL2=min(minL2,(Lvalue[j-1][d-1]+P1));
minL2=min(minL2,(minL1+P2));
Lvalue[j][d]=Lvalue[j][d]+(minL2-minL1);
}
}
intmax=Lvalue[j][0];
for(intd=minDis;d<=maxDis;++d)
{
if(Lvalue[j][d]<max)
{
disparity=d;
max=Lvalue[j][d];
}
}
disparity=disparity*scale;
//生成视差图
pPixel=(uchar*)MyDPImage_0->imageData+i*MyDPImage_0->widthStep+j;
*pPixel=disparity;
}
}
intt4=clock();
cout<<"横向DP共用时:"<<t4-t3<<"ms"<<endl;
cvNamedWindow("MyDPImage_0",1);
cvShowImage("MyDPImage_0",MyDPImage_0);
cvSaveImage("MyDPImage_0.jpg",MyDPImage_0);
#pragmaendregion
#pragmaregion实现横向DP(以左影像为准,0度方向)
IplImage*MyDPImage_0_L=cvCreateImage(cvGetSize(leftImage),leftImage->depth,1);
cvZero(MyDPImage_0_L);
for(inti=0;i<imageHeight;i++)
{
for(intj=0;j<imageWidth;j++)
{
disparity=0;
minL1=1000;
minL2=1000;
for(intd=minDis;d<=maxDis;d++)
{
//初始化为代价函数的值
Lvalue[j][d]=C(j,i,-d,rightImage,leftImage);
if(j>0)
{
minL1=min(minL1,Lvalue[j-1][d]);
}
}
for(intd=minDis;d<=maxDis;d++)
{
if(j>0)
{
minL2=min(minL2,Lvalue[j-1][d]);
minL2=min(minL2,(Lvalue[j-1][d+1]+P1));
minL2=min(minL2,(Lvalue[j-1][d-1]+P1));
minL2=min(minL2,(minL1+P2));
Lvalue[j][d]=Lvalue[j][d]+minL2-minL1;
}
}
intmax=Lvalue[j][0];
for(intd=0;d<=maxDis;++d)
{
if(Lvalue[j][d]<max)
{
disparity=d;
max=Lvalue[j][d];
}
}
disparity=disparity*scale;
//生成视差图
pPixel=(uchar*)MyDPImage_0_L->imageData+i*MyDPImage_0_L->widthStep+j;
*pPixel=disparity;
}
}
cvNamedWindow("MyDPImage_0_L",1);
cvShowImage("MyDPImage_0_L",MyDPImage_0_L);
cvSaveImage("MyDPImage_0_L.jpg",MyDPImage_0_L);
#pragmaendregion
#pragmaregion一致性检查
uchar*pLeftDepthPixel=NULL;
uchar*pRightDepthPixel=NULL;
ucharleftDepthPixel=0;
ucharrightDepthPixel=0;
uchardifDepthPixel=0;
IplImage*CheckImage_0=cvCloneImage(MyDPImage_0);
cvZero(CheckImage_0);
for(inti=0;i<imageHeight;i++)
{
for(intj=0;j<imageWidth;j++)
{
pRightDepthPixel=(uchar*)MyDPImage_0->imageData+i*MyDPImage_0->widthStep+j;
rightDepthPixel=*pRightDepthPixel;
if(j+rightDepthPixel/scale<imageWidth)
{
pLeftDepthPixel=(uchar*)MyDPImage_0_L->imageData+i*MyDPImage_0_L->widthStep+j+rightDepthPixel/scale;
leftDepthPixel=*pLeftDepthPixel;
}
else
leftDepthPixel=0;
difDepthPixel=abs((leftDepthPixel-rightDepthPixel)/scale);
pPixel=(uchar*)CheckImage_0->imageData+i*CheckImage_0->widthStep+j;
if(difDepthPixel<=1)
{
*pPixel=rightDepthPixel;
}
else
{
//否则,当前像素的视差值为零
*pPixel=0;
}
}
}
intlp,rp;
intlx,rx;
for(inti=0;i<imageHeight;i++)
{
for(intj=0;j<imageWidth;j++)
{
inttem=*((uchar*)CheckImage_0->imageData+i*CheckImage_0->widthStep+j);
if(tem==0)
{
lp=rp=0;
lx=j;
rx=j;
if(lx-1<0)
lp=*((uchar*)CheckImage_0->imageData+i*CheckImage_0->widthStep+lx);
while((lp==0)&&(lx-1>=0))
lp=*((uchar*)CheckImage_0->imageData+i*CheckImage_0->widthStep+(--lx));
if(rx+1>=imageWidth)
rp=*((uchar*)CheckImage_0->imageData+i*CheckImage_0->widthStep+rx);
while((rp==0)&&(rx+1<imageWidth))
rp=*((uchar*)CheckImage_0->imageData+i*CheckImage_0->widthStep+(++rx));
if(lp>rp)
{
*((uchar*)CheckImage_0->imageData+i*CheckImage_0->widthStep+j)=rp;
}
else
{
*((uchar*)CheckImage_0->imageData+i*CheckImage_0->widthStep+j)=lp;
}
}
}
}
cvSmooth(CheckImage_0,CheckImage_0,CV_MEDIAN,3,0,0);
cvNamedWindow("CheckImage_0",1);
cvShowImage("CheckImage_0",CheckImage_0);
cvSaveImage("CheckImage_0.jpg",CheckImage_0);
#pragmaendregion
cout<<"完成!"<<endl;
cvWaitKey(0);
return0;
}