如何在Matlab中旋转连通分量使数独网格直立以实现OCR识别?
解决旋转数独图像的OCR识别问题
咱们得先搞定数独网格的旋转校正——把歪掉的数独先“掰正”,再用你现有的流程处理,就能解决旋转后识别失效的问题了。下面结合MATLAB工具给出具体实现步骤:
1. 检测数独网格的倾斜角度
从二值图像里提取数独的轮廓,计算它的旋转角度:
% 假设im_bi是你的二值数独图像 % 提取图像边缘 edges = edge(im_bi, 'Canny'); % 霍夫变换检测直线 [H,theta,rho] = hough(edges); peaks = houghpeaks(H, 4); % 取前4个最强峰,对应数独四条边 lines = houghlines(edges, theta, rho, peaks); % 计算并调整倾斜角度 angles = []; for k = 1:length(lines) angles = [angles, lines(k).theta]; end rot_angle = median(angles); % 把角度调整到-45~45区间(适配imrotate的需求) if rot_angle > 90 rot_angle = rot_angle - 180; end
如果霍夫变换检测不准,还可以直接提取最大连通分量(数独网格)的方向角,更简单:
stats = regionprops(bwconncomp(im_bi), 'Area', 'Orientation'); [~, max_idx] = max([stats.Area]); rot_angle = stats(max_idx).Orientation;
2. 旋转校正图像
用imrotate把图像转正,保证内容清晰且不丢失:
% 旋转图像,裁剪黑边;如果想保留完整内容,把'crop'换成'loose' im_rotated = imrotate(im_bi, rot_angle, 'bilinear', 'crop');
3. 筛选数字连通分量
图像转正后,再用你熟悉的bwconncomp流程,精准筛选出数字区域:
% 获取连通分量 conn_part = bwconncomp(im_rotated); stats = regionprops(conn_part, 'Area', 'BoundingBox'); % 筛选数字(根据面积范围排除网格线和大背景,阈值需根据你的图像尺寸调整) min_area = 50; max_area = 500; digit_mask = false(size(im_rotated)); for i = 1:conn_part.NumObjects if stats(i).Area > min_area && stats(i).Area < max_area digit_mask(conn_part.PixelIdxList{i}) = true; end end % 得到仅保留数字的图像 digit_only = uint8(digit_mask) * 255;
4. 单元格分割与OCR识别
因为图像已经转正,数独单元格是整齐的网格,分割后逐个识别准确率更高:
% 计算每个单元格的尺寸 [h, w] = size(digit_only); cell_h = round(h / 9); cell_w = round(w / 9); sudoku_grid = zeros(9,9); % 遍历9x9网格 for row = 1:9 for col = 1:9 % 提取当前单元格区域 y_start = (row-1)*cell_h + 1; y_end = row*cell_h; x_start = (col-1)*cell_w + 1; x_end = col*cell_w; cell_img = digit_only(y_start:y_end, x_start:x_end); % 跳过空单元格 if max(cell_img(:)) == 0 continue; end % 调用OCR识别数字 ocr_result = ocr(cell_img); if ~isempty(ocr_result.Text) sudoku_grid(row, col) = str2double(ocr_result.Text); end end end % 输出识别后的数独网格 disp(sudoku_grid);
额外优化小技巧
- 旋转前可以用
imopen做形态学开运算,去掉较细的网格线,减少干扰; - OCR前对单元格图像做自适应二值化:
cell_img = imbinarize(cell_img, 'adaptive');,能提升识别准确率。
这样处理后,不管数独稍微旋转多少度,先转正再走流程,就能和直立数独一样正常识别数字啦!
内容的提问来源于stack exchange,提问作者tushariyer
相关产品推荐
相关产品推荐

