图像边缘检测算法代码7

更新时间:2023-11-26 08:02:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

数字图像处理技术课程设计

图像边缘检测

编程实现灰度图像的几种常用的边缘检测算法,包括:梯度边缘检测算法、Roberts边缘检测算法、Sobel边缘检测算法、拉普拉斯边缘检测算法、canny边缘检测算法、Prewitt边缘检测算法和Krisch边缘检测算法。

代码:

头文件:

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ bmpFile.h

#ifndef BMP_FILE_H #define BMP_FILE_H

BYTE *Read8BitBmpFile2Img(const char *filename,int *width,int *height); bool Write8BitImg2BmpFile(BYTE *pImg,int width,int height,const char *filename); BYTE *Read24BitBmpFile2Img(const char *filename,int *width,int *height);

bool Write24BitImg2BmpFile(BYTE *pImg,int width,int height,const char *filename);

bool Robert(BYTE *pGryImg,int width,int height,int threshold); bool Sobel(BYTE *pGryImg,int width,int height,int threshold); bool Laplace(BYTE *pGryImg,int width,int height);

bool Prewitt(BYTE *pGryImg,int width,int height,int threshold); bool Kirsch(BYTE *pGryImg,int width,int height,int threshold);

#endif

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Canny.h

BYTE *Canny(BYTE *pGryImg,int width,int height,double sigma,double dRatioLow,double dRatioHigh,BYTE *dstImg);

//dRatioHigh设置的值越高,检测出来的边缘点数目会越少

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Gradient.h

bool Gradient(BYTE *pGryImg,int width,int height,int threshold);

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

函数定义文件:

bmpFile.cpp

#include #include #include #include #include #include

#define WIDTHBYTES(bits) (((bits)+31)/32*4)

BYTE *Read8BitBmpFile2Img(const char* filename,int *width,int *height) {

FILE *BinFile; BITMAPFILEHEADER FileHeader; BITMAPINFOHEADER BmpHeader;

BYTE *plmg; unsigned int size; int Suc=1,w,h; //open file

*width=*height=0;

if((BinFile=fopen(filename,\ //read struct info

if(fread((void*)&FileHeader,1,sizeof(FileHeader),BinFile)!=sizeof(FileHeader)) Suc=-1; if(fread((void*)&BmpHeader,1,sizeof(BmpHeader),BinFile)!=sizeof(BmpHeader)) Suc=-1; if((Suc==-1)||(FileHeader.bfOffBits

{

fclose(BinFile); return NULL; }

//read Image data *width=w=BmpHeader.biWidth;

*height=h=BmpHeader.biHeight;

size=w*h;

fseek(BinFile,FileHeader.bfOffBits,SEEK_SET); if((plmg=new BYTE[size])!=NULL) {

for(int i=0;i

}

{ }

fseek(BinFile,(w+3)/4*4-w,SEEK_CUR);

fclose(BinFile);

delete plmg; plmg=NULL; return NULL;

} }

fclose(BinFile); return plmg;

bool Write8BitImg2BmpFile(BYTE *pImg,int width,int height,const char* filename) //当宽度不是4的倍数时自动添加成4的倍数 {

FILE *BinFile;

BITMAPFILEHEADER FileHeader; BITMAPINFOHEADER BmpHeader; int i,extend; bool Suc=true; BYTE p[4],*pCur;

//Open File

if((BinFile=fopen(filename,\//Fill the FileHeader

FileHeader.bfType=((WORD)('M'<<8)|'B');

FileHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+256*4L; FileHeader.bfSize=FileHeader.bfOffBits+width*height;

FileHeader.bfReserved1=0; FileHeader.bfReserved2=0;

if(fwrite((void*)&FileHeader,1,sizeof(FileHeader),BinFile)!=sizeof(FileHeader)) Suc=false; //Fill the ImgHeader BmpHeader.biSize=40;

BmpHeader.biWidth=width; BmpHeader.biHeight=height; BmpHeader.biPlanes=1; BmpHeader.biBitCount=8; BmpHeader.biCompression=0; BmpHeader.biSizeImage=0; BmpHeader.biXPelsPerMeter=0; BmpHeader.biYPelsPerMeter=0; BmpHeader.biClrUsed=0;

BmpHeader.biClrImportant=0;

if(fwrite((void*)&BmpHeader,1,sizeof(BmpHeader),BinFile)!=sizeof(BmpHeader)) Suc=false; //write Pallete for(i=0,p[3]=0;i<256;i++)

{ }

//write image data

extend=(width+3)/4*4-width; if(extend==0) {

for(pCur=pImg+(height-1)*width;pCur>=pImg;pCur-=width) { if(fwrite((void*)pCur,1,width,BinFile)!=(unsigned int)width) Suc=false;//真实的} p[3]=0;

p[0]=p[1]=p[2]=i;//blue,green,red

if(fwrite((void*)p,1,4,BinFile)!=4) { Suc=false;break;}

数据

} else {

for(pCur=pImg+(height-1)*width;pCur>=pImg;pCur-=width) { if(fwrite((void*)pCur,1,width,BinFile)!=(unsigned int)width) Suc=false;//真实的 }

for(i=0;i

if(fwrite((void*)(pCur+width-1),1,1,BinFile)!=1) Suc=false;

数据 }

}

//return

fclose(BinFile); return Suc;

BYTE *Read24BitBmpFile2Img(const char *filename,int *width,int *height) {

FILE *BinFile;

BITMAPFILEHEADER FileHeader; BITMAPINFOHEADER BmpHeader; BYTE *img;

}

unsigned int size; int Suc=1,w,h;

*width=*height=0;

if((BinFile = fopen(filename,\

return NULL;

if(fread((void *)&FileHeader,1,sizeof(FileHeader),BinFile)!=sizeof(FileHeader)) Suc=-1;

if(fread((void *)&BmpHeader,1,sizeof(BmpHeader),BinFile)!=sizeof(BmpHeader))

Suc=-1;

if((Suc==-1) || (FileHeader.bfOffBits

fclose(BinFile); return NULL;

}

*width=w=BmpHeader.biWidth;

*height=h=BmpHeader.biHeight; size=(*width)*(*height)*3;

fseek(BinFile,FileHeader.bfOffBits,SEEK_SET); if((img=new BYTE[size])!=NULL) { }

for(int i=0;i

}

fclose(BinFile); delete img; img=NULL; return NULL;

fseek(BinFile,(3*w+3)/4*4-3*w,SEEK_CUR);

fclose(BinFile); return img;

bool Write24BitImg2BmpFile(BYTE *pImg,int width,int height,const char* filename) {

FILE *BinFile;

BITMAPFILEHEADER FileHeader; BITMAPINFOHEADER BmpHeader;

}

}

}

{ }

*lpDst1 = *lpDst2;

memcpy(pGryImg, NewpGryImg1, width * height); return TRUE;

bool Kirsch(BYTE *pGryImg,int width,int height,int threshold) { BYTE *lpDst1; // 指向缓存图像的指针 BYTE *lpDst2; BYTE *NewpGryImg1; // 指向缓存图像的指针

BYTE *hNewGryImg1;

BYTE *NewpGryImg2; BYTE *hNewGryImg2; long i,j;

int tempH; // 模板高度 int tempW; // 模板宽度

FLOAT tempR; // 模板系数 int tempX; // 模板中心元素X坐标 int tempY; // 模板中心元素Y坐标 FLOAT aTemplate[9]; // 模板数组 hNewGryImg1 = new BYTE[width * height]; if (hNewGryImg1 == NULL) { return FALSE; }

NewpGryImg1 = hNewGryImg1;

// 暂时分配内存,以保存新图像

hNewGryImg2 = new BYTE[width * height]; if (hNewGryImg2 == NULL) { }

NewpGryImg2 = hNewGryImg2; // 拷贝源图像到缓存图像中

return FALSE;

lpDst1 = NewpGryImg1;

memcpy(NewpGryImg1, pGryImg, width * height); lpDst2 = NewpGryImg2;

memcpy(NewpGryImg2, pGryImg, width * height); // 设置Kirsch模板1参数 tempW = 3; tempH = 3; tempR = 1.0; tempX = 1; tempY = 1;

aTemplate[0] = 5.0; aTemplate[1] = 5.0; aTemplate[2] = 5.0; aTemplate[3] = -3.0; aTemplate[4] = 0.0; aTemplate[5] = -3.0; aTemplate[6] = -3.0; aTemplate[7] = -3.0; aTemplate[8] = -3.0;

if (!Template(NewpGryImg1, width, height, tempH, tempW, tempX, tempY, aTemplate, tempR)) { return FALSE;

}

// 设置Kirsch模板2参数 aTemplate[0] = -3.0; aTemplate[1] = 5.0; aTemplate[2] = 5.0; aTemplate[3] = -3.0; aTemplate[4] = 0.0; aTemplate[5] = 5.0; aTemplate[6] = -3.0; aTemplate[7] = -3.0; aTemplate[8] = -3.0;

if (!Template(NewpGryImg2, width, height, tempH, tempW, tempX, tempY, aTemplate, { }

return FALSE;

tempR))

//求两幅缓存图像的最大值

for(j = 0; j

}

lpDst1 = NewpGryImg1 + width * j + i;

// 指向缓存图像2倒数第j行,第i个象素的指针 lpDst2 = NewpGryImg2 + width * j + i;

if(*lpDst2 > *lpDst1) { }

*lpDst1 = *lpDst2;

memcpy(NewpGryImg2, pGryImg, width * height); // 设置Kirsch模板3参数 aTemplate[0] = -3.0; aTemplate[1] = -3.0; aTemplate[2] = 5.0; aTemplate[3] = -3.0; aTemplate[4] = 0.0; aTemplate[5] = 5.0; aTemplate[6] = -3.0; aTemplate[7] = -3.0; aTemplate[8] = 5.0;

if (!Template(NewpGryImg2, width, height, tempH, tempW, tempX, tempY, aTemplate,

tempR)) {

}

return FALSE;

//求两幅缓存图像的最大值 for(j = 0; j

for(i = 0;i

// 指向缓存图像1倒数第j行,第i个象素的指针 lpDst1 = NewpGryImg1 + width * j + i;

// 指向缓存图像2倒数第j行,第i个象素的指针 lpDst2 = NewpGryImg2 + width * j + i;

}

}

if(*lpDst2 > *lpDst1) { *lpDst1 = *lpDst2; }

memcpy(NewpGryImg2, pGryImg, width * height);

// 设置Kirsch模板4参数 aTemplate[0] = -3.0; aTemplate[1] = -3.0; aTemplate[2] = -3.0; aTemplate[3] = -3.0; aTemplate[4] = 0.0; aTemplate[5] = 5.0; aTemplate[6] = -3.0; aTemplate[7] = 5.0; aTemplate[8] = 5.0;

if (!Template(NewpGryImg2, width, height, tempH, tempW, tempX, tempY, aTemplate,

tempR)) { return FALSE; }

//求两幅缓存图像的最大值 for(j = 0; j

{ }

// 指向缓存图像1倒数第j行,第i个象素的指针 lpDst1 = NewpGryImg1 + width * j + i;

// 指向缓存图像2倒数第j行,第i个象素的指针 lpDst2 = NewpGryImg2 + width * j + i;

if(*lpDst2 > *lpDst1) { }

*lpDst1 = *lpDst2;

}

memcpy(NewpGryImg2, pGryImg, width * height);

// 设置Kirsch模板5参数 aTemplate[0] = -3.0; aTemplate[1] = -3.0; aTemplate[2] = -3.0; aTemplate[3] = -3.0; aTemplate[4] = 0.0; aTemplate[5] = -3.0; aTemplate[6] = 5.0; aTemplate[7] = 5.0; aTemplate[8] = 5.0;

if (!Template(NewpGryImg2, width, height, tempH, tempW, tempX, tempY, aTemplate,

tempR)) {

}

return FALSE;

memcpy(NewpGryImg2, pGryImg, width * height); //求两幅缓存图像的最大值 for(j = 0; j

for(i = 0;i

lpDst1 = NewpGryImg1 + width * j + i;

// 指向缓存图像2倒数第j行,第i个象素的指针 lpDst2 = NewpGryImg2 + width * j + i;

if(*lpDst2 > *lpDst1) { }

*lpDst1 = *lpDst2;

memcpy(NewpGryImg2, pGryImg, width * height);

// 设置Kirsch模板6参数 aTemplate[0] = -3.0; aTemplate[1] = -3.0; aTemplate[2] = -3.0; aTemplate[3] = 5.0; aTemplate[4] = 0.0; aTemplate[5] = -3.0; aTemplate[6] = 5.0;

本文来源:https://www.bwwdw.com/article/efnt.html

Top