boxsmoothrgb.cpp
来自「barcode readers [ from Image]」· C++ 代码 · 共 195 行
CPP
195 行
//
// BoxSmoothRgb
// Smooths a color image with an nxm box filter.
// Implemented efficiently so each filter operation takes 4 adds + 1 multiply per color.
//
// 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 "BoxSmoothRgb.h"
#include "Debug.h"
#include "Image.h"
#include "Replicate.h"
#include "RgbImageIter.h"
#include "RgbIndex.h"
#include <e32std.h>
using namespace Core;
namespace Algorithm
{
EXPORT_C CBoxSmoothRgb* CBoxSmoothRgb::NewL(int nFilterWidth, int nFilterHeight)
{
CBoxSmoothRgb *me = new (ELeave) CBoxSmoothRgb(nFilterWidth, nFilterHeight);
return me;
}
CBoxSmoothRgb::~CBoxSmoothRgb(void)
{
}
CBoxSmoothRgb::CBoxSmoothRgb(int nFilterWidth, int nFilterHeight) :
ibEmpty(true),
inFilterHeight(nFilterHeight),
inFilterWidth(nFilterWidth)
{
}
CImage CBoxSmoothRgb::FrontL()
{
if (ibEmpty) {
User::Leave(KErrGeneral);
}
ibEmpty = true;
return iImage;
}
// Do the filtering
void CBoxSmoothRgb::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.
typedef int (*RgbColArray)[][3];
RgbColArray nSums = (RgbColArray) new (ELeave) int [rSize.Width()][3];
// initialize sums to zero
Mem::FillZ(nSums, sizeof(int) * 3 * 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 = (int*) new (ELeave) int [rSize.Width()];
// initialize counts to zero
Mem::FillZ(nCounts, sizeof(int) * rSize.Width());
CleanupStack::PushL(nCounts);
int i=0;
int color;
int nHalfHeight = inFilterHeight/2;
int nHalfWidth = inFilterWidth/2;
image.LockLC();
// Create input iterator
IRgbImageIter rIn(image);
// Create indexer for input
IRgbIndex rIndex(image);
// Create an iterator for the output
IRgbImageIter rOut(iImage);
// Sum first nHalfHeight rows
rIn.Reset();
for (i=0; i<nHalfHeight; i++) {
int j=0;
for (; j<rSize.Width(); j++) {
for (color=0; color<3; color++) {
(*nSums)[j][color] += rIn[color];
}
nCounts[j]++;
rIn++;
}
rIn.NextRow();
}
// now start summing and outputing filtered values
// start output iterator
rOut.Reset();
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++) {
for (color=0; color<3; color++) {
(*nSums)[j][color] += rIndex[nNextRow][j][color];
}
nCounts[j]++;
}
}
// column sums have been updated to include the new row.
// form first sum
int nSum[3] = {0};
int nCount = 0;
int j=0;
for (; j<nHalfWidth; j++) {
for (color=0; color<3; color++) {
nSum[color] += (*nSums)[j][color];
}
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()) {
for (color=0; color<3; color++) {
nSum[color] += (*nSums)[nNextCol][color];
}
nCount += nCounts[nNextCol];
}
// output sum
for (color=0; color<3; color++) {
rOut[color] = (unsigned char) (nSum[color] / nCount);
}
rOut++;
// update for next pixel
int nPrevCol = j-nHalfWidth;
if (nPrevCol >= 0) {
for (color=0; color<3; color++) {
nSum[color] -= (*nSums)[nPrevCol][color];
}
nCount -= nCounts[nPrevCol];
}
}
// subtract previous row
int nPrevRow = i-nHalfHeight;
if (nPrevRow >= 0) {
int j=0;
for (; j<rSize.Width(); j++) {
for (color=0; color<3; color++) {
(*nSums)[j][color] -= rIndex[nPrevRow][j][color];
}
nCounts[j]--;
}
}
rOut.NextRow();
}
CleanupStack::PopAndDestroy(); // unlock bitmaps
ibEmpty = false;
CDebug::ShowImage(iImage);
CleanupStack::Check(nCounts);
CleanupStack::PopAndDestroy();
CleanupStack::Check(nSums);
CleanupStack::PopAndDestroy();
}
bool CBoxSmoothRgb::Empty() const
{
return ibEmpty;
}
};
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?