假设是单像素线白色用1(对应RGB(255,0,0))表示,背景用0(对应RBG(0,0,0))表示。

考虑3种类型的边界 水平方向  0->1  1->0   类似垂直方向也是0->1  1->0

如果是单像素,如果水平检测时 发现 0->1 或1->0变动,那么都将 mapX[i,j] 设置成1,注意是白色像素对应的位置

类似的处理也针对垂直方向mapY[i,j]

如果以个mapY[i,j] 与mapX[i,j] 同时标记成了1,那么意味着这个像素是斜方向,那么按sqrt(2)来记录。

注意一:以直角三角型为例,构成边的线段粗细大于1个像素,那么求出的结果是翻倍的,因为边界出现了2次。

注意二:以直角三角型为例,如果直角三角型内部是填充成白色的(前景色1),那么求出的结果是一样的,因为边界只出现一次。

完整代码如下,需要传入二值图片。

     /// <summary>
/// 二值图片前景是白背景是黑
/// 测试白像素的边长
/// 正负 pi/4 ,3pi/4 计1.414
/// 其余按1计
/// </summary>
/// <param name="bm"></param>
public static double? SegmentLen(Bitmap bm)
{ var map = new byte[bm.Width, bm.Height];
var mapX = new byte[bm.Width, bm.Height];
var mapY = new byte[bm.Width, bm.Height]; for (int i = ; i < bm.Width; i++)
{
for (int j = ; j < bm.Height; j++)
{
var c = bm.GetPixel(i, j);
if (c.R == )
{
map[i, j] = ; }
else
{
map[i, j] = ; }
mapX[i, j] = ;
mapY[i, j] = ;
}
}
//水平边界检测
for (int i = ; i < bm.Width - ; i++)
{ for (int j = ; j < bm.Height - ; j++)
{
if (map[i, j] == && map[i, j - ] == ) mapX[i, j] = ;
if (map[i, j] == && map[i, j - ] == ) mapX[i, j - ] = ; }
}
//垂直边界检测
for (int i = ; i < bm.Width - ; i++)
{ for (int j = ; j < bm.Height - ; j++)
{
if (map[i, j] == && map[i - , j] == ) mapY[i, j] = ;
if (map[i, j] == && map[i - , j] == ) mapY[i - , j] = ; }
}
var len = 0.0d;
for (int i = ; i < bm.Width; i++)
{ for (int j = ; j < bm.Height; j++)
{ if (mapY[i, j] == && mapX[i, j] == )
{
len += 1.414;
}
else if (mapX[i, j] == || mapY[i, j] == )
{
len += ;
}
}
}
return len; }

类似的调用代码

var filename = @"C:\t2\z4_3.jpg";
pictureBox1.ImageLocation = filename;
var tImg = new Bitmap(filename);

tImg = GenBinaryImgByThreshold(tImg, 80);
tImg = BorderCheck.FullScanBoundrExtract(tImg);
var len = BorderCheck.SegmentLen(tImg);
Console.WriteLine(len);
ShowImg(tImg);

        public Bitmap GenBinaryImgByThreshold(Bitmap bm, int threshold)
{
Color white = Color.FromArgb(, , );
Color black = Color.FromArgb(, , );
Color c = new Color();
int r;
Bitmap box1 = new Bitmap(bm.Width, bm.Height);
for (int i = ; i < bm.Width; i++)
{
for (int j = ; j < bm.Height; j++)
{
c = bm.GetPixel(i, j);
r = (c.R + c.G + c.B) / ;
if (r > threshold)
{
box1.SetPixel(i, j, black);
}
else
{
box1.SetPixel(i, j, white);
}
}
}
return box1;
}

上文涉及到的边界抽取函数:

        /// <summary>
/// 黑白图片全图检测边界抽取
/// </summary>
public static Bitmap FullScanBoundrExtract(Bitmap bm)
{
var box1 = new Bitmap(bm);//输入使用bm.Width,bm.Height,保留的点是透明的。
var b = Color.FromArgb(,, , );
var w = Color.FromArgb(,, , );
var map = new Int16[bm.Width, bm.Height];
var map2 = new Int16[bm.Width, bm.Height];
for (int i = ; i < bm.Width; i++)
{ for (int j = ; j < bm.Height; j++)
{
var c = bm.GetPixel(i, j);
if (c.R == )
{
map[i, j] = ;
}
else
{
map[i, j] = ;
box1.SetPixel(i, j, b);
}
//map2[i, j] = 0;
}
} for (int i = ; i < bm.Width - ; i++)
{ for (int j = ; j < bm.Height - ; j++)
{
if (map[i, j] == && map[i, j - ] == ) map2[i, j] = ;
if (map[i, j] == && map[i, j - ] == ) map2[i, j - ] = ; }
}
for (int i = ; i < bm.Width - ; i++)
{ for (int j = ; j < bm.Height - ; j++)
{
if (map[i, j] == && map[i - , j] == ) map2[i, j] = ;
if (map[i, j] == && map[i - , j] == ) map2[i - , j] = ; }
}
for (int i = ; i < bm.Width; i++)
{ for (int j = ; j < bm.Height; j++)
{
if (map2[i, j] == )
{ box1.SetPixel(i, j, b);
}
}
}
return box1;
}

最新文章

  1. JQuery-事件(部分)
  2. 解析Json需要设置Mime
  3. OpenStack:安装Neutron与provider network
  4. 标准类型内建函数 type()介绍
  5. ARM-Linux S5PV210 UART驱动(2)---- 终端设备驱动
  6. !!对python列表学习整理列表及数组详细介绍
  7. 域名解析-delphi 源码
  8. BZOJ 4008: [HNOI2015]亚瑟王( dp )
  9. 承载于以太网帧之上的数据包的解析——ARP、IPv4、IPv6
  10. c# 服务程序重启自身
  11. DELL Precision Tower7910重装系统+开机出现GRUB界面如何处理
  12. NYOJ--94--cigarettes
  13. 翻译:INSERT(已提交到MariaDB官方手册)
  14. [HEOI2016/TJOI2016]字符串
  15. Spring Security(十):3. What’s New in Spring Security 4.2 (新功能)
  16. no plugin found for prefix &#39;tomcat 7&#39; in the current project
  17. R语言-散点图进阶
  18. Python3基础 filter+lambda 筛选出1-20之间的奇数
  19. (转)Awesome Object Detection
  20. TensorFlow 实现线性回归

热门文章

  1. 【zipkin】链路追踪
  2. linux命令学习之:vim
  3. Android自定义view(一):制作一个最最最简单的自定义view
  4. Bootstrap(8) 路径分页标签和徽章组件
  5. MYSQL分析慢查询
  6. pthreads v3在centos7下的安装与配置
  7. python 3.6.5 hashlib 和 hmac 模块
  8. u-boot之make all执行过程分析
  9. Liunjx 文件
  10. 用VS2010打开VS2012项目