ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

zxing源码阅读

2021-04-10 22:32:07  阅读:176  来源: 互联网

标签:firstPeak int buckets zxing width 源码 阅读 score row


关于zxing识别中的源码
其中图像做二值化的部分

bool
GlobalHistogramBinarizer::getBlackRow(int y, BitArray& row) const  //image处理的成员函数, y是所在行
{
	int width = _source->width();
	if (row.size() != width)
		row = BitArray(width);
	else
		row.clearBits();

	ByteArray buffer;
	const uint8_t* luminances = _source->getRow(y, buffer); //获取一张图片第y行的数据
	std::array<int, LUMINANCE_BUCKETS> buckets = {};  //static const int LUMINANCE_BUCKETS = 1 << 5;
	for (int x = 0; x < width; x++) {
		int pixel = luminances[x];
		buckets[pixel >> LUMINANCE_SHIFT]++;
	}   //统计每一行像素点,0-255每8个单位为一个区间,类似作直方图
	int blackPoint = EstimateBlackPoint(buckets);
	if (blackPoint >= 0) {
		if (width < 3) {
			// Special case for very small images
			for (int x = 0; x < width; x++) {
				if (luminances[x] < blackPoint) {
					row.set(x);
				}
			}
		}
		else {
			if (luminances[0] < blackPoint)
				row.set(0);
			int left = luminances[0];
			int center = luminances[1];
			for (int x = 1; x < width - 1; x++) {
				int right = luminances[x + 1];
				// A simple -1 4 -1 box filter with a weight of 2.
				//相当于在该行像素上做了-1 4 -1的滤波
				if (((center * 4) - left - right) / 2 < blackPoint) {
					row.set(x);
				}
				left = center;
				center = right;
			}
			if (luminances[width-1] < blackPoint)
				row.set(width-1);
		}//二值化
		return true;
	}
	return false;
}
static int EstimateBlackPoint(const std::array<int, LUMINANCE_BUCKETS>& buckets)
{
	// Find the tallest peak in the histogram.
	auto firstPeakPos = std::max_element(buckets.begin(), buckets.end()); //找到直方图的第一个peak
	int firstPeak = static_cast<int>(firstPeakPos - buckets.begin());
	int firstPeakSize = *firstPeakPos;
	int maxBucketCount = firstPeakSize;

	// Find the second-tallest peak which is somewhat far from the tallest peak.
	int secondPeak = 0;
	int secondPeakScore = 0;
	for (int x = 0; x < LUMINANCE_BUCKETS; x++) {
		int distanceToBiggest = x - firstPeak;
		// Encourage more distant second peaks by multiplying by square of distance.
		int score = buckets[x] * distanceToBiggest * distanceToBiggest;//第二个峰值与第一个峰值距离越大,size越大,得分越高,score = 区间像素总数*距离平方
		if (score > secondPeakScore) {
			secondPeak = x;
			secondPeakScore = score;
		}
	}

	// Make sure firstPeak corresponds to the black peak.
	if (firstPeak > secondPeak) {
		std::swap(firstPeak, secondPeak);
	}

	// If there is too little contrast in the image to pick a meaningful black point, throw rather
	// than waste time trying to decode the image, and risk false positives.
	//如果两个峰值太接近,则识别失败
	if (secondPeak - firstPeak <= LUMINANCE_BUCKETS / 16) {
		return -1;
	}

	// Find a valley between them that is low and closer to the white peak.
	//在两个峰值之间找到第三个峰值,将这个峰值作为二值化的阈值
	int bestValley = secondPeak - 1;
	int bestValleyScore = -1;
	for (int x = secondPeak - 1; x > firstPeak; x--) {
		int fromFirst = x - firstPeak;
		int score = fromFirst * fromFirst * (secondPeak - x) * (maxBucketCount - buckets[x]);
		if (score > bestValleyScore) {
			bestValley = x;
			bestValleyScore = score;
		}
	}

	return bestValley << LUMINANCE_SHIFT;
}

标签:firstPeak,int,buckets,zxing,width,源码,阅读,score,row
来源: https://blog.csdn.net/weixin_43870483/article/details/115585077

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有