十二个一的客观形态

客观形态

结合这个学期图像处理课上所学的种种与对matlab的应用,对十二个一的图像进行了处理,得到十二个一本身的各种客观的数据,如每个一的粗细,角度等数据。

预处理

得到的原始图片为了美观,背景上有一些噪点作为纹理,同时因为是书法,由于毛笔的干湿因素,笔画不是完全填充,会存在空隙。
在这里插入图片描述
所以对此进行了

图像二值化,翻转颜色

    originalPic = im2bw(originalPic);
    originalPic = 1 - originalPic;

开运算去噪

    se = strel('disk', 4);
    originalPic = imopen(originalPic, se);

闭运算使笔画尽量闭合

    se = strel('disk', 20);
    originalPic = imclose(originalPic, se);

得到预处理后的图片为黑底白字的无噪点闭合的一:

在这里插入图片描述

骨架

由于一的笔画具有粗细变化,所以采取了提取骨架的方法,使用单像素点来确定一的走势。

    skel = bwmorph(originalPic, 'skel', Inf);

在这里插入图片描述

扫描二维码关注公众号,回复: 9240777 查看本文章

笔画粗细

由于一的开头结尾都有起笔与顿笔,写法不同,粗细也不同,所以采用了统计中间部分粗细的方法。
裁剪到图片中间部分

    [h, w] = size(originalPic);
    originalPic = im2bw(originalPic);
    originalPic = originalPic( : , 220: w - 150);
    thickness = sum(sum(originalPic)) / (w - 370);

计算笔画粗细
以像素为单位,由于笔画中间部分比较稳定,计算所有有笔画的部分(即值为1)的和,再除以裁剪部分的宽度,就可以得到平均每一像素的变化的粗细,即这个一的笔画的粗细。

    thickness = sum(sum(originalPic)) / (w - 370);

在这里插入图片描述

角度

仔细观察会发现每个一的笔势都是上扬的,但是上扬的角度各有不同。
计算角度的方法是依然采用截取中间段,计算中间段开始时的骨架坐标与结束时的骨架坐标,与截取的部分的宽度,使用反三角函数asin计算角度。

    myStart = 0;
    myEnd = 0;
    for k = 1 : h
        if(originalPic(k, 220) == 1)
            myStart = k;
            break;
        end
    end
    for k = 1 : h
        if(originalPic(k, w - 160) == 1)
            myEnd = k;
            break;
        end
    end
    angle = asind((myStart - myEnd) / (w - 380));

在这里插入图片描述
将骨架图片旋转

    originalPic = imrotate(originalPic, -angle);

在这里插入图片描述

弯曲程度

每个一的弯曲程度各有不同,有的比较直,有的则有比较大的弧度。
由于没有找到图像处理中计算线条弧度的方法,所以这里采用的评价弧度的指标是:
将矫正到水平的裁剪后的骨架图转置,计算每一列的像素值之和,若为0则说明无线段,若不为0则有线段。
然后计算所有有线段的像素列之和,得到的值就是裁剪后的骨架图中,存在骨架的像素行数。
将之作为评判弧度的指标,因为一的弧度越大,其骨架跨越的行数就会越多。

    mySum = sum(cut);
    mySum(mySum > 0) = 1;

在这里插入图片描述

重心

每一个一的重心都有所不同,高瘦的书法重心偏高,宽扁的书法重心偏低,不同的重心会给人不一样的感受。

对于重心的测量方法,我们分别计算所有白色有书法区域的像素的行数与列数,求和并除以像素总数,就可以得到所有像素的重心。

    [n,m]=find(originalPic > 125);
    centerX = sum(m) / length(m);
    centerY = sum(n) / length(n);

并将求出的重心在图中画出来:

    [h, w] = size(originalPic);
    [x, y] = meshgrid(1:w, 1:h);
    r = 15;       % 分别表示:高,宽,内部圆的半径
    originalPic(((x-centerX).^2+(y-centerY).^2) <= r^2) = 0;

在这里插入图片描述

高宽比

分别计算每一个一的高和宽,并相除求其高宽比。

其中求一的高与宽的方法为:
首先将图片二值化,再计算所有行/列的像素值之和。
若为0则说明这一行没有笔画,若为1则有。同时因为笔画是连续的,我们只要知道像素值之和不为0的最后一个和不为0的行/列的位置,就可以求出该笔画的长/宽。

    rowSum = sum(originalPic, 2)';
    columnSum = sum(originalPic);
    height = find(rowSum ~= 0, 1, 'last') - find(rowSum ~= 0, 1, 'first');
    width = find(columnSum ~= 0, 1, 'last') - find(columnSum ~= 0, 1, 'first');
    disp(double(height / width));

在这里插入图片描述

最后得出的统计结果为:
在这里插入图片描述
通过绘制折线图,可以发现十二个一之间存在较大的客观形态上的差异,同时,如厚度、角度与弯曲程度这样的评价参数之间有较强的关联性。
在这里插入图片描述

发布了153 篇原创文章 · 获赞 184 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/Ha1f_Awake/article/details/103846099