📄 jisuanprocessdib.cpp
字号:
{
pppp[t].pp_x=i;
pppp[t].pp_y=j;
pppp[t].pp_area=flag[t];
break;
}
}
}
}//end if(stop!=1)
}
/***************************************************************/
/*函数名称:ClearSMALL(int m_value) */
/*函数类型:void */
/*参数:int m_value,用户给定的阈值 */
/*功能:消除面积小于给定的阈值的小区域。 */
/***************************************************************/
void JisuanProcessDib::ClearSMALL(int m_value)
{
biaoji(); //调用标记函数
if(m_pBitmapInfoHeader->biBitCount<9) //灰度图像
{
if(stop!=1)//判断连通区是否太多
{
for(int i=1;i<=x_sign;i++)
{
if(flag[i]<m_value)//判断连通区的面积(像素个数)是否消除
{
for(int m=1;m<height-1;m++)
for(int n=1;n<wide-1;n++)
{
if(*(p_temp+(height-m-1)*wide+n)==i)
*(p_data+(height-m-1)*wide+n)=255;
}
}
}
}
}
else //24位彩色
{
if(stop!=1)//判断连通区是否太多
{
for(int i=1;i<=x_sign;i++)
{
if(flag[i]<m_value)//判断连通区的面积(像素个数)是否消除
{
for(int m=1;m<height-1;m++)
for(int n=1;n<wide-1;n++)
{
if(*(p_temp+(height-m-1)*wide+n)==i)
{
*(p_data+(height-m-1)*wide*3+n*3)=255;
*(p_data+(height-m-1)*wide*3+n*3+1)=255;
*(p_data+(height-m-1)*wide*3+n*3+2)=255;
}
}
}
}
}
}
}
/***************************************************************/
/*函数名称:Borderline() */
/*函数类型:void */
/*功能:对每个连通区进行边界跟踪,提取边界,输出周长。 */
/***************************************************************/
void JisuanProcessDib::Borderline()
{
biaoji(); //调用标记函数
LPBYTE lpSrc; // 指向源图像的指针
LPBYTE lpDst; // 指向缓存图像的指针
LPBYTE temp; // 指向缓存DIB图像的指针
int pixel; //像素值
bool bFindStartPoint; //是否找到起始点及回到起始点
bool bFindPoint; //是否扫描到一个边界点
Point StartPoint,CurrentPoint; //起始边界点与当前边界点
//八个方向和起始扫描方向
int Direction[8][2]={{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0}};
int BeginDirect;
if(m_pBitmapInfoHeader->biBitCount<9) //灰度图像
{
temp = new BYTE[wide*height]; // 暂时分配内存,以保存新图像
lpDst = temp; // 初始化新分配的内存,设定初始值为255
memset(lpDst, (BYTE)255, wide * height);
if(stop!=1)//判断连通区是否太多
{
//先找到最左上方的边界点
for(int t=1;t<=x_sign;t++)
{
if(flag[t]!=0)
{
bFindStartPoint = false;
for (int j = 0;j < height && !bFindStartPoint;j++)
{
for(int i = 0;i < wide && !bFindStartPoint;i++)
{
// 指向源图像倒数第j行,第i个象素的指针
lpSrc = (LPBYTE)(p_temp + wide * j + i);
//取得当前指针处的像素值,注意要转换为unsigned char型
pixel = *lpSrc;
if(pixel ==t)
{
bFindStartPoint = true;
StartPoint.Height = j;
StartPoint.Width = i;
// 指向目标图像倒数第j行,第i个象素的指针
lpDst = (LPBYTE)(temp + wide * j + i);
*lpDst = t;
}
}
}
//由于起始点是在左下方,故起始扫描沿左上方向
BeginDirect = 0;
//跟踪边界
bFindStartPoint = false;
//从初始点开始扫描
CurrentPoint.Height = StartPoint.Height;
CurrentPoint.Width = StartPoint.Width;
while(!bFindStartPoint)
{
bFindPoint = false;
while(!bFindPoint)
{
//沿扫描方向查看一个像素
lpSrc = (LPBYTE)(p_temp + wide * ( CurrentPoint.Height + Direction[BeginDirect][1])
+ (CurrentPoint.Width + Direction[BeginDirect][0]));
pixel = *lpSrc;
if(pixel == t)
{
bFindPoint = true;
CurrentPoint.Height = CurrentPoint.Height + Direction[BeginDirect][1];
CurrentPoint.Width = CurrentPoint.Width + Direction[BeginDirect][0];
if(CurrentPoint.Height == StartPoint.Height && CurrentPoint.Width == StartPoint.Width)
{
bFindStartPoint = true;
}
lpDst = (LPBYTE)(temp + wide * CurrentPoint.Height + CurrentPoint.Width);
*lpDst = t;
//扫描的方向逆时针旋转两格
BeginDirect--;
if(BeginDirect == -1)
BeginDirect = 7;
BeginDirect--;
if(BeginDirect == -1)
BeginDirect = 7;
}
else
{
//扫描方向顺时针旋转一格
BeginDirect++;
if(BeginDirect == 8)
BeginDirect = 0;
}
}//////end{while(!bFindPoint)}
}//////end{while(!bFindStartPoint)}
}//////end{if(flag[t]!=0)}
}//////end{for(int t=1;t<=x_sign;t++)}
memcpy(p_data, temp, wide * height);// 复制到原数据区
delete[] temp; // 释放内存
/////////////////////////////////////////////////
int x_line=0;
int fm[255]={0};//定义一个数组
memset(fm,0,255);//初始化赋值都为0
//统计每个边界的像素个数
for(int j=0;j<height;j++)
{
for(int i=0;i<wide;i++)
{
if(*(p_data+(height-j-1)*wide+i)!=0)
{
x_line=*(p_data+(height-j-1)*wide+i);
++fm[x_line];
}
}
}
int fn[255]={0};//定义一个数组
memset(fn,0,255);//初始化赋值都为0
int y_line=0;
int m_line=0;//定义一个总面积
for(int i=0;i<x_line;i++)
{
if(fm[i]!=0)
{
if(fn[y_line]==0)
{
fn[y_line]=fm[i];
++y_line;
}
}
m_line+=fm[i];
}
LINEDLG dlg;//输出对话框
dlg.m_shumu=y_line;//输出连通区域个数
dlg.m_zongshu=m_line;//输出连通区域的总积
CString ss[20];
//在对话框里输出每个连通区的周长(边界像素个数)
for(i=0;i<y_line;i++)
{
ss[i].Format("连通区:%3d 该区周长:%10.0d",i+1,fn[i]);
dlg.m_line+=ss[i];
}
dlg.DoModal();
/////////////////////////////////////////////////////////////////
for(i=0;i<255;i++) //初试设置pp_lin都为0
{
pppp[i].pp_line=0;
}
for(t=1;t<=x_line;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)
{
pppp[t].pp_x=i;
pppp[t].pp_y=j;
pppp[t].pp_line=fm[t];
break;
}
}
}
}//end if(stop!=1)
}
else //24位彩色
{
p_data=this->GetData();
temp = new BYTE[wide*height*3]; // 暂时分配内存,以保存新图像
lpDst = temp; // 初始化新分配的内存,设定初始值为255
memset(lpDst, (BYTE)255, wide * height*3);
if(stop!=1)//判断连通区是否太多
{
//先找到最左上方的边界点
for(int t=1;t<=x_sign;t++)
{
if(flag[t]!=0)
{
bFindStartPoint = false;
for (int j = 0;j < height && !bFindStartPoint;j++)
{
for(int i = 0;i < wide && !bFindStartPoint;i++)
{
// 指向源图像倒数第j行,第i个象素的指针
lpSrc = (LPBYTE)(p_temp + wide * j + i);
//取得当前指针处的像素值,注意要转换为unsigned char型
pixel = *lpSrc;
if(pixel ==t)
{
bFindStartPoint = true;
StartPoint.Height = j;
StartPoint.Width = i;
// 指向目标图像倒数第j行,第i个象素的指针
lpDst = (LPBYTE)(temp + wide * j*3 + i*3);
*lpDst = t;
*(lpDst+1) = t;
*(lpDst+2) = t;
}
}
}
//由于起始点是在左下方,故起始扫描沿左上方向
BeginDirect = 0;
//跟踪边界
bFindStartPoint = false;
//从初始点开始扫描
CurrentPoint.Height = StartPoint.Height;
CurrentPoint.Width = StartPoint.Width;
while(!bFindStartPoint)
{
bFindPoint = false;
while(!bFindPoint)
{
//沿扫描方向查看一个像素
lpSrc = (LPBYTE)(p_temp + wide * ( CurrentPoint.Height + Direction[BeginDirect][1])
+ (CurrentPoint.Width + Direction[BeginDirect][0]));
pixel = *lpSrc;
if(pixel == t)
{
bFindPoint = true;
CurrentPoint.Height = CurrentPoint.Height + Direction[BeginDirect][1];
CurrentPoint.Width = CurrentPoint.Width + Direction[BeginDirect][0];
if(CurrentPoint.Height == StartPoint.Height && CurrentPoint.Width == StartPoint.Width)
{
bFindStartPoint = true;
}
lpDst = (LPBYTE)(temp + 3*wide * CurrentPoint.Height + CurrentPoint.Width*3);
*lpDst = t;
*(lpDst+1) = t;
*(lpDst+2) = t;
//扫描的方向逆时针旋转两格
BeginDirect--;
if(BeginDirect == -1)
BeginDirect = 7;
BeginDirect--;
if(BeginDirect == -1)
BeginDirect = 7;
}
else
{
//扫描方向顺时针旋转一格
BeginDirect++;
if(BeginDirect == 8)
BeginDirect = 0;
}
}//////end{while(!bFindPoint)}
}//////end{while(!bFindStartPoint)}
}//////end{if(flag[t]!=0)}
}//////end{for(int t=1;t<=x_sign;t++)}
memcpy(p_data, temp, wide * height*3);// 复制到原数据区
delete[] temp; // 释放内存
/////////////////////////////////////////////////
int x_line=0;
int fm[255]={0};//定义一个数组
memset(fm,0,255);//初始化赋值都为0
//统计每个边界的像素个数
for(int j=0;j<height;j++)
for(int i=0;i<wide;i++)
{
if(*(p_data+(height-j-1)*wide*3+i*3)!=0)
{
x_line=*(p_data+(height-j-1)*wide*3+i*3);
++fm[x_line];
}
}
int fn[255]={0};//定义一个数组
memset(fn,0,255);//初始化赋值都为0
int y_line=0;
int m_line=0;//定义一个总面积
for(int i=0;i<x_line;i++)
{
if(fm[i]!=0)
{
if(fn[y_line]==0)
{
fn[y_line]=fm[i];
++y_line;
}
}
m_line+=fm[i];
}
LINEDLG dlg;//输出对话框
dlg.m_shumu=y_line;//输出连通区域个数
dlg.m_zongshu=m_line;//输出连通区域的总积
CString ss[20];
//在对话框里输出每个连通区的周长(边界像素个数)
for(i=0;i<y_line;i++)
{
ss[i].Format("连通区:%3d 该区周长:%10.0d",i+1,fn[i]);
dlg.m_line+=ss[i];
}
dlg.DoModal();
/////////////////////////////////////////////////////////////////
for(i=0;i<255;i++) //初试设置pp_lin都为0
{
pppp[i].pp_line=0;
}
for(t=1;t<=x_line;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)
{
pppp[t].pp_x=i;
pppp[t].pp_y=j;
pppp[t].pp_line=fm[t];
break;
}
}
}
}//end if(stop!=1)
}
}
//将24位彩色图像转换为24位灰度图
void JisuanProcessDib::MakeGray()
{
BYTE *p_data; //原图数据区指针
int wide,height,DibWidth; //原图长、宽、字节宽
p_data=this->GetData (); //取得原图的数据区指针
wide=this->GetWidth (); //取得原图的数据区宽度
height=this->GetHeight (); //取得原图的数据区高度
DibWidth=this->GetDibWidthBytes(); //取得原图的每行字节数
for(int j=0;j<height;j++) // 每行
for(int i=0;i<DibWidth;i+=3) // 每列
{
BYTE* pbyBlue = p_data++; //得到蓝色值
BYTE* pbyGreen = p_data++; //得到绿色值
BYTE* pbyRed = p_data++; //得 到红色值
BYTE r = *pbyRed;
BYTE g = *pbyGreen;
BYTE b = *pbyBlue;
int gray=0;
gray=(30*r+59*g+11*b)/100;
*pbyBlue = gray;
*pbyGreen = gray;
*pbyRed = gray;
}
}
//保存未处理的原图像
void JisuanProcessDib::Baoliu(LPBYTE temp)
{
// 指向DIB象素指针
LPBYTE p_data;
// 指向缓存图像的指针
LPBYTE lpDst;
// 找到DIB图像象素起始位置
p_data= GetData();
// DIB的宽度
LONG wide = GetDibWidthBytes();
// DIB的高度
LONG height = GetHeight();
// 初始化新分配的内存,设定初始值为255
lpDst = (LPBYTE)temp;
memset(lpDst, (BYTE)255, wide * height);
memcpy(lpDst,p_data,wide*height);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -