从零开始写一个图像处理程序之五(手撕边缘检测终章)

前四篇的铺垫: 

从零开始写一个图像处理程序之一(BMP彩色图转灰度图)_星空_MAX的博客-CSDN博客

 从零开始写一个图像处理程序之二(提取灰度图通道)_星空_MAX的博客-CSDN博客

从零开始写一个图像处理程序之三(卷积原理简介)_星空_MAX的博客-CSDN博客

从零开始写一个图像处理程序之四(Prewitt 算子分析)_星空_MAX的博客-CSDN博客

定义Prewitt算子(convolution kernel)简称CK:

先定义Gx:

	int CK[9]={1,1,1,0,0,0,-1,-1,-1};

边缘处理:由于经过一次卷积的话,图像会缩水一个像素,所以在原本的channel上围上一圈0

   std::vectorchannel((bihead.biHeight+2)*(bihead.biWidth+2),0);

将图片读取到新位置:

  	for(int i=0;i

 开始卷积操作:

	for(int i=0;i

将新图像填入result中:

	bfhead.bfSize=14+40+sizeof(RGBQUAD)*256+LineByte*bihead.biHeight;
	bfhead.bfOffBits=14+40+sizeof(RGBQUAD)*256;
	//将bmpfilehead写入
	fwrite(&bfhead,14,1,newfp);
	//	将bmpbithead写入
	bihead.biBitCount=8;    //更改每像素位数
	bihead.biSizeImage=LineByte*bihead.biHeight;
	fwrite(&bihead,40,1,newfp);
	//灰度为1的rgb值分别为1,1,1,所以将256位颜色的颜色表分别置为相同的灰度值
	RGBQUAD *pColorTable=new RGBQUAD[256];
	for(int i=0;i<256;i++)
	{
		pColorTable[i].rgbRed = pColorTable[i].rgbGreen = pColorTable[i].rgbBlue = i;//使颜色表中每种颜色的R,G,B分量相等且等于索引值
	}
	fwrite(pColorTable,sizeof(RGBQUAD),256,newfp);
	
	
		
	unsigned char *pNewBmpBuf=new unsigned char[LineByte*bihead.biHeight];		
	for(int i=0;i

全部代码:


#include
#include
#include

int main()
{

 BITMAPFILEHEADER bfhead;
 BITMAPINFOHEADER bihead;
 FILE *fp=fopen("newcat.bmp","rb");
  FILE *newfp=fopen("newnewcat.bmp","wb");
 if(fp==0)
  return 0;
 fread(&bfhead,14,1,fp);   //将文件头读入内存
 fread(&bihead,40,1,fp);   //将信息头读入内存
 int LineByte=(bihead.biWidth*8/8+3)/4*4; //保证每行字节数为4的整数倍
  
 unsigned char *pBmpBuf=new unsigned char[LineByte*bihead.biHeight]; //为数据区分配内存空间
 fread(pBmpBuf,LineByte*bihead.biHeight,1,fp);       //将bmp数据区读入内存
 fclose(fp); 
 
    std::vectorchannel((bihead.biHeight+2)*(bihead.biWidth+2),0);
	std::vectorresult(bihead.biHeight*bihead.biWidth,0);
	
	int CK[9]={1,1,1,0,0,0,-1,-1,-1};
	
  	for(int i=0;i

原来的灰度图:

水平检测后的图片:

 改变算子为Gy:

	int CK[9]={-1,0,1,-1,0,1,-1,0,1};

垂直检测后的图片:

 综合处理:

在同一个像素点取 P(i,j)=max[G(i),G(j)]

即横向检测和纵向检测去一个最大值:


#include
#include
#include

#define MAX(a,b) a>b?a:b

int main()
{

 BITMAPFILEHEADER bfhead;
 BITMAPINFOHEADER bihead;
 FILE *fp=fopen("newcat.bmp","rb");
  FILE *newfp=fopen("newnewcat.bmp","wb");
 if(fp==0)
  return 0;
 fread(&bfhead,14,1,fp);   //将文件头读入内存
 fread(&bihead,40,1,fp);   //将信息头读入内存
 int LineByte=(bihead.biWidth*8/8+3)/4*4; //保证每行字节数为4的整数倍
  
 unsigned char *pBmpBuf=new unsigned char[LineByte*bihead.biHeight]; //为数据区分配内存空间
 fread(pBmpBuf,LineByte*bihead.biHeight,1,fp);       //将bmp数据区读入内存
 fclose(fp); 
 
    std::vectorchannel((bihead.biHeight+2)*(bihead.biWidth+2),0);
	std::vectorresult(bihead.biHeight*bihead.biWidth,0);
	
	int CK1[9]={1,1,1,0,0,0,-1,-1,-1};
	int CK2[9]={-1,0,1,-1,0,1,-1,0,1};
	
  	for(int i=0;i

最后的边缘检测得到的图片:

 替换卷积核:

将卷积核替换为不同的内容可以对程序进行不同的处理

你可能感兴趣的:(图像处理,人工智能,c语言,c++)