findbarcode.cpp

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

CPP
318
字号
/*
	CFindBarcode. 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 "FindBarcode.h"

#include "Absolute.h"
#include "Add.h"
#include "Bars2SymFactory.h"
#include "BoxSmoothRgb.h"
#include "Clip.h"
#include "ClipRgb.h"
#include "ConnComp.h"
#include "Debug.h"
#include "HashTable.h"
#include "HistEq.h"
#include "Image.h"
#include "Multiply.h"
#include "Reduce.h"
#include "ReduceRgb.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>

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

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

/*!
  @function ConstructL
  
  @discussion  Perform the second phase construction of a CReadBarCAppView object
  */
	void CFindBarcode::ConstructL()
	{
		//iBars2SymFactory = CBars2SymFactory::NewL();
		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
  */
	CFindBarcode::~CFindBarcode()
	{
		//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 aImage: the image to be processed.
	*/
void CFindBarcode::DoItL(CImage image)
	{
		if (iProcessed) {
			return;
		}
		/* to see intermediate images in the pipeline, uncomment the line below */
		ClearArrays();
        IReplicate repl(image);
        CImage imageCopy;
        repl.CopyL(imageCopy);
		/* This is the pipeline we use:
			CReduceRgb			reduce image size 4x4 to speed processing
			CBoxSmoothRgb		smooth image to blur black and white stripes
			CRgb2Hsv			convert to hsv color space so we can get rid of colored background
			CClipRgb			clip off colored background
			CRgbAvg2Gray		convert to gray
			CHistEq				histogram equalize
			CLadder:			two pipelines below run conceptually in parallel
				CClip			clip off everything but the black stripes
				CMultiply		turn everything non-zero to 255

				CClip			clip off white background
			CAdd				Adds images from above
			CThreshold			binarize image
			CConnComp			label connected components
			CMeasureComponents	find largest connected component: this is the barcode
		 */
		CReduceRgb* pReduceRgb = CReduceRgb::NewL(4,4);
		CleanupStack::PushL(pReduceRgb);
		CSequence* pSequence = CSequence::NewL(pReduceRgb);
		CleanupStack::Pop(pReduceRgb);
		CleanupStack::PushL(pSequence);
		CBoxSmoothRgb* pBox = CBoxSmoothRgb::NewL(31,11);
		CleanupStack::PushL(pBox);
		pSequence->AddL(pBox);
		CleanupStack::Pop(pBox);
		CRgb2Hsv* pHsv = CRgb2Hsv::NewL();
		CleanupStack::PushL(pHsv);
		pSequence->AddL(pHsv);
		CleanupStack::Pop(pHsv);
		// clip off too-colorful
		CClipRgb* pClipRgb = CClipRgb::NewL(255, 64, 255, false);
		CleanupStack::PushL(pClipRgb);
		pSequence->AddL(pClipRgb);
		CleanupStack::Pop(pClipRgb);
		CRgbAvg2Gray* pGray = CRgbAvg2Gray::NewL();
		CleanupStack::PushL(pGray);
		pSequence->AddL(pGray);
		CleanupStack::Pop(pGray);
		CHistEq* pHistEq = CHistEq::NewL();
		CleanupStack::PushL(pHistEq);
		pSequence->AddL(pHistEq);
		CleanupStack::Pop(pHistEq);
		// clip off everything but the dark stripes
		CClip* pClipGray1 = CClip::NewL(96, false);
		CleanupStack::PushL(pClipGray1);
		CSequence* pSequence2 = CSequence::NewL(pClipGray1);
		CleanupStack::Pop(pClipGray1);
		CleanupStack::PushL(pSequence2);
		CMultiply *pMultiply = CMultiply::NewL(255);
		CleanupStack::PushL(pMultiply);
		pSequence2->AddL(pMultiply);
		CleanupStack::Pop(pMultiply);
		// clip off too-bright 
		CClip* pClipGray2 = CClip::NewL(224, false);
		CleanupStack::PushL(pClipGray2);
		CAdd* pAdd = CAdd::NewL();
		CleanupStack::PushL(pAdd);
		CLadder* pLadder = CLadder::NewL(pSequence2, pClipGray2, pAdd);
		CleanupStack::Pop(pAdd);
		CleanupStack::Pop(pClipGray2);
		CleanupStack::Pop(pSequence2);
		CleanupStack::PushL(pLadder);
		pSequence->AddL(pLadder);
		CleanupStack::Pop(pLadder);
		// binarize and threshold off too-dark
		CThreshold* pThreshGray = CThreshold::NewL(192, true);
		CleanupStack::PushL(pThreshGray);
		pSequence->AddL(pThreshGray);
		CleanupStack::Pop(pThreshGray);
		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);
		if (ipGeometry) {
			ipGeometry->Reset();
			delete ipGeometry;
			ipGeometry = NULL;
		}
		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;
			}
		}
		if (best != -1 && ipGeometry->At(best).nPixels > 1000) {
			iRectangle = TRect(
				ipGeometry->At(best).nBoundLeft*4 + 3,
				ipGeometry->At(best).nBoundTop*4 + 3, 
				ipGeometry->At(best).nBoundRight*4 + 3,
				ipGeometry->At(best).nBoundBottom*4 + 3);
			iFoundBarcode = true;
		} else {
			iFoundBarcode = false;
		}

		CleanupStack::PopAndDestroy(pMC);
		CleanupStack::PopAndDestroy(pSequence);
		iProcessed = true;
	}

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

void CFindBarcode::SetProcessed()
{
	iProcessed = true;
}

/*!
	@function ClearArrays
	@discussion Clear the code and position arrays.
	*/
void CFindBarcode::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 CFindBarcode::FoundBarcode() const
	{
		return iFoundBarcode;
	}

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

	bool CFindBarcode::ProcessedImage() const
	{
		return iProcessed;
	}

⌨️ 快捷键说明

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