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

📄 jisuanprocessdib.cpp

📁 学习数字图像处理
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// JisuanProcessDib.cpp: implementation of the JisuanProcessDib class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "DSplit.h"
#include "JisuanProcessDib.h"
#include "SquareDlg.h"
#include "LINEDLG.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

JisuanProcessDib::JisuanProcessDib()
{
	x_sign=0;
	m_temp=0;
	x_temp=0;
	y_temp=0;
    p_temp=0;
	stop=0;
}

JisuanProcessDib::~JisuanProcessDib()
{
	
}

/***************************************************************/
/*函数名称:erzhihua(int yuzhi_gray)                           */
/*函数类型:void                                               */
/*参数:int yuzhi_gray,用户给定的阈值                         */
/*功能:对图像使用固定阈值法进行二值化。                       */
/***************************************************************/
void JisuanProcessDib::erzhihua(int yuzhi_gray)
{
	p_data=this->GetData ();   //取得原图的数据区指针
    wide=this->GetWidth ();  //取得原图的数据区宽度
    height=this->GetHeight ();   //取得原图的数据区高度
    if(m_pBitmapInfoHeader->biBitCount<9)	//灰度图像
	{
		for(int j=0;j<height;j++)	// 每行
			for(int i=0;i<wide;i++)	// 每列
			{
				int temp=0;
				temp= *(p_data+(height-j-1)*wide+i);
				if(temp<yuzhi_gray)
					*(p_data+(height-j-1)*wide+i)=0;
				else
					*(p_data+(height-j-1)*wide+i)=255;
			}
	}
	else	//24位彩色
	{
		for(int j=0;j<height;j++)	// 每行
			for(int i=0;i<wide;i++)	// 每列
			{
				int temp=0;
				temp= *(p_data+(height-j-1)*wide*3+i*3);
				if(temp<yuzhi_gray)
				{
					*(p_data+(height-j-1)*wide*3+i*3)=0;
					*(p_data+(height-j-1)*wide*3+i*3+1)=0;
					*(p_data+(height-j-1)*wide*3+i*3+2)=0;
				}
				else
				{
					*(p_data+(height-j-1)*wide*3+i*3)=255;
					*(p_data+(height-j-1)*wide*3+i*3+1)=255;
					*(p_data+(height-j-1)*wide*3+i*3+2)=255;
				}
			}
	}
}

/***************************************************************/
/*函数名称:xiaochugulidianHEI()                               */
/*函数类型:void                                               */
/*功能:消除孤立黑点。                                         */
/***************************************************************/
void JisuanProcessDib::xiaochugulidianHEI()
{
	p_data=this->GetData ();   //取得原图的数据区指针
    wide=this->GetWidth ();  //取得原图的数据区宽度
    height=this->GetHeight ();   //取得原图的数据区高度
	if(m_pBitmapInfoHeader->biBitCount<9)	//灰度图像
	{
		for(int j=1;j<height-1;j++)	// 每行
			for(int i=1;i<wide-1;i++)	// 每列
			{
				int temp=0;	
				if(*(p_data+(height-j-1)*wide+i)==0)//本身为黑点
				{
					for(int m=0;m<3;m++)
						for(int n=0;n<3;n++)
						{
							temp+=*(p_data+(height-j-m)*wide+i+n-1);
						}
					if(temp>=255*6)///周围8个中点有大于等于6个白点
						*(p_data+(height-j-1)*wide+i)=255;
				}
			}
	}
	else	//24位彩色
	{
		for(int j=1;j<height-1;j++)	// 每行
			for(int i=1;i<wide-1;i++)	// 每列
			{
				int temp=0;	
				if(*(p_data+(height-j-1)*wide*3+i*3)==0)//本身为黑点
				{
					for(int m=0;m<3;m++)
						for(int n=0;n<3;n++)
						{
							temp+=*(p_data+(height-j-m)*wide*3+(i+n-1)*3);
						}
					if(temp>=255*6)///周围8个中点有大于等于6个白点
					{
						*(p_data+(height-j-1)*wide*3+i*3)=255;
						*(p_data+(height-j-1)*wide*3+i*3+1)=255;
						*(p_data+(height-j-1)*wide*3+i*3+2)=255;
					}
				}
			}
	}
}

/***************************************************************/
/*函数名称:xiaochugulidianBAI()                               */
/*函数类型:void                                               */
/*功能:消除孤立白点。                                         */
/***************************************************************/
void JisuanProcessDib::xiaochugulidianBAI()
{
	p_data=this->GetData ();   //取得原图的数据区指针
    wide=this->GetWidth ();  //取得原图的数据区宽度
    height=this->GetHeight ();   //取得原图的数据区高度
	if(m_pBitmapInfoHeader->biBitCount<9)	//灰度图像
	{
		for(int j=1;j<height-1;j++)	// 每行
			for(int i=1;i<wide-1;i++)	// 每列
			{
				int temp=0;			;
				if(*(p_data+(height-j-1)*wide+i)==255)//本身为白点
				{
					for(int m=0;m<3;m++)
						for(int n=0;n<3;n++)
						{
							temp+=*(p_data+(height-j-m)*wide+i+n-1);
						}
					if(temp<=255*3)///周围8个点中有小于等于2个白点
						*(p_data+(height-j-1)*wide+i)=0;
				}
			}
	}
	else	//24位彩色
	{
		for(int j=1;j<height-1;j++)	// 每行
			for(int i=1;i<wide-1;i++)	// 每列
			{
				int temp=0;			;
				if(*(p_data+(height-j-1)*wide*3+i*3)==255)//本身为白点
				{
					for(int m=0;m<3;m++)
						for(int n=0;n<3;n++)
						{
							temp+=*(p_data+(height-j-m)*wide*3+(i+n-1)*3);
						}
					if(temp<=255*3)///周围8个点中有小于等于2个白点
					{
						*(p_data+(height-j-1)*wide*3+i*3)=0;
						*(p_data+(height-j-1)*wide*3+i*3+1)=0;
						*(p_data+(height-j-1)*wide*3+i*3+2)=0;
					}
				}
			}
	}
}

/***************************************************************/
/*函数名称:biaoji()                                           */
/*函数类型:void                                               */
/*功能:对图像进行标记,划分成不同的连通区域。                  */
/***************************************************************/
void JisuanProcessDib::biaoji()
{
	x_sign=0; 
	m_temp=0;
	x_temp=0;
	y_temp=0;
	stop=0;
	memset(flag,0,255);
	p_data=this->GetData ();   //取得原图的数据区指针
    wide=this->GetWidth ();  //取得原图的数据区宽度
    height=this->GetHeight ();   //取得原图的数据区高度
    if(m_pBitmapInfoHeader->biBitCount<9)	//灰度图像
	{
		p_temp=new BYTE[wide*height];//开辟一个临时内存区
		memset(p_temp,255,wide*height);
		//从左到右标号
		for(int j=1;j<height-1;j++)	// 每行
		{
			if(stop==1)//判断连通区是否太多
				break;
			for(int i=1;i<wide-1;i++)	// 每列
			{
				if(x_sign>250)
				{
					AfxMessageBox("连通区数目太多,请增大阈值");
					stop=1;
					break;
				}
				if(*(p_data+(height-j-1)*wide+i)==0)//若当前点为黑点
				{
					if(*(p_data+(height-j-1+1)*wide+i+1)==0)//右上
					{
						*(p_temp+(height-j-1)*wide+i)=*(p_temp+(height-j-1+1)*wide+i+1);
						x_temp=*(p_temp+(height-j-1+1)*wide+i+1);
						flag[x_temp]+=1;
						if(*(p_data+(height-j-1)*wide+i-1)==0&&*(p_temp+(height-j-1)*wide+i-1)!=x_temp)//左前
						{
							y_temp=*(p_temp+(height-j-1)*wide+i-1);
							for(int m=1;m<=height-1;m++)
								for(int n=1;n<=wide-1;n++)
								{
									if(*(p_temp+(height-m-1)*wide+n)==y_temp)
									{	
										flag[y_temp]=0;
										*(p_temp+(height-m-1)*wide+n)=x_temp;
										flag[x_temp]+=1;
									}
								}
						}//end//左前
						if(*(p_data+(height-j-1+1)*wide+i-1)==0&&*(p_temp+(height-j-1+1)*wide+i-1)!=x_temp)//左上
						{
							y_temp=*(p_temp+(height-j-1+1)*wide+i-1);
							for(int m=1;m<=height-1;m++)
								for(int n=1;n<=wide-1;n++)
								{
									if(*(p_temp+(height-m-1)*wide+n)==y_temp)
									{	
										flag[y_temp]=0;
										*(p_temp+(height-m-1)*wide+n)=x_temp;
										flag[x_temp]+=1;
									}
								}
						}//end//左上
					}
					else if(*(p_data+(height-j-1+1)*wide+i)==0)//正上
					{
						*(p_temp+(height-j-1)*wide+i)=*(p_temp+(height-j-1+1)*wide+i);
						x_temp=*(p_temp+(height-j-1+1)*wide+i);
						flag[x_temp]+=1;
					}
					else if(*(p_data+(height-j-1+1)*wide+i-1)==0)//左上
					{
						*(p_temp+(height-j-1)*wide+i)=*(p_temp+(height-j-1+1)*wide+i-1);
						x_temp=*(p_temp+(height-j-1+1)*wide+i-1);
						flag[x_temp]+=1;
					}
					else if(*(p_data+(height-j-1)*wide+i-1)==0)//左前
					{
						*(p_temp+(height-j-1)*wide+i)=*(p_temp+(height-j-1)*wide+i-1);
						x_temp=*(p_temp+(height-j-1)*wide+i-1);
						flag[x_temp]+=1;
					}
					else//没有
					{				
						++x_sign;
						m_temp=x_sign;
						*(p_temp+(height-j-1)*wide+i)=m_temp;
						flag[m_temp]=1;
						
					}
				}//end if
			}// 每列
		}//end 每行
	}
	else	//24位彩色
	{
		p_temp=new BYTE[wide*height];//开辟一个临时内存区
		memset(p_temp,255,wide*height);
		//从左到右标号
		for(int j=1;j<height-1;j++)	// 每行
		{
			if(stop==1)//判断连通区是否太多
				break;
			for(int i=1;i<wide-1;i++)	// 每列
			{
				if(x_sign>250)
				{
					AfxMessageBox("连通区数目太多,请增大阈值");
					stop=1;
					break;
				}
				if(*(p_data+(height-j-1)*wide*3+i*3)==0)//若当前点为黑点
				{
					
					if(*(p_data+(height-j-1+1)*wide*3+(i+1)*3)==0)//右上
					{
						*(p_temp+(height-j-1)*wide+i)=*(p_temp+(height-j-1+1)*wide+(i+1));
						x_temp=*(p_temp+(height-j-1+1)*wide+(i+1));
						flag[x_temp]+=1;
						if(*(p_data+(height-j-1)*wide*3+(i-1)*3)==0&&*(p_temp+(height-j-1)*wide+(i-1))!=x_temp)//左前
						{
							y_temp=*(p_temp+(height-j-1)*wide+(i-1));
							for(int m=1;m<=height-1;m++)
								for(int n=1;n<=wide-1;n++)
								{
									if(*(p_temp+(height-m-1)*wide+n)==y_temp)
									{	
										flag[y_temp]=0;
										*(p_temp+(height-m-1)*wide+n)=x_temp;
										
										flag[x_temp]+=1;
									}
								}
						}//end//左前
						if(*(p_data+(height-j-1+1)*wide*3+(i-1)*3)==0&&*(p_temp+(height-j-1+1)*wide+(i-1))!=x_temp)//左上
						{
							y_temp=*(p_temp+(height-j-1+1)*wide+(i-1));
							for(int m=1;m<=height-1;m++)
								for(int n=1;n<=wide-1;n++)
								{
									if(*(p_temp+(height-m-1)*wide+n)==y_temp)
									{	
										flag[y_temp]=0;
										*(p_temp+(height-m-1)*wide+n)=x_temp;
										
										flag[x_temp]+=1;
									}
								}
						}//end//左上
					}
					else if(*(p_data+(height-j-1+1)*wide*3+i*3)==0)//正上
					{
						*(p_temp+(height-j-1)*wide+i)=*(p_temp+(height-j-1+1)*wide+i);
						x_temp=*(p_temp+(height-j-1+1)*wide+i);
						flag[x_temp]+=1;
					}
					else if(*(p_data+(height-j-1+1)*wide*3+(i-1)*3)==0)//左上
					{
						*(p_temp+(height-j-1)*wide+i)=*(p_temp+(height-j-1+1)*wide+(i-1));
						x_temp=*(p_temp+(height-j-1+1)*wide+(i-1));
						flag[x_temp]+=1;
					}
					else if(*(p_data+(height-j-1)*wide*3+(i-1)*3)==0)//左前
					{
						*(p_temp+(height-j-1)*wide+i)=*(p_temp+(height-j-1)*wide+i-1);
						x_temp=*(p_temp+(height-j-1)*wide+(i-1));
						flag[x_temp]+=1;
					}
					else//没有
					{				
						++x_sign;
						m_temp=x_sign;
						*(p_temp+(height-j-1)*wide+i)=m_temp;
						
						flag[m_temp]=1;
					}
				}//end if
			}// 每列
		}//end 每行
	}
}

/***************************************************************/
/*函数名称:LianTong()                                         */
/*函数类型:void                                               */
/*功能:对连通区调整,输出每个连通区的面积。                    */
/***************************************************************/
void JisuanProcessDib::LianTong()
{
	biaoji();  //调用标记函数
	if(stop!=1)//判断连通区是否太多
	{
		int fg[255]={0};//定义一个数组
		memset(fg,0,255);//初始化赋值都为0
		int y_sign=0;
		int m_Area=0;//定义一个面积
		for(int i=1;i<=x_sign;i++)
		{
			if(flag[i]!=0)
			{
				if(fg[y_sign]==0)
				{
					fg[y_sign]=flag[i];
					++y_sign;
				}			
			}
			m_Area+=flag[i];
		}
		SquareDlg  dlg;//输出对话框
		dlg.m_number=y_sign;//输出连通区域个数
		dlg.m_squareALL=m_Area;//输出连通区域的总积
		CString ss[20];
		//在对话框里输出每个连通区的面积(区域像素个数)
		for(i=0;i<y_sign;i++)
		{
			ss[i].Format("连通区:%3d  该区面积:%10.0d",i+1,fg[i]);
			dlg.m_ShuChu+=ss[i];
		}
		dlg.DoModal();
		for(i=0;i<255;i++) //初试设置pp_area都为0
		{
			pppp[i].pp_area=0;
		}
		for(int t=1;t<=x_sign;t++)
		{	pppp[t].pp_number=t;
		for(int j=1;j<height-1;j++)
			for(int i=1;i<wide-1;i++)
			{
				if(*(p_temp+(height-j-1)*wide+i)==t)

⌨️ 快捷键说明

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