You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:20:48