zerocrossinghoriz.cpp

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

CPP
144
字号
//
// ZeroCrossing
//   Finds the center of a circle in an image which consists of
//   potential circle-edges.
//
// Copyright (C) 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 "ZeroCrossingHoriz.h"

#include "Array.h"
#include "Debug.h"
#include "Image.h"
#include "GrayImageIter.h"
#include "GrayIndex.h"
#include "ImageSize.h"
#include "Replicate.h"

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

using namespace Core;

namespace Algorithm
{
	EXPORT_C CZeroCrossingHoriz* CZeroCrossingHoriz::NewL(int nMinStrength)
	{	
		return new (ELeave) CZeroCrossingHoriz(nMinStrength);	
	}

	CZeroCrossingHoriz::~CZeroCrossingHoriz()
	{
	}

	CZeroCrossingHoriz::CZeroCrossingHoriz(int nMinStrength) :
		inMinStrength(nMinStrength)
	{
	}

		// Input parameters:
		//   image: the input image. This is a byte gray image with 0x80 representing
	    //       0, 0x00 representing -128, 0xff representing +127, in other words
	    //       a signed image.
		// Output parameters:
		//   position: array of arrays of zero crossing positions
		void CZeroCrossingHoriz::FindZeroCrossingsL(CImage image, 
			CArray<CArrayFixFlat<TReal>*>*& position)
		{
			IImageSize size(image);
			position = CArray<CArrayFixFlat<TReal>*>::NewL(size.Height());
			int i=0;
			for (; i<size.Height(); i++) {
				(*position)[i] = NULL;
			}
			CleanupStack::PushL(position);

			image.LockLC();
			IGrayImageIter it(image);
			IGrayIndex index(image);
			for (i=0; !it.End(); it.NextRow(), i++) {
				(*position)[i] = new (ELeave) CArrayFixFlat<TReal>(16);
				int pos = 1;
				int minValue = int(it()) - 128; // convert to signed int
				int maxValue = minValue;
				int minPos = pos;
				int maxPos = minPos;
				for (it++; !it.REnd(); it++, pos++) {
					int thisPixel = int(it()) - 128; // convert to signed int
					if (thisPixel < minValue) {
						minValue = thisPixel;
						minPos = pos;
					}
					if (thisPixel > maxValue) {
						maxValue = thisPixel;
						maxPos = pos;
					}
					// is this a zero crossing
					if (minValue < -inMinStrength && maxValue > inMinStrength) {
						// search backwards from this point to the minimum, and forward
						// from this point to the maximum, in order to get a better idea
						// of the actual point of the zero crossing
						int backPos = pos, backVal;
						int fwdPos = pos, fwdVal;
						if (thisPixel < 0) { // search backwards for the peak
							backVal = index[i][backPos];
							while (backPos > 0 && index[i][backPos-1] > backVal) {
								backVal = index[i][--backPos];
							}
							// search forwards for the min
							fwdVal = index[i][fwdPos];
							while (fwdPos < size.Width()-1 && index[i][fwdPos+1] < fwdVal) {
								fwdVal = index[i][++fwdPos];
							}
						} else { // search backwards for the min
							backVal = index[i][backPos];
							while (backPos > 0 && index[i][backPos-1] < backVal) {
								backVal = index[i][--backPos];
							}
							// search forwards for the max
							fwdVal = index[i][fwdPos];
							while (fwdPos < size.Width()-1 && index[i][fwdPos+1] > fwdVal) {
								fwdVal = index[i][++fwdPos];
							}
					    }
						
						// fit the line a * x + b = y to the values
						//   x = backPos, y = backVal
						//   x = fwdPos, y = fwdVal
						backVal -= 128; // convert from unsigned char
						fwdVal -= 128; // convert from unsigned char
						TReal a = TReal(fwdVal - backVal) / TReal(fwdPos - backPos);
						TReal b = TReal(fwdVal) - a * TReal(fwdPos);
						// now compute the point x such that a * x + b = 0
						// and append to the position list
						(*position)[i]->AppendL(-b / a);
						// now start the next search for a zero crossing
						minValue = maxValue = thisPixel;
					}
				}
			}
			CleanupStack::PopAndDestroy(); // unlock bitmaps

			CleanupStack::Check(position);
			CleanupStack::Pop();

		}

};

⌨️ 快捷键说明

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