boxsmooth.cpp
来自「barcode readers [ from Image]」· C++ 代码 · 共 173 行
CPP
173 行
//
// BoxSmooth
// Smooths a gray image with an nxm box filter.
// Implemented efficiently so each filter operation takes 4 adds + 1 multiply.
//
// Copyright (C) 2003, 2006 by Jon A. Webb (Contact via GMail; username is jonawebb)
//
// This library 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.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
//
#include "BoxSmooth.h"
#include "Debug.h"
#include "GrayImageIter.h"
#include "GrayIndex.h"
#include "Image.h"
#include "Replicate.h"
#include <e32std.h>
using namespace Core;
namespace Algorithm
{
EXPORT_C CBoxSmooth* CBoxSmooth::NewL(int nFilterWidth, int nFilterHeight)
{
CBoxSmooth *me = new (ELeave) CBoxSmooth(nFilterWidth, nFilterHeight);
return me;
}
CBoxSmooth::~CBoxSmooth(void)
{
}
CBoxSmooth::CBoxSmooth(int nFilterWidth, int nFilterHeight) :
ibEmpty(true),
inFilterHeight(nFilterHeight),
inFilterWidth(nFilterWidth)
{
}
CImage CBoxSmooth::FrontL()
{
if (ibEmpty) {
User::Leave(KErrGeneral);
}
ibEmpty = true;
return iImage;
}
// Do the filtering
void CBoxSmooth::PushL(CImage image)
{
// Need to create an output image of the same size as the input.
IReplicate rRepl(image);
rRepl.CastL(iImage);
// Get the image size
IImageSize rSize(image);
// The computation is done by maintaining a sum for each column of the input. The column sum is
// maintained, after initialization, simply by subtracting off the top row and adding on the
// bottom one.
// Allocate space for the sums.
int *nSums = new (ELeave) int [rSize.Width()];
CleanupStack::PushL(nSums);
// We handle the filtering at the edge of the image slightly cleverly by keeping track of the
// number of pixels that have been added in the column sums. When the box filter extends
// outside the image we sum just the pixels that lie within the image and divide by their
// count. This means we have to maintain a count of the number of pixels in each column sum.
int *nCounts = new (ELeave) int [rSize.Width()];
CleanupStack::PushL(nCounts);
int i=0;
int nHalfHeight = inFilterHeight/2;
int nHalfWidth = inFilterWidth/2;
// initialize counts to zero
for (; i<rSize.Width(); i++) {
nSums[i] = 0;
nCounts[i] = 0;
}
image.LockLC();
// Create input iterator
IGrayImageIter rIn(image);
// Create indexer for input
IGrayIndex rIndex(image);
// Create an iterator for the output
IGrayImageIter rOut(iImage);
// Sum first nHalfHeight rows
for (i=0; i<nHalfHeight; i++) {
int j=0;
for (; j<rSize.Width(); j++) {
nSums[j] += rIn++();
nCounts[j] ++;
}
rIn.NextRow();
}
// now start summing and outputing filtered values
// start output iterator
for (i=0; i<rSize.Height(); i++) {
// add next row
int nNextRow = i+nHalfHeight;
if (nNextRow < rSize.Height()) {
int j=0;
for (; j<rSize.Width(); j++) {
nSums[j] += rIndex[nNextRow][j];
nCounts[j]++;
}
}
// column sums have been updated to include the new row.
// form first sum
int nSum = 0;
int nCount = 0;
int j=0;
for (; j<nHalfWidth; j++) {
nSum += nSums[j];
nCount += nCounts[j];
}
// first sum has been calculated. Now work across the image
// and calculate all the other sums and assign them to the
// output image
for (j=0; j<rSize.Width(); j++) {
int nNextCol = j+nHalfWidth;
if (nNextCol < rSize.Width()) {
nSum += nSums[nNextCol];
nCount += nCounts[nNextCol];
}
// output sum
rOut++() = (unsigned char) (nSum / nCount);
// update for next pixel
int nPrevCol = j-nHalfWidth;
if (nPrevCol >= 0) {
nSum -= nSums[nPrevCol];
nCount -= nCounts[nPrevCol];
}
}
// subtract previous row
int nPrevRow = i-nHalfHeight;
if (nPrevRow >= 0) {
int j=0;
for (; j<rSize.Width(); j++) {
nSums[j] -= rIndex[nPrevRow][j];
nCounts[j]--;
}
}
rOut.NextRow();
}
CleanupStack::PopAndDestroy(); // unlock bitmaps
ibEmpty = false;
CleanupStack::PopAndDestroy(nCounts);
CleanupStack::PopAndDestroy(nSums);
CDebug::ShowImage(iImage);
}
bool CBoxSmooth::Empty() const
{
return ibEmpty;
}
};
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?