⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 contourtrack.c

📁 本下载文件是《C/C++图像处理编程》一书的演示程序
💻 C
字号:
//    Ex11
//  轮廓跟踪
 
#include <windows.h>
#include "image32.h"
#include "stdio.h"

extern HDC	  hMemDC;
extern struct IMAGE	*image;
extern struct IMAGE *Image[10];
  
void ColorToGray(int m,int n);                                            //  变灰阶
void histog(struct IMAGE *image,long *pg,int Xs, int Ys, int Dx, int Dy);
int  Otsu(long *pg,long *pg1);                     
void GT_Threshold(struct IMAGE *image,int x,int y,int Dx,int Dy,int thre);
 
#define		MAX_DOTN	5000

extern long  pg[256],pg1[256];
extern int   T_gray[256],thre_v;

HWND     hwnd;
int      fff,number,fmax,fmin;
long     sss;
double   factor;
int      *code;
struct   DOT *dot;
BYTE     ThreTable[256];
int      code_n,dot_n;
int      inc[8][2] = { {+1, 0},{+1,-1},{ 0,-1},{-1,-1},
                       {-1, 0},{-1,+1},{ 0,+1},{+1,+1}  };
int      Trx1,Try1,Trx2,Try2;

void set_thre(int track_f, int isr)         //  设置阈值标志和阈值
{            	     
   int  k;

   for (k=0;k<256;k++) {
      if (track_f==0) {
	 if (k>isr) ThreTable[k]=0;
	 else       ThreTable[k]=1;
      }
      else {
	 if (k<isr) ThreTable[k]=0;
	 else       ThreTable[k]=1;
      }
   }
}

void delay(int n)           //  延时子程序,延时 n 毫秒
{
   DWORD  StartTime,CurrentTime,m;
 
   StartTime=GetTickCount();
   do {
      CurrentTime=GetTickCount();
      m=(CurrentTime-StartTime);
   }
   while((int) m<n);
}

void DrawDot(int x,int y,DWORD c)
{
   HDC  hDC;

   hDC = GetDC(hwnd);
   SetPixel(hDC,x,y,c);
   ReleaseDC(hwnd,hDC);
   delay(5);
}

int  SingleTrack(struct IMAGE *image,int i, int j, int iop, int *code)
{                                                 //  区域边界跟踪
   int  kw,code_n;
   int  curr[2],next[2]; 
   int  n,n1;
   int  ki,kj,inv,ns,ne;
  
   code[0]=i;    code[1]=j;
   code_n=3;	               

   curr[0]=i;    curr[1]=j;	   
   code[3]=-1;
   do {
      kw=0;	                   
      ns=iop;    ne=ns-8;      
      for (n=ns;n>ne;n--) {   
	     n1 = (n+8) % 8;	  
	     ki=curr[0]+inc[n1][0];
 	     kj=curr[1]+inc[n1][1];
         if ((ki>=Trx1)&&(kj>=Try1)&&(ki<=Trx2)&&(kj<=Try2)) {	
		    inv = getpixel(image,ki, kj);  
	        if (ThreTable[inv]==1) break;	
		 }
	  }
      if (n!=ne) {
	     next[0]=ki;  next[1]=kj;
	     iop=n1;	             
		 DrawDot(ki,kj,0x00ff0000);
	  }
      else  kw = 1;
  
      if ((curr[0]==i)&&(curr[1]==j)&&(iop==code[3]))  break;
      code[code_n++]=iop;	  
      curr[0]=next[0];   curr[1]=next[1];
      if (iop%2) iop++;                  
      iop=(iop+1)%8;	              
   }
   while(kw==0);	                  

   code[2]=code_n-3;	     
   return(code_n-3);
}

int CodeToTable(int *code,struct DOT *dot) 
{                     
   int  nn[8][8]={
	   { 0,0,0,0,2,2,2,2 }, 
       { 1,1,1,1,0,3,3,3 },  
       { 1,1,1,1,0,0,3,3 }, 
       { 1,1,1,1,0,0,0,3 }, 
       { 1,1,1,1,0,0,0,0 }, 
	   { 0,3,3,3,2,2,2,2 },
       { 0,0,3,3,2,2,2,2 },
       { 0,0,0,3,2,2,2,2 }  };
   int  i,j,n,k,k1,ki,kj,d;
   int  dot_n;

   dot_n=0;	                        

   n=code[2];	                    
   code[n+3]=code[3];	            
   ki=code[0];   kj=code[1];	    
   if (n==1) {
      dot[0].x=dot[1].x=ki;
      dot[0].y=dot[1].y=kj;
 	  return(2);
   }
   for (i=3;i<n+3;i++) {	        
      k=code[i]%8;   k1=code[i+1]%8;
      d=nn[k][k1];	                
      ki+=inc[k][0];   kj+=inc[k][1];
      if (d!=0) {	                 
	 dot[dot_n].x  =ki;
	 dot[dot_n++].y=kj;              
	 if (d==3) {
	   dot[dot_n].x  =ki;
	   dot[dot_n++].y=kj;            
	 }
      }
   }

   for (i=0;i<dot_n-1;i++) {         
      k=i;      n=dot[i].y;
      for (j=i+1;j<dot_n;j++) {
	 if (dot[j].y<n) {
	    k=j;	n=dot[j].y;
	 }
      }
      ki=dot[i].x;          kj=dot[i].y;
      dot[i].x=dot[k].x;    dot[i].y=n;
      dot[k].x=ki;          dot[k].y=kj;
   }
   for (i=1;i<dot_n;i++) {	         
      for (j=dot_n-1;j>=i;j--) {
	 if (dot[j-1].y!=dot[j].y) continue;
	 if (dot[j-1].x>dot[j].x) {
	    ki=dot[j-1].x;          kj=dot[j-1].y;
	    dot[j-1].x=dot[j].x;    dot[j-1].y=dot[j].y;
	    dot[j].x=ki;            dot[j].y=kj;
	 }
      }
   }
   return(dot_n);                       
}

int perimeter(int *code)
{
   int i,e=0,fff=0,code_n;

   code_n=code[2];
   for (i=0;i<code_n;i++) {
	  if ((code[i]%2)==0) fff++;
	  else                e++;
   }
   fff+=(e*7/5);
   return(fff);
}

int area(struct DOT *dot,int dot_n)
{
   int  i,sss=0;

   for (i=0;i<dot_n;i+=2) {
	  sss+=(dot[i+1].x-dot[i].x+1);
   }
   return(sss);
}

double form_factor(int fff,int sss)
{
   double cv;

   cv=(double)fff*fff/sss/12.56;
   if (cv<1) cv=1;
   return(cv);
}

void fillarea(struct IMAGE *image,struct DOT *dot,int dot_n,int g)
{
   int      i,j,x,y,wid,hei,c;
   LOGPEN   lppena = {PS_SOLID,1,1,RGB(0,0,0)};
   COLORREF	clrref;
   HPEN     hPen;
   
   if (g<750) c=0;
   else       c=255;
   wid=image->wid;
   hei=image->hei;
   hMemDC=CreateMemDC();
   if (g%512==0) clrref=RGB(0,0,255);
   else if (g%512==1) clrref=RGB(0,255,0);
   else if (g%512==2) clrref=RGB(255,0,0);
   lppena.lopnColor=clrref;
   hPen=SelectObject(hMemDC,CreatePenIndirect(&lppena));
   for (i=0;i<dot_n;i+=2) {
	  x=dot[i].x;  y=dot[i].y;
	  j=dot[i+1].x-x+1;
	  if (j==1)  {
		 SetPixel(hMemDC,x,y,clrref);
		 setpixel(image,x,y,c);
	  }
	  else if ((j>0)&&(x>=0)&&(x<wid)&&(y>=0)&&(y<hei)) {
		 if (dot[i+1].y==y) {
		    MoveToEx(hMemDC,x,y,NULL);
		    LineTo(hMemDC,dot[i+1].x+1,y);
		    setwin(image,x,y,j,1,c);
		 }
	  }
   }
   DeleteObject(SelectObject(hMemDC,hPen));
   DeleteMemDC(hMemDC);
}

void MutiTrack(struct IMAGE *image,int x,int y,int Dx,int Dy,int t)
{
   int  i,j,c0,c1,c2;
   BYTE *sc;

   Trx1=x;			Try1=y;
   Trx2=x+Dx-1;		Try2=y+Dy-1;
   if (t==0) {
	  c0=255;		c1=1024;  
   }
   else {
	  c0=0;			c1=512;
   }
 
   dot =(struct DOT *) malloc(sizeof(struct DOT)*MAX_DOTN);
   code=(int*) malloc(sizeof(int)*MAX_DOTN);      
   sc=malloc(image->bpl);

   for (j=y;j<y+Dy-1;j++) {
 	  getimage(image,x,j,Dx,1,sc);
	  for (i=x;i<x+Dx-1;i++) {
		 if (ThreTable[sc[i-x]]==1) {
		    code_n=SingleTrack(image,i,j,4,code);
		    if (code_n==-1) break;
		    fff=perimeter(code);
		    dot_n=CodeToTable(code,dot);
		    sss=area(dot,dot_n);
		    factor=form_factor(fff,sss);
			if ((fff>fmin)&&(fff<fmax)) {
	          if ((factor>1.50)&&(fff>145)) c2=2;
			  else  c2=1;
			  number++;
			}
			else c2=0;
 		    fillarea(image,dot,dot_n,c1+c2);
 		    getimage(image,x,j,Dx,1,sc);
		 }
	  }
   }
   free(sc);
   free(code);                          
   free(dot);
}

int  Percent(int *pg,int t)
{
   int  i,m,n,k;

   for (i=0,m=0;i<t;i++)   m+=pg[i];
   for (i=0,n=0;i<256;i++) n+=pg[i];
   k=100*m/n;
   return k;
}

void ContourTrack(HWND hWnd)
{
   int   s,t,u;
   char  StringT[30];

   if ((Image[0]->hdib==NULL)||(Image[0]->bitcount<8)) return; 

   ClearDDB();
   WriteDDB(Image[0],  0,  0, 0, 0,512,512);

   ColorToGray(0,1);
   histog(Image[1],pg,0,0,Image[1]->wid,Image[1]->hei);
 
   t=Otsu(pg,pg1);
   GT_Threshold(Image[1],0,0,Image[1]->wid,Image[1]->hei,t);

   fmax=MAX_DOTN-10;		fmin=15;
   number=0;
   u=Percent(pg,t);
   if (u<50) s=0;
   else {
	  s=1;	  u=100-u;
   }
   if (u>30) return;
 
   hwnd=hWnd;
   set_thre(s,t);
   MutiTrack(Image[1],0,0,Image[1]->wid,Image[1]->hei,s);

   hMemDC=CreateMemDC();
   TextOut(hMemDC,600,20,"对象个数",8);
   sprintf(StringT,"%5d",number);
   TextOut(hMemDC,700,20,StringT,strlen(StringT));
   TextOut(hMemDC,600,50,"对象占空比",10);
   sprintf(StringT,"%5d %%",u);
   TextOut(hMemDC,700,50,StringT,strlen(StringT));
   DeleteMemDC(hMemDC);

   InvalidateRect(hWnd,NULL,FALSE);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -