分享

「玩一玩」绘制投影直方图(我希望各位需要的能自己动手写下)

 命運之輪 2012-06-14
我在这篇《字符识别练习 分拆字符(验证码、车牌号、身份证号等)》帖子里用到了图像的投影直方图,然后就有不少筒子跟帖「求源码」。
你们可知道?我真心希望你们阅读下我给出的参考文献,自己动脑思考下,自己动手尝试下?
做这个直方图真的一点都不难啊,怎么就养成了有原理不思考,上来就要看源码的习惯呢?也许我不是专业人士,理解不了。我的认知里面,看源码还不如看原理清晰,看到原理我可以构思出个大概,用我自己的方式来实现。看源码,我的思路完全被禁锢在作者的思路里,遇上写作习惯差的,还能把脑袋绕晕。

下面我详解下怎么做。一看就明白了,真的很简单。
以下代码并非最佳效率,但可以说是最简单的,追求效率或者其他的自行改造。

投影直方图
projection histogram

从形式上看,是这样的(黑白样本):



放大看就类似于这样:



也就是说将样本图的每一列(以垂直投影为例),投影到直方图的某个坐标x上。

最简单的实现方法就来了:

变量:
Bitmap bmp (Width x Height)
int histo[Width]

1.遍历样本的每一点bmp.GetPixel(x,y)
2.如果颜色为黑,那么histo[x]++
3.统计完成,开始绘制

C# code
for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { Color color = bmp.GetPixel(x, y); if (color.R < 50 && color.G < 50 && color.B < 50) histo[x]++; } }


绘制直方图

绘制直方图非常简单,只需要遍历每个histo[x]的值,即可

1.从y=height到y=height-histo[x]绘制一列线条
2.遍历histo[],直到画完所有点

C# code
Bitmap tmp = new Bitmap(bmp.Width, bmp.Height); using (Graphics g = Graphics.FromImage(tmp)) for (int i = 0; i < bmp.Width; i++) { g.DrawLine( Pens.Black, i, tmp.Height, i, tmp.Height - histo[i]); }


完成了。

完整代码(黑白样本)

C# code
Bitmap getProjectHistogram(Bitmap bmp) { int width = bmp.Width; int height = bmp.Height; int[] histo = null; histo = new int[width]; for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) { Color color = bmp.GetPixel(x, y); if (color.R < 50 && color.G < 50 && color.B < 50) histo[x]++; } // draw Bitmap tmp = new Bitmap(width, height); using (Graphics g = Graphics.FromImage(tmp)) for (int i = 0; i < width; i++) g.DrawLine( Pens.Black, i, height, i, height - histo[i]); return tmp; }



mutation

可以使用多个histo[]数组分别储存各个通道(A、R、G、B)的投影直方图(如果是彩色图像的话)

欢迎各位贴出自己的成果。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约