图像灰度均衡

简介: //图像灰度均衡int GrayEqualize(BYTE *image,DWORD dwWidth,DWORD dwHeight,WORD wBitCount){ DWORD height=dwHeight; DWORD width=dwWidth; WORD bitCount=wBitCou...

//图像灰度均衡
int GrayEqualize(BYTE *image,DWORD dwWidth,DWORD dwHeight,WORD wBitCount)
{
 DWORD height=dwHeight;
 DWORD width=dwWidth;
 WORD bitCount=wBitCount;
 DWORD lineBytes=(width*bitCount+31)/32*4;
 BYTE *temp=image;

 BYTE grayMap[256];
 DWORD grayNum[256];

 BYTE BgrayMap[256];
 DWORD BgrayNum[256];
 BYTE GgrayMap[256];
 DWORD GgrayNum[256];
 BYTE RgrayMap[256];
 DWORD RgrayNum[256];

 DWORD i=0;
 DWORD j=0;
 int n=0;
 int m=0;
 BYTE b=0;
 BYTE g=0;
 BYTE r=0;
 long c=0;
 long bc=0,gc=0,rc=0;

 if(temp==NULL)
 {
  return -1;
 }

 for(n=0;n<256;n++)
 {
  grayNum[n]=0;
  grayMap[n]=0;

  BgrayNum[n]=0;
  BgrayMap[n]=0;
  GgrayNum[n]=0;
  GgrayMap[n]=0;
  RgrayNum[n]=0;
  RgrayMap[n]=0;
 }

 if(bitCount==8)
 {
  for(i=0;i<height;i++)
  {
   for(j=0;j<width;j++)
   {
    g=*(temp+lineBytes*(height-1-i)+j);
    grayNum[g]++;
   }
  }
  for(n=0;n<256;n++)
  {
   c=0;
   for(m=0;m<=n;m++)
   {
    c+=grayNum[m];
   }
   grayMap[n]=(BYTE)(c*255/height/width);
  }
  for(i=0;i<height;i++)
  {
   for(j=0;j<width;j++)
   {
    g=*(temp+lineBytes*(height-1-i)+j);
    *(temp+lineBytes*(height-1-i)+j)=grayMap[g];
   }
  }
 }
 else if(bitCount==24)
 {
  for(i=0;i<height;i++)
  {
   for(j=0;j<width*3;j++)
   {
    b=*(temp+lineBytes*(height-1-i)+j);
    j++;
    g=*(temp+lineBytes*(height-1-i)+j);
    j++;
    r=*(temp+lineBytes*(height-1-i)+j);

    BgrayNum[b]++;
    GgrayNum[g]++;
    RgrayNum[r]++;
   }
  }
  for(n=0;n<256;n++)
  {
   bc=0;gc=0;rc=0;
   for(m=0;m<=n;m++)
   {
    bc+=BgrayNum[m];
    gc+=GgrayNum[m];
    rc+=RgrayNum[m];
   }
   BgrayMap[n]=(BYTE)(bc*255/height/width);
   GgrayMap[n]=(BYTE)(gc*255/height/width);
   RgrayMap[n]=(BYTE)(rc*255/height/width);
  }
  for(i=0;i<height;i++)
  {
   for(j=0,n=0;j<width*3;j++,n++)
   {
    b=*(temp+lineBytes*(height-1-i)+j);
    j++;
    g=*(temp+lineBytes*(height-1-i)+j);
    j++;
    r=*(temp+lineBytes*(height-1-i)+j);

    *(temp+lineBytes*(height-1-i)+n)=BgrayMap[b];
    n++;
    *(temp+lineBytes*(height-1-i)+n)=GgrayMap[g];
    n++;
    *(temp+lineBytes*(height-1-i)+n)=RgrayMap[r];
   }
  }
 }
 else
 {
  return -1;
 }

 return 0;
}

//图像线性灰度变换
int LineTranslation(BYTE *image,DWORD dwWidth,DWORD dwHeight,
     WORD wBitCount,double k,double d)
{
 DWORD dwLineBytes=(dwWidth*wBitCount+31)/32*4;
 DWORD i=0;
 DWORD j=0;
 DWORD n=0;
 BYTE b=0;
 BYTE g=0;
 BYTE r=0;
 double nb=0;
 double ng=0;
 double nr=0;
 double f=0;

 if(image==NULL)
 {
  return -1;
 }
 
 if(wBitCount==8)
 {
  for(i=0;i<dwHeight;i++)
  {
   for(j=0;j<dwWidth;j++)
   {
    g=*(image+dwLineBytes*(dwHeight-1-i)+j);
    f=g*k+d;
    if(f>255) f=255;
    if(f<0) f=0;
    *(image+dwLineBytes*(dwHeight-1-i)+j)=(BYTE)f;
   }
  }
 }
 else if(wBitCount==24)
 {
  for(i=0;i<dwHeight;i++)
  {
   for(j=0,n=0;j<dwWidth*3;j++,n++)
   {
    b=*(image+dwLineBytes*(dwHeight-1-i)+j);
    j++;
    g=*(image+dwLineBytes*(dwHeight-1-i)+j);
    j++;
    r=*(image+dwLineBytes*(dwHeight-1-i)+j);
    
    nb=b*k+d;
    if(nb>255) nb=255;
    if(nb<0) nb=0;
    ng=g*k+d;
    if(ng>255) ng=255;
    if(ng<0) ng=0;
    nr=r*k+d;
    if(nr>255) nr=255;
    if(nr<0) nr=0;
    
    *(image+dwLineBytes*(dwHeight-1-i)+n)=(BYTE)nb;
    n++;
    *(image+dwLineBytes*(dwHeight-1-i)+n)=(BYTE)ng;
    n++;
    *(image+dwLineBytes*(dwHeight-1-i)+n)=(BYTE)nr;
   }
  }
 }
 else
 {
  return -1;
 }

 return 0;
}

//图像灰度拉伸变换
int GrayStretch(BYTE* image,DWORD dwWidth,DWORD dwHeight,WORD wBitCount,
    int pt1x,int pt1y,int pt2x,int pt2y)

 BYTE map[256];
 int n=0;
 DWORD dwLineBytes=(dwWidth*wBitCount+31)/32*4;
 DWORD i=0;
 DWORD j=0;
 BYTE b=0;
 BYTE g=0;
 BYTE r=0;
 double avg=0.0;
 int ag=0;

 if(image==NULL)
 {
  return -1;
 }

 for(n=0;n<=pt1x;n++)
 {
  if(pt1x>0)
  {
   map[n]=(BYTE)pt1y*n/pt1x;
  }
  else
  {
   map[n]=0;
  }
 }
 for(;n<=pt2x;n++)
 {
  if(pt2x!=pt1x)
  {
   map[n]=pt1y+(BYTE)((pt2y-pt1y)*(n-pt1x)/(pt2x-pt1x));
  }
  else
  {
   map[n]=pt1y;
  }
 }
 for(;n<256;n++)
 {
  if(pt2x!=255)
  {
   map[n]=pt2y+(BYTE)((255-pt2y)*(n-pt2x)/(255-pt2x));
  }
  else
  {
   map[n]=255;
  }
 }
 
 if(wBitCount==8)
 {
  for(i=0;i<dwHeight;i++)
  {
   for(j=0;j<dwWidth;j++)
   {
    g=*(image+dwLineBytes*(dwHeight-1-i)+j);
    *(image+dwLineBytes*(dwHeight-1-i)+j)=map[g];
   }
  }
 }
 else if(wBitCount==24)
 {
  for(i=0;i<dwHeight;i++)
  {
   for(j=0,n=0;j<dwWidth*3;j++,n++)
   {
    b=*(image+dwLineBytes*(dwHeight-1-i)+j);
    j++;
    g=*(image+dwLineBytes*(dwHeight-1-i)+j);
    j++;
    r=*(image+dwLineBytes*(dwHeight-1-i)+j);
    
    avg=(b+g+r)/3.0;
    ag=(int)avg;
    
    *(image+dwLineBytes*(dwHeight-1-i)+n)=(BYTE)map[ag];
    n++;
    *(image+dwLineBytes*(dwHeight-1-i)+n)=(BYTE)map[ag];
    n++;
    *(image+dwLineBytes*(dwHeight-1-i)+n)=(BYTE)map[ag];
   }
  }
 }
 else
 {
  return -1;
 }

 return 0;
}

//图像阈值变换
int ThresholdTranslation(BYTE* image,DWORD dwWidth,DWORD dwHeight,
       WORD wBitCount,BYTE bytThreshold)
{
 DWORD i=0;
 DWORD j=0;
 DWORD n=0;
 BYTE b=0;
 BYTE g=0;
 BYTE r=0;
 double avg=0.0;
 DWORD dwLineBytes=(dwWidth*wBitCount+31)/32*4;

 if(wBitCount==8)
 {
  for(i=0;i<dwHeight;i++)
  {
   for(j=0;j<dwWidth;j++)
   {
    g=*(image+dwLineBytes*(dwHeight-1-i)+j);
    if(g<bytThreshold)
    {
     *(image+dwLineBytes*(dwHeight-1-i)+j)=0;
    }
    else
    {
     *(image+dwLineBytes*(dwHeight-1-i)+j)=255;
    }
   }
  }
 }
 else if(wBitCount==24)
 {
  for(i=0;i<dwHeight;i++)
  {
   for(j=0,n=0;j<dwWidth*3;j++,n++)
   {
    b=*(image+dwLineBytes*(dwHeight-1-i)+j);
    j++;
    g=*(image+dwLineBytes*(dwHeight-1-i)+j);
    j++;
    r=*(image+dwLineBytes*(dwHeight-1-i)+j);

    avg=(b+g+r)/3.0;
    if(avg<bytThreshold)
    {
     avg=0;
    }
    else
    {
     avg=255;
    }

    *(image+dwLineBytes*(dwHeight-1-i)+n)=(BYTE)avg;
    n++;
    *(image+dwLineBytes*(dwHeight-1-i)+n)=(BYTE)avg;
    n++;
    *(image+dwLineBytes*(dwHeight-1-i)+n)=(BYTE)avg;
   }
  }
 }
 else
 {
  return -1;
 }

 return 0;
}

#endif

测试程序:

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>

#include "Bitmap.h"
#include "Algorithm.h"

int main(int argc,char **argv)
{
 char image_path[256];
 char save_path[256];
 int ret=0;
 DWORD dwHeight=0;
 DWORD dwWidth=0;
 WORD wBitCount=0;
 int select=0;
 bool con=TRUE;
 int pt1x,pt1y,pt2x,pt2y;
 double k=0,d=0;
 int p=0,t=0;

 if(argc==2)
 {
  memcpy(image_path,argv[1],256*sizeof(char));
 }
 else
 {
  printf("Please input the path of the bitmap(.bmp):\n");
  scanf("%s",image_path);
 }

 ret=TIMage_Read(image_path);
 if(ret!=0)
 {
  printf("FAILED: read the bitmap %s.\n",image_path);
  return -1;
 }

 dwHeight=TIMage_GetHeight();
 dwWidth=TIMage_GetWidth();
 wBitCount=TIMage_GetBitCount();

 while(con==TRUE)
 {
  printf("-----Main Menu-----\n");
  printf(" 1. GrayEqualize\n");
  printf(" 2. GrayStretch\n");
  printf(" 3. LineTranslation\n");
  printf(" 4. LogTranslation\n");
  printf(" 5. ThresholdTranslation\n");
  printf(" 6. WindowTranslation\n");
  printf(" 7. Erosion\n");
  printf(" 8. Dilation\n");
  printf(" 9. Open\n");
  printf(" 10. Close\n");
  printf(" 11. Thining.\n");
  printf("99. Save the BITMAP\n");
  printf(" 0. EXIT\n");
  
  scanf("%d",&select);

  switch(select)
  {
  case 0:
   con=FALSE;
   break;
  case 1://GrayEqualize
   ret=GrayEqualize(TIMagePixelMatrix,dwWidth,dwHeight,wBitCount);
   if(ret==-1)
   {
    printf("FAILED: GrayEqulaize.\n");
    con=FALSE;
    break;
   }
   printf("Successed: GrayEqualize.\n");
   break;
  case 2://GrayStretch
   printf("Input the coordinate of two point(pt1x,pt1y,pt2x,pt2y):\n");
   scanf("%d,%d,%d,%d",&pt1x,&pt1y,&pt2x,&pt2y);
   ret=GrayStretch(TIMagePixelMatrix,dwWidth,dwHeight,wBitCount,pt1x,pt1y,pt2x,pt2y);
   if(ret==-1)
   {
    printf("FAILED: GrayStretch.\n");
    con=FALSE;
    break;
   }
   printf("Successed: GrayStretch.\n");
   break;
  case 3://LineTranslation
   printf("Input k,d:\n");
   scanf("%d,%d",&k,&d);
   ret=LineTranslation(TIMagePixelMatrix,dwWidth,dwHeight,wBitCount,k,d);
   if(ret==-1)
   {
    printf("FAILED: LineTranslation.\n");
    con=FALSE;
    break;
   }
   printf("Successed: LineTranslation.\n");
   break;
  case 4://LogTranslation
   printf("Input k:\n");
   scanf("%d",&p);
   ret=LogTranslation(TIMagePixelMatrix,dwWidth,dwHeight,wBitCount,p);
   if(ret==-1)
   {
    printf("FAILED: LogTranslation.\n");
    con=FALSE;
    break;
   }
   printf("Successed: LogTranslation.\n");
   break;
  case 5://ThresholdTranslation
   printf("Input the Threshold:\n");
   scanf("%d",&p);
   ret=ThresholdTranslation(TIMagePixelMatrix,dwWidth,dwHeight,wBitCount,p);
   if(ret==-1)
   {
    printf("FAILED: ThresholdTranslation.\n");
    con=FALSE;
    break;
   }
   printf("Successed: ThresholdTranslation.\n");
   break;
  case 6://WindowTranslation
   printf("Input the down and up Value(down,up):\n");
   scanf("%d,%d",&p,&t);
   ret=WindowTranslation(TIMagePixelMatrix,dwWidth,dwHeight,wBitCount,p,t);
   if(ret==-1)
   {
    printf("FAILED: WindowTranslation.\n");
    con=FALSE;
    break;
   }
   printf("Successed: WindowTranslation.\n");
   break;
  case 7://Erosion
   printf("Direction: 0-Horizontal 1-Vertically\n");
   scanf("%d",&p);
   printf("Element Size: 3 or 5 or 7\n");
   scanf("%d",&t);
   ret=Erosion(TIMagePixelMatrix,dwWidth,dwHeight,wBitCount,p,t);
   if(ret==-1)
   {
    printf("FAILED: Erosion.\n");
    con=FALSE;
    break;
   }
   printf("Successed: Erosion.\n");
   break;
  case 8://Dilation
   printf("Direction: 0-Horizontal 1-Vertically\n");
   scanf("%d",&p);
   printf("Element Size: 3 or 5 or 7\n");
   scanf("%d",&t);
   ret=Dilation(TIMagePixelMatrix,dwWidth,dwHeight,wBitCount,p,t);
   if(ret==-1)
   {
    printf("FAILED: Dilation.\n");
    con=FALSE;
    break;
   }
   printf("Successed: Dilation.\n");
   break;
  case 9:
   printf("Direction: 0-Horizontal 1-Vertically\n");
   scanf("%d",&p);
   printf("Element Size: 3 or 5 or 7\n");
   scanf("%d",&t);
   ret=OpenClose(TIMagePixelMatrix,dwWidth,dwHeight,wBitCount,0,p,t);
   if(ret==-1)
   {
    printf("FAILED: Open.\n");
    con=FALSE;
    break;
   }
   printf("Successed: Open.\n");
   break;
  case 10:
   printf("Direction: 0-Horizontal 1-Vertically\n");
   scanf("%d",&p);
   printf("Element Size: 3 or 5 or 7\n");
   scanf("%d",&t);
   ret=OpenClose(TIMagePixelMatrix,dwWidth,dwHeight,wBitCount,1,p,t);
   if(ret==-1)
   {
    printf("FAILED: Close.\n");
    con=FALSE;
    break;
   }
   printf("Successed: Close.\n");
   break;
  case 11:
   ret=Thining(TIMagePixelMatrix,dwWidth,dwHeight,wBitCount);
   if(ret==-1)
   {
    printf("FAILED: Thining.\n");
    con=FALSE;
    break;
   }
   printf("Successed: Thining.\n");
   break;
  case 99://Save the image to a bitmap file
   printf("Please input the path you want to save the bitmap(.bmp):\n");
   scanf("%s",save_path);   
   ret=TIMage_Write(save_path);
   if(ret!=0)
   {
    printf("FAILED: save the bitmap %s.\n",save_path);
    con=FALSE;
    return -1;
   }  
   printf("Successed to save the bitmap.\n");
   break;
  default:
   con=FALSE;
   break;
  }
 }
 
 return 0;
}

相关文章
|
算法 C++
OpenCV-白平衡(灰度世界算法)
OpenCV-白平衡(灰度世界算法)
403 0
|
6月前
|
算法 测试技术 持续交付
四种灰度分布方案
【6月更文挑战第10天】产品迭代加速,灰度发布成为降低风险、优化用户体验的关键。它允许新老版本并存,逐步引入流量验证新版本稳定性。
|
6月前
|
算法 计算机视觉
图像处理之特殊灰度算法技巧
图像处理之特殊灰度算法技巧
60 0
|
文字识别 算法 计算机视觉
计算机视觉图像常用基本算法(阈值化、形态学变化、模糊)
计算机视觉图像常用基本算法(阈值化、形态学变化、模糊)
204 0
|
算法 计算机视觉
图像分割—灰度阈值分割
图像分割—灰度阈值分割
|
机器学习/深度学习 编解码 弹性计算
|
数据挖掘 Python
python实现图像灰度处理
python实现图像灰度处理
223 0
python实现图像灰度处理
|
存储 传感器 移动开发
LabVIEW图像灰度分析与变换(基础篇—4)
LabVIEW图像灰度分析与变换(基础篇—4)
LabVIEW图像灰度分析与变换(基础篇—4)
|
计算机视觉
LabVIEW图像灰度测量(基础篇—7)
LabVIEW图像灰度测量(基础篇—7)
LabVIEW图像灰度测量(基础篇—7)