【影象演算法】高斯模糊+徑向縮放模糊
【原文:http://blog.csdn.net/meegomeego/article/details/8790309】
初學圖形程式設計,開始記錄
工作內容:通過學習某知名商業引擎,構建新遊戲引擎,對新引擎進行簡單測試。
札記:
1、移植程式碼大部分時間都是很枯燥的,不用想只需要重複的做,重複的做。。。。, 最多要改的地方就是編碼規範,然後是在許多模組沒有建立的基礎上對把移植好的模組編譯連線,最重要的技巧就是註釋,許多設計沒有建立的模組太多,只能留下空實現的函式,以後用到的時候再實現吧。
2、這次做完了Texture模組,雖然還沒有做任何渲染相關的程式碼,但是測試還是需要的,不然以後累加起來可能就忘記了。
2.1。測試流程:載入一個圖片到快取,操作快取(即畫素),做出特定的模糊效果,再另儲存為檔案,進行檢視。(注:檔案操作和DDS影象檔案讀取已經做完)
2.2。製作高斯模糊(累加畫素求平均值):
輸入:畫素資料指標,高斯模糊半徑(X和Y分量上各一個)
演算法流程:1、遍歷每一個畫素點
2、以這個畫素點為中心,根據高斯模糊半徑建立一個區域,此區域內的畫素用來計算中心點畫素的高斯模糊值。
3、遍歷這個區域的每一個畫素,累加RGBA的各個分量值(我測試的圖片是32位的DDS檔案)。
4、用各個分量除以累加的數量組合成一個畫素(即高斯模糊後的畫素點)。
注:
1、使用unsigned char儲存一個畫素的分量,但累加的時候要使用更大儲存空間的型別比如unsigned int,否則會溢位。
2、這次操作的影象是讀DDS檔案,儲存格式為BMP,發現兩種格式檔案的RGBA的通道儲存順序是不一致的,所以操作的時候要改為正確的才能進行儲存。
3、BMP格式解析檔案是從下到上進行倒置儲存的。
4、進行多次遍歷畫素點的時候要保持遍歷的順序,否則容易出現貼圖倒置或翻轉的效果。
事例程式碼:
//---------------------------------------------------------------------------
void FillPerPixelGaussBlur(yqg_IPixelData * pDest, DWORD originX, DWORD originY, BYTE * pSrc, DWORD radiusX, DWORD radiusY)
{
// 記錄共受多少個畫素的影響
DWORD t_Num = 0;
// 獲得高斯模糊半徑內的畫素區域
DWORD t_pixelLeft = originX > radiusX ? originX-radiusX : 0;
DWORD t_pixelTop = originY > radiusY ? originY-radiusY : 0;
DWORD t_pixelRight = (originX+radiusX) < pDest->GetWidth() ? originX+radiusX : pDest->GetWidth();
DWORD t_pixelBottom= (originY+radiusY) < pDest->GetHeight() ? originY+radiusY : pDest->GetHeight();
DWORD t_pPixels[4];
for(int t_d = 0; t_d < 4; ++t_d)
{
t_pPixels[t_d] = 0;
}
// 遍歷區域內的每個元素
for(DWORD t_dX = t_pixelLeft; t_dX < t_pixelRight; ++t_dX)
{
for(DWORD t_dY = t_pixelTop; t_dY < t_pixelBottom; ++t_dY)
{
// 計數
++t_Num;
// 將影響畫素分值新增到高斯模糊畫素上
BYTE * t_pOrigin = (BYTE*)&(((DWORD*)pSrc)[t_dX + t_dY * pDest->GetWidth()]);
t_pPixels[0] = t_pPixels[0] + *(t_pOrigin+0); //Red
t_pPixels[1] = t_pPixels[1] + *(t_pOrigin+1); //Green
t_pPixels[2] = t_pPixels[2] + *(t_pOrigin+2); //Blue
t_pPixels[3] = t_pPixels[3] + *(t_pOrigin+3); //Alpha
}
}
// 取累加後的畫素平均值,即高斯模糊
if(t_Num != 0)
{
BYTE * t_pDestPixel = pDest->operator()(originX, originY);
*(t_pDestPixel+0) = (BYTE)(t_pPixels[0] / t_Num);//Blue
*(t_pDestPixel+1) = (BYTE)(t_pPixels[1] / t_Num);//Green
*(t_pDestPixel+2) = (BYTE)(t_pPixels[2] / t_Num);//Red
*(t_pDestPixel+3) = (BYTE)(t_pPixels[3] / t_Num);
}
}
//---------------------------------------------------------------------------
2.3。製作徑向縮放模糊(針對任意一點,迴圈數量,根據數量值求出單位縮放,確定當前數量下的畫素點,進行累加,然後求平均值):
輸入:畫素資料指標,徑向縮放中心點(指定的畫素位置),數量
演算法流程:1、遍歷每一個畫素點
2、迴圈數量,根據每個數量下的單位縮放值和中心點累加畫素值。
3、求平均值,即該畫素點的徑向縮放模糊值。
注:做縮放值和畫素點的計算時要確定型別,如unsigned int相減是不會的得到負數的,細節很重要。
事例程式碼:
//---------------------------------------------------------------------------
void FillPerPixelRadialBlur(yqg_IPixelData * pDest, BYTE * pSrc, DWORD dCenterX, DWORD dCenterY, DWORD dNum, DWORD dCurrentPosX, DWORD dCurrentPosY)
{
// 縮放值
float t_fScale;
// 根據縮放值和中心點計算後用來累加畫素點的位置
DWORD t_caluPixelPosX;
DWORD t_caluPixelPosY;
// 臨時儲存累加的計算結果,並初始化
DWORD t_pPixels[4];
for(int t_d = 0; t_d < 4; ++t_d)
{
t_pPixels[t_d] = 0;
}
// 遍歷數量
for(DWORD t_dIndex = 0; t_dIndex < dNum; ++t_dIndex)
{
// 計算縮放值
t_fScale = 1.0f + (-(dNum*1.0f/pDest->GetWidth()) * t_dIndex) / (dNum - 1);
// 計算累加畫素點的位置
t_caluPixelPosX = (DWORD)(((int)dCurrentPosX - (int)dCenterX) * t_fScale + dCenterX);
t_caluPixelPosY = (DWORD)(((int)dCurrentPosY - (int)dCenterY) * t_fScale + dCenterY);
t_caluPixelPosX = (t_caluPixelPosX > (pDest->GetWidth() - 1)) ? (pDest->GetWidth() - 1) : t_caluPixelPosX;
t_caluPixelPosY = (t_caluPixelPosY > (pDest->GetHeight() - 1)) ? (pDest->GetHeight() - 1) : t_caluPixelPosY;
// 將影響畫素分值新增到徑向縮放模糊畫素上
BYTE * t_pOrigin = (BYTE*)&(((DWORD*)pSrc)[t_caluPixelPosX + t_caluPixelPosY * pDest->GetWidth()]);
t_pPixels[0] = t_pPixels[0] + *(t_pOrigin+0); //Red
t_pPixels[1] = t_pPixels[1] + *(t_pOrigin+1); //Green
t_pPixels[2] = t_pPixels[2] + *(t_pOrigin+2); //Blue
t_pPixels[3] = t_pPixels[3] + *(t_pOrigin+3); //Alpha
}
// 取累加後的畫素平均值,即高斯模糊
BYTE * t_pDestPixel = pDest->operator()(dCurrentPosX, dCurrentPosY);
*(t_pDestPixel+0) = (BYTE)(t_pPixels[0] / dNum);//Blue
*(t_pDestPixel+1) = (BYTE)(t_pPixels[1] / dNum);//Green
*(t_pDestPixel+2) = (BYTE)(t_pPixels[2] / dNum);//Red
*(t_pDestPixel+3) = (BYTE)(t_pPixels[3] / dNum);
}
//---------------------------------------------------------------------------
以下是原圖和效果圖
相關文章
- 學習OpenCV:濾鏡系列(5)——徑向模糊:縮放&旋轉OpenCV
- 高斯模糊的演算法演算法
- Android影象處理 - 高斯模糊的原理及實現Android
- Java 實現高斯模糊和影象的空間卷積Java卷積
- 後處理 - 高斯模糊
- Flutter BackdropFilter 實現高斯模糊FlutterFilter
- win10螢幕字型縮放模糊怎麼辦_win10縮放後字型模糊如何解決Win10
- Android實現快速高斯模糊Android
- matlab練習程式(旋轉、徑向模糊)Matlab
- Android模糊影象教程(2)Android
- Android模糊影象教程(3)Android
- Android模糊影象教程(1)Android
- Android模糊影象教程(4)Android
- Android模糊影象教程(5)Android
- Android動態高斯模糊效果教程Android
- Android NDK之旅——圖片高斯模糊Android
- Android 圖片高斯模糊處理Android
- Android 圖片高斯模糊解決方案Android
- Flutter學習 —- 螢幕截圖和高斯模糊Flutter
- Flutter學習 ---- 螢幕截圖和高斯模糊Flutter
- 前端 -- 頁面濾鏡效果及高斯模糊效果前端
- C++影象縮放C++
- Java 實現高斯模糊和影像的空間卷積Java卷積
- Android:簡單靠譜的動態高斯模糊效果Android
- [work] 影象縮放——雙線性插值演算法演算法
- matlab練習程式(模糊集影象增強)Matlab
- Android專案實戰(五十七):Glide 高斯模糊效果AndroidIDE
- Fresco實踐-高斯模糊、圓形圓角、URL、File、Assets、Resource
- box-shadow 模糊半徑與擴充套件半徑套件
- OpenCV(iOS)影象尺寸縮放(14)OpenCViOS
- Android自定義弧形[方形加弧形]IamgeView並新增高斯模糊AndroidView
- 運動模糊演算法推論演算法
- 如何在 pyqt 中解決啟用 DPI 縮放後 QIcon 模糊的問題QT
- 直播平臺原始碼,用CSS製作毛玻璃效果(高斯模糊效果)原始碼CSS
- [譯] GAN 的 Keras 實現:構建影象去模糊應用Keras
- 影象縮放--插值法(opencv,原理)OpenCV
- [Python影象處理] 六.影象縮放、影象旋轉、影象翻轉與影象平移Python
- 這可能是實現高斯模糊(毛玻璃)最簡單的庫了