车牌识别算法实践(三):基础算法(续)

本文介绍了车牌识别算法中的关键步骤,包括使用大津法进行自适应阈值处理,通过统计行或列的白线段和黑线段来定位车牌区域。在字符识别阶段,采用K-近邻(KNN)算法进行字模匹配,通过欧氏距离计算匹配度,并利用特定字符集优化匹配效率。同时,文中还提及了错误识别情况的处理策略,以提高识别准确性。
摘要由CSDN通过智能技术生成

基础算法篇漏掉了几个算法,其中也有我曾认为过于简单无需说明的,干脆再来个续集补全吧。

统计灰度图像的直方图。很简单,无需赘言。有整体和局部统计两个函数:

// 统计灰度图像的直方图
//
// src:    图像数据首地址
// width:  图像宽度
// height: 图像高度
// count:  直方图数据指针
//
void CPlate::StatsHistogram(void *src, int width, int height, int *count)
{
	int i, j;
	int n = width * height;
	uint8 *p;
	int *ct;

	memset(count, 0, 256 * sizeof(int));

	for (i = 0, p = (uint8 *)src, ct = count; i < n; i++, p++)
		ct[*p]++;
}

// 统计灰度图像指定范围的图像块的直方图
//
// src:    图像数据首地址
// x:      起始坐标x
// y:      起始坐标y
// w:      图像块宽度
// h:      图像块高度
// count:  直方图数据指针
//
void CPlate::StatsHistogram(void *src, int x, int y, int w, int h, int *count)
{
	int i, j;
	uint8 *p0, *p;
	int *ct;

	memset(count, 0, 256 * sizeof(int));

	for (i = 0, p0 = (uint8 *)src + y * W, ct = count; i < h; i++, p0 += W)
		for (j = 0, p = p0 + x; j < w; j++, p++)
			ct[*p]++;
}

然后是大津法(OTSU)自适应阈值的搜索算法。它是一种基于最大类间方差的经典算法,网络上介绍其原理的资料很多,这里就不多解释了。与众不同的是,下列函数代码中加了个初始阈值,从这个阈值开始向前、向后搜索最佳阈值,而不是每次都从0开始搜索。这是因为车牌区域统计出的类间方差曲线类似于开口向下的抛物线,在最佳阈值处有极大值。利用此性质可加速最佳阈值的搜索。

// 用大津法计算灰度图像二值化分割的阈值
//
// count:     直方图数据指针
// threshold: 指定初始阈值,将从这个阈值开始搜索
// back:      背景平均灰度
// fore:      前景平均灰度
//
// 返回值:    灰度阈值(等于参数threshold返回值)
//
int CPlate::OTSU_Threshold(int *count, int &threshold, int &back, int &fore)
{
    int i, j;
    int *ct;

	// w0为前景像素点数
	// s0为前景像素点的灰度值总和
	// u0为前景像素点平均灰度
	// w1为背景像素点数
	// s1为背景像素点的灰度值总和
	// u1为背景像素点平均灰度
	// u为整幅图像的平均灰度
	// u0, u1, u都带有4位小数
    int w0, w1, s0, s1;
	int ww0, ww1, ss0, ss1;
	int ctt;
	int found = 0;
	int u0, u1, u, du0, du1;
	int64 delta, max_delta;

	// 统计前景相关数据
	for (i = 0, ww1 = 0, ss1 = 0, ct = count; i < threshold; i++, ct++)
    {
		if (*ct)
		{
			ww1 += *ct;
			ss1 += *ct * i;
		}
	}

	// 统计背景相关数据
	for (i = threshold, ww0 = 0, ss0 = 0, ct = count + i; i < 256; i++, ct++)
    {
		if (*ct)
		{
	        ww0 += *ct;
		    ss0 += *ct * i;
		}
	}

	if (ww0 + ww1 == 0)  return threshold;

	// 整幅图像的平均灰度
	u = ((ss0 + ss1) << 4) / (ww0 + ww1);

	u0 = ww0 ? (ss0 << 4) / ww0 : u;
	u1 = ww1 ? (ss1 << 4) / ww1 : u;
	du0 = u0 - u;
	du1 = u1 - u;
	max_delta = (int64)ww0 * du0 * du0 + (int64)ww1 * du1 * du1;

	// 向前搜索,找出前景与背景图像的类间方差最大者
	if (1)
	{
		w0 = ww0;  w1 = ww1; s0 = ss0; s1 = ss1;
		for (i = threshold - 1, ct = count + i, ctt = 0; i > 0 && ctt < 2; i--, ct--)
		{
			if (*ct)
			{
				w0 += *ct;
				w1 -= *ct;
				s0 += *ct * i;
				s1 -= *ct * i;
				u0 = w0 ? (s0 << 4) / w0 : u;
				u1 = w1 ? (s1 << 4) / w1 : u;

				du0 = u0 - u;
				du1 = u1 - u;
				delta = (int64)w0 * du0 * du0 + (int64)w1 * du1 * du1;

				// 在找到最佳阈值之前,delta >= max_delta 的条件会持续或间隔一两个灰度值出现
				// 找到之后,就再也不会出现了
				// delta值的变化类似于开口向下的抛物线,而max_delta是极大值
				if (delta >= max_delta)
				{
					max_delta = delta;
					threshold = i;
					found = 1;
					ctt = 0;
				}
				else ctt++;
			}
		}
	}
 
	if (!found)
	{
		//
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值