📄 vlimageproc.cpp
字号:
return (-1); /* failure */
}
for (i = 0; i < 256;i++)
{
lHistogram[i]=0;
}
iMaxGrayValue = 0;
iMinGrayValue = 255;
/* temp variables to optimize memory access */
width = src->width;
x1 = window->x;
x2 = x1 + (window->width);
y1 = window->y;
y2 = y1 + (window->height);
input = src->pixel;
output = dest->pixel;
/* proceed to get the Histogram */
for (j=y1; j<y2; j++)
{
for (i=x1; i<x2; i++)
{
index = VL_GRAY_PIXEL * (j*width + i);
pixel = input[index];
lHistogram[pixel]++;
if(iMinGrayValue > pixel)
iMinGrayValue = pixel;
if(iMaxGrayValue < pixel)
iMaxGrayValue = pixel;
}
}
//iteration for the iThreshold
iNewThreshold = (iMinGrayValue + iMaxGrayValue)/2;
iThreshold = 0;
for(iIterationTimes = 0; iThreshold != iNewThreshold && iIterationTimes < 100;iIterationTimes ++)
{
iThreshold = iNewThreshold;
lP1 =0;
lP2 =0;
lS1 = 0;
lS2 = 0;
//get the mean Gray value for the two parts
for (i = iMinGrayValue;i < iThreshold;i++)
{
lP1 += lHistogram[i]*i;
lS1 += lHistogram[i];
}
iMean1GrayValue = (unsigned char)(lP1 / lS1);
for (i = iThreshold+1;i < iMaxGrayValue;i++)
{
lP2 += lHistogram[i]*i;
lS2 += lHistogram[i];
}
iMean2GrayValue = (unsigned char)(lP2 / lS2);
iNewThreshold = (iMean1GrayValue + iMean2GrayValue)/2;
}
/* depart the image by iThreshold */
for (j=y1; j<y2; j++)
{
for (i=x1; i<x2; i++)
{
index = VL_GRAY_PIXEL * (j*width + i);
if(input[index] > iThreshold)
output[index] = 255;
else
output[index] = 0;
}
}
return (0); /* success */
}
/*************************************************************************
*
* Function Name:
* vlEdgedetect()
*
* Paremetres:
* CvlImage *src - pointer to src GRAY image
* CvlWindow *window - compute area(a rectangle)
* CvlImage *dest - pointer to dest GRAY image(it can be src GRAY image)
*
* return:
* int - sucess 0,else -1.
*
* Remarks:
* This function is used for detecting the edges of a two_GRAY_value image.
*
************************************************************************/
int CvlImageProc::vlEdgedetect (CvlImage *src, CvlWindow *window, CvlImage *dest)
{
int i, j;
int index, width;
int x1, x2, y1, y2;
vlPixel *input;
vlPixel *output;
vlPixel *temp;//hold the temp results
int tempindex;
vlPixel nw,n,ne,w,e,sw,s,se;//8 points around one point
/* verify parameters */
if ((!src) || (!window) || (!dest)) {
MessageBox(NULL,"one of the parameters is NULL\n","warnning",MB_OK);
return (-1); /* failure */
}
/* make sure we have a RGB picture */
if (src->format != GRAY) {
MessageBox(NULL,"src image is not GRAY\n","warnning",MB_OK);
return (-1); /* failure */
}
/* temp variables to optimize memory access */
width = src->width;
x1 = window->x;
x2 = x1 + (window->width);
y1 = window->y;
y2 = y1 + (window->height);
input = src->pixel;
output = dest->pixel;
temp = new vlPixel [(window->width)*(window->height)];
tempindex = -1;
/* proceed to conversion */
for (j=y1; j<y2; j++)
{
for (i=x1; i<x2; i++)
{
tempindex++;
if(i==0||j==0||i==src->width||j==src->width)
continue;
index = VL_GRAY_PIXEL * (j*width + i);
nw = input[index+width-1];
n = input[index+width];
ne = input[index+width+1];
w = input[index-1];
e = input[index+1];
sw = input[index-width-1];
s = input[index-width];
se = input[index-width+1];
if(nw+n+ne+w+e+sw+s+se==0)
temp[tempindex]=255;
else
temp[tempindex]=input[index];
}
}
tempindex = 0;
for (j=y1; j<y2; j++)
{
for (i=x1; i<x2; i++)
{
index = VL_GRAY_PIXEL * (j*width + i);
output[index]=temp[tempindex];
tempindex++;
}
}
delete [] temp;//release memory.
return (0); /* success */
}
//连续轮廓搜索函数
int searchedge(vlPixel * input, vlPixel * output, int x1, int x2, int y1, int y2, int j,int i,int Width,int K)
{
int Top=1;
loop:
CPoint *Stack=new CPoint[10000];//I think it's enough
if(Stack==NULL)
goto loop;
Stack->x=j;
Stack->y=i;
int Res=1;//
int I,J;
while(Top!=0)
{
Top--;
I=(Stack+Top)->y;
J=(Stack+Top)->x;
*(output+I*Width+J)=K;
*(input+I*Width+J)=255;
if(I>=y1&&I<y2&&J-1>=x1&&J-1<x2&&*(input+I*Width+J-1)==0)
{
(Stack+Top)->y=I;
(Stack+Top)->x=J-1;
*(input+I*Width+J-1)=255;
*(output+I*Width+J-1)=K;
Res++;
Top++;
}
if(I>=y1&&I<y2&&J+1>=x1&&J+1<x2&&*(input+I*Width+J+1)==0)
{
(Stack+Top)->y=I;
(Stack+Top)->x=J+1;
*(input+I*Width+J+1)=255;
*(output+I*Width+J+1)=K;
Res++;
Top++;
}
if(I-1>=y1&&I-1<y2&&J>=x1&&J<x2&&*(input+(I-1)*Width+J)==0)
{
(Stack+Top)->y=I-1;
(Stack+Top)->x=J;
*(input+(I-1)*Width+J)=255;
*(output+(I-1)*Width+J)=K;
Res++;
Top++;
}
if(I+1>=y1&&I+1<y2&&J>=x1&&J<x2&&*(input+(I+1)*Width+J)==0)
{
(Stack+Top)->y=I+1;
(Stack+Top)->x=J;
*(input+(I+1)*Width+J)=255;
*(output+(I+1)*Width+J)=K;
Res++;
Top++;
}
if(I-1>=y1&&I-1<y2&&J-1>=x1&&J-1<x2&&*(input+(I-1)*Width+J-1)==0)
{
(Stack+Top)->y=I-1;
(Stack+Top)->x=J-1;
*(input+(I-1)*Width+J-1)=255;
*(output+(I-1)*Width+J-1)=K;
Res++;
Top++;
}
if(I-1>=y1&&I-1<y2&&J+1>=x1&&J+1<x2&&*(input+(I-1)*Width+J+1)==0)
{
(Stack+Top)->y=I-1;
(Stack+Top)->x=J+1;
*(input+(I-1)*Width+J+1)=255;
*(output+(I-1)*Width+J+1)=K;
Res++;
Top++;
}
if(I+1>=y1&&I+1<y2&&J-1>=x1&&J-1<x2&&*(input+(I+1)*Width+J-1)==0)
{
(Stack+Top)->y=I+1;
(Stack+Top)->x=J-1;
*(input+(I+1)*Width+J-1)=255;
*(output+(I+1)*Width+J-1)=K;
Res++;
Top++;
}
if(I+1>=y1&&I+1<y2&&J+1>=x1&&J+1<x2&&*(input+(I+1)*Width+J+1)==0)
{
(Stack+Top)->y=I+1;
(Stack+Top)->x=J+1;
*(input+(I+1)*Width+J+1)=255;
*(output+(I+1)*Width+J+1)=K;
Res++;
Top++;
}
}
delete []Stack;
return Res;
}
/*************************************************************************
*
* Function Name:
* vlCircleHough()
*
* Paremetres:
* CvlImage *src - pointer to src GRAY image
* CvlWindow *window - compute area(a rectangle)
* CvlImage *dest - pointer to dest GRAY image(it can be src GRAY image)
*
* return:
* int - sucess 0,else -1.
*
* Remarks:
* This function is used for Circle detection with Hough translation.
*
************************************************************************/
int CvlImageProc::vlCircleHough(CvlImage *src, CvlWindow *window, CvlImage *dest, int dmin, int dmax)
{
int i, j;
int index, width;
int x1, x2, y1, y2;
vlPixel *input;
vlPixel *output;
int linepoints[30];//Please filt the noise first to make sure the apart lines less then 30
for(i=0; i<30; i++)
linepoints[i]=0;
/* verify parameters */
if ((!src) || (!window) || (!dest)) {
MessageBox(NULL,"one of the parameters is NULL\n","warnning",MB_OK);
return (-1); /* failure */
}
/* make sure we have a RGB picture */
if (src->format != GRAY) {
MessageBox(NULL,"src image is not GRAY\n","warnning",MB_OK);
return (-1); /* failure */
}
/* temp variables to optimize memory access */
width = src->width;
x1 = window->x;
x2 = x1 + (window->width);
y1 = window->y;
y2 = y1 + (window->height);
input = src->pixel;
output = dest->pixel;
/* find the different connected lines and the number of their points */
int linenum=0;
for (j=y1; j<y2; j++)
{
for (i=x1; i<x2; i++)
{
index = VL_GRAY_PIXEL * (j*width + i);
if(input[index]==0)
{
linepoints[linenum]=searchedge(input,output,x1,x2,y1,y2,i,j,width,linenum);
linenum++;
}
}
}
//do fast hough translation on the selected lines, find the real objects and their number
int fixstep,count=5;//step--departure among 3 points; count--round times
int step;
int x_K,y_K,x_L,y_L,x_M,y_M;//three points on the line(circle)
int *a,*b;//the centre of the circle
int *r;//the radius of the circle
int *C;//count different (a,b,r)
int at,bt,rt;//temp (a,b,r)
double k_KL,k_LM,d_KL,d_LM;//slopes and intercepts
int N;//number of different (a,b,r)
int MAX;//the most likely number of (a,b,r)
int TH;//the threshold to judge whether the Circle is a real one
int found=0;//found the same (a,b,r)?
objectnum = 0;
int k,l;
int stack[700];//enough for a circle with the diameter less than 200 pixels
for (k=0; k<linenum; k++)
{
if(linepoints[k]<(int)(4*dmax)&&linepoints[k]>(int)(3.14*dmin))
{
//find the first point of line[k]
for(j=y1; j<y2; j++)
for(i=x1; i<x2; i++)
{
index = VL_GRAY_PIXEL * (j*width + i);
if(output[index]==k)
{
i=x2;
j=y2;
}//force it to escape from the circulation
}
stack[0]=index;
//search withershins to push all the points into the stack
for(i=1;i<linepoints[k];i++)
{
int before;//the point before
if(i==1)
before=stack[0];
else
before=stack[i-2];
if (output[stack[i-1]+1]==k && stack[i-1]+1 != before)//e
{
stack[i]=stack[i-1]+1;
if(stack[i]==index)
break;
continue;
}
if (output[stack[i-1]+width+1]==k && stack[i-1]+width+1 != before)//ne
{
stack[i]=stack[i-1]+width+1;
if(stack[i]==index)
break;
continue;
}
if (output[stack[i-1]+width]==k && stack[i-1]+width != before)//n
{
stack[i]=stack[i-1]+width;
if(stack[i]==index)
break;
continue;
}
if (output[stack[i-1]+width-1]==k && stack[i-1]+width-1 != before)//nw
{
stack[i]=stack[i-1]+width-1;
if(stack[i]==index)
break;
continue;
}
if (output[stack[i-1]-1]==k && stack[i-1]-1 != before)//w
{
stack[i]=stack[i-1]-1;
if(stack[i]==index)
break;
continue;
}
if (output[stack[i-1]-width-1]==k && stack[i-1]-width-1 != before)//sw
{
stack[i]=stack[i-1]-width-1;
if(stack[i]==index)
break;
continue;
}
if (output[stack[i-1]-width]==k && stack[i-1]-width != before)//s
{
stack[i]=stack[i-1]-width;
if(stack[i]==index)
break;
continue;
}
if (output[stack[i-1]-width+1]==k && stack[i-1]-width+1 != before)//se
{
stack[i]=stack[i-1]-width+1;
if(stack[i]==index)
break;
continue;
}
break;
}//now the variable i is the points' number around
//do the fast hough translation based on the 3 points departed by fixed steps
a = new int [i*count/3];
b = new int [i*count/3];
r = new int [i*count/3];
C = new int [i*count/3];
N = 0;
fixstep=i/8;
for (step=fixstep; step<fixstep+count; step++)
for(j=0; j<i-step*2; j++)
{
x_K = stack[j]%width;
y_K = stack[j]/width;
x_L = stack[j+step]%width;
y_L = stack[j+step]/width;
x_M = stack[j+step*2]%width;
y_M = stack[j+step*2]/width;
k_KL= -(double)(x_K-x_L)/(double)(y_K-y_L);
d_KL= (double)(y_K+y_L - (x_K+x_L)*k_KL)/2;
k_LM= -(double)(x_L-x_M)/(double)(y_L-y_M);
d_LM= (double)(y_L+y_M - (x_L+x_M)*k_LM)/2;
at = (int)((d_LM-d_KL)/(k_KL-k_LM));
bt = (int)(k_KL*at+d_KL);
rt = (int)sqrt((x_L-at)*(x_L-at) + (y_L-bt)*(y_L-bt));
if(N==0)
{
a[N]=at;
b[N]=bt;
r[N]=rt;
C[N]=1;
N++;
}
else
{
for (l=0; l<N; l++)
{
if(at==a[l]&&bt==b[l]&&rt==r[l])
{
C[l]++;
found=1;
break;
}
else
found=0;
}
if(found==0)
{
a[N]=at;
b[N]=bt;
r[N]=rt;
C[N]=1;
N++;
}
}
if(j%step==step-1)
j+=step*2;
}
//select the most likely circle
MAX = 0;
for (l=0; l<N; l++)
if(C[MAX]<C[l])
MAX=l;
TH = (i*count/3)/20;
if (C[MAX]>TH&&r[MAX]>10&&r[MAX]<30)
{
objectcoordinates[objectnum][0] = a[MAX];
objectcoordinates[objectnum][1] = b[MAX];
objectr[objectnum] = r[MAX];
objectnum++;
}
if (objectnum==12)
break;
delete [] a;
delete [] b;
delete [] r;
delete [] C;
}
}
return (0); /* success */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -