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