📄 imageprocess.cpp
字号:
{
InputImage[i] = 0;
}
}
if(r != NULL) delete []r;
if(mid != NULL) delete []mid;
}
void Image_SUSAN_Principle(BYTE* InputImage , int ImgW , int ImgH ,int bt)
{
int Imagesize = ImgW*ImgH;
if (InputImage==NULL || Imagesize==0) return ;
int i, j, n, max_no=1850;
int Width=ImgW, Height=ImgH;
int *r =new int[Imagesize];
BYTE *mid = new BYTE[Imagesize];
BYTE *in=InputImage;
BYTE *p,*cp,*bp,bbp[516];
double temp;
bbp[0]=bbp[1]=bbp[515]=bbp[514]=0;
bp=bbp+258;
for(int k=-256;k<257;k++)
{
temp=((float)k)/((float)bt);
temp=temp*temp;
temp=temp*temp*temp;
temp=100.0*exp(-temp)+0.5;
bbp[k+258] = (BYTE)(temp);
}
memset (mid,100,Width*Height);
memset (r,0,Width*Height * sizeof(int));
for(i=3;i<Height-3;i++)
for(j=3;j<Width-3;j++)
{
n=100;
p=in + (i-3)*Width + j - 1;
cp=bp + in[i*Width+j];
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p);
p+=Width-3;
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p);
p+=Width-5;
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p);
p+=Width-6;
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p);
p+=2;
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p);
p+=Width-6;
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p);
p+=Width-5;
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p);
p+=Width-3;
n+=*(cp-*p++);
n+=*(cp-*p++);
n+=*(cp-*p);
if (n<=max_no)
r[i*Width+j] = max_no - n;
}
int_to_uchar(r,InputImage,Imagesize);
/*int max_r=r[0];
int min_r=r[0];
for (i=1; i<Imagesize; i++)
{
if ( r[i] > max_r )
max_r=r[i];
if ( r[i] < min_r )
min_r=r[i];
}
max_r-=min_r;
if(max_r!=0)
{
for (i=0; i<Imagesize; i++)
{
temp=(r[i]-min_r)*255.0/max_r+0.5;
InputImage[i] = (BYTE)(temp);
}
}//*/
if(mid!=NULL) delete []mid;
if(r!=NULL) delete []r;
}
//***********************************************************
//函数类别: 图像的边缘细化
//函数名称:
// Image_SUSAN_Edge_Normal
//函数用途:
// 被Image_SUSAN_Edge_Normal函数调用;
//
//参数说明:
// int *r 图像的对象指针
// int x_size
// int y_size
// BYTE *mid 边缘信息的输出的指针
//说 明:
// 利用SUSAN边缘检测的原理编制的
//原始作者: 陆宏伟
//原始日期: 3/20/1999
//***********************************************************
void Image_SUSAN_thin(int *r,BYTE *mid,int x_size,int y_size)
{
int l[9], centre,
b01, b12, b21, b10,
p1, p2, p3, p4,
b00, b02, b20, b22,
m, n, a, b, x, y, i, j;
BYTE *mp;
for(i=4; i<y_size-4; i++)
{
for(j=4; j<x_size-4; j++)
{
if (mid[i*x_size+j]<8)
{
centre = r[i*x_size+j];
// count number of neighbours
mp=mid + (i-1)*x_size + j-1;
n = (*mp<8) +
(*(mp+1)<8) +
(*(mp+2)<8) +
(*(mp+x_size)<8) +
(*(mp+x_size+2)<8) +
(*(mp+x_size+x_size)<8) +
(*(mp+x_size+x_size+1)<8) +
(*(mp+x_size+x_size+2)<8);
// n==0 no neighbours - remove point
if (n==0)
mid[i*x_size+j]=100;
// n==1 - extend line if I can
// extension is only allowed a few times - the value of mid is used to control this */
if ( (n==1) && (mid[i*x_size+j]<6) )
{
/* find maximum neighbour weighted in direction opposite the
neighbour already present. e.g.
have: O O O weight r by 0 2 3
X X O 0 0 4
O O O 0 2 3 //*/
l[0]=r[(i-1)*x_size+j-1]; l[1]=r[(i-1)*x_size+j]; l[2]=r[(i-1)*x_size+j+1];
l[3]=r[(i )*x_size+j-1]; l[4]=0; l[5]=r[(i )*x_size+j+1];
l[6]=r[(i+1)*x_size+j-1]; l[7]=r[(i+1)*x_size+j]; l[8]=r[(i+1)*x_size+j+1];
if (mid[(i-1)*x_size+j-1]<8) { l[0]=0; l[1]=0; l[3]=0; l[2]*=2;
l[6]*=2; l[5]*=3; l[7]*=3; l[8]*=4; }
else { if (mid[(i-1)*x_size+j]<8) { l[1]=0; l[0]=0; l[2]=0; l[3]*=2;
l[5]*=2; l[6]*=3; l[8]*=3; l[7]*=4; }
else { if (mid[(i-1)*x_size+j+1]<8) { l[2]=0; l[1]=0; l[5]=0; l[0]*=2;
l[8]*=2; l[3]*=3; l[7]*=3; l[6]*=4; }
else { if (mid[(i)*x_size+j-1]<8) { l[3]=0; l[0]=0; l[6]=0; l[1]*=2;
l[7]*=2; l[2]*=3; l[8]*=3; l[5]*=4; }
else { if (mid[(i)*x_size+j+1]<8) { l[5]=0; l[2]=0; l[8]=0; l[1]*=2;
l[7]*=2; l[0]*=3; l[6]*=3; l[3]*=4; }
else { if (mid[(i+1)*x_size+j-1]<8) { l[6]=0; l[3]=0; l[7]=0; l[0]*=2;
l[8]*=2; l[1]*=3; l[5]*=3; l[2]*=4; }
else { if (mid[(i+1)*x_size+j]<8) { l[7]=0; l[6]=0; l[8]=0; l[3]*=2;
l[5]*=2; l[0]*=3; l[2]*=3; l[1]*=4; }
else { if (mid[(i+1)*x_size+j+1]<8) { l[8]=0; l[5]=0; l[7]=0; l[6]*=2;
l[2]*=2; l[1]*=3; l[3]*=3; l[0]*=4; } }}}}}}}
// find the highest point
for(m=0,y=0; y<3; y++)
for(x=0; x<3; x++)
if (l[y+y+y+x]>m) { m=l[y+y+y+x]; a=y; b=x; }
if (m>0)
{
if (mid[i*x_size+j]<4)
mid[(i+a-1)*x_size+j+b-1] = 4;
else
mid[(i+a-1)*x_size+j+b-1] = mid[i*x_size+j]+1;
if ( (a+a+b) < 3 ) // need to jump back in image
{
i+=a-1;
j+=b-2;
if (i<4) i=4;
if (j<4) j=4;
}
}
}
if (n==2)
{
// put in a bit here to straighten edges
b00 = mid[(i-1)*x_size+j-1]<8; // corners of 3x3
b02 = mid[(i-1)*x_size+j+1]<8;
b20 = mid[(i+1)*x_size+j-1]<8;
b22 = mid[(i+1)*x_size+j+1]<8;
if ( ((b00+b02+b20+b22)==2) && ((b00|b22)&(b02|b20)))
{ /* case: move a point back into line.
e.g. X O X CAN become X X X
O X O O O O
O O O O O O //*/
if (b00)
{
if (b02) { x=0; y=-1; }
else { x=-1; y=0; }
}
else
{
if (b02) { x=1; y=0; }
else { x=0; y=1; }
}
if (((float)r[(i+y)*x_size+j+x]/(float)centre) > 0.7)
{
if ( ( (x==0) && (mid[(i+(2*y))*x_size+j]>7) && (mid[(i+(2*y))*x_size+j-1]>7) && (mid[(i+(2*y))*x_size+j+1]>7) ) ||
( (y==0) && (mid[(i)*x_size+j+(2*x)]>7) && (mid[(i+1)*x_size+j+(2*x)]>7) && (mid[(i-1)*x_size+j+(2*x)]>7) ) )
{
mid[(i)*x_size+j]=100;
mid[(i+y)*x_size+j+x]=3; // no jumping needed
}
}
}
else
{
b01 = mid[(i-1)*x_size+j ]<8;
b12 = mid[(i )*x_size+j+1]<8;
b21 = mid[(i+1)*x_size+j ]<8;
b10 = mid[(i )*x_size+j-1]<8;
// right angle ends - not currently used
#ifdef IGNORETHIS
if ( (b00&b01)|(b00&b10)|(b02&b01)|(b02&b12)|(b20&b10)|(b20&b21)|(b22&b21)|(b22&b12) )
{ /* case; right angle ends. clean up.
e.g.; X X O CAN become X X O
O X O O O O
O O O O O O //*/
if ( ((b01)&(mid[(i-2)*x_size+j-1]>7)&(mid[(i-2)*x_size+j]>7)&(mid[(i-2)*x_size+j+1]>7)&
((b00&((2*r[(i-1)*x_size+j+1])>centre))|(b02&((2*r[(i-1)*x_size+j-1])>centre)))) |
((b10)&(mid[(i-1)*x_size+j-2]>7)&(mid[(i)*x_size+j-2]>7)&(mid[(i+1)*x_size+j-2]>7)&
((b00&((2*r[(i+1)*x_size+j-1])>centre))|(b20&((2*r[(i-1)*x_size+j-1])>centre)))) |
((b12)&(mid[(i-1)*x_size+j+2]>7)&(mid[(i)*x_size+j+2]>7)&(mid[(i+1)*x_size+j+2]>7)&
((b02&((2*r[(i+1)*x_size+j+1])>centre))|(b22&((2*r[(i-1)*x_size+j+1])>centre)))) |
((b21)&(mid[(i+2)*x_size+j-1]>7)&(mid[(i+2)*x_size+j]>7)&(mid[(i+2)*x_size+j+1]>7)&
((b20&((2*r[(i+1)*x_size+j+1])>centre))|(b22&((2*r[(i+1)*x_size+j-1])>centre)))) )
{
mid[(i)*x_size+j]=100;
if (b10&b20) j-=2;
if (b00|b01|b02) { i--; j-=2; }
}
}
#endif
if ( ((b01+b12+b21+b10)==2) && ((b10|b12)&(b01|b21)) && ((b01&((mid[(i-2)*x_size+j-1]<8)|(mid[(i-2)*x_size+j+1]<8)))|(b10&((mid[(i-1)*x_size+j-2]<8)|(mid[(i+1)*x_size+j-2]<8)))|(b12&((mid[(i-1)*x_size+j+2]<8)|(mid[(i+1)*x_size+j+2]<8)))|(b21&((mid[(i+2)*x_size+j-1]<8)|(mid[(i+2)*x_size+j+1]<8)))) )
{ /* case; clears odd right angles.
e.g.; O O O becomes O O O
X X O X O O
O X O O X O //*/
mid[(i)*x_size+j]=100;
i--; // jump back
j-=2;
if (i<4) i=4;
if (j<4) j=4;
}
}
}// end of if (n==2)
// n>2 the thinning is done here without breaking connectivity
if (n>2)
{
b01 = mid[(i-1)*x_size+j ]<8;
b12 = mid[(i )*x_size+j+1]<8;
b21 = mid[(i+1)*x_size+j ]<8;
b10 = mid[(i )*x_size+j-1]<8;
if((b01+b12+b21+b10)>1)
{
b00 = mid[(i-1)*x_size+j-1]<8;
b02 = mid[(i-1)*x_size+j+1]<8;
b20 = mid[(i+1)*x_size+j-1]<8;
b22 = mid[(i+1)*x_size+j+1]<8;
p1 = b00 | b01;
p2 = b02 | b12;
p3 = b22 | b21;
p4 = b20 | b10;
if( ((p1 + p2 + p3 + p4) - ((b01 & p2)+(b12 & p3)+(b21 & p4)+(b10 & p1))) < 2)
{
mid[(i)*x_size+j]=100;
i--;
j-=2;
if (i<4) i=4;
if (j<4) j=4;
}
}
}//end of if (n>2)
}//end of if (mid[i*x_size+j]<8)
}//end of for(j=4; j<x_size-4; j++)
}//end of for(i=4; i<y_size-4; i++)
}
BOOL Image_Binary_HoughTransform(BYTE* InputImage , int ImgW , int ImgH ,BYTE TargetGray)
{
int Imagesize=ImgW*ImgH;
if (InputImage==NULL || Imagesize==0) return FALSE;
int i,j;
int *Hough = new int[Imagesize];
int **TargetRowAddress = new int*[ImgH];
BYTE **SourceRowAddress = new BYTE*[ImgH];
//initialize
memset(Hough, 0, Imagesize*sizeof(int));
SourceRowAddress[0] = InputImage;
TargetRowAddress[0] = Hough;
for(i=1 ; i<ImgH ;i++)
{
SourceRowAddress[i] = SourceRowAddress[i-1] + ImgW;
TargetRowAddress[i] = TargetRowAddress[i-1] + ImgW;
}
double theta, dtheta = 2*3.1415926/ImgW;
CProgressDlg * MsgHandler = new CProgressDlg();
MsgHandler->Create(NULL);
MsgHandler->SetStatus("Binary Hough Transform Process");
int nG, angle;
for(j=0; j<ImgH; j++)
{
for(i=0; i<ImgW; i++)
{
if(SourceRowAddress[j][i]==TargetGray)
{
for(theta=0.0,angle=0;angle<ImgW;angle++)
{
nG=int(i*cos(theta)+j*sin(theta) + 0.5);
if(nG>=0&&nG<ImgH)
TargetRowAddress[nG][angle]++;
theta += dtheta;
}
}
}
MsgHandler->SetPos(100 * j /ImgH );
if(MsgHandler->m_bCancel) break;
}
if(!MsgHandler->m_bCancel)
int_to_uchar(Hough,InputImage,Imagesize);
if(Hough!=NULL) delete []Hough;
if(TargetRowAddress!=NULL) delete []TargetRowAddress;
if(SourceRowAddress!=NULL) delete []SourceRowAddress;
MsgHandler->DestroyWindow();
delete MsgHandler;
return TRUE;
}
BOOL Image_Binary_RadonTransform(BYTE* InputImage , int ImgW , int ImgH ,BYTE TargetGray)
{
int Imagesize=ImgW*ImgH;
if (InputImage==NULL || Imagesize==0) return FALSE;
int i, x0=ImgW/2,y0=ImgH/2,x ;
int *Hough = new int[Imagesize];
int **TargetRowAddress = new int*[ImgH];
BYTE **SourceRowAddress = new BYTE*[ImgH];
//initialize
memset(Hough, 0, Imagesize*sizeof(int));
SourceRowAddress[0] = InputImage;
TargetRowAddress[0] = Hough;
for(i=1 ; i<ImgH ;i++)
{
SourceRowAddress[i] = SourceRowAddress[i-1] + ImgW;
TargetRowAddress[i] = TargetRowAddress[i-1] + ImgW;
}
double theta, dtheta = 2*PI/ImgH;
double *LutSin = new double[ImgH];
double *LutCos = new double[ImgH];
BYTE *lpTmp, *bTest = new BYTE[ImgH+ImgW];
for(theta=0.0, i=0; i<ImgH; i++)
{
LutCos[i] = cos(theta);
LutSin[i] = sin(theta);
theta += dtheta;
}
int angle, length , wx, wy;
double rx, ry;
CProgressDlg * MsgHandler = new CProgressDlg();
MsgHandler->Create(NULL);
MsgHandler->SetStatus("Binary Radon Transform Process");
for(angle=0;angle<ImgH;angle++)
{
for(i=0; i<ImgW; i++)
{
x = i/2;
rx = x*LutCos[angle];
ry = x*LutSin[angle];
length = int(sqrt(x0*x0 - x*x));
lpTmp = bTest;
memset(bTest, 0, ImgH+ImgW);
for(int r=-length; r<=length; r++)
{
wx = int(rx - r*LutSin[angle] + x0 + 0.5);
wy = int(ry + r*LutCos[angle] + y0 + 0.5);
if(wx>=0&&wx<ImgW&&wy>=0&&wy<ImgH)
{
if(SourceRowAddress[wy][wx]==TargetGray)
*lpTmp = 1;
}
lpTmp++;
}
int templength , step =40 , number , threshold, k, iLineIntegral;
templength = 2*(length+1);
threshold = int(step*0.75);
lpTmp = bTest;
for(iLineIntegral =0, r=0; r<templength; r+=step)
{
for(number=0, k=0; k<step; k++)
{
if(*lpTmp++) number++;
}
if(number>threshold) iLineIntegral += number;
}
TargetRowAddress[angle][i] = iLineIntegral;
}
MsgHandler->SetPos(100 * angle /ImgH );
if(MsgHandler->m_bCancel) break;
}
if(!MsgHandler->m_bCancel) int_to_uchar(Hough,InputImage,Imagesize);
if(bTest !=NULL) delete []bTest;
if(Hough !=NULL) delete []Hough;
if(LutSin!=NULL) delete []LutSin;
if(LutCos!=NULL) delete []LutCos;
if(TargetRowAddress!=NULL) delete []TargetRowAddress;
if(SourceRowAddress!=NULL) delete []SourceRowAddress;
MsgHandler->DestroyWindow();
delete MsgHandler;
return TRUE;
}
//***********************************************************
//函数类别: 二值图像的处理
//函数名称:
// Image_Binary_Erosion
//函数用途:
// 进行二值图腐蚀运算
//
//参数说明:
//调用函数:
//
//被调函数:
// some function , at all, I don't know
//原始作者: 陆宏伟
//原始日期: 21/4/1999
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -