?? enhance.cpp
字號:
#include "stdafx.h"
#include "cdib.h"
#include "math.h"
#include <direct.h>
#include <complex>
using namespace std;
#include "GlobalApi.h"
/*************************************************************************
*
* \函數名稱:
* HistogramEqualize()
*
* \輸入參數:
* CDib * pDib - 指向CDib類的指針,含有原始圖象信息
*
* \返回值:
* BOOL - 成功則返回TRUE,否則返回FALSE
*
* \說明:
* 該函數對指定的圖象進行直方圖均衡化處理
*
*************************************************************************
*/
BOOL HistogramEqualize(CDib* pDib)
{
// 指向源圖像的指針
unsigned char* lpSrc;
// 臨時變量
int nTemp;
// 循環變量
int i,j;
// 累積直方圖,即灰度映射表
BYTE byMap[256];
// 直方圖
int nCount[256];
// 圖象的高度和寬度
CSize sizeImage;
sizeImage = pDib->GetDimensions();
// 獲得圖象數據存儲的高度和寬度
CSize SizeSaveImage;
SizeSaveImage = pDib->GetDibSaveDim();
// 重置計數為0
for (i = 0; i < 256; i ++)
{
// 清零
nCount[i] = 0;
}
// 計算各個灰度值的計數,即得到直方圖
for (i = 0; i < sizeImage.cy; i ++)
{
for (j = 0; j < sizeImage.cx; j ++)
{
lpSrc = (unsigned char *)pDib->m_lpImage + SizeSaveImage.cx * i + j;
// 計數加1
nCount[*(lpSrc)]++;
}
}
// 計算累積直方圖
for (i = 0; i < 256; i++)
{
// 初始為0
nTemp = 0;
for (j = 0; j <= i ; j++)
{
nTemp += nCount[j];
}
// 計算對應的新灰度值
byMap[i] = (BYTE) (nTemp * 255 / sizeImage.cy / sizeImage.cx);
}
// 每行
for(i = 0; i < sizeImage.cy; i++)
{
// 每列
for(j = 0; j < sizeImage.cx; j++)
{
// 指向DIB第i行,第j個象素的指針
lpSrc = (unsigned char*)pDib->m_lpImage + pDib->GetPixelOffset(i,j);
// 計算新的灰度值
*lpSrc = byMap[*lpSrc];
}
}
// 返回
return TRUE;
}
/*************************************************************************
*
* \函數名稱:
* GraySegLinTrans()
*
* \輸入參數:
* CDib* pDib - 指向CDib類的指針,含有原始圖象信息
* int nX1 - 分段線性灰度變換第一個拐點的X坐標
* int nY1 - 分段線性灰度變換第一個拐點的Y坐標
* int nX2 - 分段線性灰度變換第二個拐點的X坐標
* int nY2 - 分段線性灰度變換第二個拐點的Y坐標
*
* \返回值:
* BOOL - 成功返回TRUE,否則返回FALSE。
*
* \說明:
* 該函數用來對圖像進行分段線性灰度變換,輸入參數中包含了兩個拐點的坐標
*
*************************************************************************
*/
BOOL GraySegLinTrans(CDib* pDib, int nX1, int nY1, int nX2, int nY2)
{
// 指向源圖像的指針
unsigned char* lpSrc;
// 循環變量
int i,j;
// 灰度映射表
BYTE byMap[256];
// 圖像每行的字節數
//LONG lLineBytes;
// 圖象的高度和寬度
CSize sizeImage;
sizeImage = pDib->GetDimensions();
// 獲得圖象數據存儲的高度和寬度
CSize SizeSaveImage;
SizeSaveImage = pDib->GetDibSaveDim();
// 計算圖像每行的字節數
//lLineBytes = WIDTHBYTES(sizeImage.cx * 8);
// 計算灰度映射表
for (i = 0; i <= nX1; i++)
{
// 判斷nX1是否大于0(防止分母為0)
if (nX1 > 0)
{
// 線性變換
byMap[i] = (BYTE) nY1 * i / nX1;
}
else
{
// 直接賦值為0
byMap[i] = 0;
}
}
for (; i <= nX2; i++)
{
// 判斷nX1是否等于nX2(防止分母為0)
if (nX2 != nX1)
{
// 線性變換
byMap[i] = nY1 + (BYTE) ((nY2 - nY1) * (i - nX1) / (nX2 - nX1));
}
else
{
// 直接賦值為nY1
byMap[i] = nY1;
}
}
for (; i < 256; i++)
{
// 判斷nX2是否等于255(防止分母為0)
if (nX2 != 255)
{
// 線性變換
byMap[i] = nY2 + (BYTE) ((255 - nY2) * (i - nX2) / (255 - nX2));
}
else
{
// 直接賦值為255
byMap[i] = 255;
}
}
// 對圖象的象素值進行變換
// 每行
for(i = 0; i < sizeImage.cy; i++)
{
// 每列
for(j = 0; j < sizeImage.cx; j++)
{
// 指向DIB第i行,第j個象素的指針
lpSrc = (unsigned char*)pDib->m_lpImage + pDib->GetPixelOffset(i,j);
// 計算新的灰度值
*lpSrc = byMap[*lpSrc];
}
}
// 返回
return TRUE;
}
/*************************************************************************
*
* \函數名稱:
* GeneralTemplate()
*
* \輸入參數:
* CDib * pDib - 指向CDib類的指針,含有原始圖象信息
* int nTempWidth - 模板的寬度
* int nTempHeight - 模板的高度
* int nTempCenX - 模板中心的X坐標(相對于模板)
* int nTempCenY - 模板中心的Y坐標(相對于模板)
* double* pdbTemp - 模板數組的指針
* double* dbCoef - 模板的系數
*
* \返回值:
* BOOL - 成功則返回TRUE,否則返回FALSE
*
* \說明:
* 該函數用指定的模板對pDib指向的圖象進行模板操作。模板的定義了寬度,高度,
* 中心坐標和系數,模板的數據存放在pdbTemp中。對圖象進行模板操作后,仍
* 然存放在pDib指向的CDib對象中。需要注意的是,該函數只能處理8位的圖象,
* 否則,指向的數據將出錯。
*
*************************************************************************
*/
BOOL GeneralTemplate(CDib* pDib, int nTempWidth, int nTempHeight,
int nTempCenX, int nTempCenY,
double* pdbTemp, double dbCoef)
{
// 臨時存放圖像數據的指針
LPBYTE lpImage;
// 循環變量
int i,j,k,l;
// 指向源圖像的指針
unsigned char* lpSrc;
// 指向要復制區域的指針
unsigned char* lpDst;
// 計算結果
double dbResult;
// 圖象的高度和寬度
CSize sizeImage;
sizeImage = pDib->GetDimensions();
// 獲得圖象數據存儲的尺寸
int nSizeImage;
nSizeImage = pDib->GetSizeImage();
// 給臨時存放數據分配內存
lpImage = (LPBYTE) new char[nSizeImage];
// 判斷是否內存分配失敗
if (lpImage == NULL)
{
// 分配內存失敗
return FALSE;
}
// 將原始圖像的數據拷貝到臨時存放內存中
memcpy(lpImage, pDib->m_lpImage, nSizeImage);
// 進行模板操作
// 行(除去邊緣幾行)
for(i = nTempCenY ; i < sizeImage.cy - nTempHeight + nTempCenY + 1; i++)
{
// 列(除去邊緣幾列)
for(j = nTempCenX; j < sizeImage.cx - nTempWidth + nTempCenX + 1; j++)
{
// 指向新DIB第i行,第j個象素的指針
lpDst = (unsigned char*)lpImage + pDib->GetPixelOffset(i,j);
dbResult = 0;
// 計算
for (k = 0; k < nTempHeight; k++)
{
for (l = 0; l < nTempWidth; l++)
{
// 指向DIB第i - nTempCenY + k行,第j - nTempCenX + l個象素的指針
lpSrc = (unsigned char*)pDib->m_lpImage + pDib->GetPixelOffset(i-nTempCenY+k, j-nTempCenX+l);
// 保存象素值
dbResult += (* lpSrc) * pdbTemp[k * nTempWidth + l];
}
}
// 乘上系數
dbResult *= dbCoef;
// 取絕對值
dbResult = (double ) fabs(dbResult);
// 判斷是否超過255
if(dbResult > 255)
{
// 直接賦值為255
* lpDst = 255;
}
else
{
// 賦值
* lpDst = (unsigned char) (dbResult + 0.5);
}
}
}
// 復制變換后的圖像
memcpy(pDib->m_lpImage, lpImage, nSizeImage);
// 釋放內存
delete[]lpImage;
// 返回
return TRUE;
}
/*************************************************************************
*
* 函數名稱:
* MedianFilter()
*
* \輸入參數:
* CDib * pDib - 指向CDib類的指針,含有原始圖象信息
* int nTempWidth - 模板的寬度
* int nTempHeight - 模板的高度
* int nTempCenX - 模板中心的X坐標(相對于模板)
* int nTempCenY - 模板中心的Y坐標(相對于模板)
*
* \返回值:
* BOOL - 成功則返回TRUE,否則返回FALSE
*
* 說明:
* 該函數對指定的DIB圖像進行中值濾波。
*
************************************************************************/
BOOL MedianFilter(CDib* pDib, int nTempWidth, int nTempHeight,
int nTempCenX, int nTempCenY)
{
// 臨時存放圖像數據的指針
LPBYTE lpImage;
// 循環變量
int i,j,k,l;
// 指向源圖像的指針
unsigned char* lpSrc;
// 指向要復制區域的指針
unsigned char* lpDst;
// 圖象的高度和寬度
CSize sizeImage;
sizeImage = pDib->GetDimensions();
// 獲得圖象數據存儲的尺寸
int nSizeImage;
nSizeImage = pDib->GetSizeImage();
// 指向濾波器數組的指針
unsigned char* pUnchFltValue;
// 給臨時存放數據分配內存
lpImage = (LPBYTE) new char[nSizeImage];
// 判斷是否內存分配失敗
if (lpImage == NULL)
{
// 返回
return FALSE;
}
// 將原始圖像的數據拷貝到臨時存放內存中
memcpy(lpImage, pDib->m_lpImage, nSizeImage);
// 暫時分配內存,以保存濾波器數組
pUnchFltValue = new unsigned char[nTempHeight * nTempWidth];
// 判斷是否內存分配失敗
if (pUnchFltValue == NULL)
{
// 釋放已分配內存
delete[]lpImage;
// 返回
return FALSE;
}
// 開始中值濾波
// 行(除去邊緣幾行)
for(i = nTempCenY; i < sizeImage.cy - nTempHeight + nTempCenY + 1; i++)
{
// 列(除去邊緣幾列)
for(j = nTempCenX; j < sizeImage.cx - nTempWidth + nTempCenX + 1; j++)
{
// 指向新DIB第i行,第j個象素的指針
lpDst = (unsigned char*)lpImage + pDib->GetPixelOffset(i,j);
//lpDst = (unsigned char*)lpImage + sizeImage.cx * (sizeImage.cy - 1 - i) + j;
// 讀取濾波器數組
for (k = 0; k < nTempHeight; k++)
{
for (l = 0; l < nTempWidth; l++)
{
// 指向DIB第i - nTempCenY + k行,第j - nTempCenX + l個象素的指針
lpSrc = (unsigned char*)pDib->m_lpImage + pDib->GetPixelOffset(i-nTempCenY+k, j-nTempCenX+l);
//lpSrc = (unsigned char*)pDib->m_lpImage + sizeImage.cx * (sizeImage.cy - 1 - i + nTempCenY - k) + j - nTempCenX + l;
// 保存象素值
pUnchFltValue[k * nTempWidth + l] = *lpSrc;
}
}
// 獲取中值
//* lpDst = GetMedianValue(pUnchFltValue, nTempHeight * nTempWidth);
}
}
// 復制變換后的圖像
memcpy(pDib->m_lpImage, lpImage, nSizeImage);
// 釋放內存
delete[]lpImage;
delete[]pUnchFltValue;
// 返回
return TRUE;
}
/*************************************************************************
*
* 函數名稱:
* GetMedianValue()
*
* 參數:
* unsigned char * pUnchFltValue - 指向要獲取中值的數組指針
* int iFilterLen - 數組長度
*
* 返回值:
* unsigned char - 返回指定數組的中值。
*
* 說明:
* 該函數用冒泡法對一維數組進行排序,并返回數組元素的中值。
*
************************************************************************/
unsigned char GetMedianValue(unsigned char * pUnchFltValue, int iFilterLen)
{
// 循環變量
int i;
int j;
// 中間變量
unsigned char bTemp;
// 用冒泡法對數組進行排序
for (j = 0; j < iFilterLen - 1; j ++)
{
for (i = 0; i < iFilterLen - j - 1; i ++)
{
if (pUnchFltValue[i] > pUnchFltValue[i + 1])
{
// 互換
bTemp = pUnchFltValue[i];
pUnchFltValue[i] = pUnchFltValue[i + 1];
pUnchFltValue[i + 1] = bTemp;
}
}
}
// 計算中值
if ((iFilterLen & 1) > 0)
{
// 數組有奇數個元素,返回中間一個元素
bTemp = pUnchFltValue[(iFilterLen + 1) / 2];
}
else
{
// 數組有偶數個元素,返回中間兩個元素平均值
bTemp = (pUnchFltValue[iFilterLen / 2] + pUnchFltValue[iFilterLen / 2 + 1]) / 2;
}
// 返回中值
return bTemp;
}
/*************************************************************************
*
* \函數名稱:
* LinearSharpen()
*
* \輸入參數:
* LPBYTE lpImage - 指向圖象數據得指針
* int nWidth - 圖象數據寬度
* int nHeight - 圖象數據高度
*
* \返回值:
* 無
*
* \說明:
* 線性銳化圖象增強
* 本函數采用拉普拉斯算子對圖象進行線性銳化
* 在原來圖象上加上拉普拉斯算子銳化的信息
*
*************************************************************************
*/
void LinearSharpen (LPBYTE lpImage, int nWidth, int nHeight)
{
// 遍歷圖象的縱坐標
int y;
// 遍歷圖象的橫坐標
int x;
double * pdGrad ;
pdGrad = new double[nWidth*nHeight];
// 初始化為0
memset(pdGrad, 0, nWidth*nHeight*sizeof(double)) ;
// 設置模板系數
static int nWeight[3][3] ;
nWeight[0][0] = -1 ;
nWeight[0][1] = -1 ;
nWeight[0][2] = -1 ;
nWeight[1][0] = -1 ;
nWeight[1][1] = 8 ;
nWeight[1][2] = -1 ;
nWeight[2][0] = -1 ;
nWeight[2][1] = -1 ;
nWeight[2][2] = -1 ;
//這個變量用來表示Laplacian算子象素值
int nTmp[3][3];
// 臨時變量
double dGrad;
// 模板循環控制變量
int yy ;
int xx ;
for(y=1; y<nHeight-1 ; y++ )
for(x=1 ; x<nWidth-1 ; x++ )
{
dGrad = 0 ;
// Laplacian算子需要的各點象素值
// 模板第一行
nTmp[0][0] = lpImage[(y-1)*nWidth + x - 1 ] ;
nTmp[0][1] = lpImage[(y-1)*nWidth + x ] ;
nTmp[0][2] = lpImage[(y-1)*nWidth + x + 1 ] ;
// 模板第二行
nTmp[1][0] = lpImage[y*nWidth + x - 1 ] ;
nTmp[1][1] = lpImage[y*nWidth + x ] ;
nTmp[1][2] = lpImage[y*nWidth + x + 1 ] ;
// 模板第三行
nTmp[2][0] = lpImage[(y+1)*nWidth + x - 1 ] ;
nTmp[2][1] = lpImage[(y+1)*nWidth + x ] ;
nTmp[2][2] = lpImage[(y+1)*nWidth + x + 1 ] ;
// 計算梯度
for(yy=0; yy<3; yy++)
for(xx=0; xx<3; xx++)
{
dGrad += nTmp[yy][xx] * nWeight[yy][xx] ;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -