?? bingxingbianjiedib.cpp
字號:
}
//判斷右面的點,如果為白,則壓入堆棧
//注意防止越界
if(iCurrentPixelx < wide - 1)
{
lpSrc = (LPBYTE)temp + wide * iCurrentPixely + iCurrentPixelx + 1;
//取得當前指針處的像素值,注意要轉換為unsigned char型
pixel = *lpSrc;
if (pixel == 255)
{
StackPoint++;
Seeds[StackPoint].Height = iCurrentPixely;
Seeds[StackPoint].Width = iCurrentPixelx + 1;
}
}
//判斷下面的點,如果為白,則壓入堆棧
//注意防止越界
if(iCurrentPixely > 0)
{
lpSrc = (LPBYTE)temp + wide * (iCurrentPixely - 1) + iCurrentPixelx;
//取得當前指針處的像素值,注意要轉換為unsigned char型
pixel = *lpSrc;
if (pixel == 255)
{
StackPoint++;
Seeds[StackPoint].Height = iCurrentPixely - 1;
Seeds[StackPoint].Width = iCurrentPixelx;
}
}
}
//釋放堆棧
delete Seeds;
}
}
///***************************************************************/
/*函數名稱:Yuzhifenge(int Yuzhi)
/*函數類型:void
/*參數說明:Yuzhi ---閾值選取
/*功能:對圖像進行閾值分割。
/***************************************************************/
void BingXingBianJieDib::Yuzhifenge(int Yuzhi)
{
// 指向源圖像的指針
LPBYTE p_data;
LPBYTE lpSrc;
// 指向緩存圖像的指針
LPBYTE lpDst;
// 指向緩存DIB圖像的指針
LPBYTE temp;
//循環變量
long i;
long j;
//圖像的高和寬
long wide;
long height;
p_data=GetData();
if(m_pBitmapInfoHeader->biBitCount<9) //灰度圖像
wide=GetWidth();
else //24位彩色
wide=GetDibWidthBytes();
height=GetHeight();
temp=new BYTE[wide*height];
memset(temp,255,wide*height);
for (j=0;j<height;j++)
{
for(i=0;i<wide;i++)
{
lpSrc=p_data+wide*j+i;
lpDst=temp+wide*j+i;
if(abs(*lpSrc-Yuzhi)<30)
*lpDst=Yuzhi;
}
}
memcpy(p_data,temp,wide*height);
delete temp;
}
///***************************************************************/
/*函數名稱:Qiyuzengzhang(CPoint point)
/*函數類型:void
/*參數說明:point ---獲得生長點
/*功能:對圖像進行區域生長。
/***************************************************************/
void BingXingBianJieDib::Qiyuzengzhang(CPoint point)
{
// 循環變量
int i;
int j;
// 指向DIB象素指針
LPBYTE p_data;
// 找到DIB圖像象素起始位置
p_data=GetData();
// DIB的寬度
LONG wide = GetWidth();
// DIB的高度
LONG height =GetHeight();
if(m_pBitmapInfoHeader->biBitCount<9) //灰度圖像
{
// 計算種子點一的灰度值
unsigned char zhongzi=*(p_data+point.y*wide+point.x);
// 對各像素進行灰度轉換
for (j = 0; j < height; j ++)
{
for (i = 0; i < wide; i ++)
{
//獲取各顏色分量
unsigned char temp = *((unsigned char *)p_data + wide * j +i);
if (abs(temp - zhongzi) < 10) //當前點同種子一灰度值比較接近
{
//將種子一的顏色賦給當前像素
*((unsigned char *)p_data + wide * j + i ) = temp;
}
else
*((unsigned char *)p_data + wide * j + i ) =255;
}
}
}
else //24位彩色
{
// 計算種子點一的灰度值
int zhongzi=*(p_data+(height-point.y)*wide*3+point.x*3);
int zhongzi2=*(p_data+(height-point.y)*wide*3+point.x*3+1);
int zhongzi3=*(p_data+(height-point.y)*wide*3+point.x*3+2);
// 對各像素進行灰度轉換
for (j = 0; j < height; j ++)
{
for (i = 0; i < wide; i ++)
{
//獲取各顏色分量
int temp = *((unsigned char *)p_data + 3*wide * j +i*3);
int temp2 = *((unsigned char *)p_data + 3*wide * j +i*3+1);
int temp3 = *((unsigned char *)p_data + 3*wide * j +i*3+2);
if (abs(temp - zhongzi) < 10&&abs(temp2 - zhongzi2) < 10&&abs(temp3 - zhongzi3) < 10) //當前點同種子一灰度值比較接近
{
//將種子一的顏色賦給當前像素
*(p_data + 3*wide * j + i*3 ) = temp;
*(p_data +3*wide* j + i*3+1 ) = temp2;
*(p_data +3*wide * j + i*3+2 ) = temp3;
}
else
{
*(p_data + 3*wide * j + i*3 ) =255;
*(p_data + 3*wide * j + i*3+1 ) =255;
*(p_data + 3*wide * j + i*3+2 ) = 255;
}
}
}
}
}
///***************************************************************/
/*函數名稱:Zhifangtu(float *fPs_Y) */
/*函數類型:void */
/*變量說明:tongji 灰度分布密度統計 */
/*功能:對圖像進行灰度直方圖統計。 */
/*****************************************************************/
void BingXingBianJieDib::Zhifangtu(float *tongji)
{
// 循環變量
int i;
int j;
// 灰度計數
int huidu[256];
int wide,height; //原圖長、寬
// 變量初始化
memset(huidu,0,sizeof(huidu));
if(m_pBitmapInfoHeader->biBitCount<9) //灰度圖像
{
wide=this->GetWidth ();
height=this->GetHeight ();
int width= (((wide*24) + 31) / 32 * 4) ;
LPBYTE temp1=new BYTE[wide*height+1024]; //新圖像緩沖區
//拷貝原圖像到緩存圖像
memcpy( temp1,m_pData,wide*height );
// 對各像素進行灰度統計
for (i = 0; i < height; i ++)
{
for (j = 0; j <wide; j ++)
{
unsigned char temp = temp1[wide* i + j] ;
// 灰度統計計數
huidu[temp]++;
}
}
// 計算灰度分布密度
for(i=0;i<256;i++)
tongji[i] = huidu[i] / (height * wide *1.0f);
}
else //24位彩色
{
wide=this->GetDibWidthBytes();
height=this->GetHeight ();
LPBYTE temp1=new BYTE[wide*height]; //新圖像緩沖區
//拷貝原圖像到緩存圖像
memcpy(temp1,m_pData,wide*height );
// 對各像素進行灰度統計
for (i = 0; i < height; i ++)
{
for (j = 0; j <wide; j ++)
{
unsigned char temp = temp1[wide* i + j] ;
// 灰度統計計數
huidu[temp]++;
}
}
// 計算灰度分布密度
for(i=0;i<256;i++)
tongji[i] = huidu[i] / (height * wide *1.0f);
}
}
///***************************************************************/
/*函數名稱:BanYuZhi(int Yuzhi)
/*函數類型:void
/*參數說明:Yuzhi ---閾值選取
/*功能:對圖像進行半閾值分割。
/***************************************************************/
void BingXingBianJieDib::BanYuZhi(int Yuzhi)
{
// 指向源圖像的指針
LPBYTE p_data;
LPBYTE lpSrc;
// 指向緩存圖像的指針
LPBYTE lpDst;
// 指向緩存DIB圖像的指針
LPBYTE temp;
//循環變量
long i;
long j;
//圖像的高和寬
long wide;
long height;
p_data=GetData();
if(m_pBitmapInfoHeader->biBitCount<9) //灰度圖像
{
wide=GetWidth();
}
else //24位彩色
wide=GetDibWidthBytes();
height=GetHeight();
temp=new BYTE[wide*height];
memset(temp,255,wide*height);
for (j=0;j<height;j++)
{
for(i=0;i<wide;i++)
{
lpSrc=p_data+wide*j+i;
lpDst=temp+wide*j+i;
if((*lpSrc-Yuzhi)<30)
*lpDst=*lpSrc;
}
}
memcpy(p_data,temp,wide*height);
delete temp;
}
///***************************************************************/
/*函數名稱:Lunkuotiqu(CPoint SeedPoint)
/*函數類型:void
/*參數說明:SeedPoint ---種子點選取
/*功能:對24位彩色圖像進行輪廓提取。
/***************************************************************/
void BingXingBianJieDib::Lunkuotiqu(CPoint SeedPoint)
{
LPBYTE p_data ; //原圖數據區指針
int R,G,B,R1,G1,B1;
int wide,height; //原圖長、寬
// 指向源圖像的指針
LPBYTE lpSrc;
// 指向緩存圖像的指針
LPBYTE lpDst;
// 指向緩存DIB圖像的指針
LPBYTE temp;
//循環變量
int i;
int j;
p_data=GetData();
wide=GetWidth();
height=GetHeight();
temp = new BYTE[wide * height*3];
// 初始化新分配的內存,設定初始值為255
memset(temp, 255, wide * height*3);
lpSrc=p_data+wide*3*(height-SeedPoint.y)+3*SeedPoint.x;
R1=*lpSrc;
lpSrc++;
G1=*lpSrc;
lpSrc++;
B1=*lpSrc;
for(j=0;j<height;j++)
{
for(i=0;i<wide;i++)
{
lpSrc = (LPBYTE)p_data + wide * j*3 + i*3;
// 指向目標圖像倒數第j行,第i個象素的指針
lpDst = (LPBYTE)temp + wide * j*3 + i*3;
int I;
I=0;
for(int k=i-1;k<i+2;k++)
{
for(int l=j-1;l<j+2;l++)
{
if(k>=0&&l>=0&&k<wide&&l<height)
{
R=*(p_data+l*wide*3+k*3);
G=*(p_data+l*wide*3+k*3+1);
B=*(p_data+l*wide*3+k*3+2);
if(abs(R-R1)<10&&abs(G-G1)<10&&abs(B-B1)<10)
I++;
}
}
}
if(I!=9)
{
*lpDst=*lpSrc;
*(lpDst+1)=*(lpSrc+1);
*(lpDst+2)=*(lpSrc+2);
}
else
{
*lpDst=255;
*(lpDst+1)=255;
*(lpDst+2)=255;
}
}
}
memcpy(p_data,temp, wide * height*3);
delete temp;
}
/*************************************************************/
//此算法只適用于左邊有邊界的圖像//
/*************************************************************/
void BingXingBianJieDib::Lunkuogenzong(CPoint SeedPoint)
{
// 指向源圖像的指針
LPBYTE lpSrc;
LPBYTE p_data ;
int R1,G1,B1;
int R,G,B;
// 指向緩存圖像的指針
LPBYTE lpDst;
// 指向緩存DIB圖像的指針
LPBYTE temp;
int wide;
int height;
//循環變量
int i;
int j;
//像素值
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;
p_data=GetData();
wide=this->GetWidth();
height=this->GetHeight();
// 暫時分配內存,以保存新圖像
temp = new BYTE[wide*height*3];
// 初始化新分配的內存,設定初始值為255
lpDst = temp;
memset(temp, (BYTE)255, wide * height*3);
//先找到最左方的邊界點
lpSrc=p_data+wide*3*(height-SeedPoint.y)+3*SeedPoint.x;//確定鼠標點的色度值
R1=*lpSrc;
lpSrc++;
G1=*lpSrc;
lpSrc++;
B1=*lpSrc;
bFindStartPoint = false;
int s= height-SeedPoint.y;
for(i=SeedPoint.x;i>1;i--) //從鼠標點開始向左尋找邊界起始點
{
lpSrc = (LPBYTE)p_data + wide * (height-SeedPoint.y)*3 + i*3;
// 指向目標圖像倒數第j行,第i個象素的指針
lpDst = (LPBYTE)temp + wide * (height-SeedPoint.y)*3 + i*3;
int count;
count=0;
for(int k=i-1;k<i+2;k++)
{
for(int l=s-1;l<s+2;l++)
{
if(k>=0&&l>=0&&k<wide&&l<height)
{
R=*(p_data+l*wide*3+k*3);
G=*(p_data+l*wide*3+k*3+1);
B=*(p_data+l*wide*3+k*3+2);
if(abs(R-R1)<10&&abs(G-G1)<10&&abs(B-B1)<10)
count++;
}
}
}
if(count!=9)
{
bFindStartPoint = true;
StartPoint.Height = s;
StartPoint.Width = i;
// 指向目標圖像倒數第j行,第i個象素的指針
lpDst = (LPBYTE)(temp + wide * s*3 + i*3);
*lpDst = 0;
*(lpDst+1)=0;
*(lpDst+2)=0;
break;
}
}
//由于起始點是在左下方,故起始掃描沿左上方向
BeginDirect = 0;
//跟蹤邊界
bFindStartPoint = false;
//從初始點開始掃描
CurrentPoint.Height = StartPoint.Height;
CurrentPoint.Width = StartPoint.Width;
while(!bFindStartPoint)
{
bFindPoint = false;
while(!bFindPoint)
{
//沿掃描方向查看一個像素
lpSrc = (LPBYTE)(p_data + 3*wide * ( CurrentPoint.Height + Direction[BeginDirect][1])
+ 3*(CurrentPoint.Width + Direction[BeginDirect][0]));
R =*lpSrc;
G=*(lpSrc+1);
B=*(lpSrc+2);
if(abs(R-R1)<10&&abs(G-G1)<10&&abs(B-B1)<10)
{
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 + 3*CurrentPoint.Width);
*lpDst = *lpSrc;
*(lpDst+1) = *(lpSrc+1);
*(lpDst+2) = *(lpSrc+2);
//掃描的方向逆時針旋轉兩格
BeginDirect--;
if(BeginDirect == -1)
BeginDirect = 7;
BeginDirect--;
if(BeginDirect == -1)
BeginDirect = 7;
}
else
{
//掃描方向順時針旋轉一格
BeginDirect++;
if(BeginDirect == 8)
BeginDirect = 0;
}
}
}
// 復制圖像
memcpy(p_data, temp, 3*wide * height);
// 釋放內存
delete temp;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -