hysterisisthreshold.cpp

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

CPP
186
字号
//
// HysterisisThreshold
//   Finds connected components that are everywhere greater than the lower
//   threshold, and somwhere greater than the upper.
//
// 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 "HysterisisThreshold.h"

#include "ConnComp.h"
#include "Debug.h"
#include "Image.h"
#include "GrayImageIter.h"
#include "ImageSize.h"
#include "Ladder.h"
#include "Replicate.h"
#include "Sequence.h"
#include "ShortImageIter.h"
#include "Threshold.h"

#include <e32std.h>
#include <fbs.h>

using namespace Core;

namespace Algorithm
{
	class CHysterisisJoin: public MJoin
	{
		// Lifecycle
	public:
		static CHysterisisJoin* NewL()
		{
			return new (ELeave) CHysterisisJoin;
		}

		~CHysterisisJoin()
		{
		}
	private:
		CHysterisisJoin() 
		{
		}

		// Operations
	public:
		// Input is a connected-component labeled image low-thresholded and a high-thresholded image.
		// (The labeled image is type short, the thresholded image is byte).
		// First we mark all components in the labeled image that have a non-zero pixel
		// in the thresholded image. Then we output 255 for all pixels that belong to
		// components that were so labeled.
		CImage DoJoinL(CImage imgLow, CImage imgHigh)
		{
			// nKeep holds the labels of components that we will keep, i.e. that at
			// some point are above the threshold.
			// Initialize it to zero.
			// The input labeled image is unsigned short so there can be up to 2^16 = 32768
			// labels
			const int twoP16 = 0x10000;
			unsigned char *nKeep = new (ELeave) unsigned char [twoP16];
			CleanupStack::PushL(nKeep);
			int i = 0;
			for (; i<twoP16; i++) {
				nKeep[i] = 0;
			}
			// get iterators for the low-thresholded and labeled image
			// and the high-thresholded image
			IShortImageIter itLow(imgLow);
			IGrayImageIter itHigh(imgHigh);
			// Set the mapping of the labels of all pixels that have a corresponding non-zero pixel
			// in the high-thresholded image to 255
			for (; !itLow.End(); itLow.NextRow(), itHigh.NextRow()) {
				for (; !itLow.REnd(); itLow++, itHigh++) {
					if (itHigh() != 0 && itLow() != 0) {
						nKeep[itLow()] = 255;
					}
				}
			}
			// assign the mapping
			IReplicate rRepl(imgLow);
			CImage imgOut;
			rRepl.CastL(imgOut, EGray256);
			IGrayImageIter itOut(imgOut);
			for (itLow.Reset(); !itLow.End(); itLow.NextRow(), itOut.NextRow()) {
				for (; !itLow.REnd(); itLow++, itOut++) {
					itOut() = nKeep[itLow()];
				}
			}
			CleanupStack::Check(nKeep);
			CleanupStack::PopAndDestroy(/* nKeep */);
			return imgOut;
		}
	};

	EXPORT_C CHysterisisThreshold* CHysterisisThreshold::NewL(int nLowThreshold, int nHighThreshold)
	{	
		CHysterisisThreshold* me = new (ELeave) CHysterisisThreshold(nLowThreshold, nHighThreshold);	
		CleanupStack::PushL(me);
		me->ConstructL();
		CleanupStack::Pop();
		return me;
	}

	CHysterisisThreshold::~CHysterisisThreshold()
	{
		delete iLadder; // which deletes everything belonging to it
	}

	CHysterisisThreshold::CHysterisisThreshold(int nLowThreshold, int nHighThreshold) :
		ibEmpty(true),
		iLowThreshold(nLowThreshold),
		iHighThreshold(nHighThreshold),
		iLadder(NULL)
	{
	}

	//
	// Here is the pipeline:
	//       />threshold(low) -> byte2short -> connected components ->\ 
	// image|                                                          -> hysterisis join
	//       \>threshold(high) -------------------------------------->/ 
	//
	void CHysterisisThreshold::ConstructL()
	{
		CThreshold* pThreshLo = CThreshold::NewL(iLowThreshold, true);
		CleanupStack::PushL(pThreshLo);
		CSequence *pPipe1 = CSequence::NewL(pThreshLo);
		CleanupStack::Pop(); // pThreshLo will be freed by pPipe1
		CleanupStack::PushL(pPipe1);
		CConnComp *pCC1 = CConnComp::NewL();
		CleanupStack::PushL(pCC1);
		pPipe1->AddL(pCC1);
		CleanupStack::Pop(/* pCC1 */); // owned by pPipe1 now

		CThreshold *pThreshHi = CThreshold::NewL(iHighThreshold, true);
		CleanupStack::PushL(pThreshHi);

		MJoin* pJoin = CHysterisisJoin::NewL();
		CleanupStack::PushL(pJoin);
		iLadder = CLadder::NewL(pPipe1, pThreshHi, pJoin);

		// pPipe1, pThreshHi, and pJoin will be freed by iLadder
		CleanupStack::Pop();
		CleanupStack::Pop();
		CleanupStack::Pop();
	}

	CImage CHysterisisThreshold::FrontL() 
	{
		if (ibEmpty) {
			User::Leave(KErrGeneral);
			return CImage();
		}
		ibEmpty = true;
		return iImage;
	}

	void CHysterisisThreshold::PushL(CImage image)
	{
		iLadder->PushL(image);
		iImage = iLadder->FrontL();
		CDebug::ShowImage(iImage);
		ibEmpty = false;
	}

	bool CHysterisisThreshold::Empty() const
	{
		return ibEmpty;
	}
};

⌨️ 快捷键说明

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