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

📄 threshold.c

📁 本下载文件是《C/C++图像处理编程》一书的演示程序
💻 C
字号:
//     Ex10
//  大津法二值化
  
#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);                                            //  变灰阶

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

void histog(struct IMAGE *image,long *pg,int Xs, int Ys, int Dx, int Dy)
{                                     //  统计直方图                              
   BYTE  *sc;
   int   i,j;

   sc=(BYTE*) malloc(Dx);
   for (i=0;i<256;i++)  pg[i]=0;
   for(i=0;i<Dy;i++) {
      getimage(image,Xs, Ys+i, Dx, 1, sc);
      for (j=0;j<Dx;j++)  pg[sc[j]]++;	
   }
   free(sc);
}

int  Otsu(long *pg,long *pg1)         //  大津法取阈值
{
   int  i,j,p;
   double A,B,An,Bn,u,v,qqq[256],max,min;

   An=Bn=0;
   for (i=0;i<256;i++) {
      An+=pg[i];     Bn+=pg[i]*(i+1);
   }
   for (j=0;j<256;j++) {
      A=B=0;
      for (i=0;i<=j;i++) {
	 A+=pg[i];	 B+=pg[i]*(i+1);
      }
      if (A) u=B/A;
      else   u=0;
      if (An-A) v=(Bn-B)/(An-A);
      else      v=0;
      qqq[j]=A*(An-A)*(u-v)*(u-v);  
   }

   max=min=qqq[0];		p=0;
   for (i=1;i<256;i++) {            
      if (qqq[i]>max) {
	     max=qqq[i];
	     p=i;
      }
	  else if (qqq[i]<min) min=qqq[i];
   }

   if (pg1!=0) {
     for (i=0;i<256;i++) {
       pg1[i]=(long) (120*(qqq[i]-min)/(max-min));
	 }
   }
   return(p);
}

void draw_histog(long *pg,int x,int y,int h,int flag) 
{                                     //  绘制直方图
   LOGPEN  lppen = {PS_SOLID,1,1,RGB(255,0,0)};
   DWORD Hist1[256];
   int   i,j,k,l,t;
   HPEN  hPen;
 
   hMemDC=CreateMemDC();
   for (j=0;j<256;j++)  Hist1[j]=pg[j];
   k=1;
   for (j=0,k=1;j<200;j++) {
      for (i=0,t=0;i<256;i++) {
         if ((int)(Hist1[i]/k)<h) t++;
	  }
	  if (t>252) break;
 	  k++;
   }
   for (i=0;i<256;i++) {
	  Hist1[i]/=k;
      if ((int) Hist1[i]>h)  Hist1[i]=h;
   }

   lppen.lopnColor=RGB(128,128,128);
   hPen=SelectObject(hMemDC,CreatePenIndirect(&lppen));

   MoveToEx(hMemDC,x,y,NULL);
   LineTo(hMemDC,x+256,y);

   DeleteObject(SelectObject(hMemDC,hPen));
   lppen.lopnColor=RGB(0,0,0);
   hPen=SelectObject(hMemDC,CreatePenIndirect(&lppen));

   MoveToEx(hMemDC,x,y-Hist1[0],NULL);
   for (i=0;i<256;i++) {
      l=Hist1[i];
      if (l>0) {
         if (flag==0)
		    MoveToEx(hMemDC,x+i,y,NULL);
         LineTo(hMemDC,x+i,y-l);
	  }
   }

   DeleteObject(SelectObject(hMemDC,hPen));
   DeleteMemDC(hMemDC);
}

void Threshold_G(int *T_gray,int thre)
{                                     //  灰度变换--两值化 
  int  i,w,b;                  

  thre_v=thre;
  b=0;      w=255;
  for (i=0;i<thre_v;i++)   T_gray[i]=b;
  for (i=thre_v;i<256;i++) T_gray[i]=w;
}

void GT(struct IMAGE *image,int x,int y,int Dx,int Dy)
{                                     //  实现灰度变换
  BYTE buf[2048];
  int  i,j;

  for (i=0;i<Dy;i++) {   
    getimage(image,x,y+i,Dx,1,buf); 
    for (j=0;j<Dx;j++) {
       buf[j]=T_gray[buf[j]];                                //  查表
    }
    setimage(image,x,y+i,Dx,1,buf);
  }
}

void GT_Threshold(struct IMAGE *image,int x,int y,int Dx,int Dy,int thre)
{                                     //  灰度变换--两值化 
  Threshold_G(T_gray,thre);           
  GT(image,x,y,Dx,Dy);                
}

void Threshold(HWND hWnd)
{
   int   t;
   char  StringT[20];

   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);
   draw_histog(pg,128,650,125,0);
   draw_histog(pg1,640,650,125,1);
   hMemDC=CreateMemDC();
   MoveToEx(hMemDC,128+t,655,NULL);
   LineTo(hMemDC,128+t,670);
   MoveToEx(hMemDC,640+t,655,NULL);
   LineTo(hMemDC,640+t,670);
   TextOut(hMemDC,470,600,"二值化阈值",10);
   sprintf(StringT,"%5d",t);
   TextOut(hMemDC,490,630,StringT,strlen(StringT));
   DeleteMemDC(hMemDC);

   GT_Threshold(Image[1],0,0,Image[1]->wid,Image[1]->hei,t);
   WriteDDB(Image[1],512,  0, 0, 0,512,512);

   InvalidateRect(hWnd,NULL,FALSE);
}

 

⌨️ 快捷键说明

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