?? edgecontour.cpp
字號:
//目標圖像中含有0和255外的其它灰度值
if(pixel != 255 && pixel != 0)
return FALSE;
}
//判斷上面的點,如果為白,則壓入堆棧
//注意防止越界
if(iCurrentPixely < lHeight - 1)
{
lpSrc = (char *)lpDIBBits + lWidth * (iCurrentPixely + 1) + iCurrentPixelx;
//取得當前指針處的像素值,注意要轉換為unsigned char型
pixel = (unsigned char)*lpSrc;
if (pixel == 255)
{
StackPoint++;
Seeds[StackPoint].Height = iCurrentPixely + 1;
Seeds[StackPoint].Width = iCurrentPixelx;
}
//目標圖像中含有0和255外的其它灰度值
if(pixel != 255 && pixel != 0)
return FALSE;
}
//判斷右面的點,如果為白,則壓入堆棧
//注意防止越界
if(iCurrentPixelx < lWidth - 1)
{
lpSrc = (char *)lpDIBBits + lWidth * iCurrentPixely + iCurrentPixelx + 1;
//取得當前指針處的像素值,注意要轉換為unsigned char型
pixel = (unsigned char)*lpSrc;
if (pixel == 255)
{
StackPoint++;
Seeds[StackPoint].Height = iCurrentPixely;
Seeds[StackPoint].Width = iCurrentPixelx + 1;
}
//目標圖像中含有0和255外的其它灰度值
if(pixel != 255 && pixel != 0)
return FALSE;
}
//判斷下面的點,如果為白,則壓入堆棧
//注意防止越界
if(iCurrentPixely > 0)
{
lpSrc = (char *)lpDIBBits + lWidth * (iCurrentPixely - 1) + iCurrentPixelx;
//取得當前指針處的像素值,注意要轉換為unsigned char型
pixel = (unsigned char)*lpSrc;
if (pixel == 255)
{
StackPoint++;
Seeds[StackPoint].Height = iCurrentPixely - 1;
Seeds[StackPoint].Width = iCurrentPixelx;
}
//目標圖像中含有0和255外的其它灰度值
if(pixel != 255 && pixel != 0)
return FALSE;
}
}
//釋放堆棧
delete Seeds;
// 返回
return TRUE;
}
/*************************************************************************
*
* 函數名稱:
* ContourDIB()
*
* 參數:
* LPSTR lpDIBBits - 指向源DIB圖像指針
* LONG lWidth - 源圖像寬度(象素數,必須是4的倍數)
* LONG lHeight - 源圖像高度(象素數)
* 返回值:
* BOOL - 運算成功返回TRUE,否則返回FALSE。
*
* 說明:
* 該函數用于對圖像進行輪廓提取運算。
*
* 要求目標圖像為只有0和255兩個灰度值的灰度圖像。
************************************************************************/
BOOL WINAPI ContourDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight)
{
// 指向源圖像的指針
LPSTR lpSrc;
// 指向緩存圖像的指針
LPSTR lpDst;
// 指向緩存DIB圖像的指針
LPSTR lpNewDIBBits;
HLOCAL hNewDIBBits;
//循環變量
long i;
long j;
unsigned char n,e,s,w,ne,se,nw,sw;
//像素值
unsigned char pixel;
// 暫時分配內存,以保存新圖像
hNewDIBBits = LocalAlloc(LHND, lWidth * lHeight);
if (hNewDIBBits == NULL)
{
// 分配內存失敗
return FALSE;
}
// 鎖定內存
lpNewDIBBits = (char * )LocalLock(hNewDIBBits);
// 初始化新分配的內存,設定初始值為255
lpDst = (char *)lpNewDIBBits;
memset(lpDst, (BYTE)255, lWidth * lHeight);
for(j = 1; j <lHeight-1; j++)
{
for(i = 1;i <lWidth-1; i++)
{
// 指向源圖像倒數第j行,第i個象素的指針
lpSrc = (char *)lpDIBBits + lWidth * j + i;
// 指向目標圖像倒數第j行,第i個象素的指針
lpDst = (char *)lpNewDIBBits + lWidth * j + i;
//取得當前指針處的像素值,注意要轉換為unsigned char型
pixel = (unsigned char)*lpSrc;
//目標圖像中含有0和255外的其它灰度值
// if(pixel != 255 && pixel != 0)
// return FALSE;
if(pixel == 0)
{
*lpDst = (unsigned char)0;
nw = (unsigned char)*(lpSrc + lWidth -1);
n = (unsigned char)*(lpSrc + lWidth );
ne = (unsigned char)*(lpSrc + lWidth +1);
w = (unsigned char)*(lpSrc -1);
e = (unsigned char)*(lpSrc +1);
sw = (unsigned char)*(lpSrc - lWidth -1);
s = (unsigned char)*(lpSrc - lWidth );
se = (unsigned char)*(lpSrc - lWidth +1);
//如果相鄰的八個點都是黑點
if(nw+n+ne+w+e+sw+s+se==0)
{
*lpDst = (unsigned char)255;
}
}
}
}
// 復制腐蝕后的圖像
memcpy(lpDIBBits, lpNewDIBBits, lWidth * lHeight);
// 釋放內存
LocalUnlock(hNewDIBBits);
LocalFree(hNewDIBBits);
// 返回
return TRUE;
}
/*************************************************************************
*
* 函數名稱:
* TraceDIB()
*
* 參數:
* LPSTR lpDIBBits - 指向源DIB圖像指針
* LONG lWidth - 源圖像寬度(象素數,必須是4的倍數)
* LONG lHeight - 源圖像高度(象素數)
* 返回值:
* BOOL - 運算成功返回TRUE,否則返回FALSE。
*
* 說明:
* 該函數用于對圖像進行輪廓跟蹤運算。
*
* 要求目標圖像為只有0和255兩個灰度值的灰度圖像。
************************************************************************/
BOOL WINAPI TraceDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight)
{
// 指向源圖像的指針
LPSTR lpSrc;
// 指向緩存圖像的指針
LPSTR lpDst;
// 指向緩存DIB圖像的指針
LPSTR lpNewDIBBits;
HLOCAL hNewDIBBits;
// 圖像每行的字節數
LONG lLineBytes;
//循環變量
long i;
long j;
//像素值
unsigned char 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;
// 計算圖像每行的字節數
lLineBytes = WIDTHBYTES(lWidth * 8);
// 暫時分配內存,以保存新圖像
hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight);
if (hNewDIBBits == NULL)
{
// 分配內存失敗
return FALSE;
}
// 鎖定內存
lpNewDIBBits = (char * )LocalLock(hNewDIBBits);
// 初始化新分配的內存,設定初始值為255
lpDst = (char *)lpNewDIBBits;
memset(lpDst, (BYTE)255, lLineBytes * lHeight);
//先找到最左上方的邊界點
bFindStartPoint = false;
for (j = 0;j < lHeight && !bFindStartPoint;j++)
{
for(i = 0;i < lWidth && !bFindStartPoint;i++)
{
// 指向源圖像倒數第j行,第i個象素的指針
lpSrc = (char *)lpDIBBits + lLineBytes * j + i;
//取得當前指針處的像素值,注意要轉換為unsigned char型
pixel = (unsigned char)*lpSrc;
if(pixel == 0)
{
bFindStartPoint = true;
StartPoint.Height = j;
StartPoint.Width = i;
// 指向目標圖像倒數第j行,第i個象素的指針
lpDst = (char *)lpNewDIBBits + lLineBytes * j + i;
*lpDst = (unsigned char)0;
}
}
}
//由于起始點是在左下方,故起始掃描沿左上方向
BeginDirect = 0;
//跟蹤邊界
bFindStartPoint = false;
//從初始點開始掃描
CurrentPoint.Height = StartPoint.Height;
CurrentPoint.Width = StartPoint.Width;
while(!bFindStartPoint)
{
bFindPoint = false;
while(!bFindPoint)
{
//沿掃描方向查看一個像素
lpSrc = (char *)lpDIBBits + lLineBytes * ( CurrentPoint.Height + Direction[BeginDirect][1])
+ (CurrentPoint.Width + Direction[BeginDirect][0]);
pixel = (unsigned char)*lpSrc;
if(pixel == 0)
{
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 = (char *)lpNewDIBBits + lLineBytes * CurrentPoint.Height + CurrentPoint.Width;
*lpDst = (unsigned char)0;
//掃描的方向逆時針旋轉兩格
BeginDirect--;
if(BeginDirect == -1)
BeginDirect = 7;
BeginDirect--;
if(BeginDirect == -1)
BeginDirect = 7;
}
else
{
//掃描方向順時針旋轉一格
BeginDirect++;
if(BeginDirect == 8)
BeginDirect = 0;
}
}
}
// 復制腐蝕后的圖像
memcpy(lpDIBBits, lpNewDIBBits, lWidth * lHeight);
// 釋放內存
LocalUnlock(hNewDIBBits);
LocalFree(hNewDIBBits);
// 返回
return TRUE;
}
/*************************************************************************
*
* 函數名稱:
* MyDIB()
*
* 參數:
* LPSTR lpDIBBits - 指向源DIB圖像指針
* LONG lWidth - 源圖像寬度(象素數,必須是4的倍數)
* LONG lHeight - 源圖像高度(象素數)
* 返回值:
* BOOL - 邊緣檢測成功返回TRUE,否則返回FALSE。
*
* 說明:
* 該函數用水平邊緣檢測算子對圖像進行邊緣檢測運算。
*
* 要求目標圖像為灰度圖像。
************************************************************************/
BOOL WINAPI MyDIB(LPSTR lpDIBBits, LONG lWidth, LONG lHeight)
{
// 指向緩存圖像的指針
LPSTR lpDst1;
LPSTR lpDst2;
// 指向緩存DIB圖像的指針
LPSTR lpNewDIBBits1;
HLOCAL hNewDIBBits1;
LPSTR lpNewDIBBits2;
HLOCAL hNewDIBBits2;
//循環變量
long i;
long j;
// 模板高度
int iTempH;
// 模板寬度
int iTempW;
// 模板系數
FLOAT fTempC;
// 模板中心元素X坐標
int iTempMX;
// 模板中心元素Y坐標
int iTempMY;
//模板數組
FLOAT aTemplate[9];
// 暫時分配內存,以保存新圖像
hNewDIBBits1 = LocalAlloc(LHND, lWidth * lHeight);
if (hNewDIBBits1 == NULL)
{
// 分配內存失敗
return FALSE;
}
// 鎖定內存
lpNewDIBBits1 = (char * )LocalLock(hNewDIBBits1);
// 暫時分配內存,以保存新圖像
hNewDIBBits2 = LocalAlloc(LHND, lWidth * lHeight);
if (hNewDIBBits2 == NULL)
{
// 分配內存失敗
return FALSE;
}
// 鎖定內存
lpNewDIBBits2 = (char * )LocalLock(hNewDIBBits2);
// 拷貝源圖像到緩存圖像中
lpDst1 = (char *)lpNewDIBBits1;
memcpy(lpNewDIBBits1, lpDIBBits, lWidth * lHeight);
lpDst2 = (char *)lpNewDIBBits2;
memcpy(lpNewDIBBits2, lpDIBBits, lWidth * lHeight);
// 設置Prewitt模板參數
iTempW = 3;
iTempH = 3;
fTempC = 1.0;
iTempMX = 1;
iTempMY = 1;
aTemplate[0] = 0.0;
aTemplate[1] = 0.0;
aTemplate[2] = 0.0;
aTemplate[3] = -1.0;
aTemplate[4] = 1.0;
aTemplate[5] = 0.0;
aTemplate[6] = 0.0;
aTemplate[7] = 0.0;
aTemplate[8] = 0.0;
// 調用Template()函數
if (!Template(lpNewDIBBits1, lWidth, lHeight,
iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC))
{
return FALSE;
}
// 設置Prewitt模板參數
aTemplate[0] = 0.0;
aTemplate[1] = -1.0;
aTemplate[2] = 0.0;
aTemplate[3] = 0.0;
aTemplate[4] = 1.0;
aTemplate[5] = 0.0;
aTemplate[6] = 0.0;
aTemplate[7] = 0.0;
aTemplate[8] = 0.0;
// 調用Template()函數
if (!Template(lpNewDIBBits2, lWidth, lHeight,
iTempH, iTempW, iTempMX, iTempMY, aTemplate, fTempC))
{
return FALSE;
}
//求兩幅緩存圖像的最大值
for(j = 0; j <lHeight; j++)
{
for(i = 0;i <lWidth-1; i++)
{
// 指向緩存圖像1倒數第j行,第i個象素的指針
lpDst1 = (char *)lpNewDIBBits1 + lWidth * j + i;
// 指向緩存圖像2倒數第j行,第i個象素的指針
lpDst2 = (char *)lpNewDIBBits2 + lWidth * j + i;
if(*lpDst2 > *lpDst1)
*lpDst1 = *lpDst2;
}
}
// 復制經過模板運算后的圖像到源圖像
memcpy(lpDIBBits, lpNewDIBBits1, lWidth * lHeight);
// 釋放內存
LocalUnlock(hNewDIBBits1);
LocalFree(hNewDIBBits1);
LocalUnlock(hNewDIBBits2);
LocalFree(hNewDIBBits2);
// 返回
return TRUE;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -