这是原图
灰度
二值化
细化
灰度均衡
均衡
边缘检测 采用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;
}