?? templatetrans.cpp
字號:
/************************************************************************** * 文件名:TemplateTrans.cpp * * 圖像模板變換API函數庫: * * Template() - 圖像模板變換,通過改變模板,可以用它實現 * 圖像的平滑、銳化、邊緣識別等操作。 * MedianFilter() - 圖像中值濾波。 * GetMedianNum() - 獲取中值。被函數MedianFilter()調用來求中值。 * ReplaceColorPal() - 更換偽彩色編碼表。 * *************************************************************************/#include "stdafx.h"#include "TemplateTrans.h"#include "DIBAPI.h"#include <math.h>#include <direct.h>/************************************************************************* * * 函數名稱: * Template() * * 參數: * LPSTR lpDIBBits - 指向源DIB圖像指針 * LONG lWidth - 源圖像寬度(象素數) * LONG lHeight - 源圖像高度(象素數) * int iTempH - 模板的高度 * int iTempW - 模板的寬度 * int iTempMX - 模板的中心元素X坐標 ( < iTempW - 1) * int iTempMY - 模板的中心元素Y坐標 ( < iTempH - 1) * FLOAT * fpArray - 指向模板數組的指針 * FLOAT fCoef - 模板系數 * * 返回值: * BOOL - 成功返回TRUE,否則返回FALSE。 * * 說明: * 該函數用指定的模板(任意大小)來對圖像進行操作,參數iTempH指定模板 * 的高度,參數iTempW指定模板的寬度,參數iTempMX和iTempMY指定模板的中心 * 元素坐標,參數fpArray指定模板元素,fCoef指定系數。 * ************************************************************************/BOOL WINAPI Template(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, int iTempH, int iTempW, int iTempMX, int iTempMY, FLOAT * fpArray, FLOAT fCoef){ // 指向復制圖像的指針 LPSTR lpNewDIBBits; HLOCAL hNewDIBBits; // 指向源圖像的指針 unsigned char* lpSrc; // 指向要復制區域的指針 unsigned char* lpDst; // 循環變量 LONG i; LONG j; LONG k; LONG l; // 計算結果 FLOAT fResult; // 圖像每行的字節數 LONG lLineBytes; // 計算圖像每行的字節數 lLineBytes = WIDTHBYTES(lWidth * 8); // 暫時分配內存,以保存新圖像 hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight); // 判斷是否內存分配失敗 if (hNewDIBBits == NULL) { // 分配內存失敗 return FALSE; } // 鎖定內存 lpNewDIBBits = (char * )LocalLock(hNewDIBBits); // 初始化圖像為原始圖像 memcpy(lpNewDIBBits, lpDIBBits, lLineBytes * lHeight); // 行(除去邊緣幾行) for(i = iTempMY; i < lHeight - iTempH + iTempMY + 1; i++) { // 列(除去邊緣幾列) for(j = iTempMX; j < lWidth - iTempW + iTempMX + 1; j++) { // 指向新DIB第i行,第j個象素的指針 lpDst = (unsigned char*)lpNewDIBBits + lLineBytes * (lHeight - 1 - i) + j; fResult = 0; // 計算 for (k = 0; k < iTempH; k++) { for (l = 0; l < iTempW; l++) { // 指向DIB第i - iTempMY + k行,第j - iTempMX + l個象素的指針 lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i + iTempMY - k) + j - iTempMX + l; // 保存象素值 fResult += (* lpSrc) * fpArray[k * iTempW + l]; } } // 乘上系數 fResult *= fCoef; // 取絕對值 fResult = (FLOAT ) fabs(fResult); // 判斷是否超過255 if(fResult > 255) { // 直接賦值為255 * lpDst = 255; } else { // 賦值 * lpDst = (unsigned char) (fResult + 0.5); } } } // 復制變換后的圖像 memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight); // 釋放內存 LocalUnlock(hNewDIBBits); LocalFree(hNewDIBBits); // 返回 return TRUE;}/************************************************************************* * * 函數名稱: * MedianFilter() * * 參數: * LPSTR lpDIBBits - 指向源DIB圖像指針 * LONG lWidth - 源圖像寬度(象素數) * LONG lHeight - 源圖像高度(象素數) * int iFilterH - 濾波器的高度 * int iFilterW - 濾波器的寬度 * int iFilterMX - 濾波器的中心元素X坐標 * int iFilterMY - 濾波器的中心元素Y坐標 * * 返回值: * BOOL - 成功返回TRUE,否則返回FALSE。 * * 說明: * 該函數對DIB圖像進行中值濾波。 * ************************************************************************/BOOL WINAPI MedianFilter(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, int iFilterH, int iFilterW, int iFilterMX, int iFilterMY){ // 指向源圖像的指針 unsigned char* lpSrc; // 指向要復制區域的指針 unsigned char* lpDst; // 指向復制圖像的指針 LPSTR lpNewDIBBits; HLOCAL hNewDIBBits; // 指向濾波器數組的指針 unsigned char * aValue; HLOCAL hArray; // 循環變量 LONG i; LONG j; LONG k; LONG l; // 圖像每行的字節數 LONG lLineBytes; // 計算圖像每行的字節數 lLineBytes = WIDTHBYTES(lWidth * 8); // 暫時分配內存,以保存新圖像 hNewDIBBits = LocalAlloc(LHND, lLineBytes * lHeight); // 判斷是否內存分配失敗 if (hNewDIBBits == NULL) { // 分配內存失敗 return FALSE; } // 鎖定內存 lpNewDIBBits = (char * )LocalLock(hNewDIBBits); // 初始化圖像為原始圖像 memcpy(lpNewDIBBits, lpDIBBits, lLineBytes * lHeight); // 暫時分配內存,以保存濾波器數組 hArray = LocalAlloc(LHND, iFilterH * iFilterW); // 判斷是否內存分配失敗 if (hArray == NULL) { // 釋放內存 LocalUnlock(hNewDIBBits); LocalFree(hNewDIBBits); // 分配內存失敗 return FALSE; } // 鎖定內存 aValue = (unsigned char * )LocalLock(hArray); // 開始中值濾波 // 行(除去邊緣幾行) for(i = iFilterMY; i < lHeight - iFilterH + iFilterMY + 1; i++) { // 列(除去邊緣幾列) for(j = iFilterMX; j < lWidth - iFilterW + iFilterMX + 1; j++) { // 指向新DIB第i行,第j個象素的指針 lpDst = (unsigned char*)lpNewDIBBits + lLineBytes * (lHeight - 1 - i) + j; // 讀取濾波器數組 for (k = 0; k < iFilterH; k++) { for (l = 0; l < iFilterW; l++) { // 指向DIB第i - iFilterMY + k行,第j - iFilterMX + l個象素的指針 lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i + iFilterMY - k) + j - iFilterMX + l; // 保存象素值 aValue[k * iFilterW + l] = *lpSrc; } } // 獲取中值 * lpDst = GetMedianNum(aValue, iFilterH * iFilterW); } } // 復制變換后的圖像 memcpy(lpDIBBits, lpNewDIBBits, lLineBytes * lHeight); // 釋放內存 LocalUnlock(hNewDIBBits); LocalFree(hNewDIBBits); LocalUnlock(hArray); LocalFree(hArray); // 返回 return TRUE;}/************************************************************************* * * 函數名稱: * GetMedianNum() * * 參數: * unsigned char * bpArray - 指向要獲取中值的數組指針 * int iFilterLen - 數組長度 * * 返回值: * unsigned char - 返回指定數組的中值。 * * 說明: * 該函數用冒泡法對一維數組進行排序,并返回數組元素的中值。 * ************************************************************************/unsigned char WINAPI GetMedianNum(unsigned char * bArray, 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 (bArray[i] > bArray[i + 1]) { // 互換 bTemp = bArray[i]; bArray[i] = bArray[i + 1]; bArray[i + 1] = bTemp; } } } // 計算中值 if ((iFilterLen & 1) > 0) { // 數組有奇數個元素,返回中間一個元素 bTemp = bArray[(iFilterLen + 1) / 2]; } else { // 數組有偶數個元素,返回中間兩個元素平均值 bTemp = (bArray[iFilterLen / 2] + bArray[iFilterLen / 2 + 1]) / 2; } // 返回中值 return bTemp;}/************************************************************************* * * 函數名稱: * GradSharp() * * 參數: * LPSTR lpDIBBits - 指向源DIB圖像指針 * LONG lWidth - 源圖像寬度(象素數) * LONG lHeight - 源圖像高度(象素數) * BYTE bThre - 閾值 * * 返回值: * BOOL - 成功返回TRUE,否則返回FALSE。 * * 說明: * 該函數用來對圖像進行梯度銳化。 * ************************************************************************/BOOL WINAPI GradSharp(LPSTR lpDIBBits, LONG lWidth, LONG lHeight, BYTE bThre){ // 指向源圖像的指針 unsigned char* lpSrc; unsigned char* lpSrc1; unsigned char* lpSrc2; // 循環變量 LONG i; LONG j; // 圖像每行的字節數 LONG lLineBytes; // 中間變量 BYTE bTemp; // 計算圖像每行的字節數 lLineBytes = WIDTHBYTES(lWidth * 8); // 每行 for(i = 0; i < lHeight; i++) { // 每列 for(j = 0; j < lWidth; j++) { // 指向DIB第i行,第j個象素的指針 lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i)+ j; // 指向DIB第i+1行,第j個象素的指針 lpSrc1 = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 2 - i) + j; // 指向DIB第i行,第j+1個象素的指針 lpSrc2 = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j + 1; bTemp = abs((*lpSrc)-(*lpSrc1)) + abs((*lpSrc)-(*lpSrc2)); // 判斷是否小于閾值 if (bTemp < 255) { // 判斷是否大于閾值,對于小于情況,灰度值不變。 if (bTemp >= bThre) { // 直接賦值為bTemp *lpSrc = bTemp; } } else { // 直接賦值為255 *lpSrc = 255; } } } // 返回 return TRUE;}/************************************************************************* * * 函數名稱: * ReplaceColorPal() * * 參數: * LPSTR lpDIB - 指向源DIB圖像指針 * BYTE * bpColorsTable - 偽彩色編碼表 * * 返回值: * BOOL - 成功返回TRUE,否則返回FALSE。 * * 說明: * 該函數用指定的偽彩色編碼表來替換圖像的調試板,參數bpColorsTable * 指向要替換的偽彩色編碼表。 * ************************************************************************/BOOL WINAPI ReplaceColorPal(LPSTR lpDIB, BYTE * bpColorsTable){ // 循環變量 int i; // 顏色表中的顏色數目 WORD wNumColors; // 指向BITMAPINFO結構的指針(Win3.0) LPBITMAPINFO lpbmi; // 指向BITMAPCOREINFO結構的指針 LPBITMAPCOREINFO lpbmc; // 表明是否是Win3.0 DIB的標記 BOOL bWinStyleDIB; // 創建結果 BOOL bResult = FALSE; // 獲取指向BITMAPINFO結構的指針(Win3.0) lpbmi = (LPBITMAPINFO)lpDIB; // 獲取指向BITMAPCOREINFO結構的指針 lpbmc = (LPBITMAPCOREINFO)lpDIB; // 獲取DIB中顏色表中的顏色數目 wNumColors = ::DIBNumColors(lpDIB); // 判斷顏色數目是否是256色 if (wNumColors == 256) { // 判斷是否是WIN3.0的DIB bWinStyleDIB = IS_WIN30_DIB(lpDIB); // 讀取偽彩色編碼,更新DIB調色板 for (i = 0; i < (int)wNumColors; i++) { if (bWinStyleDIB) { // 更新DIB調色板紅色分量 lpbmi->bmiColors[i].rgbRed = bpColorsTable[i * 4]; // 更新DIB調色板綠色分量 lpbmi->bmiColors[i].rgbGreen = bpColorsTable[i * 4 + 1]; // 更新DIB調色板藍色分量 lpbmi->bmiColors[i].rgbBlue = bpColorsTable[i * 4 + 2]; // 更新DIB調色板保留位 lpbmi->bmiColors[i].rgbReserved = 0; } else { // 更新DIB調色板紅色分量 lpbmc->bmciColors[i].rgbtRed = bpColorsTable[i * 4]; // 更新DIB調色板綠色分量 lpbmc->bmciColors[i].rgbtGreen = bpColorsTable[i * 4 + 1]; // 更新DIB調色板藍色分量 lpbmc->bmciColors[i].rgbtBlue = bpColorsTable[i * 4 + 2]; } } } // 返回 return bResult; }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -