📄 mapblurrer.cpp
字号:
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation; either version 2 of the *
* License, or (at your option) any later version. *
* *
***************************************************************************/
/**
@file
MapBlurrer.cpp
@brief
Utility that blur maps
*/
#include "MapUtil.h"
#include "MapBlurrer.h"
#include <iostream>
#include <fstream>
#include <vector>
#include "OgreImageCodec.h"
#include "OgreILCodecs.h"
#include "fileutils.h"
namespace Ogre
{
//-----------------------------------------------------------------------
MapBlurrer::MapBlurrer()
{
}
//-----------------------------------------------------------------------
MapBlurrer::~MapBlurrer()
{
}
//-----------------------------------------------------------------------
void MapBlurrer::AverageBlur(Image *BlurImage)
{
uint height = BlurImage->getHeight ();
uint width = BlurImage->getWidth ();
uint Bpp = BlurImage->getNumElemBytes (BlurImage->getFormat ());
uchar *tempImageData = new uchar[width*height*Bpp];
uchar *BlurImageData = BlurImage->getData ();
int w[3][3] = {{1, 1, 1}, {1, 1, 1}, {1, 1, 1}};
// or
//int w[3][3] = {{1, 2, 1}, {2, 4, 2}, {1, 2, 1}}
int totalWeight = 0;
for (uint i = 0; i < 3; i++)
for (uint j = 0; j < 3; j++)
totalWeight += w[i][j];
Real invTotalW = 1.0f / totalWeight;
uint row_current = 0;
for (uint x = 0; x < width; x++)
{
for (uint z = 0; z < height; z++)
{
/* Show progress */
DEBUG_PROGRESS_OUTPUT(".")
uint tempY = 0;
uint cur_row = row_current;
for (uint i = 0; i < 3; i++)
{
for (uint j = 0; j < 3; j++)
tempY += w[i][j] * BlurImageData [row_current + cur_row - height + z + j - 1];
cur_row += height;
}
//Save the value into the temporary image data
BlurImageData[row_current + z] = uchar (tempY *invTotalW);
}
row_current += height;
}
//Delete temporary memory
if(tempImageData)
delete [] tempImageData;
tempImageData = 0;
}
//-----------------------------------------------------------------------
void MapBlurrer::gaussianBlur(Image *BlurImage, int sigma)
{
//Create space to hold the (1D) kernel values
//Ignore values outside 3 standard deviations
int kernelRadius = int (3*sigma);
int kernelSize = kernelRadius * 2 + 1;
double *kernel = new double[kernelSize];
//Fill the kernel values
Real precal_divider = (1.0f / (2*sigma*sigma)) / (Math::Sqrt(2*Math::PI) * sigma);
for(int x = -kernelRadius; x <= kernelRadius; ++x)
kernel[x+kernelRadius] = Math::Exp ( -(x*x) * precal_divider);
//Normalize the values
double kernelTotal = 0.0f;
for(int i = 0; i < kernelSize; ++i)
kernelTotal += kernel[i];
for(int i = 0; i < kernelSize; ++i)
kernel[i] /= kernelTotal;
uint height = BlurImage->getHeight ();
uint width = BlurImage->getWidth ();
uint Bpp = BlurImage->getNumElemBytes (BlurImage->getFormat ());
uchar *tempImageData = new uchar[width*height*Bpp];
uchar *BlurImageData = BlurImage->getData ();
std::cout << "blurring : ";
//Apply the kernel in the x direction, saving the data in tempImageData
//Loop through pixels
uint row_current = 0;
int width_size = width*Bpp;
for (uint y = 0; y < height; ++y)
{
/* Show progress */
DEBUG_PROGRESS_OUTPUT(".")
for(uint x = 0; x < width; ++x)
{
for(uint z = 0; z < Bpp; ++z)
{
//Keep a running total of the pixel's new value
double newValue = 0.0;
//Loop through values in kernel
for(int kx = -kernelRadius; kx <= kernelRadius; ++kx)
{
//Calculate the pixel column to read
int pixelColumn = (x + kx)*Bpp;
//If the pixel is outside the image, stop at the edge
if(pixelColumn < 0)
pixelColumn = 0 + z;
if(pixelColumn >= width_size)
pixelColumn = width_size - (Bpp - z);
pixelColumn += z;//step to the good color channel
//Add kernel value*pixel value to the new value
newValue += kernel[kx + kernelRadius] * BlurImageData [row_current + pixelColumn];
}
//Save the value into the temporary image data
tempImageData[row_current + x * Bpp + z] = uchar (newValue);
}
}
row_current += width_size;
}
//Now apply the kernel in the y direction to tempImageData
//Loop through pixels
row_current = 0;
for (uint y = 0; y < height; ++y)
{
/* Show progress */
DEBUG_PROGRESS_OUTPUT(".")
for (uint x = 0; x<width; ++x)
{
for (uint z = 0; z < Bpp; ++z)
{
//Keep a running total of the pixel's new value
double newValue=0.0;
//Loop through values in kernel
for (int kx = -kernelRadius; kx <= kernelRadius; ++kx)
{
//Calculate the pixel row to read
int pixelRow = y + kx;
//If the pixel is outside the image, stop at the edge
if(pixelRow < 0)
pixelRow = 0 + z;
if(pixelRow >= (int)height)
pixelRow = height - (Bpp - z);
//Add kernel value*pixel value to the new value
newValue += kernel[kx+kernelRadius] * tempImageData[pixelRow * width_size + x * Bpp + z];
}
//Save the value into the destination image data
BlurImageData[row_current + x * Bpp + z]= uchar (newValue);
}
}
row_current += width_size;
}
//Delete temporary memory
if(tempImageData)
delete [] tempImageData;
tempImageData=NULL;
if(kernel)
delete [] kernel;
kernel = NULL;
std::cout << "\n";
}
}//namespace Ogre
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -