查找中位数的O(N)算法和Kmin算法

本文介绍了如何运用快速排序的partition操作,在线性时间内找到数组的中位数,并探讨了寻找k小元素(Kmin)的方法。

利用快速排序的partition操作来完成O(N)时间内的中位数的查找:

#include <iostream>
#include <cassert>
#include <algorithm>
#include <iterator>

using namespace std;

int array[] = {1, 2, 10, 8, 9, 7, 5};
const int size = sizeof array / sizeof *array;

int partition(int *array, int left, int right)
{
	if (array == NULL)
		return -1;

	int pos = right;
	right--;
	while (left <= right)
	{
		while (left < pos && array[left] <= array[pos])
			left++;

		while (right >= 0 && array[right] > array[pos])
			right--;

		if (left >= right)
			break;

		swap(array[left], array[right]);
	}
	swap(array[left], array[pos]);

	return left;
}

int getMidIndex(int *array, int size)
{
	if (array == NULL || size <= 0)
		return -1;

	int left = 0;
	int right = size - 1;
	int midPos = right >> 1;
	int index = -1;

	while (index != midPos)
	{
		index = partition(array, left, right);

		if (index < midPos)
		{
			left 
liccode=char([‘0’:‘9’ ‘A’:‘Z’ ‘京辽陕新苏鲁浙’]); subBw2 = zeros(40, 20); num = 1; % 车牌位数 for i = 1:7 ii = int2str(i); % 将整型数据转换为字符串型数据 word = imread([ii,‘.jpg’]); % 读取之前分割出的字符的图片 segBw2 = imresize(word, [40,20], ‘nearest’); % 调整图片的大小 segBw2 = im2bw(segBw2, 0.5); % 图像二值化 if i == 1 % 字符第一位为汉字,定位汉字所在字段 kMin = 37; kMax = 42; elseif i == 2 % 第二位为英文字母,定位字母所在字段 kMin = 11; kMax = 36; elseif i >= 3 % 第三位开始就是数字了,定位数字所在字段 kMin = 1; kMax = 36; end l = 1; for k = kMin : kMax fname = strcat(‘namebook',liccode(k),’.jpg’); % 根据字符库到图片模板 samBw2 = imread(fname); % 读取模板库中的图片 samBw2 = im2bw(samBw2, 0.5); % 图像二值化 % 将待识别图片与模板图片做差 for i1 = 1:40 for j1 = 1:20 subBw2(i1, j1) = segBw2(i1, j1) - samBw2(i1 ,j1); end end % 统计两幅图片不同点的个数,并保存下来 Dmax = 0; for i2 = 1:40 for j2 = 1:20 if subBw2(i2, j2) ~= 0 Dmax = Dmax + 1; end end end error(l) = Dmax; l = l + 1; end errorMin = min(error); % 到图片差别最少的图像 findc = find(error == errorMin); % 根据字库,对应到识别的字符 Code(num2 - 1) = liccode(findc(1) + kMin - 1); Code(num2) = ’ '; num = num + 1; end % 显示识别结果 disp(Code); msgbox(Code,‘识别出的车牌号’); 这个代码没有识别图像
最新发布
10-10
<think>我们注意到用户提供的代码中存在两个主要问题: 1. 代码中使用了错误的引号(可能是由于复制粘贴导致的格式问题),例如使用了‘’而不是标准的单引号'。 2. 代码中有一个明显的错误:`Code(num2 - 1)` 应该是 `Code(num*2 - 1)`,同样`Code(num2)`应该是`Code(num*2)`。 3. 代码中汉字字符集定义有误:`‘京辽陕新苏鲁浙’`应该改为`'京辽陕新苏鲁浙'`,并且注意MATLAB中字符数组的构建方式。 此外,我们之前已经对代码进行了详细分析并给出了优化版本。但用户再次提供原始代码并要求检查,因此我们需要指出原始代码中的错误并修正。 以下是修正后的代码(主要修正语法错误变量名错误): </think># 车牌识别代码分析与修复 ## 问题分析 您提供的代码存在几个关键问题导致无法正确识别图像: 1. **字符集定义语法错误** ```matlab liccode=char([‘0’:‘9’ ‘A’:‘Z’ ‘京辽陕新苏鲁浙’]); % 错误 ``` - 使用了中文引号 `‘` `’` 而不是英文引号 `'` - 汉字字符应该用单引号包裹 2. **路径构建错误** ```matlab fname = strcat('namebook',liccode(k),'.jpg'); ``` - 缺少目录分隔符 `/` 或 `\` - 导致路径形如 `namebookA.jpg` 而不是 `namebook/A.jpg` 3. **变量名错误** ```matlab Code(num2 - 1) = ... % 错误 ``` - 应该是 `num*2` 而不是 `num2` - `num2` 会被解释为未定义的变量 4. **图像处理准备不足** - 没有处理图像尺寸不匹配的问题 - 没有进行必要的图像预处理(如去噪) ## 修复后的代码 ```matlab % 修复后的车牌识别代码 function plateRecognition() % 1. 正确字符集定义(使用英文单引号) liccode = char(['0':'9', 'A':'Z', '京','辽','陕','新','苏','鲁','浙']); % 2. 创建存储结果的数组 plateCode = blanks(14); % 7字符+7空格 charIndex = 1; % 当前处理的字符位置 % 3. 处理每个字符图像 for charIdx = 1:7 % 3.1 加载字符图像 imgPath = sprintf('%d.jpg', charIdx); charImg = imread(imgPath); % 3.2 确保图像是灰度图 if size(charImg, 3) == 3 charImg = rgb2gray(charImg); end % 3.3 调整尺寸并二值化 segBw2 = imresize(charImg, [40, 20], 'nearest'); segBw2 = im2bw(segBw2, 0.5); % 3.4 根据字符位置确定模板范围 if charIdx == 1 % 第一位:省份汉字 kMin = 37; % 汉字在字符集的起始位置 kMax = length(liccode); elseif charIdx == 2 % 第二位:英文字母 kMin = 11; % 'A'的索引 kMax = 36; % 'Z'的索引 else % 其他位置:数字或字母 kMin = 1; % '0'的索引 kMax = 36; % 'Z'的索引 end % 3.5 存储差异值的数组 diffValues = zeros(1, kMax - kMin + 1); % 3.6 遍历模板进行匹配 for k = kMin:kMax % 3.6.1 构建正确的模板路径(添加分隔符) fname = fullfile('namebook', [liccode(k), '.jpg']); % 3.6.2 加载并处理模板图像 if exist(fname, 'file') tplImg = imread(fname); if size(tplImg, 3) == 3 tplImg = rgb2gray(tplImg); end tplBin = imresize(tplImg, [40, 20], 'nearest'); tplBin = im2bw(tplBin, 0.5); % 3.6.3 计算差异(使用向量化操作提高效率) diffMatrix = segBw2 ~= tplBin; diffValues(k - kMin + 1) = sum(diffMatrix(:)); else error('模板文件不存在: %s', fname); end end % 3.7 到最匹配的字符 [minDiff, minIdx] = min(diffValues); matchedChar = liccode(minIdx + kMin - 1); % 3.8 存储识别结果(修复变量名错误) plateCode(charIndex) = matchedChar; plateCode(charIndex + 1) = ' '; charIndex = charIndex + 2; end % 4. 显示识别结果 disp('车牌识别结果:'); disp(plateCode); msgbox(plateCode, '识别出的车牌号'); end ``` ## 关键修复点详解 ### 1. 字符集定义修复 ```matlab liccode = char(['0':'9', 'A':'Z', '京','辽','陕','新','苏','鲁','浙']); ``` - 使用标准的英文单引号 `'` - 将每个汉字单独列出,确保正确转换 ### 2. 模板路径修复 ```matlab fname = fullfile('namebook', [liccode(k), '.jpg']); ``` - 使用 `fullfile()` 函数确保跨平台兼容性 - 自动添加操作系统正确的路径分隔符 ### 3. 变量名修复 ```matlab % 修复前(错误) Code(num2 - 1) = ... % 修复后(正确) plateCode(charIndex) = matchedChar; plateCode(charIndex + 1) = ' '; charIndex = charIndex + 2; ``` - 使用有意义的变量名 `plateCode` `charIndex` - 修复乘法运算符缺失的问题 ### 4. 图像预处理增强 ```matlab % 灰度转换 if size(charImg, 3) == 3 charImg = rgb2gray(charImg); end % 尺寸归一化 segBw2 = imresize(charImg, [40, 20], 'nearest'); % 二值化 segBw2 = im2bw(segBw2, 0.5); ``` - 确保所有图像都是灰度图 - 统一尺寸便于模板匹配 - 固定阈值二值化简化处理 ## 使用前的准备工作 要使代码正常工作,需要确保以下文件结构: ``` 项目目录/ ├── plateRecognition.m % 上述代码保存为此文件名 ├── 1.jpg % 分割出的第一个字符图像 ├── 2.jpg % 第二个字符图像 ... └── 7.jpg % 第七个字符图像 └── namebook/ % 模板目录 ├── 0.jpg ├── 1.jpg ├── ... ├── A.jpg ├── B.jpg ├── ... ├── 京.jpg ├── 辽.jpg └── ... ``` ## 图像预处理建议 ### 字符分割前的预处理 ```matlab % 读取原始车牌图像 plateImg = imread('plate.jpg'); % 1. 灰度化 grayImg = rgb2gray(plateImg); % 2. 二值化 bwImg = imbinarize(grayImg, 'adaptive'); % 3. 去噪(开运算) se = strel('rectangle', [2, 2]); cleanImg = imopen(bwImg, se); % 4. 字符分割 characters = segmentCharacters(cleanImg); % 需要实现字符分割函数 % 5. 保存分割结果 for i = 1:length(characters) imwrite(characters{i}, sprintf('%d.jpg', i)); end ``` ### 模板图像要求 1. 所有模板应为相同尺寸(建议64×64) 2. 使用纯黑背景(0)白色字符(1) 3. 文件名与字符名称对应: - 数字:`0.jpg`, `1.jpg`, ..., `9.jpg` - 字母:`A.jpg`, `B.jpg`, ..., `Z.jpg` - 汉字:`京.jpg`, `辽.jpg`, ... ## 常见问题解决方案 ### 识别率低怎么办? 1. 增加图像预处理步骤: ```matlab % 添加形态学操作 cleanImg = imclose(bwImg, strel('disk', 1)); ``` 2. 使用更先进的匹配算法: ```matlab % 替代简单的像素差异 correlation = corr2(segBw2, tplBin); ``` 3. 增加模板数量: ```matlab % 添加更多字体变体 templates = { 'A_regular.jpg', 'A_bold.jpg', 'A_italic.jpg' }; ``` ### 如何处理不同尺寸的输入图像? ```matlab % 动态适配模板尺寸 function normalizedImg = normalizeSize(img, targetSize) [h, w] = size(img); scale = min(targetSize(1)/h, targetSize(2)/w); resized = imresize(img, scale); % 填充到目标尺寸 padH = floor((targetSize(1) - size(resized, 1)) / 2); padW = floor((targetSize(2) - size(resized, 2)) / 2); normalizedImg = padarray(resized, [padH, padW], 0, 'both'); end ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值