⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bars2symupcx2.cpp

📁 barcode readers [ from Image]
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			TInt32 bestConv = -9999999, nextBestConv = -9999999;
			int d;
			// estimate first two digits
			for (d=0; d<10; d++) {
				int d1;
				for (d1=0; d1<10; d1++) {
					int j;
					TInt32 conv = 0;
					for (j=0; j<LeftWidth+DigitWidth*2; j++) {
						int k;
						for (k=0; k<pixelsPerBar; k++) {
							conv += index[row][pos + j*pixelsPerBar + k] * iLeftConv[d][d1][j];
						}
					}
					if (conv > bestConv) {
						nextBestConv = bestConv;
						bestConv = conv;
						bestDigit = d;
						bestDigit1 = d1;
					} else {
						nextBestConv = Max(nextBestConv,conv);
					}
				}
			}
			code[0] = (TUint8) bestDigit;
			CountDigits[0][bestDigit]++;
			code[1] = (TUint8) bestDigit1;
			CountDigits[1][bestDigit]++;
			totalConv += bestConv;
			TInt lastDigit = bestDigit1;
			for (i=2; i<Digits; i++) {
				pos = nOffset + (LeftWidth + (i-1) * DigitWidth) * pixelsPerBar; // position of start of next digit
				int bestDigit = -1;
				TInt32 bestConv = -9999999, nextBestConv = -9999999;
				int d;
				for (d=0; d<10; d++) {
					TInt32 conv = 0;
					int j;
					for (j=0; j<DigitWidth*2; j++) {
						int k;
						for (k=0; k<pixelsPerBar; k++) {
							conv += index[row][pos + j*pixelsPerBar + k] * iPairConv[lastDigit][d][j];
						}
					}
					if (conv > bestConv) {
						nextBestConv = bestConv;
						bestConv = conv;
						bestDigit = d;
					} else {
						nextBestConv = Max(nextBestConv,conv);
					}
				}
				code[i] = (TUint8) bestDigit;
				CountDigits[i][bestDigit]++;
				totalConv += bestConv;
				lastDigit = bestDigit;
			}
			// estimate first two digits of right side of pattern
			pos = nOffset + MidOffset * pixelsPerBar; // position of start of right side
			bestConv = -9999999;
			nextBestConv = -9999999;
			for (d=0; d<10; d++) {
				int d1;
				for (d1=0; d1<10; d1++) {
					TInt32 conv = 0;
					int j;
					for (j=0; j<MidWidth+DigitWidth*2; j++) {
						int k;
						// note sign change in convolution sum below -- right side of pattern
						// reverses black and white compared to left side
						for (k=0; k<pixelsPerBar; k++) {
							conv -= index[row][pos + j*pixelsPerBar + k] * iMidConv[d][d1][j];
						}
					}
					if (conv > bestConv) {
						nextBestConv = bestConv;
						bestConv = conv;
						bestDigit = d;
						bestDigit1 = d1;
					} else {
						nextBestConv = Max(nextBestConv,conv);
					}
				}
			}
			code[Digits] = (TUint8) bestDigit;
			CountDigits[Digits][bestDigit]++;
			code[Digits+1] = (TUint8) bestDigit1;
			CountDigits[Digits+1][bestDigit1]++;
			totalConv += bestConv;
			lastDigit = bestDigit1;
			for (i=2; i<Digits; i++) {
				pos = nOffset + (MidOffset + MidWidth + (i-1) * DigitWidth) * pixelsPerBar; // position of start of next digit
				int bestDigit = -1;
				TInt32 bestConv = -9999999, nextBestConv = -9999999;
				int d;
				for (d=0; d<10; d++) {
					TInt32 conv = 0;
					int j;
					for (j=0; j<DigitWidth*2; j++) {
						int k;
						for (k=0; k<pixelsPerBar; k++) {
							conv -= index[row][pos + j*pixelsPerBar + k] * iPairConv[lastDigit][d][j];
						}
					}
					if (conv > bestConv) {
						nextBestConv = bestConv;
						bestConv = conv;
						bestDigit = d;
					} else {
						nextBestConv = Max(nextBestConv,conv);
					}
				}
				code[Digits+i] = (TUint8) bestDigit;
				CountDigits[Digits+i][bestDigit]++;
				totalConv += bestConv;
				lastDigit = bestDigit;
			}
			CleanupStack::PopAndDestroy(); // unlock images
			/* if (VerifyCheckDigit(code)) */ {
				if (iHash->Find(&code[0], Digits*2)) {
					((CodeValue*)(iHash->Value()))->Add(totalConv);
				} else {
					TBuf8<Digits*2>* pCode = new TBuf8<Digits*2>(code);
					iCodes->AppendL(pCode); // so it gets deleted later
					iHash->AddL(&(*pCode)[0], Digits*2, new CodeValue(totalConv));
				}
			}
		}
		// now run through the hash table and find the most common
		// and second-most common reading of this barcode
		int countMostCommon = -1, countNextMost = -1;
		TBuf8<Digits*2> codeMostCommon;
		int convMostCommon = -1;
		if (iHash->First()) {
			do {
				int count = ((CodeValue*)iHash->Value())->Count();
				if (count > countMostCommon) {
					countNextMost = countMostCommon;
					codeMostCommon.Copy(iHash->Key(), Digits*2);
					countMostCommon = count;
					convMostCommon = ((CodeValue*)iHash->Value())->Conv();
				} else if (count > countNextMost) {
					countNextMost = count;
				}
			} while (iHash->Next());

			ClearHash();
			int certainty = 0;
			for (i=0; i<Digits*2; i++) {
				int j;
				int most = -1, nextMost = -1;
				for (j=0; j<10; j++) {
					if (CountDigits[i][j] > most) {
						nextMost = most;
						most = CountDigits[i][j];
					} else {
						nextMost = Max(nextMost, CountDigits[i][j]);
					}
				}
				if (most > nextMost*10) {
					certainty++;
				}
			}
			if (/* countMostCommon > countNextMost*3/2 && 
				countMostCommon > size.Height()/4 && */
				/* certainty > 9 && */
				VerifyCheckDigit(codeMostCommon)) {
					pCode = TurnDigitsToText(codeMostCommon);
					return true;
			}
		} else {
			ClearHash();
		}
		return false;
	}

	// find the position of the left edge of the bar code at row
	// nRow
	int CBars2SymUpc::EstimateLeftEdge(CImage image, TInt nRow)
	{
		TInt nCol;
		IImageSize size(image);
		TInt nExp = size.Width() / TotalWidth; // number of pixels per bar
		// shift the barcode across the image
		TInt bestConv = -9999999;
		TInt bestPos = -1;
		image.LockLC();
		IGrayIndex in(image);
		for (nCol = 1; nCol < size.Width() - (TotalWidth + 1) * nExp; nCol++) {
			TInt j;
			TInt conv = 0;
			for (j=0; j<nExp; j++) {
				TInt nOffset = j + nCol;
				// left pattern is 1, 0, 1, surrounded by 0 0
				conv += in[nRow][nOffset - nExp] // 0
					-in[nRow][nOffset] // 1
					+in[nRow][nOffset + nExp] // 0
					-in[nRow][nOffset + 2*nExp] // 1
					+in[nRow][nOffset + 3*nExp] // 0
					// mid pattern in 0 1 0 1 0 surrounded by 1 1
					-in[nRow][nOffset + (MidOffset - 1) * nExp] // 1
					+in[nRow][nOffset + (MidOffset) * nExp] // 0
					-in[nRow][nOffset + (MidOffset + 1) * nExp] // 1
					+in[nRow][nOffset + (MidOffset + 2) * nExp] // 0
					-in[nRow][nOffset + (MidOffset + 3) * nExp] // 1
					+in[nRow][nOffset + (MidOffset + 4) * nExp] // 0
					-in[nRow][nOffset + (MidOffset + 5) * nExp] // 1
					// right pattern is 1, 0, 1, surrounded by 0 0 
					+in[nRow][nOffset + (RightOffset - 1) * nExp] // 0
					-in[nRow][nOffset + (RightOffset) * nExp] // 1
					+in[nRow][nOffset + (RightOffset + 1) * nExp] // 0
					-in[nRow][nOffset + (RightOffset + 2) * nExp] // 1
					+in[nRow][nOffset + (RightOffset + 3) * nExp]; // 0
			}
			if (conv > bestConv) {
				bestConv = conv;
				bestPos = nCol;
			}
		}
		CleanupStack::PopAndDestroy(); // unlock image
		return bestPos;
	}

	void CBars2SymUpc::NormalizePattern(
		TReal* pfCoeff, 
		TInt nLength, 
		TInt16 *pnCoeff, 
		bool bNormZero,
		bool bConvInt)
	{
		// first normalize so sum = 0 if required
		TInt i;
		TReal sum;
		if (bNormZero) {
			sum = 0.0;
			for (i=0; i<nLength; i++) {
				sum += pfCoeff[i];
			}
			sum /= nLength;
			for (i=0; i<nLength; i++) {
				pfCoeff[i] -= sum;
			}
		}
		// now normalize so sum of absolute values is 1
		sum = 0.0;
		for (i=0; i<nLength; i++) {
			sum += Abs(pfCoeff[i]);
		}
		for (i=0; i<nLength; i++) {
			pfCoeff[i] /= sum;
		}
		// finally scale and convert to int if required
		if (bConvInt) {
			for (i=0; i<nLength; i++) {
				Math::Int(pnCoeff[i], pfCoeff[i] * 256.0);
			}
		}
	}

	int CBars2SymUpc::BarcodeWidth() const
	{
		return TotalWidth;
	}

	const TDesC& CBars2SymUpc::Name() const
	{
		_LIT(KUpcName, "UPC");
		return KUpcName;
	}

	CBars2Sym::CodeType* CBars2SymUpc::TurnDigitsToText(TBuf8<Digits*2>& code) 
	{
#ifdef UNICODE
		const TUint16 digits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
#else
		const TUint8 digits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
#endif	
		CBars2Sym::CodeType* pResult = new CBars2Sym::CodeType;
		int i;
		for (i=0; i<Digits*2; i++) {
			pResult->Append(digits[code[i]]);
		}
		pResult->ZeroTerminate();
		return pResult;
	}

	bool CBars2SymUpc::VerifyCheckDigit(TBuf8<Digits*2>& digits)
	{
		// compute check digit
		// add even numbered digits
		int evenSum = 0;
		int i;
		for (i=0;i<Digits*2;i+=2) {
			evenSum += digits[i];
		}
		// add odd numbered digits
		int oddSum = 0;
		for (i=1;i<Digits*2-1;i+=2) {
			oddSum += digits[i];
		}
		// compute even digit sum * 3 + odd digit sum;
		int total = evenSum*3+oddSum;
		// check digit is this sum subtracted from the next higher multiple of 10
		int checkDigit = (total/10 + 1) * 10 - total;
		return digits[Digits*2-1] == checkDigit;
	}

⌨️ 快捷键说明

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