工程编译环境vc6.0+opencv1.0
#include <stdlib.h>
#include <stdio.h>
#include <iostream.h>
#include <math.h>
#include <cv.h>
#include <highgui.h>
#ifdef _CH_
#pragma package <opencv>
#endif
#include <stdio.h>
#include <stdlib.h>
struct record//两个代表偏移
{
int up,down,left,right;//差距
unsigned char dataup;
unsigned char datadown;
unsigned char dataleft;
unsigned char dataright;// int **BT;
};//负责记录空间位置,和边界像素值//换成指针结构体?
IplImage* inpaint_mask = 0;
IplImage* img0 = 0;
IplImage* img = 0;
IplImage* inpainted = 0;
CvPoint prev_pt = {-1,-1};
unsigned char aver(unsigned char *data,unsigned char *bill,IplImage* masktt,int i,int j,int k,int step,int channels);
void scan(unsigned char *data,unsigned char *bill,IplImage* masktt,record *re,int i,int j,int k,int step,int channels);//分别扫描出左右上下最短距离赋给t采样
unsigned char biline(record *re,int wh,int i,int j);
double lagrange(double *x,double *y,double xx,int n);
double xlag(record re[],int i);
double ylag(record re[],int j);
void cvrepair(IplImage* img,IplImage* mask,IplImage* masktt);//img破坏图像,mask轨迹母板,masktt2值图像
void on_mouse( int event, int x, int y, int flags, void* zhang)
{
if( !img )
return;
if( event == CV_EVENT_LBUTTONUP || !(flags & CV_EVENT_FLAG_LBUTTON) )
prev_pt = cvPoint(-1,-1);
else if( event == CV_EVENT_LBUTTONDOWN )
prev_pt = cvPoint(x,y);
else if( event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON) )
{
CvPoint pt = cvPoint(x,y);
if( prev_pt.x < 0 )
prev_pt = pt;
cvLine( inpaint_mask, prev_pt, pt, cvScalarAll(255), 15, 8);
cvLine( img, prev_pt, pt, CV_RGB(0, 255, 0), 15, 8);
prev_pt = pt;
cvShowImage( "image", img );
}
}
int main()
{
char strIn[1024]; char strOut[1024];
cout<<"请输入原始图片路径:";
cin>>strIn;
//cout<<endl;
cout<<"请输入结果图片路径: ";
cin>>strOut;
if( (img0 = cvLoadImage(strIn,-1)) == 0 )
return 0;
printf( "Hot keys: \n"
"\tESC - quit the program\n"
"\tr - restore the original image\n"
"\ti or ENTER - run inpainting algorithm\n"
"\t\t(before running it, paint something on the image)\n" );
cvNamedWindow( "image", 1 );
img = cvCloneImage( img0 );
inpainted = cvCloneImage( img0 );
inpaint_mask = cvCreateImage( cvGetSize(img), 8, 1 );
cvZero( inpaint_mask );
cvZero( inpainted );
cvShowImage( "image", img );
//cvShowImage( "watershed transform", inpainted );
cvSetMouseCallback( "image", on_mouse, 0 );
for(;;)
{
int c = cvWaitKey(0);
if( (char)c == 27 )
break;
if( (char)c == 'r' )
{
cvZero( inpaint_mask );
cvCopy( img0, img,0 );
cvShowImage( "image", img );
}
if( (char)c == 'i' || (char)c == '\n' )
{
cvNamedWindow( "Mask image", 1 );
cvShowImage( "Mask image", inpaint_mask );
cvWaitKey(0);
cvNamedWindow( "inpainted image", 1 );
cvrepair( img, inpaint_mask,inpainted);
//cvInpaint( img, inpaint_mask, inpainted, 3, CV_INPAINT_TELEA );
cvShowImage( "inpainted image", inpainted );
cvSaveImage(strOut, inpainted);
}
}
return 1;
}
void cvrepair(IplImage* img,IplImage* mask,IplImage* inpainted)//img破坏图像,mask轨迹母板,masktt2值图像
{ int x=img->height;
int y=img->width;
int step=img->widthStep;
int channels=img->nChannels;
unsigned char *origin=(uchar *)inpainted->imageData;
unsigned char *data=(uchar *)img->imageData;
int i,j,k;
unsigned char *bill=(uchar *)mask->imageData;
for(i=0;i<x;i++)
for(j=0;j<y;j++)
{ for( k=0;k<channels;k++)
origin[i*step+j*channels+k]=data[i*step+j*channels+k];//原图
}
for(i=0;i<x;i++)//边界
{ for(j=0;j<y;j++)
{ if(bill[i*step+j*channels]==1)
{ for(k=0;k<channels;k++)
{ unsigned char buff=aver(origin,bill,mask,i,j,k,step,channels);
origin[i*step+j*channels+k]=buff;//像素点覆
}
}
}
}
}
unsigned char aver(unsigned char data[],unsigned char bill[],IplImage* masktt,int i,int j,int k,int step,int channels)
{ record re[2];
scan(data,bill,masktt,re,i,j,k,step,channels);//扫描采样->re
int len=re[1].down-re[1].up;
int lon=re[1].right-re[1].left;
int wh=len/(lon+len);//高宽比
return biline(re,wh,i,j);//目标还原像素值
}
void scan(uchar data[],uchar bill[],IplImage* masktt,record *re,int i,int j,int k,int step,int channels)//分别扫描出左右上下最短距离赋给t采样
{ int m,p,n,q;
int h=masktt->height;
int w=masktt->width;
for(m=0;m<i;m++)
{ if(bill[(i-m)*step+j*channels]==0)
{ if(m!=i)//上边界有像素 完成2个采样,边缘记0
{ re[1].dataup=data[(i-m)*step+j*channels+k];
re[1].up=m;//上边界第1个最近
if((bill[(i-m-1)*step+j*channels]==0)&&((m+1)!=i))
{ re[2].dataup=data[(i-m-1)*step+j*channels+k];re[2].up=m+1;}//上边界第2个最近
else{ re[2].dataup=0;re[2].up=i;}
}
else//上边界有像素破坏
{ re[1].up=i;re[1].dataup=0;
re[2].up=i;re[2].dataup=0;
}
printf("find up");break;
}
}
for(p=i;p<h;p++)
{ if(bill[p*step+j*channels]==0)
{ if(p!=h)//下边界有像素
{ re[1].datadown=data[p*step+j*channels+k];//下边界第1个最近
re[1].down=p;
if((bill[(p+1)*step+j*channels]==0)&&((p+1)!=h))
{ re[2].datadown=data[(p+1)*step+j*channels+k];re[2].down=p+1; }//下边界第2个最近
else{ re[2].datadown=0;re[2].down=h;}
}
else
{ re[1].down=h;re[1].datadown=0;
re[2].down=h;re[2].datadown=0;
}
printf("find down");break;
}
}
for(n=0;n<j;n++)
{ if(bill[i*step+(j-n)*channels]==0)
{ if(n!=j)//上边界有像素 完成2个采样,边缘记0
{ re[1].dataleft=data[i*step+(j-n)*channels+k];
re[1].left=n;//上边界第1个最近
if((bill[i*step+(j-n-1)*channels]==0)&&((n+1)!=j))
{ re[2].dataleft=data[i*step+(j-n-1)*channels+k];re[2].left=n+1;}//上边界第2个最近
else { re[2].dataleft=0;re[2].left=j;}
}
else//上边界有像素破坏
{ re[1].left=j;re[1].dataleft=0;
re[2].left=j;re[2].dataleft=0;
}
break;
}
}
for(q=j;q<w;q++)
{ if(bill[i*step+q*channels]==0)
{ if(q!=w)//下边界有像素
{ re[1].dataright=data[i*step+q*channels+k];//下边界第1个最近
re[1].right=q;
if((bill[i*step+(q+1)*channels]==0)&&((q+1)!=w))
{ re[2].dataright=data[i*step+(q+1)*channels+k];re[2].right=q+1; }//下边界第2个最近
else{ re[2].dataright=0;re[2].right=w;}
}
else
{ re[1].right=w;re[1].dataright=0;
re[2].right=w;re[2].dataright=0;
}
break;
}
}
}
unsigned char biline(record *re,int wh,int i,int j)//双线性插值算法
{ double temp=(double)wh*ylag(re,j)+(double)(1-wh)*xlag(re,i);//强制转型
return (uchar)temp;
}
double ylag(record re[],int j)
{ double x[3],y[3];
x[0]=re[2].left;y[0]=re[2].dataleft;
x[1]=re[1].left;y[1]=re[1].dataleft;
x[2]=re[1].left;y[2]=re[1].dataleft;
x[3]=re[2].left;y[3]=re[2].dataleft;
return lagrange(x,y,j,4);
}
double xlag(record re[],int i)
{ double x[3],y[3];
x[0]=re[2].up;y[0]=re[2].dataup;
x[1]=re[1].up;y[1]=re[1].dataup;
x[2]=re[1].down;y[2]=re[1].datadown;
x[3]=re[2].down;y[3]=re[2].datadown;
return lagrange(x,y,i,4);
}
double lagrange(double *x,double *y,double xx,int n) /*拉格朗日插值算法*/
{ int i,j;
double *a,yy=0.0; /*a作为临时变量,记录拉格朗日插值多项式*/
a=(double *)malloc(n*sizeof(double));
for(i=0;i<=n-1;i++)
{ a[i]=y[i];
for(j=0;j<=n-1;j++)
if(j!=i) a[i]*=(xx-x[j])/(x[i]-x[j]);
yy+=a[i];
}
free(a);
return yy;
}
然后在调试的时候报错
unhandled exception in tss3.exe:0xC0000005:Access Violation.
停下的位置在scan()函数里的
for(p=i;p<h;p++)
{ if(bill[p*step+j*channels]==0)
{ if(p!=h)//下边界有像素
{ re[1].datadown=data[p*step+j*channels+k];//下边界第1个最近
re[1].down=p;
if((bill[(p+1)*step+j*channels]==0)&&((p+1)!=h))
{ re[2].datadown=data[(p+1)*step+j*channels+k];re[2].down=p+1; }//下边界第2个最近
else{ re[2].datadown=0;re[2].down=h;}
}
else
{ re[1].down=h;re[1].datadown=0;
re[2].down=h;re[2].datadown=0;
}
printf("find down");break;
}
}
的第二次循环
时间比较紧迫所以就不等了