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

阿拉伯、乌尔都文草书文本行分割异常问题咨询

解决阿拉伯文/乌尔都文草书文本行分割的边界溢出问题

阿拉伯文和乌尔都文的草书天生有字符跨行延伸、连笔紧密的特点,单纯依赖暗像素密度的突变点来裁剪行,很容易把相邻行的字符片段包含进来。我给你几个针对性的解决方案,结合代码示例(基于你用的Matlab环境):

1. 基于行峰值+字符高度的边界调整

先找到暗像素密度的峰值(对应每行文本的中心位置),再通过统计字符的最大高度来确定每行的上下边界,避免截断或误包含相邻行:

% 计算每行暗像素密度(假设暗像素为0,根据你的图像调整)
rowDensity = sum(img == 0, 2);

% 检测密度峰值(作为行中心),调整MinPeakHeight适配你的文本密度
[rowPeaks, peakPositions] = findpeaks(rowDensity, 'MinPeakHeight', mean(rowDensity)*1.5);

% 统计所有字符的最大高度(通过连通域分析)
cc = bwconncomp(img);
stats = regionprops(cc, 'BoundingBox');
maxCharHeight = max([stats.BoundingBox(:,4)]);

% 计算行边界,处理重叠情况
divisions = [];
for i = 1:length(peakPositions)
    % 从峰值向上下扩展半字符高度
    top = max(1, peakPositions(i) - floor(maxCharHeight/2));
    bottom = min(size(img,1), peakPositions(i) + ceil(maxCharHeight/2));
    
    % 处理相邻行边界重叠:取中间值作为分界
    if i > 1 && top < divisions(end)
        top = floor((divisions(end) + peakPositions(i))/2);
    end
    divisions = [divisions; top; bottom];
end

% 分割行
for i = 1:2:length(divisions)
    line = img(divisions(i):divisions(i+1), :);
    % 这里添加你的行处理逻辑
end

2. 结合垂直连通域分组

草书的同一行字符通常是连通的(连笔特性),可以通过连通域的y坐标分组,精准划分每行:

% 二值化图像(根据你的图像调整阈值)
imgBinary = imbinarize(img);

% 8连通域检测(适配草书连笔)
cc = bwconncomp(imgBinary, 8);
stats = regionprops(cc, 'Centroid', 'BoundingBox');

% 按连通域的y中心坐标排序
[yCoords, sortIdx] = sort([stats.Centroid(:,2)]);
statsSorted = stats(sortIdx);

% 按y坐标差分组:同一行的字符y中心差小于半字符高度
groupedRows = [];
currentGroup = statsSorted(1).BoundingBox;
maxCharHeight = max([statsSorted.BoundingBox(:,4)]);

for i = 2:length(statsSorted)
    yDiff = statsSorted(i).Centroid(2) - statsSorted(i-1).Centroid(2);
    if yDiff < maxCharHeight/2
        currentGroup = [currentGroup; statsSorted(i).BoundingBox];
    else
        groupedRows = [groupedRows; currentGroup];
        currentGroup = statsSorted(i).BoundingBox;
    end
end
groupedRows = [groupedRows; currentGroup];

% 计算每组的行边界
divisions = [];
for g = 1:size(groupedRows,1)
    groupBox = groupedRows(g,:);
    top = min(groupBox(:,2));
    bottom = max(groupBox(:,2) + groupBox(:,4));
    divisions = [divisions; top; bottom];
end

% 分割行
for i = 1:2:length(divisions)
    line = img(divisions(i):divisions(i+1), :);
    % 行处理逻辑
end

3. 形态学预处理优化密度检测

先对图像做水平膨胀,让同一行的字符更紧密连通,不同行的间隔更明显,再进行密度分割:

% 二值化
imgBinary = imbinarize(img);

% 水平结构元素膨胀(长度根据字符间距调整)
se = strel('line', 20, 0); % 20为水平长度,0表示水平方向
imgDilated = imdilate(imgBinary, se);

% 计算膨胀后的行密度
rowDensity = sum(imgDilated == 0, 2);

% 找密度突变点,再微调边界到空白行
diffDensity = diff(rowDensity);
breakPoints = find(abs(diffDensity) > 10) + 1; % 你的原阈值10

divisions = [1];
for bp = breakPoints
    % 向上找最近的空白行
    top = bp;
    while top > 1 && rowDensity(top-1) > 0
        top = top - 1;
    end
    % 向下找最近的空白行
    bottom = bp;
    while bottom < size(img,1) && rowDensity(bottom+1) > 0
        bottom = bottom + 1;
    end
    % 取中间值作为分界
    divisions = [divisions; floor((top + bottom)/2)];
end
divisions = [divisions; size(img,1)];

% 分割行
for i = 1:length(divisions)-1
    line = img(divisions(i):divisions(i+1), :);
    % 行处理逻辑
end

小提示

你可以组合这些方法,比如先做形态学膨胀,再用连通域分组,能进一步提升分割精度——毕竟阿拉伯文/乌尔都文草书的书写特性,需要结合密度、连通性、字符形态多维度判断。

内容的提问来源于stack exchange,提问作者saud00

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:33:32