⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 segment.cpp

📁 将数字图像处理的一般算法都集中在一个MFC的框架中
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	int pixelByte=nBitCount/8;

	//循环变量,遍历像素的每个通道,比如彩色图像三个分量
	int k;

	//循环变量,用于模板卷积运算
	int  c, r;
	
	//中间变量
	int sum;

	//模板卷积运算,边缘像素不处理
	for(i=maskH/2;i<height-maskH/2; i++){
		for(j=maskW/2; j<width-maskH/2; j++){
			//对每个通道数据进行卷积
			for(k=0; k<pixelByte; k++){
				//卷积求和
				sum=0;
				for(r=-maskH/2;r<=maskH/2;r++){
					for(c=-maskW/2;c<=maskW/2;c++){
						sum += *(mask+(r+maskH/2)*maskW+c+maskW/2) 
							* *(imgIn+(i+r)*lineByte+(j+c)*pixelByte+k);
					}
				}
				
				//取绝对值
				sum=abs(sum);
				if(sum>255)
					sum=255;
				else if(sum<0)
					sum=0;
				
				*(imgOut+i*lineByte+j*pixelByte+k)=sum;
			}
		}
	}
}


/***********************************************************************
* 函数名称:
* EdgeByAnyMask()
*
*函数参数:
*  int *mask   -二维的模板
*  int maskW   -模板宽
*  int maskH   -模板高
*
*返回值:
*   无
*
*说明:根据自定义模板检测边缘,同时适合于灰度和彩色图像
***********************************************************************/
void ImgSegment::EdgeByAnyMask(int *mask ,int maskW, int maskH)
{
	//释放m_pImgDataOut指向的图像数据空间
	if(m_pImgDataOut!=NULL){
		delete []m_pImgDataOut;
    	m_pImgDataOut=NULL;
	}
	//释放颜色表空间
	if(m_lpColorTableOut!=NULL){
		delete []m_lpColorTableOut;
		m_lpColorTableOut=NULL;
	}

	//输出图像与输入图像为同一类型
	m_nBitCountOut=m_nBitCount;

	//输出图像颜色表长度
	m_nColorTableLengthOut=ComputeColorTabalLength(m_nBitCountOut);

	//输出图像颜色表,与输入图像相同
	if(m_nColorTableLengthOut!=0){
    	m_lpColorTableOut=new RGBQUAD[m_nColorTableLengthOut];
		memcpy(m_lpColorTableOut,m_lpColorTable,sizeof(RGBQUAD)*m_nColorTableLengthOut);
	}

	//输出图像的宽高,与输入图像相等
	m_imgWidthOut=m_imgWidth;
	m_imgHeightOut=m_imgHeight;

	//每行像素所占字节数,输出图像与输入图像相同
	int lineByte=(m_imgWidth*m_nBitCount/8+3)/4*4;

	//申请输出图像缓冲区
	m_pImgDataOut=new unsigned char[lineByte*m_imgHeight];

	//模板卷积函数调用
	TemplateEdge(m_pImgData, m_imgWidth, m_imgHeight, m_nBitCount,
		       mask, maskW, maskH, m_pImgDataOut);	
}

/***********************************************************************
* 函数名称:
* Krisch()
*
*函数参数:
*  无
*
*返回值:
*   无
*
*说明:Krisch边缘检测,同时适合于灰度和彩色图像
***********************************************************************/
void ImgSegment::Krisch()
{
	//释放m_pImgDataOut指向的图像数据空间
	if(m_pImgDataOut!=NULL){
		delete []m_pImgDataOut;
    	m_pImgDataOut=NULL;
	}
	//释放颜色表空间
	if(m_lpColorTableOut!=NULL){
		delete []m_lpColorTableOut;
		m_lpColorTableOut=NULL;
	}

	//输出图像与输入图像为同一类型
	m_nBitCountOut=m_nBitCount;

	//输出图像颜色表长度
	m_nColorTableLengthOut=ComputeColorTabalLength(m_nBitCountOut);

	//输出图像颜色表,与输入图像相同
	if(m_nColorTableLengthOut!=0){
    	m_lpColorTableOut=new RGBQUAD[m_nColorTableLengthOut];
		memcpy(m_lpColorTableOut,m_lpColorTable,
			sizeof(RGBQUAD)*m_nColorTableLengthOut);
	}

	//输出图像的宽高,与输入图像相等
	m_imgWidthOut=m_imgWidth;
	m_imgHeightOut=m_imgHeight;

	//每行像素所占字节数,输出图像与输入图像相同
	int lineByte=(m_imgWidth*m_nBitCount/8+3)/4*4;

	//申请输出图像缓冲区
	m_pImgDataOut=new unsigned char[lineByte*m_imgHeight];

	//输出图像缓冲区初始化为0
	memset(m_pImgDataOut, 0, lineByte*m_imgHeight);

	//循环变量,图像的坐标
	int i,j;

	//每像素占字节数,输出图像与输入图像相同
	int pixelByte=m_nBitCount/8;

	//循环变量,遍历像素的每个通道,比如彩色图像三个分量
	int k;	

	//两个指针变量
	unsigned  char *p1, *p2;
	//申请临时缓冲区,存放中间结果
	unsigned char *buf=new unsigned char[lineByte* m_imgHeight];

	//模板数组
	int mask[9];

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

	//模板卷积函数调用
	TemplateEdge(m_pImgData, m_imgWidth, m_imgHeight, m_nBitCount,
		         mask, 3, 3, buf);

	//求两幅缓存图像的最大值,并将大的值存入m_pImgDataOut中
	for(i=0;i<m_imgHeight;i++){
		for(j=0;j<m_imgWidth;j++){
			for(k=0;k<pixelByte;k++){
				p1=m_pImgDataOut+i*lineByte+j*pixelByte+k;
				p2=buf+i*lineByte+j*pixelByte+k;
				if(*p1<*p2)
					*p1=*p2;
			}
		}
	}

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

	//模板卷积函数调用
	TemplateEdge(m_pImgData, m_imgWidth, m_imgHeight, m_nBitCount, 
		         mask, 3, 3, buf);

	//求两幅缓存图像的最大值,并将大的值存入m_pImgDataOut中
	for(i=0;i<m_imgHeight;i++){
		for(j=0;j<m_imgWidth;j++){
			for(k=0;k<pixelByte;k++){
				p1=m_pImgDataOut+i*lineByte+j*pixelByte+k;
				p2=buf+i*lineByte+j*pixelByte+k;
				if(*p1<*p2)
					*p1=*p2;
			}
		}
	}

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

	//模板卷积函数调用
	TemplateEdge(m_pImgData, m_imgWidth, m_imgHeight, m_nBitCount, 
		         mask, 3, 3, buf);

	//求两幅缓存图像的最大值,并将大的值存入m_pImgDataOut中
	for(i=0;i<m_imgHeight;i++){
		for(j=0;j<m_imgWidth;j++){
			for(k=0;k<pixelByte;k++){
				p1=m_pImgDataOut+i*lineByte+j*pixelByte+k;
				p2=buf+i*lineByte+j*pixelByte+k;
				if(*p1<*p2)
					*p1=*p2;
			}
		}
	}


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

	//模板卷积函数调用
	TemplateEdge(m_pImgData, m_imgWidth, m_imgHeight, m_nBitCount, 
		         mask, 3, 3, buf);

	//求两幅缓存图像的最大值,并将大的值存入m_pImgDataOut中
	for(i=0;i<m_imgHeight;i++){
		for(j=0;j<m_imgWidth;j++){
			for(k=0;k<pixelByte;k++){
				p1=m_pImgDataOut+i*lineByte+j*pixelByte+k;
				p2=buf+i*lineByte+j*pixelByte+k;
				if(*p1<*p2)
					*p1=*p2;
			}
		}
	}

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

	//模板卷积函数调用
	TemplateEdge(m_pImgData, m_imgWidth, m_imgHeight, m_nBitCount, mask, 3, 3, buf);

	//求两幅缓存图像的最大值,并将大的值存入m_pImgDataOut中
	for(i=0;i<m_imgHeight;i++){
		for(j=0;j<m_imgWidth;j++){
			for(k=0;k<pixelByte;k++){
				p1=m_pImgDataOut+i*lineByte+j*pixelByte+k;
				p2=buf+i*lineByte+j*pixelByte+k;
				if(*p1<*p2)
					*p1=*p2;
			}
		}
	}

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

	//模板卷积函数调用
	TemplateEdge(m_pImgData, m_imgWidth, m_imgHeight, m_nBitCount, 
		         mask, 3, 3, buf);

	//求两幅缓存图像的最大值,并将大的值存入m_pImgDataOut中
	for(i=0;i<m_imgHeight;i++){
		for(j=0;j<m_imgWidth;j++){
			for(k=0;k<pixelByte;k++){
				p1=m_pImgDataOut+i*lineByte+j*pixelByte+k;
				p2=buf+i*lineByte+j*pixelByte+k;
				if(*p1<*p2)
					*p1=*p2;
			}
		}
	}

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

	//模板卷积函数调用
	TemplateEdge(m_pImgData, m_imgWidth, m_imgHeight, m_nBitCount, 
		         mask, 3, 3, buf);

	//求两幅缓存图像的最大值,并将大的值存入m_pImgDataOut中
	for(i=0;i<m_imgHeight;i++){
		for(j=0;j<m_imgWidth;j++){
			for(k=0;k<pixelByte;k++){
				p1=m_pImgDataOut+i*lineByte+j*pixelByte+k;
				p2=buf+i*lineByte+j*pixelByte+k;
				if(*p1<*p2)
					*p1=*p2;
			}
		}
	}

	// 设置Kirsch模板8参数
	mask[0] = 5;
	mask[1] = 5;
	mask[2] = -3;
	mask[3] = 5;
	mask[4] = 0;
	mask[5] = -3;
	mask[6] = -3;
	mask[7] = -3;
	mask[8] = -3;
	//模板卷积函数调用
	TemplateEdge(m_pImgData, m_imgWidth, m_imgHeight, m_nBitCount, 
		         mask, 3, 3, buf);

	//求两幅缓存图像的最大值,并将大的值存入m_pImgDataOut中
	for(i=0;i<m_imgHeight;i++){
		for(j=0;j<m_imgWidth;j++){
			for(k=0;k<pixelByte;k++){
				if(*(m_pImgDataOut+i*lineByte+j*pixelByte+k)<*(buf+i*lineByte+j*pixelByte+k))
					*(m_pImgDataOut+i*lineByte+j*pixelByte+k)=*(buf+i*lineByte+j*pixelByte+k);
			}
		}
	}
}

/***********************************************************************
* 函数名称:
* GaussLaplacian()
*
*函数参数:
*  无
*
*返回值:
*   无
*
*说明:Gauss-Laplacian边缘检测,同时适合于灰度和彩色图像
***********************************************************************/
void ImgSegment::GaussLaplacian()
{
	//定义Gauss-Laplacian模板
	int mask[25];
	mask[0] = -2;
	mask[1] = -4;
	mask[2] = -4;
	mask[3] = -4;
	mask[4] = -2;
	mask[5] = -4;
	mask[6] = 0;
	mask[7] = 8;
	mask[8] = 0;
	mask[9] = -4;
	mask[10] = -4;
	mask[11] = 8;
	mask[12] = 24;
	mask[13] = 8;
	mask[14] = -4;
	mask[15] = -4;
	mask[16] = 0;
	mask[17] = 8;
	mask[18] = 0;
	mask[19] = -4;
	mask[20] = -2;
	mask[21] = -4;
	mask[22] = -4;
	mask[23] = -4;
	mask[24] = -2;

	//释放m_pImgDataOut指向的图像数据空间
	if(m_pImgDataOut!=NULL){
		delete []m_pImgDataOut;
    	m_pImgDataOut=NULL;
	}
	//释放颜色表空间
	if(m_lpColorTableOut!=NULL){
		delete []m_lpColorTableOut;
		m_lpColorTableOut=NULL;
	}

	//输出图像与输入图像为同一类型
	m_nBitCountOut=m_nBitCount;

	//输出图像颜色表长度
	m_nColorTableLengthOut=ComputeColorTabalLength(m_nBitCountOut);

	//输出图像颜色表,与输入图像相同
	if(m_nColorTableLengthOut!=0){
    	m_lpColorTableOut=new RGBQUAD[m_nColorTableLengthOut];
		memcpy(m_lpColorTableOut,m_lpColorTable,sizeof(RGBQUAD)*m_nColorTableLengthOut);
	}

	//输出图像的宽高,与输入图像相等
	m_imgWidthOut=m_imgWidth;
	m_imgHeightOut=m_imgHeight;

	//每行像素所占字节数,输出图像与输入图像相同
	int lineByte=(m_imgWidth*m_nBitCount/8+3)/4*4;

	//申请输出图像缓冲区
	m_pImgDataOut=new unsigned char[lineByte*m_imgHeight];

	//模板卷积函数调用
	TemplateEdge(m_pImgData, m_imgWidth, m_imgHeight, m_nBitCount, mask, 5, 5, m_pImgDataOut);

}


/***********************************************************************
* 函数名称:
* HoughTransform()
*
*函数参数:
*  unsigned char *imgBinaryIn  -二值图像输入数据指针
*  int width  -图像的 宽
*  int height -图像的高
*  int *houghBuf  -Hough变换所需要的缓冲区指针
*  int  houghWidth  -Hough变换缓冲区的宽
*  int houghHeight  -Hough变换缓冲区的高
*  float radiusResolution  -Hough变换的极坐标半径的检测分辨率
*  float angleResolution  -Hough变换的角度检测分辨率 
*  float *radius  -用来返回Hough变换检测出来的最长直线的极半径
*  float *angle   -用来返回Hough变换检测出来的最长直线的角度

*返回值:
*   无
*
*说明:给定图像数据,通过线检测hough变换检测直线
***********************************************************************/
void ImgSegment::HoughTransform(unsigned char *imgBinaryIn, int width, 
			int height, int *houghBuf, int  houghWidth, int houghHeight,
		    float radiusResolution, float angleResolution, 
		    float *radius, float *angle)
{
	//申请循环变量
	int i, j;

	//清理变换空间累加数组
	for(i=0;i<houghHeight;i++){
		for(j=0;j<houghWidth;j++){
			*(houghBuf+i*houghWidth+j)=0;
		}
	}

	//循环变量
	int r, a;

	//中间变量
	float tempR, tempA; 

	//遍历图像数据
	for(i=0;i<height;i++){
		for(j=0;j<width;j++){
			//出现一个目标点
			if(*(imgBinaryIn+i*width+j)==0){

				//a代表角度的循环变量,在变换空间累加数组的垂直方向上
				for(a=0;a<houghHeight;a++){

					//按照给定变换角度的分辨率,求取角度
					tempA=(a-houghHeight/2)*angleResolution;

					//根据当前遍历的角度及x,y值求取对应极半径
					tempR=(j-width/2)*cos(tempA*2*3.1415926/360)+(i-height/2)*sin(tempA*2*3.1415926/360);
					r=tempR/radiusResolution;

					//累加数组累加
					*(houghBuf+a*houghWidth+ r+houghWidth/2)+=1;
				}
			}
		}
	}

	//求累加数组的极大值,并记录此时的数组坐标
	int max, maxR, maxA;
	max=*(houghBuf+0*houghWidth+0);
	maxR=0;
	maxA=0;
	for(a=0;a<houghHeight;a++){
		for(r=0;r<houghWidth;r++){
			if(max<=*(houghBuf+a*houghWidth+r)){
				max=*(houghBuf+a*houghWidth+r);
				maxR=r;
				maxA=a;
			}
		}
	}

	//将极大值位置转换成极坐标半径和角度,并通过参数返回
	*radius=(maxR-houghWidth/2)*radiusResolution;
	*angle=(maxA-houghHeight/2)*angleResolution;
}


/***********************************************************************
* 函数名称:
* Hough()
*
*函数参数:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -