假设是单像素线白色用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;
}

黑白二值图像周长测量--C#实现的更多相关文章

  1. [ZZ] Shadow Map

    Shadow Map 如何能够高效的产生更接近真实的阴影一直是视频游戏的一个很有挑战的工作,本文介绍目前所为人熟知的两种阴影技术之一的ShadowMap(阴影图)技术.     ShadowMap技术 ...

  2. matlab中图像显示函数

    image函数是显示图像的最基本的方法.该函数还产生了图像对象的句柄,并允许对对象的属性进行设置. imagesc函数也具有image的功能,所不同的是imagesc函数还自动将输入数据比例化,以全色 ...

  3. ArcGIS API for JavaScript介绍

    ArcGIS API for JavaScript中的类是按照模块组织的,主要包含esri.esri/geometry.esri/renderers.esri/symbols.esri/symbols ...

  4. matlab图像基础知识

    1.MATLAB支持的几种图像文件格式: ⑴JPEG(Joint Photogyaphic Expeyts Group):一种称为联合图像专家组的图像压缩格式. ⑵BMP(Windows Bitmap ...

  5. GIS应用及OpenGIS介绍

    转自:http://blog.csdn.net/cdl2008sky/article/details/7266680 GIS的三大应用第一类是政府应用,“电子政务” 是当今政府加强信息化建设的新方向, ...

  6. MATLAB图像处理基础

    MATLAB图像处理基础 2.2.1 图像文件格式及图像类型 1.MATLAB支持的几种图像文件格式: ⑴JPEG(Joint Photogyaphic Expeyts Group):一种称为联合图像 ...

  7. Android仿微信图片上传,可以选择多张图片,缩放预览,拍照上传等

    仿照微信,朋友圈分享图片功能 .可以进行图片的多张选择,拍照添加图片,以及进行图片的预览,预览时可以进行缩放,并且可以删除选中状态的图片 .很不错的源码,大家有需要可以下载看看 . 微信 微信 微信 ...

  8. Hough transform(霍夫变换)

    主要内容: 1.Hough变换的算法思想 2.直线检测 3.圆.椭圆检测 4.程序实现 一.Hough变换简介 Hough变换是图像处理中从图像中识别几何形状的基本方法之一.Hough变换的基本原理在 ...

  9. 深度解读 AlphaGo 算法原理

    http://blog.csdn.net/songrotek/article/details/51065143 http://blog.csdn.net/dinosoft/article/detail ...

随机推荐

  1. TZOJ 3665 方格取数(2)(最大点权独立集)

    描述 给你一个m*n的格子的棋盘,每个格子里面有一个非负数. 从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取数所在的2个格子不能相邻,并且取出的数的和最大. 输入 包括多个测试实例 ...

  2. f5时间设置

    方法一:NTP(推荐) 注:修改ntp server后大约需要10分钟左右才能同步成功. 查看ntp状态: 方法二:手动修改

  3. Delphi:基于jcl的Bugsplat Crash收集单元

    //BugSplat Crash模拟.net数据封装 unit uBugSplat; interface uses Windows, SysUtils, Classes, StrUtils, Shel ...

  4. 【校招面试 之 网络】第2题 TCP的可靠传输、流量控制、滑动窗口

    1.可靠传输 (1)三次握手 TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接: (1)第一次握手:建立连接时,客户端A发送SYN包(SYN=j)到服务器B,并进入SYN_S ...

  5. unbutu中安装jdk并编写第一个java程序

    第一部分:安装jdk 1.首先在putty控制台中输入如下命令,检验系统中是否已经装有jdk. java -version 如果显式的结果如下图,则说明没有安装. openjdk是在linux下默认安 ...

  6. Git下的.DS_Store文件

    .DS_Store 是什么 使用 Mac 的用户可能会注意到,系统经常会自动在每个目录生成一个隐藏的 .DS_Store 文件..DS_Store(英文全称 Desktop Services Stor ...

  7. (八) .launch文件 ---编写简单的启动脚本文件

    下面我们将介绍,如何编写一个启动脚本程序:(.launch文件) 还记得我们在 创建ROS软件包教程 中创建的第一个程序包(beginner_tutorials)吗,现在我们要使用它. 在 begin ...

  8. CSS学习总结1:CSS样式

    1.CSS背景 属性 background-color:为元素设置背景色,值可以是任何合法的颜色值.实例:p {background-color: gray;} background-image:为元 ...

  9. VFIO简介 (转载)

    VFIO简介 LTCChina | Nov 20 2013 | Comment (1) | Visits (15204) 概述 VFIO是一套用户态驱动框架,它提供两种基本服务: 向用户态提供访问硬件 ...

  10. iOS.C

    iOS开发中C语言的应用: 1. NS_ENUM & NS_OPTIONS http://nshipster.com/ns_enum-ns_options/