decodeimage.cpp

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

CPP
288
字号
/*
	CDecodeImage. Given an image, decode all the barcodes in it
	and show the first one found to the user.
	This code is a derivative work of the SnapShot example
	application distributed with the Symbian 6.0 SDK.
	Copyright (C) 2006  Jon A. Webb

	This program is free software; you can redistribute it and/or
	modify it under the terms of the GNU General Public License
	as published by the Free Software Foundation; either version 2
	of the License, or (at your option) any later version.

	This program 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 General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

*/

#include "DecodeImage.h"

#include "Absolute.h"
#include "Bars2SymFactory.h"
#include "BoxSmooth.h"
#include "CannyHoriz.h"
#include "ColorThreshold.h"
#include "ConnComp.h"
#include "Debug.h"
#include "HashTable.h"
#include "HistEq.h"
#include "Image.h"
#include "Multiply.h"
#include "Reduce.h"
#include "Replicate.h"
#include "Rgb2Hsv.h"
#include "Rgb64K216M.h"
#include "RgbAvg2Gray.h"
#include "Sequence.h"
#include "Threshold.h"
#include "Widths2Bars.h"
#include "ZeroCrossingHoriz.h"

#include <aknnotewrappers.h>
#include <baclipb.h>
#include <gdi.h>
#include <w32std.h>

#define TEST

using namespace Core;
using namespace Algorithm;
/*!
  @function CDecodeImage
  
  @discussion Perform the first phase of two phase construction 
  */
	CDecodeImage::CDecodeImage() :
	    iBars(NULL),
		iBars2SymFactory(NULL),
		iFoundBarcode(false),
		ipGeometry(NULL),
		iPosition(NULL),
		iProcessed(false)
	{
	}

/*!
  @function CDecodeImage
  
  @discussion Perform the second phase of two phase construction 
  */
	CDecodeImage* CDecodeImage::NewL()
	{
		CDecodeImage* pMe = new (ELeave) CDecodeImage;
		CleanupStack::PushL(pMe);
		pMe->ConstructL();
		CleanupStack::Pop(pMe);
		return pMe;
	}

/*!
  @function ConstructL
  
  @discussion  Perform the second phase construction of a CReadBarCAppView object
  */
	void CDecodeImage::ConstructL()
	{
		iBars2SymFactory = CBars2SymFactory::NewL(true);
		iCodeList = new (ELeave) CArrayFixFlat<CBars2Sym::CodeType*>(4);
		iCodes = CArray<CBars2Sym::CodeType*>::NewL(iBars2SymFactory->Count());
		int i;
		for (i=0; i<iBars2SymFactory->Count(); i++) {
			(*iCodes)[i] = NULL;
		}
		User::LeaveIfError(iFsSession.Connect());
	}


/*!
  @function Destructor
  
  @discussion Destructor
  */
	CDecodeImage::~CDecodeImage()
	{
		delete iBars2SymFactory;
		iBars2SymFactory = NULL;
		ClearArrays();
		delete iCodeList;
		iCodeList = NULL;
		delete iCodes;
		iCodes = NULL;

		if (ipGeometry) {
			ipGeometry->Reset();
			delete ipGeometry;
		}
		ipGeometry = NULL;

		if (iBars) {
			iBars->Reset();
			delete iBars;
		}
		iBars = NULL;
		iFsSession.Close();
	}

/*!
	@function DoItL
	@discussion Given an image, decode all barcode sequences in it and 
		show the user the first one. Save the others into a list so they 
		can be retrieved later. For each decodeder, save each new barcode sequence
		only the first time.
	@param gc: the graphics context for the window to so debugging results etc.
	@param drawRect: the rectangle for showing debugging results.
	@param aImage: the image to be processed.
	*/
void CDecodeImage::DoItL(CWindowGc& gc, TRect drawRect, CFbsBitmap* aImage)
	{
		if (iProcessed) {
			return;
		}
		/* to see intermediate images in the pipeline, uncomment the line below */
		CDebug::InitializeDebugging(gc, drawRect);
		ClearArrays();
		CImage image(*aImage);
        IReplicate repl(image);
        CImage imageCopy;
        repl.CopyL(imageCopy);
		/* This is the pipeline we use:
		 */
		CRgb2Hsv* pRgb = CRgb2Hsv::NewL();
		CleanupStack::PushL(pRgb);
		CSequence* pSequence = CSequence::NewL(pRgb);
		CleanupStack::Pop(pRgb);
		CleanupStack::PushL(pSequence);
		CColorThreshold* pThresh = CColorThreshold::NewL(255, 128, 255, false);
		CleanupStack::PushL(pThresh);
		pSequence->AddL(pThresh);
		CleanupStack::Pop(pThresh);
		CRgbAvg2Gray* pGray = CRgbAvg2Gray::NewL();
		CleanupStack::PushL(pGray);
		pSequence->AddL(pGray);
		CleanupStack::Pop(pGray);
        CReduce* pReduce = CReduce::NewL(4,4);
        CleanupStack::PushL(pReduce);
        pSequence->AddL(pReduce);
        CleanupStack::Pop(pReduce);
		CCannyHoriz* pCanny = CCannyHoriz::NewL(0.5);
		CleanupStack::PushL(pCanny);
		pSequence->AddL(pCanny);
		CleanupStack::Pop(pCanny);
		CAbsolute* pAbs = CAbsolute::NewL();
		CleanupStack::PushL(pAbs);
		pSequence->AddL(pAbs);
		CleanupStack::Pop(pAbs);
		CThreshold* pGThresh = CThreshold::NewL(8);
		CleanupStack::PushL(pGThresh);
		pSequence->AddL(pGThresh);
		CleanupStack::Pop(pGThresh);
		CMultiply* pMult = CMultiply::NewL(50);
		CleanupStack::PushL(pMult);
		pSequence->AddL(pMult);
		CleanupStack::Pop(pMult);
		CBoxSmooth* pBox = CBoxSmooth::NewL(31,11);
		CleanupStack::PushL(pBox);
		pSequence->AddL(pBox);
		CleanupStack::Pop(pBox);
		CThreshold* pGThresh2 = CThreshold::NewL(128);
		CleanupStack::PushL(pGThresh2);
		pSequence->AddL(pGThresh2);
		CleanupStack::Pop(pGThresh2);
		CConnComp* pConnComp = CConnComp::NewL();
		CleanupStack::PushL(pConnComp);
		pSequence->AddL(pConnComp);
		CleanupStack::Pop(pConnComp);

		pSequence->PushL(imageCopy);
		CImage resultImage = pSequence->FrontL();
		CMeasureComponents* pMC = CMeasureComponents::NewL();
		CleanupStack::PushL(pMC);
		pMC->MeasureComponentsL(resultImage, ipGeometry);
		int i;
		int size = 0;
		int best = -1;
		for (i=0; i<ipGeometry->Count(); i++) {
			ComponentGeometry* pCG = &ipGeometry->At(i);
			if (pCG->nPixels > size) {
				best = i;
				size = pCG->nPixels;
			}
		}
#ifdef NOTE
		_LIT(KResult, "%d, %d, %d, %d");
		TBuf<64> buf;
		buf.Format(KResult, ipGeometry->At(best).nBoundTop, ipGeometry->At(best).nBoundBottom,
			ipGeometry->At(best).nBoundLeft, ipGeometry->At(best).nBoundRight);
		CAknInformationNote* informationNote = 
			new (ELeave) CAknInformationNote();
		CleanupStack::PushL(informationNote);
		informationNote->ExecuteLD(buf); 
		CleanupStack::Pop(informationNote);
#else
		iRectangle = TRect(
			ipGeometry->At(best).nBoundTop*4, 
			ipGeometry->At(best).nBoundLeft*4,
			ipGeometry->At(best).nBoundBottom*4,
			ipGeometry->At(best).nBoundRight*4);
		iFoundBarcode = true;
#endif
		CleanupStack::PopAndDestroy(pMC);

        CDebug::FinishDebugging();
		CleanupStack::PopAndDestroy(pSequence);
		iProcessed = true;
	}

/*!
	@function ResetProcessed
	@discussion Reset the processed flag so DoItL will actuall process the next
		image it sees.
	*/
void CDecodeImage::ResetProcessed() 
	{
		iProcessed = false;
	}

/*!
	@function ClearArrays
	@discussion Clear the code and position arrays.
	*/
void CDecodeImage::ClearArrays()
	{
		int i;
		for (i=0; i<iCodeList->Count(); i++) {
			delete (*iCodeList)[i];
			(*iCodeList)[i] = NULL;
		}
		iCodeList->Reset();
		for (i=0; i<iCodes->Count(); i++) {
			(*iCodes)[i] = NULL;
		}
		if (iPosition) {
			for (i=0; i<iPosition->Count(); i++) {
				if ((*iPosition)[i]) {
					(*iPosition)[i]->Reset();
					delete (*iPosition)[i];
				}
			}
			delete iPosition;
			iPosition = NULL;
		}
	}

	bool CDecodeImage::FoundBarcode() const
	{
		return iFoundBarcode;
	}

	TRect CDecodeImage::BarcodeRectangle() const
	{
		return iRectangle;
	}

⌨️ 快捷键说明

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