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 + -
显示快捷键?