measurecomponents.cpp

来自「barcode readers [ from Image]」· C++ 代码 · 共 129 行

CPP
129
字号
//
// CMeasureComponents -- reports geometric parameters of components in a
//     connected component-labeled image
//
// Copyright (C) 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 "MeasureComponents.h"

#include "HashTable.h"
#include "Image.h"
#include "ImageSize.h"
#include "RGBIndex.h"
#include "ShortImageIter.h"

#include <e32math.h>
#include <e32std.h>

using namespace Core;

namespace Algorithm
{

    EXPORT_C CMeasureComponents* CMeasureComponents::NewL()
    {
        CMeasureComponents* pMe = new (ELeave) CMeasureComponents();
		CleanupStack::PushL(pMe);
        pMe->ConstructL();
		CleanupStack::Pop(pMe);
        return pMe;
    }

    CMeasureComponents::CMeasureComponents() 
    {
    }

    CMeasureComponents::~CMeasureComponents(void)
    {
    }

    void CMeasureComponents::ConstructL()
    {
    }

    void CMeasureComponents::MeasureComponentsL(CImage image, CArrayFixSeg<ComponentGeometry>*& pResult)
    {
		// segmented array is used because the hash table holds pointers to the
		// ComponentGeometry objects, so we do not want them to move around
		pResult = new (ELeave) CArrayFixSeg<ComponentGeometry>(128);
		CleanupStack::PushL(pResult);
		CHashTable<TInt, ComponentGeometry*>* pHash = CHashTable<TInt, ComponentGeometry*>::NewL(10);
		CleanupStack::PushL(pHash);

		int row = 0;
		image.LockLC(); // so we can access the bitmap contents
		IShortImageIter it(image);
		for (; !it.End(); it.NextRow(), row++) {
			int col = 0;
			// optimization if we are looking at the same component
			TInt currComponent = -1;
			ComponentGeometry *pComponent = NULL;
			for (; !it.REnd(); it++, col++) {
				if (it()) { // non-zero component
					if (currComponent != it()) { // different component
						currComponent = it();
						if (!pHash->Find(&currComponent)) {
							// this is a new component not seen before
							pComponent = &pResult->ExtendL();
							pComponent->nColor = currComponent;
							pComponent->nPixels = 1;
							pComponent->nCenterX = row;
							pComponent->nCenterY = col;
							pComponent->nBoundTop = pComponent->nBoundBottom = row;
							pComponent->nBoundLeft = pComponent->nBoundRight = col;
							pHash->AddL(&currComponent, pComponent);
						} else { // this component was seen before but it is not the current component
							// Find made this the current component in the hash table
							pComponent = pHash->Value();
							pComponent->nPixels ++;
							pComponent->nCenterX += row;
							pComponent->nCenterY += col;
							// this is a left to right, top to bottom scan so top cannot change
							// and bottom is always the current row
							pComponent->nBoundBottom = row;
							pComponent->nBoundLeft = Min(pComponent->nBoundLeft, col);
							pComponent->nBoundRight = Max(pComponent->nBoundRight, col);
						}
					} else { // we are still in the same component
						pComponent->nPixels ++;
						pComponent->nCenterX += row;
						pComponent->nCenterY += col;
						// this is a left to right, top to bottom scan so top cannot change
						// and bottom is always the current row
						pComponent->nBoundBottom = row;
						pComponent->nBoundLeft = Min(pComponent->nBoundLeft, col);
						pComponent->nBoundRight = Max(pComponent->nBoundRight, col);
					}
				}
			}
		}
		CleanupStack::PopAndDestroy(); // unlock bitmaps

		// now calculate the actual centers of all the components
		int i;
		for (i=0; i<pResult->Count(); i++) {
			ComponentGeometry *pComponent = &pResult->At(i);
			pComponent->nCenterX /= pComponent->nPixels;
			pComponent->nCenterY /= pComponent->nPixels;
		}
    	CleanupStack::PopAndDestroy(pHash);
		CleanupStack::Pop(pResult);
    }

};

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?