📄 jisuanprocessdib.cpp
字号:
// 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 + -