图像处理(最初版)(参考了各位高手的算法和程序 集大成 还没进行优化)

这是原图




这是经过处理的照片

灰度


二值化


细化


灰度均衡

均衡


边缘检测 采用sob算子




膨胀

腐蚀




窗口变换




对数变换



灰度拉伸变换




线性灰度变换






主程序#include <graphics.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <process.h>

void display(byte *temp,struct BMP_img img,int x,int y);
int read_img(FILE *infile, struct BMP_img *img);
void writebmp(byte *path,byte *temp,struct BMP_img img);

void displaygray(BMP_img img,int x,int y);              //显示灰度
void displaytwo(BMP_img img,BYTE k,int x,int y);            //显示二值图像
void Thining(struct BMP_img img,int x,int y);             //图像细化
int GrayEqualize(BMP_img img,int x,int y);                 //均衡
int edgesob(struct BMP_img img,int x,int y);             //边缘检测 sob算子
void junhenghua(struct BMP_img img,int x,int y);                                       //直方图灰度均衡化
int Dilation(struct BMP_img img,int type,int num,int x,int y);                         //膨胀 num=3,5,7 type 0 水平
int Erosion(struct BMP_img img,int type,int num,int x,int y);                          //腐蚀 num 3,5,7
int WindowTranslation(struct BMP_img img,int type,int num,int down,int up,int x,int y);//窗口变换
int LogTranslation(struct BMP_img img,int k,int x,int y);                              //对数变换
int ThresholdTranslation(struct BMP_img img,byte bytThreshold,int x,int y);            //图像阈值变换
int GrayStretch(struct BMP_img img,int pt1x,int pt1y,int pt2x,int pt2y,int x,int y);   //图像灰度拉伸变换
int LineTranslation(struct BMP_img img,double k,double d,int x,int y);                 //图像线性灰度变换

void main()
{   
 int i=0;
 char path[20];
 FILE *f1;
 BMP_img img1;

     //printf("请输入图片路径\n");
  // scanf("%s",path);
  
 if((f1=fopen("c:\\4.bmp","rb"))==NULL)
 {
    printf( "\n 不能打开 %s \n", path);
    exit(-1);
 }


 if((read_img(f1, &img1))==0)
 {
  printf("\n 图像读取失败 \n");
  fclose(f1);
  exit(-1);
 }
 
 initgraph(1024,800);

   display(img1.image,img1,0,0);
     displaygray(img1,0,1);
  displaytwo(img1,120,0,2);                                                         //图像阈值变换
     GrayStretch(img1,10,10,100,100,0,3);                                               //图像灰度拉伸变换
  LineTranslation(img1,2,10,1,0);                              //图像线性灰度变换
  Thining(img1,1,1);
  edgesob(img1,1,2);/**/
  junhenghua(img1,1,3);
     GrayEqualize(img1,2,0);
     Dilation(img1,0,3,2,1);
     WindowTranslation(img1,0,3,50,20,2,2);
     LogTranslation(img1,10,2,3);
     Erosion(img1,1,5,3,0);
   
  fclose(f1);

  while(1);
}
各个函数

#include "math.h"
typedef unsigned long       DWORD;
typedef int                 BOOL;
typedef unsigned char       BYTE;
typedef unsigned short      WORD;
typedef float               FLOAT;
typedef unsigned char       byte;

struct BMP_img
{
 long width;
 long height;
 char bmp_type;        /* 8bit 24bit; */
    BYTE *image;
    byte *header_info;
 
 
 int header_length;
};

void writebmp(const char *path,byte *temp,struct BMP_img img)
{
    FILE *f2;
    DWORD lineBytes=(img.width*img.bmp_type+31)/32*4;

    if((f2=fopen(path,"wb"))==NULL)
    {
        printf("\n不能创建%s图\n",path);
        exit(-1);
    }
       if(fwrite(img.header_info,img.header_length*sizeof(BYTE),1,f2)!=1)
    {
        printf("不能写入%s图\n",path);
        fclose(f2);
       
    }
    fseek(f2,img.header_length*sizeof(byte),SEEK_SET);
   
    if(fwrite(temp,img.height*lineBytes*sizeof(BYTE),1,f2)!=1)
    {
        printf("不能写入%s图\n",path);
        fclose(f2);
       
    }
    fclose(f2);


}
void display(byte *temp,struct BMP_img img,int x,int y)
{
    int i,j,n;
    DWORD lineBytes=(img.width*img.bmp_type+31)/32*4;

       for(i=0;i<img.height;i++)
    {
        for(j=0,n=0;n<img.width*3,j<img.width;n+=3,j++)
           
        { 

         putpixel(j+x*img.width,y*img.height+img.height-i,RGB(*(temp+i*lineBytes+n+2),*(temp+i*lineBytes+n+1),*(temp+i*lineBytes+n)));
        }
    }
      //free(temp);
}
void displaygray(BMP_img img,int x,int y)
{   
    int i,j,n;
   
    double gray=0;
    DWORD lineBytes=(img.width*img.bmp_type+31)/32*4;
    byte *temp=(byte *)malloc(sizeof(byte)*img.height*lineBytes);
        
       for(i=0;i<img.height;i++)
   {
        for(j=0,n=0;n<img.width*3,j<img.width;n+=3,j++)

     { 
       gray= 0.299*(float)(img.image[lineBytes*i+n+2])+0.578*(float)(*(img.image+lineBytes*i+n+1))+0.114*(float)(*(img.image+lineBytes*i+n));
       temp[i*lineBytes+n]=(byte)gray;
       temp[i*lineBytes+n+1]=(byte)gray;
       temp[i*lineBytes+n+2]=(byte)gray;
           
     }
   }
   display(temp,img,x,y);
   writebmp("G:\\temp\\gray.bmp",temp,img);
   free(temp);

}
void displaytwo(BMP_img img,BYTE k,int x,int y)
{
    int i,j,n;
  
    double gray=0;
    DWORD lineBytes=(img.width*img.bmp_type+31)/32*4;
    byte *temp=(byte *)malloc(sizeof(byte)*img.height*lineBytes);
    byte temp1;
   
    for(i=0;i<img.height;i++)
    {
        for(j=0,n=0;n<img.width*3,j<img.width;n+=3,j++)
           
        { 

         gray= 0.299*(float)(img.image[lineBytes*i+n+2])+0.578*(float)(*(img.image+lineBytes*i+n+1))+0.114*(float)(*(img.image+lineBytes*i+n));
         temp1=(byte)gray;
         temp[i*lineBytes+n+0]=255*(temp1/k);
         temp[i*lineBytes+n+1]=255*(temp1/k);
         temp[i*lineBytes+n+2]=255*(temp1/k);
       
        }
    }   
    display(temp,img,x,y);
    writebmp("G:\\temp\\bmptwo.bmp",temp,img);
       free(temp);
 }


//图像细化
void Thining(struct BMP_img img,int xx,int yy)
{

 static int erasetable[256]={
  0,0,1,1,0,0,1,1,1,1,0,1,1,1,0,1,1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,
  0,0,1,1,0,0,1,1,1,1,0,1,1,1,0,1,1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,
  1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  1,1,0,0,1,1,0,0,1,1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,1,1,0,0,1,1,1,1,0,1,1,1,0,1,1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,
  0,0,1,1,0,0,1,1,1,1,0,1,1,1,0,1,1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
  1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
  1,1,0,0,1,1,0,0,1,1,0,1,1,1,0,0,1,1,0,0,1,1,1,0,1,1,0,0,1,0,0,0
 };

   
  DWORD lineBytes=(img.width*img.bmp_type+31)/32*4;

  long dwWidth=0;
     dwWidth=img.width;
  long dwHeight=0;
     dwHeight=img.height;
  BYTE *temp=(BYTE*)malloc(dwHeight*dwWidth*sizeof(BYTE));
                                          //DWORD dwLineBytes=(dwWidth*24+31)/32*4;
  BYTE *temp1=(byte *)malloc(sizeof(byte)*lineBytes*img.height);
  int i,j,n;
 
  double gray;
  BYTE g=0;
  BYTE zs=0,s=0,ys=0,z=0,y=0,zx=0,x=0,yx=0;
  int num=0;

 

   
   
  for(i=0;i<img.height;i++)
  {
      for(j=0,n=0;n<img.width*3,j<img.width;n+=3,j++)
         
      { 
         
         gray= 0.299*(float)(img.image[lineBytes*i+n+2])+0.578*(float)(*(img.image+lineBytes*i+n+1))+0.114*(float)(*(img.image+lineBytes*i+n));
            temp1[i*img.width+j]=(byte)gray;
        }
    }   

 


 
 if(!temp)
 {
  exit(-1);
 }
 
 for(i=0;i<dwHeight;i++)
 {
  for(j=0;j<dwWidth;j++)
  {
   g=temp1[dwWidth*i+j];
   if(g<=120)
   {
    temp1[dwWidth*i+j]=(BYTE)0;
   }
   else
   {
    temp1[dwWidth*i+j]=(BYTE)255;
   }
  }
 }

 memcpy(temp,temp1,dwWidth*dwHeight*sizeof(BYTE));

 for(i=1;i<dwHeight-1;i++)
 {
  for(j=1;j<dwWidth-1;j++)
  {
   g=temp1[dwWidth*i+j];
   if(g==0)
   {
    z=temp1[dwWidth*i+j-1];
    y=temp1[dwWidth*i+j+1];
    if(z==255 || y==255)
    {
     zs=temp1[dwWidth*(i+1)+j-1];
     s=temp1[dwWidth*(i+1)+j];
     ys=temp1[dwWidth*(i+1)+j+1];
     zx=temp1[dwWidth*(i-1)+j-1];
     x=temp1[dwWidth*(i-1)+j];
     yx=temp1[dwWidth*(i-1)+j+1];
     num=zs/255+s/255*2+ys/255*4+z/255*8+y/255*16+zx/255*32+x/255*64+yx/255*128;
     if(erasetable[num]==1)
     {
      temp[dwWidth*i+j]=(BYTE)255;
      temp1[dwWidth*i+j]=(BYTE)255;
     }
    }
   }
  }
 }

 for(i=1;i<dwHeight-1;i++)
 {
  for(j=1;j<dwWidth-1;j++)
  {
   g=temp[dwWidth*i+j];
   if(g==0)
   {
    s=temp1[dwWidth*(i+1)+j];
    x=temp1[dwWidth*(i-1)+j];
    if(s==255 || x==255)
    {
     zs=temp1[dwWidth*(i+1)+j-1];
     z=temp1[dwWidth*i+j-1];
     y=temp1[dwWidth*i+j+1];
     ys=temp1[dwWidth*(i+1)+j+1];
     zx=temp1[dwWidth*(i-1)+j-1];
     yx=temp1[dwWidth*(i-1)+j+1];
     num=zs/255+s/255*2+ys/255*4+z/255*8+y/255*16+zx/255*32+x/255*64+yx/255*128;
     if(erasetable[num]==1)
     {
      temp[dwWidth*i+j]=(BYTE)255;
      temp1[dwWidth*i+j]=(BYTE)255;
     }
    }
   }
  }
 }
 /*for(i=0;i<dwHeight;i++)
     for(j=0;j<dwWidth;j++)
 putpixel(j+img.width,img.height+img.height-i,RGB(*(temp+i*dwWidth+j+2),*(temp+i*dwWidth+j+1),*(temp+i*dwWidth+j)));*/
  for(i=0;i<img.height;i++)
      for(j=0,n=0;j<dwWidth,n<dwWidth*3;j++,n+=3){
          temp1[i*lineBytes+n]=temp[i*dwWidth+j];
          temp1[i*lineBytes+n+1]=temp[i*dwWidth+j];
          temp1[i*lineBytes+n+2]=temp[i*dwWidth+j];}

    //memcpy(temp1,temp,dwHeight*dwWidth*sizeof(BYTE));
    display(temp1,img,xx,yy);
    writebmp("G:\\temp\\thining.bmp",temp1,img);
       free(temp1);
    free(temp);
   
 
}
 //图像灰度均衡
int GrayEqualize(BMP_img img,int x,int y)
{
 
 DWORD height=img.height;
 DWORD width=img.width;
 WORD bitCount=img.bmp_type;
 DWORD lineBytes=(width*bitCount+31)/32*4;
 BYTE *temp=(byte*)malloc(sizeof(byte)*lineBytes*height);
 memcpy(temp,img.image,sizeof(byte)*lineBytes*height);

 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];
   }
  }
  /*for(i=0;i<height;i++)
      for(j=0,n=0;n<width*3,j<width;n+=3,j++)
 putpixel(j+img.width,img.height+img.height-i,RGB(*(temp+i*lineBytes+n+2),*(temp+i*lineBytes+n+1),*(temp+i*lineBytes+n)));
 */
  display(temp,img,x,y);
  writebmp("G:\\temp\\grayequlize.bmp",temp,img);
 
  free(temp);
 
  
 }
 else
 {
  return -1;
 }

 return 0;
}
int edgesob(struct BMP_img img,int x,int y)
{
   
    long sumX, sumY,SUM;
    int I,J,X,Y,i,j,n;
    int height=img.height;
    int width=img.width;
    DWORD lineBytes=(img.width*img.bmp_type+31)/32*4;
 
    int            GX[3][3];
    int            GY[3][3];
    /* 3x3 GX Sobel mask.  Ref: www.cee.hw.ac.uk/hipr/html/sobel.html */
    GX[0][0] = -1; GX[0][1] = 0; GX[0][2] = 1;
    GX[1][0] = -2; GX[1][1] = 0; GX[1][2] = 2;
    GX[2][0] = -1; GX[2][1] = 0; GX[2][2] = 1;
   
    /* 3x3 GY Sobel mask.  Ref: www.cee.hw.ac.uk/hipr/html/sobel.html */
    GY[0][0] =  1; GY[0][1] =  2; GY[0][2] =  1;
    GY[1][0] =  0; GY[1][1] =  0; GY[1][2] =  0;
    GY[2][0] = -1; GY[2][1] = -2; GY[2][2] = -1;
   
    double gray=0;
    byte *temp=(BYTE*)malloc(height*lineBytes*sizeof(BYTE));
    byte *temp1=(BYTE*)malloc(height*width*sizeof(BYTE));
    //fread(temp,sizeof(byte),height*lineBytes,infile);

   
 for(i=0;i<img.height;i++)
  {
      for(j=0,n=0;n<img.width*3,j<img.width;n+=3,j++)
         
      { 
         
         gray= 0.299*(float)(img.image[lineBytes*i+n+2])+0.578*(float)(*(img.image+lineBytes*i+n+1))+0.114*(float)(*(img.image+lineBytes*i+n));

            temp[i*width+j]=(byte)gray;
        }
    }   
      
   
   
   
    /*---------------------------------------------------
    SOBEL ALGORITHM STARTS HERE
    ---------------------------------------------------*/
    for(Y=0; Y<height; Y++) 
       {
          for(X=0; X<width; X++)
          {
            sumX = 0;
            sumY = 0;
           
            /* image boundaries */
             if(Y==0 || Y==height-1)
                SUM = 0;
            else if(X==0 || X==width-1)
                SUM = 0;
           
            /* Convolution starts here */
            else {
               
                /*-------X GRADIENT APPROXIMATION------*/
                    for(I=-1; I<=1; I++)
                    {
                      for(J=-1; J<=1; J++) 
                      {
                        sumX = sumX + (int)( (*(temp + X + I + (Y + J)*width)) * GX[I+1][J+1]);
                      }
                    }
                if(sumX>255)  sumX=255;
                if(sumX<0)    sumX=0;
               
                /*-------Y GRADIENT APPROXIMATION-------*/
                  for(I=-1; I<=1; I++) 
                  {
                    for(J=-1; J<=1; J++) 
                    {
                        sumY = sumY + (int)( (*(temp + X + I + (Y + J)*width)) * GY[I+1][J+1]);
                    }
                  }
                if(sumY>255)   sumY=255;
                if(sumY<0)     sumY=0;
               
                SUM = abs(sumX) + abs(sumY); /*---GRADIENT MAGNITUDE APPROXIMATION (Myler p.218)----*/
            }
           
            *(temp1+ X + Y*width) = 255 - (unsigned char)(SUM);  /* make edges black and background white */
       
          }
    }
    for(i=0;i<height;i++)
        for(j=0,n=0;n<width*3,j<width;n+=3,j++){
            temp[i*lineBytes+n]=temp1[i*width+j];
            temp[i*lineBytes+n+1]=temp1[i*width+j];
            temp[i*lineBytes+n+2]=temp1[i*width+j];}

    display(temp,img,x,y);
    writebmp("G:\\temp\\edgesob.bmp",temp,img);
   
   


    //printf("See edgeSob.bmp for results\n");
    //fclose(bmpInput);
    //fclose(bmpOutput);
    free(temp);      /* Finished with edgeImage.data */
    free(temp1);  /* Finished with originalImage.data */
    return 0;
}
void junhenghua(struct BMP_img img,int x,int y)
{
 long height=img.height;
 long width=img.width;
 int n[256]={0};
 long m;
 long lineBytes=(img.width*img.bmp_type+31)/32*4;
 double gray=0;
    long i,j,max,min;
 byte *temp=(BYTE*)malloc(height*lineBytes*sizeof(BYTE));
    byte *temp1=(BYTE*)malloc(height*width*sizeof(BYTE));
 
 double p[256]={0};
    double c[256]={0};
 //fread(temp,sizeof(byte),height*lineBytes,infile);
 
 
 for(i=0;i<img.height;i++)
 {
  for(j=0,m=0;m<img.width*3,j<img.width;m+=3,j++)
   
  { 
   
   gray= 0.299*(float)(img.image[lineBytes*i+m+2])+0.578*(float)(*(img.image+lineBytes*i+m+1))+0.114*(float)(*(img.image+lineBytes*i+m));
   
   temp[i*width+j]=(byte)gray;
   n[(byte)gray]++;
  }
 } 
 
 
 
 for(i=0;i<256;i++){
  p[i] = (double)n[i]/(height*width);
 }
 
 for(i=0;i<256;i++){
  for(j=0;j<=i;j++){
   c[i]+=p[j]; //累计直方图
  }
 }
 max=min=temp[0];
 for(i=0;i<height;i++){
  for(j=0;j<width;j++){
   if(max<temp[i*width+j]){max=temp[i*width+j];}
   else if(min>temp[i*width+j]){min=temp[i*width+j];}
  }
 }
 // printf("%d %d\n",max,min);
 for(i=0;i<height;i++){
  for(j=0;j<width;j++){
   temp1[i*width+j]=(byte)(c[temp[i*width+j]]*(max-min)+min);
  }
 }
 for(i=0;i<height;i++)
  for(j=0,m=0;j<width,m<width*3;j++,m+=3){
   temp[i*lineBytes+m]=temp1[i*width+j];
   temp[i*lineBytes+m+1]=temp1[i*width+j];
   temp[i*lineBytes+m+2]=temp1[i*width+j];}
  
  //fprintf(ft,"%c%c\n%d %d\n%d\n",'P','5',width,height,L);
  display(temp,img,x,y);
  writebmp("G:\\temp\\junheng.bmp",temp,img);
  
  free(temp);
  free(temp1);
  
}
int read_img(FILE *infile, BMP_img *img)
{
      unsigned char n=0;
     

      int compression;
    //unsigned char *temp;      /* used for read the image data */
           
    fseek(infile, 0x12, SEEK_SET);
    fread(&img->width, sizeof(long), 1, infile);
    fseek(infile, 0x16, SEEK_SET);
    fread(&img->height, sizeof(long), 1, infile);

    printf( "\n 宽度=%d  高度=%d \n", img->width, img->height);

    fseek(infile, 0x1C, SEEK_SET);
    fread(&img->bmp_type, sizeof(int), 1, infile);
   

    /*if(bits_per_pixel==8)
        bmp_img->bmp_type=8;
    else if(bits_per_pixel==24)
        bmp_img->bmp_type=24;

    if((bmp_img->width*bits_per_pixel)%32==0)
       n=0;
    else
        n=4-(bmp_img->width*3)%4;*/
              
    fprintf(stderr, "\n bmp_type=%d \n", img->bmp_type);
    DWORD lineBytes=(img->width*img->bmp_type+31)/32*4;


    fseek(infile, 0x1E, SEEK_SET);
    fread(&compression, sizeof(int), 1, infile);
    if(compression==0) {
        fprintf(stderr, "\n bmp图片为非压缩! \n");
    }

    fseek(infile, 0x0A, SEEK_SET);
    fread(&img->header_length, sizeof(int), 1, infile);
    fprintf(stderr, "\n 文件头长度 = %d \n", img->header_length);


    img->header_info=(unsigned char *)malloc(sizeof(unsigned char)*img->header_length);
    if(img->header_info==NULL) {
        fprintf(stderr, "\n Allocation error for bmp_head_buffer \n");
        exit(-1);
    }
    fseek(infile, 0x00, SEEK_SET);
    fread(img->header_info, img->header_length, 1, infile);
 

   

    /* read the image data to mono or color array */
    if(img->bmp_type==8)
    {
        img->image=(unsigned char *)malloc(sizeof(unsigned char)*(img->width*img->height));
        if(img->image==NULL)
        {
            fprintf(stderr, "\n Allocation error for temp in read_bmp() \n");
            return 0;
        }

        fseek(infile, img->header_length, SEEK_SET);
        if(fread(&img->image, sizeof(unsigned char), img->width*img->height, infile)!=(size_t)(img->width*img->height))
        {
            if(feof(infile)) fprintf(stderr, "\n Premature end of file %s \n", infile);
            else             fprintf(stderr, "\n File read error %s \n", infile);
            return 0;
        }

       
    }
    else if(img->bmp_type==24)
    {
        img->image=(unsigned char *)malloc(sizeof(unsigned char)*((lineBytes)*img->height));
        if(img->image==NULL)
        {
            fprintf(stderr, "\n Allocation error for temp in read_bmp() \n");
            return 0;
        }

        fseek(infile, img->header_length, SEEK_SET);
        fread(img->image, sizeof(unsigned char), (lineBytes)*img->height, infile);
        /*if(fread(img->image, sizeof(unsigned char), (lineBytes)*img->height, infile)!=(size_t)((lineBytes)*img->height))
        {
            if(feof(infile)) fprintf(stderr, "\n Premature end of file %s \n", infile);
            else             fprintf(stderr, "\n File read error %s \n", infile);
          return 0;
        } */


    }

    return 1;
}
//图像膨胀
int Dilation(struct BMP_img img,int type,int num,int x,int y)
{
 int dwWidth=img.width;
 int dwHeight=img.height;
 byte wBitCount=img.bmp_type;
 DWORD dwLineBytes=(dwWidth*wBitCount+31)/32*4;
 byte *image=(BYTE*)malloc(dwHeight*dwLineBytes*sizeof(BYTE));
 memcpy(image,img.image,dwHeight*dwLineBytes*sizeof(byte));
  int i=0;
  int j=0;
  int n=0;
 BYTE b=0;
 BYTE g=0;
 BYTE r=0;
 double avg=0;
 BYTE *temp;
 int k=0;

 if(image==NULL)
 {
  return -1;
 }
 if(num!=3 && num!=5 &&num!=7)
 {
  return -1;
 }

 temp=(BYTE*)malloc(dwHeight*dwLineBytes*sizeof(BYTE));
 memcpy(temp,img.image,dwHeight*dwLineBytes*sizeof(byte));

 if(!temp)
 {
  return -1;
 }
 memset(temp,255,dwLineBytes*dwHeight*sizeof(BYTE));

 if(wBitCount==8)
 {
  //如果为非二值图像,则转化为二值图像
  for(i=0;i<dwHeight;i++)
  {
   for(j=0;j<dwWidth;j++)
   {
    g=*(image+dwLineBytes*i+j);
    if(g>=120)
    {
     *(image+dwLineBytes*i+j)=255;
    }
    else
    {
     *(image+dwLineBytes*i+j)=0;
    }

   }
  }

  if(type==0)
  {
   //水平方向
   for(i=0;i<dwHeight;i++)
   {
    for(j=(num-1)/2;j<dwWidth-(num-1)/2;j++)
    {
     for(k=-(num-1)/2;k<=(num-1)/2;k++)
     {
      g=*(image+dwLineBytes*i+j+k);
      if(g==0)
      {
       *(temp+dwLineBytes*i+j)=0;
       break;
      }
     }
    }
   }
  }
  else
  {
   //垂直方向
   for(i=(num-1)/2;i<dwHeight-(num-1)/2;i++)
   {
    for(j=0;j<dwWidth;j++)
    {
     for(k=-(num-1)/2;k<=(num-1)/2;k++)
     {
      g=*(image+dwLineBytes*(i+k)+j);
      if(g==0)
      {
       *(temp+dwLineBytes*i+j)=0;
       break;
      }
     }
    }
   }
  }
 }
 else if(wBitCount==24)
 {
  //如果不是二值图像,需要先转换为二值图像
  for(i=0;i<dwHeight;i++)
  {
   for(j=0,n=0;j<dwWidth*3;j++,n++)
   {
    b=*(image+dwLineBytes*i+j);
    j++;
    g=*(image+dwLineBytes*i+j);
    j++;
    r=*(image+dwLineBytes*i+j);

    avg=(b+g+r)/3.0;

    if(avg>=120)
    {
     avg=255;
    }
    else
    {
     avg=0;
    }

    *(image+dwLineBytes*i+n)=(BYTE)avg;
    n++;
    *(image+dwLineBytes*i+n)=(BYTE)avg;
    n++;
    *(image+dwLineBytes*i+n)=(BYTE)avg;
   }
  }

  if(type==0)
  {
   //水平方向
   for(i=0;i<dwHeight;i++)
   {
    for(j=(num-1)/2;j<(dwWidth-(num-1)/2)*3;j++)
    {
     for(k=-(num-1)/2;k<=(num-1)/2;k++)
     {
      b=*(image+dwLineBytes*i+j+k*3);
      g=*(image+dwLineBytes*i+j+1+k*3);
      r=*(image+dwLineBytes*i+j+2+k*3);
      if(b==0 && g==0 && r==0)
      {
       *(temp+dwLineBytes*i+j)=0;
       j++;
       *(temp+dwLineBytes*i+j)=0;
       j++;
       *(temp+dwLineBytes*i+j)=0;
       break;
      }
     }
    }
   }
  }
  else
  {
   //垂直方向
   for(i=(num-1)/2;i<dwHeight-(num-1)/2;i++)
   {
    for(j=0;j<dwWidth*3;j++)
    {
     for(k=-(num-1)/2;k<=(num-1)/2;k++)
     {
      b=*(image+dwLineBytes*(i+k)+j);
      g=*(image+dwLineBytes*(i+k)+j+1);
      r=*(image+dwLineBytes*(i+k)+j+2);
      if(b==0 && g==0 && r==0)
      {
       *(temp+dwLineBytes*i+j)=0;
       j++;
       *(temp+dwLineBytes*i+j)=0;
       j++;
       *(temp+dwLineBytes*i+j)=0;
       break;
      }
     }
    }
   }
  }
 }
 else
 {
  free(temp);
  temp=NULL;
 
  return -1;
 }

  display(temp,img,x,y);
  writebmp("g:\\temp\\Dilation.bmp",temp,img);
  free(image);
 free(temp);
 temp=NULL;
 return 0;
}
//图像腐蚀
int Erosion(BMP_img img,int type,int num,int x,int y)//(BYTE* image,DWORD dwWidth,DWORD dwHeight,WORD wBitCount,int type,int num)
 
{
 int dwWidth=img.width;
    int dwHeight=img.height;
    byte wBitCount=img.bmp_type;
    DWORD dwLineBytes=(dwWidth*wBitCount+31)/32*4;
    byte *image=(byte *)malloc(sizeof(byte)*dwHeight*dwLineBytes);
 memcpy(image,img.image,sizeof(byte)*dwHeight*dwLineBytes);
    int i=0;
    int j=0;
    int n=0;
    BYTE b=0;
    BYTE g=0;
    BYTE r=0;
    double avg=0;
    BYTE *temp=NULL;
    int k=0;

 if(image==NULL)
 {
  return -1;
 }
 if(num!=3 && num!=5 && num!=7)
 {
  return -1;
 }

 temp=(BYTE*)malloc(dwHeight*dwLineBytes*sizeof(BYTE));
 if(!temp)
 {
  return -1;
 }
 memset(temp,0,dwLineBytes*dwHeight*sizeof(BYTE));

 if(wBitCount==8)
 {
  //如果为非二值图像,则转化为二值图像
  for(i=0;i<dwHeight;i++)
  {
   for(j=0;j<dwWidth;j++)
   {
    g=*(image+dwLineBytes*i+j);
    if(g>=120)
    {
     *(image+dwLineBytes*i+j)=255;
    }
    else
    {
     *(image+dwLineBytes*i+j)=0;
    }

   }
  }

  if(type==0)
  {
   //水平方向
   for(i=0;i<dwHeight;i++)
   {
    for(j=(num-1)/2;j<dwWidth-(num-1)/2;j++)
    {
     for(k=-(num-1)/2;k<=(num-1)/2;k++)
     {
      g=*(image+dwLineBytes*i+j+k);
      if(g==255)
      {
       *(temp+dwLineBytes*i+j)=255;
       break;
      }
     }
    }
   }
  }
  else
  {
   //垂直方向
   for(i=(num-1)/2;i<dwHeight-(num-1)/2;i++)
   {
    for(j=0;j<dwWidth;j++)
    {
     for(k=-(num-1)/2;k<=(num-1)/2;k++)
     {
      g=*(image+dwLineBytes*(i+k)+j);
      if(g==255)
      {
       *(temp+dwLineBytes*i+j)=255;
       break;
      }
     }
    }
   }
  }
 }
 else if(wBitCount==24)
 {
  //如果不是二值图像,需要先转换为二值图像
  for(i=0;i<dwHeight;i++)
  {
   for(j=0,n=0;j<dwWidth*3;j++,n++)
   {
    b=*(image+dwLineBytes*i+j);
    j++;
    g=*(image+dwLineBytes*i+j);
    j++;
    r=*(image+dwLineBytes*i+j);

    avg=(b+g+r)/3.0;

    if(avg>=120)
    {
     avg=255;
    }
    else
    {
     avg=0;
    }

    *(image+dwLineBytes*i+n)=(BYTE)avg;
    n++;
    *(image+dwLineBytes*i+n)=(BYTE)avg;
    n++;
    *(image+dwLineBytes*i+n)=(BYTE)avg;
   }
  }

  if(type==0)
  {
   //水平方向
   for(i=0;i<dwHeight;i++)
   {
    for(j=(num-1)/2;j<(dwWidth-(num-1)/2)*3;j++)
    {
     for(k=-(num-1)/2;k<=(num-1)/2;k++)
     {
      b=*(image+dwLineBytes*i+j+k*3);
      g=*(image+dwLineBytes*i+j+1+k*3);
      r=*(image+dwLineBytes*i+j+2+k*3);
      if(b==255 && g==255 && r==255)
      {
       *(temp+dwLineBytes*i+j)=255;
       j++;
       *(temp+dwLineBytes*i+j)=255;
       j++;
       *(temp+dwLineBytes*i+j)=255;
       break;
      }
     }
    }
   }
  }
  else
  {
   //垂直方向
   for(i=(num-1)/2;i<dwHeight-(num-1)/2;i++)
   {
    for(j=0;j<dwWidth*3;j++)
    {
     for(k=-(num-1)/2;k<=(num-1)/2;k++)
     {
      b=*(image+dwLineBytes*(i+k)+j);
      g=*(image+dwLineBytes*(i+k)+j+1);
      r=*(image+dwLineBytes*(i+k)+j+2);
      if(b==255 && g==255 && r==255)
      {
       *(temp+dwLineBytes*i+j)=255;
       j++;
       *(temp+dwLineBytes*i+j)=255;
       j++;
       *(temp+dwLineBytes*i+j)=255;
       break;
      }
     }
    }
   }
  }
 }
 else
 {
  free(temp);
  temp=NULL;
  return -1;
 }
memcpy(image,temp,dwLineBytes*dwHeight*sizeof(BYTE));
/*for(i=0;i<dwHeight;i++)
  for(j=0,n=0;j<dwWidth,n<dwWidth*3;j++,n+=3)
 putpixel(j+img.width,img.height+img.height-i,RGB(*(image+i*dwLineBytes+n+2),*(image+i*dwLineBytes+n+1),*(image+i*dwLineBytes+n)));*/
 display(image,img,x,y);
 writebmp("g:\\temp\\Erosion.bmp",image,img);
 free(temp);
 free(image);
 return 0;
}


//图像窗口变换
int WindowTranslation(struct BMP_img img,int type,int num,int down,int up,int x,int y)//(BYTE *image,DWORD dwWidth,DWORD dwHeight,WORD wBitCount, int down,int up)
     
{


 int width=img.width;
    int height=img.height;
    byte bitCount=img.bmp_type;
    int lineBytes=(width*bitCount+31)/32*4;
    byte *temp=(byte *)malloc(sizeof(byte)*height*lineBytes);
    memcpy(temp,img.image,sizeof(byte)*height*lineBytes);
    int i=0;
    int j=0;
    int n=0;

 BYTE g=0;
 BYTE b=0;
 BYTE r=0;
 double avg=0;
 
 if(bitCount==8)
 {
  for(i=0;i<height;i++)
  {
   for(j=0;j<width;j++)
   {
    g=*(temp+lineBytes*(height-1-i)+j);
    if(g<down)
    {
     *(temp+lineBytes*(height-1-i)+j)=0;
    }
    if(g>up)
    {
     *(temp+lineBytes*(height-1-i)+j)=255;
    }
   }
  }
 }
 else if(bitCount==24)
 {
  for(i=0;i<height;i++)
  {
   for(j=0,n=0;j<width*3;j++,n++)
   {
    b=*(temp+lineBytes*i+j);
    j++;
    g=*(temp+lineBytes*i+j);
    j++;
    r=*(temp+lineBytes*i+j);
   
    avg=(b+g+r)/3.0;
    if(avg<down) avg=0;
    if(avg>up) avg=255;
   
    *(temp+lineBytes*i+n)=(BYTE)avg;
    n++;
    *(temp+lineBytes*i+n)=(BYTE)avg;
    n++;
    *(temp+lineBytes*i+n)=(BYTE)avg;
   }
  }

  display(temp,img,x,y);
  writebmp("g:\\temp\\windowtranslation.bmp",temp,img);
 
 }
 
 else
 {
  return -1;
 }
free(temp);
 return 0;
}

//图像对数变换
int LogTranslation(struct BMP_img img,int k,int x,int y)//(BYTE *image,DWORD dwWidth,DWORD dwHeight,WORD wBitCount, int k)
     
{
 int width=img.width;
    int height=img.height;
    byte bitCount=img.bmp_type;
    int lineBytes=(width*bitCount+31)/32*4;
    byte *temp=(byte *)malloc(sizeof(byte)*height*lineBytes);
    memcpy(temp,img.image,sizeof(byte)*height*lineBytes);
    int i=0;
    int j=0;
    int n=0;

 BYTE b=0;
 BYTE g=0;
 BYTE r=0;

 if(temp==NULL)
 {
  return -1;
 }
 
 if(bitCount==8)
 {
  for(i=0;i<height;i++)
  {
   for(j=0;j<width;j++)
   {
    g=*(temp+lineBytes*i+j);
    *(temp+lineBytes*i+j)=(BYTE)(k*log(g+1));
   }
  }
 }
 else if(bitCount==24)
 {
  for(i=0;i<height;i++)
  {
   for(j=0,n=0;j<width*3;j++,n++)
   {
    b=*(temp+lineBytes*i+j);
    j++;
    g=*(temp+lineBytes*i+j);
    j++;
    r=*(temp+lineBytes*i+j);
   
    *(temp+lineBytes*i+n)=(BYTE)(k*log(b+1));
    n++;
    *(temp+lineBytes*i+n)=(BYTE)(k*log(g+1));
    n++;
    *(temp+lineBytes*i+n)=(BYTE)(k*log(r+1));
   }
  }

  display(temp,img,x,y);
  writebmp("g:\\temp\\LogTranslation.bmp",temp,img);
  free(temp);

 }
 else
 {
  return -1;
  free(temp);
 }
 
 return 0;
}
//图像线性灰度变换
int LineTranslation(struct BMP_img img,double k,double d,int x,int y)//(BYTE *image,DWORD dwWidth,DWORD dwHeight,WORD wBitCount,double k,double d)
    
{
 int dwWidth=img.width;
    int dwHeight=img.height;
    byte wBitCount=img.bmp_type;
    int dwLineBytes=(dwWidth*wBitCount+31)/32*4;
    byte *image=(byte *)malloc(sizeof(byte)*dwHeight*dwLineBytes);
    memcpy(image,img.image,sizeof(byte)*dwHeight*dwLineBytes);
    int i=0;
    int j=0;
    int 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;
   }
  }
  display(image,img,x,y);
  writebmp("g:\\temp\\LineTranslation.bmp",image,img);
  free(image);


 }
 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;
   }
  }
  display(image,img,x,y);
  writebmp("g:\\temp\\LineTranslation.bmp",image,img);
  free(image);


 }
 else
 {
  return -1;
 }

 return 0;
}

//图像灰度拉伸变换
int GrayStretch(struct BMP_img img,int pt1x,int pt1y,int pt2x,int pt2y,int x,int y)//(BYTE* image,DWORD dwWidth,DWORD dwHeight,WORD wBitCount, int pt1x,int pt1y,int pt2x,int pt2y)
  
{
 int dwWidth=img.width;
    int dwHeight=img.height;
    byte wBitCount=img.bmp_type;
    int dwLineBytes=(dwWidth*wBitCount+31)/32*4;
    byte *image=(byte *)malloc(sizeof(byte)*dwHeight*dwLineBytes);
    memcpy(image,img.image,sizeof(byte)*dwHeight*dwLineBytes);
    int i=0;
    int j=0;
    int n=0;

    BYTE map[256];

 
 
   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];
   }
  }
  display(image,img,x,y);
  writebmp("g:\\temp\\GrayStretch.bmp",image,img);
  free(image);

 }
 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];
   }
  }
  display(image,img,x,y);
  writebmp("g:\\temp\\GrayStretch.bmp",image,img);
  free(image);

 }
 else
 {
  return -1;
 }

 return 0;
}

//图像阈值变换
int ThresholdTranslation(struct BMP_img img,byte bytThreshold,int x,int y)//(BYTE* image,DWORD dwWidth,DWORD dwHeight,WORD wBitCount,BYTE bytThreshold)
      
{
 int dwWidth=img.width;
    int dwHeight=img.height;
    byte wBitCount=img.bmp_type;
    int dwLineBytes=(dwWidth*wBitCount+31)/32*4;
    byte *image=(byte *)malloc(sizeof(byte)*dwHeight*dwLineBytes);
    memcpy(image,img.image,sizeof(byte)*dwHeight*dwLineBytes);
    int i=0;
    int j=0;
    int n=0;
 BYTE b=0;
 BYTE g=0;
 BYTE r=0;
 double avg=0.0;
 

 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;
    }
   }
  }
  display(image,img,x,y);
  writebmp("g:\\temp\\ThresholdTranslation.bmp",image,img);
  free(image);


 }
 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;
   }
  }

  display(image,img,x,y);
  writebmp("g:\\temp\\ThresholdTranslation.bmp",image,img);
  free(image);

 }
 else
 {
  return -1;
 }

 return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值