熱門關(guān)注
三陰交穴 足三里穴 涌泉穴 太溪穴 太沖穴 迎香穴 腎俞穴 血海穴 關(guān)元穴 風池穴 中脘穴 陰陵泉穴 肩井穴
人體穴位網(wǎng)
  您當前的位置:首頁 > 百科全說

圖像處理經(jīng)典算法

時間:2022-10-22 14:35:40   來源:人體穴位網(wǎng)  作者:eeocool.cn

圖像處理經(jīng)典算法

  圖像處理,是對圖像進行分析、加工、和處理,使其滿足視覺、心理以及其他要求的技術(shù)。圖像處理是信號處理在圖像域上的一個應用。目前大多數(shù)的圖像是以數(shù)字形式存儲,因而圖像處理很多情況下指數(shù)字圖像處理。

  

  本文接下來,簡單粗略介紹下數(shù)字圖像處理領(lǐng)域中的24個經(jīng)典算法,然后全部算法用vc實現(xiàn)。由于篇幅所限,只給出某一算法的主體代碼。

  ok,請細看。

  一、256色轉(zhuǎn)灰度圖

  算法介紹(百度百科):

  什么叫灰度圖?任何顏色都有紅、綠、藍三原色組成,假如原來某點的顏色為RGB(R,G,B),那么,我們可以通過下面幾種方法,將其轉(zhuǎn)換為灰度:

  1.浮點算法:Gray=R*0.3+G*0.59+B*0.11

  2.整數(shù)方法:Gray=(R*30+G*59+B*11)/100

  3.移位方法:Gray =(R*28+G*151+B*77)>>8;

  4.平均值法:Gray=(R+G+B)/3;

  5.僅取綠色:Gray=G;

  通過上述任一種方法求得Gray后,將原來的RGB(R,G,B)中的R,G,B統(tǒng)一用Gray替換,形成新的顏色RGB(Gray,Gray,Gray),用它替換原來的RGB(R,G,B)就是灰度圖了。

  灰度分為256階。所以,用灰度表示的圖像稱作灰度圖。

  程序?qū)崿F(xiàn):

  ok,知道了什么叫灰度圖,下面,咱們就來實現(xiàn)此256色灰度圖。

  這個Convert256toGray(),即是將256色位圖轉(zhuǎn)化為灰度圖:

  LPSTR lpDIB;

  // 由DIB句柄得到DIB指針并鎖定DIB

  lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)hDIB);

  // 指向DIB象素數(shù)據(jù)區(qū)的指針

  LPSTR   lpDIBBits;

  // 指向DIB象素的指針

  BYTE * lpSrc;

  // 圖像寬度

  // 圖像高度

  LONG   lHeight;

  // 圖像每行的字節(jié)數(shù)

  // 指向BITMAPINFO結(jié)構(gòu)的指針(Win3.0)

  LPBITMAPINFO lpbmi;

  // 指向BITMAPCOREINFO結(jié)構(gòu)的指針

  LPBITMAPCOREINFO lpbmc;

  // 獲取指向BITMAPINFO結(jié)構(gòu)的指針(Win3.0)

  lpbmi = (LPBITMAPINFO)lpDIB;

  // 獲取指向BITMAPCOREINFO結(jié)構(gòu)的指針

  lpbmc = (LPBITMAPCOREINFO)lpDIB;

  // 灰度映射表

  BYTE bMap[256];

  // 計算灰度映射表(保存各個顏色的灰度值),并更新DIB調(diào)色板

  // 計算該顏色對應的灰度值

  bMap[i] = (BYTE)(0.299 * lpbmi->bmiColors[i].rgbRed +

  0.587 * lpbmi->bmiColors[i].rgbGreen +

  0.114 * lpbmi->bmiColors[i].rgbBlue + 0.5);

  // 更新DIB調(diào)色板紅色分量

  lpbmi->bmiColors[i].rgbRed = i;

  // 更新DIB調(diào)色板綠色分量

  lpbmi->bmiColors[i].rgbGreen = i;

  // 更新DIB調(diào)色板藍色分量

  lpbmi->bmiColors[i].rgbBlue = i;

  // 更新DIB調(diào)色板保留位

  lpbmi->bmiColors[i].rgbReserved = 0;

  // 找到DIB圖像象素起始位置

  lpDIBBits = ::FindDIBBits(lpDIB);

  // 獲取圖像寬度

  lWidth = ::DIBWidth(lpDIB);

  // 獲取圖像高度

  lHeight = ::DIBHeight(lpDIB);

  // 計算圖像每行的字節(jié)數(shù)

  // 更換每個象素的顏色索引(即按照灰度映射表換成灰度值)

  //逐行掃描

  //逐列掃描

  // 指向DIB第i行,第j個象素的指針

  lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;

  // 變換

  *lpSrc = bMap[*lpSrc];

  //解除鎖定

  變換效果(以下若無特別說明,圖示的右邊部分都是為某一算法變換之后的效果):

  二、Walsh變換

  算法介紹:

  有關(guān)Walsh變換的深入介紹,請看此論文:http://www.informatics.org.cn/doc/ucit200510/ucit20051005.pdf

  程序?qū)崿F(xiàn):

  函數(shù)名稱:WALSH()

  參數(shù):

  double * f    - 指向時域值的指針

  double * F    - 指向頻域值的指針

  r      -2的冪數(shù)

  返回值:無。

  說明:該函數(shù)用來實現(xiàn)快速沃爾什-哈達瑪變換。

  // 沃爾什-哈達瑪變換點數(shù)

  // 循環(huán)變量

  int  i,j,k;

  // 中間變量

  int  bfsize,p;

  // 計算快速沃爾什變換點數(shù)

  // 分配運算所需的數(shù)組

  // 將時域點寫入數(shù)組X1

  memcpy(X1, f, sizeof(double) * count);

  // 蝶形運算

  for(i = 0; i < bfsize / 2; i++)

  p = j * bfsize;

  X2[i + p] = X1[i + p] + X1[i + p + bfsize / 2];

  X2[i + p + bfsize / 2] = X1[i + p] - X1[i + p + bfsize / 2];

  // 互換X1和X2

  // 調(diào)整系數(shù)

  p = 0;

  if (j & (1<<i))

  p += 1 << (r-i-1);

  F[j] = X1[p] / count;

  // 釋放內(nèi)存

  函數(shù)名稱:DIBWalsh1()

  參數(shù):

  LPSTR lpDIBBits    - 指向源DIB圖像指針

  LONG  lWidth       - 源圖像寬度(象素數(shù))

  LONG  lHeight      - 源圖像高度(象素數(shù))

  返回值:BOOL               - 成功返回TRUE,否則返回FALSE。

  說明:該函數(shù)用來對圖像進行沃爾什-哈達瑪變換。于上面不同的是,此處是將二維

  矩陣轉(zhuǎn)換成一個列向量,然后對該列向量進行一次一維沃爾什-哈達瑪變換。

  BOOL WINAPI DIBWalsh1(LPSTR lpDIBBits, LONG lWidth, LONG lHeight)

  // 指向源圖像的指針

  unsigned char* lpSrc;

  // 循環(huán)變量

  // 進行付立葉變換的寬度和高度(2的整數(shù)次方)

  // 中間變量

  double dTemp;

  int  wp;

  int  hp;

  // 圖像每行的字節(jié)數(shù)

  // 計算圖像每行的字節(jié)數(shù)

  // 賦初值

  wp = 0;

  hp = 0;

  // 計算進行離散余弦變換的寬度和高度(2的整數(shù)次方)

  wp++;

  hp++;

  // 分配內(nèi)存

  // 列

  // 行

  // 指向DIB第j行,第i個象素的指針

  lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i;

  // 給時域賦值

  f[j + i * w] = *(lpSrc);

  // 調(diào)用快速沃爾什-哈達瑪變換

  WALSH(f, F, wp + hp);

  // 列

  // 行

  // 計算頻譜

  dTemp = fabs(F[i * w + j] * 1000);

  // 判斷是否超過255

  if (dTemp > 255)

  // 對于超過的,直接設(shè)置為255

  dTemp = 255;

  // 指向DIB第j行,第i個象素的指針

  lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - j) + i;

  // 更新源圖像

  * (lpSrc) = (BYTE)(dTemp);

  //釋放內(nèi)存

  // 返回

  變換效果:

  三、二值化變換

  算法描述:

  二值化是圖像分割的一種方法。在二值化圖象的時候把大于某個臨界灰度值的像素灰度設(shè)為灰度極大值,把小于這個值的像素灰度設(shè)為灰度極小值,從而實現(xiàn)二值化。

  根據(jù)閾值選取的不同,二值化的算法分為固定閾值和自適應閾值。 比較常用的二值化方法則有:雙峰法、P參數(shù)法、迭代法和OTSU法等。

  程序?qū)崿F(xiàn):

  void CMyDIPView::OnDraw(CDC* pDC)

  CMyDIPDoc* pDoc = GetDocument();

  ASSERT_VALID(pDoc);

  if(pDoc->m_hDIB == NULL)

  // TODO: add draw code for native data here

  unsigned char *lpSrc;

  LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->m_hDIB);

  int cxDIB = (int) ::DIBWidth(lpDIB);         // Size of DIB - x

  int cyDIB = (int) ::DIBHeight(lpDIB);        // Size of DIB - y

  LPSTR lpDIBBits=::FindDIBBits (lpDIB);

  // 計算圖像每行的字節(jié)數(shù)

  // 每行

  // 每列

  // 指向DIB第i行,第j個象素的指針

  lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (cyDIB - 1 - i) + j;

  // 計算新的灰度值

  //*(lpSrc) = BYTE(255-*lpSrc);

  ::GlobalUnlock((HGLOBAL) pDoc->m_hDIB);

  ::PaintDIB(pDC->m_hDC, &rect, pDoc->m_hDIB, &rcDIB, pDoc->m_palDIB);

  // TODO: Add your command handler code here

  unsigned char *lpSrc;

  CMyDIPDoc* pDoc = GetDocument();

  ASSERT_VALID(pDoc);

  if(pDoc->m_hDIB == NULL)

  LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) pDoc->m_hDIB);

  LPSTR lpDIBBits=::FindDIBBits (lpDIB);

  int cxDIB = (int) ::DIBWidth(lpDIB);         // Size of DIB - x

  int cyDIB = (int) ::DIBHeight(lpDIB);        // Size of DIB - y

  long lLineBytes = WIDTHBYTES(cxDIB * 8);     // 計算圖像每行的字節(jié)數(shù)

  // 每行

  // 每列

  // 指向DIB第i行,第j個象素的指針

  lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (cyDIB - 1 - i) + j;

  // 計算新的灰度值

  if(*lpSrc<122) *lpSrc=BYTE(0);

  else *lpSrc = BYTE(255);

  ::GlobalUnlock((HGLOBAL) pDoc->m_hDIB);

  變換效果:

  四、閾值變換

  算法描述:

  輸入圖像像元密度值(灰度、亮度值)按對數(shù)函數(shù)關(guān)系變換為輸出圖像。

  程序?qū)崿F(xiàn):

  //參數(shù)說明:

  //LPSTR lpDIBBits:指向源DIB圖像指針

  //LONG  lWidth:源圖像寬度(象素數(shù))

  //LONG  lHeight:源圖像高度(象素數(shù))

  //BYTE  bThre:閾值

  //程序說明:

  //該函數(shù)用來對圖像進行閾值變換。對于灰度值小于閾值的象素直接設(shè)置

  灰度值為0;灰度值大于閾值的象素直接設(shè)置為255。

  BOOL WINAPI ThresholdTrans(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, BYTE bThre)

  // 指向源圖像的指針

  unsigned char* lpSrc;

  // 循環(huán)變量

  // 圖像每行的字節(jié)數(shù)

  // 計算圖像每行的字節(jié)數(shù)

  // 每行

  // 每列

  // 指向DIB第i行,第j個象素的指針

  lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;

  // 判斷是否小于閾值

  if ((*lpSrc) < bThre)

  // 直接賦值為0

  *lpSrc = 0;

  // 直接賦值為255

  *lpSrc = 255;

  // 返回

  五、傅立葉變換

  算法描述:

  關(guān)于此傅里葉變換算法的具體介紹,請參考本BLOG文章:十、從頭到尾徹底理解傅里葉變換算法、上。

  程序?qū)崿F(xiàn):

  函數(shù)名稱:FFT()

  參數(shù):

  complex * TD - 指向時域數(shù)組的指針

  complex * FD - 指向頻域數(shù)組的指針

  r      -2的冪數(shù),即迭代次數(shù)

  返回值:無。

  說明:該函數(shù)用來實現(xiàn)快速付立葉變換。

  VOID WINAPI FFT(complex * TD, complex * FD, int r)

  // 付立葉變換點數(shù)

  // 循環(huán)變量

  int  i,j,k;

  // 中間變量

  int  bfsize,p;

  // 角度

  complex *W,*X1,*X2,*X;

  // 計算付立葉變換點數(shù)

  // 分配運算所需存儲器

  W  = new complex[count / 2];

  X1 = new complex[count];

  X2 = new complex[count];

  // 計算加權(quán)系數(shù)

  for(i = 0; i < count / 2; i++)

  angle = -i * PI * 2 / count;

  W[i] = complex (cos(angle), sin(angle));

  // 將時域點寫入X1

  memcpy(X1, TD, sizeof(complex) * count);

  // 采用蝶形算法進行快速付立葉變換

  for(i = 0; i < bfsize / 2; i++)

  p = j * bfsize;

  X2[i + p] = X1[i + p] + X1[i + p + bfsize / 2];

  X2[i + p + bfsize / 2] = (X1[i + p] - X1[i + p + bfsize / 2]) * W[i * (1<<k)];

  X  = X1;

  // 重新排序

  p = 0;

  if (j&(1<<i))

  p+=1<<(r-i-1);

  FD[j]=X1[p];

  // 釋放內(nèi)存

查看評論

標簽:

相關(guān)閱讀:

    無相關(guān)信息
上一篇:論壇營銷發(fā)帖推廣技巧     下一篇:返回列表

評論:圖像處理經(jīng)典算法

首頁 | 高級搜索 | 聯(lián)系我們 | 信息反饋 | 網(wǎng)站地圖 | 返回頂部 | RSS訂閱

Copyright © 2012 - eeocool.cn All Rights Reserved.

人體穴位網(wǎng) 版權(quán)所有