黑白二值图像周长测量--C#实现
假设是单像素线白色用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#实现的更多相关文章
- [ZZ] Shadow Map
Shadow Map 如何能够高效的产生更接近真实的阴影一直是视频游戏的一个很有挑战的工作,本文介绍目前所为人熟知的两种阴影技术之一的ShadowMap(阴影图)技术. ShadowMap技术 ...
- matlab中图像显示函数
image函数是显示图像的最基本的方法.该函数还产生了图像对象的句柄,并允许对对象的属性进行设置. imagesc函数也具有image的功能,所不同的是imagesc函数还自动将输入数据比例化,以全色 ...
- ArcGIS API for JavaScript介绍
ArcGIS API for JavaScript中的类是按照模块组织的,主要包含esri.esri/geometry.esri/renderers.esri/symbols.esri/symbols ...
- matlab图像基础知识
1.MATLAB支持的几种图像文件格式: ⑴JPEG(Joint Photogyaphic Expeyts Group):一种称为联合图像专家组的图像压缩格式. ⑵BMP(Windows Bitmap ...
- GIS应用及OpenGIS介绍
转自:http://blog.csdn.net/cdl2008sky/article/details/7266680 GIS的三大应用第一类是政府应用,“电子政务” 是当今政府加强信息化建设的新方向, ...
- MATLAB图像处理基础
MATLAB图像处理基础 2.2.1 图像文件格式及图像类型 1.MATLAB支持的几种图像文件格式: ⑴JPEG(Joint Photogyaphic Expeyts Group):一种称为联合图像 ...
- Android仿微信图片上传,可以选择多张图片,缩放预览,拍照上传等
仿照微信,朋友圈分享图片功能 .可以进行图片的多张选择,拍照添加图片,以及进行图片的预览,预览时可以进行缩放,并且可以删除选中状态的图片 .很不错的源码,大家有需要可以下载看看 . 微信 微信 微信 ...
- Hough transform(霍夫变换)
主要内容: 1.Hough变换的算法思想 2.直线检测 3.圆.椭圆检测 4.程序实现 一.Hough变换简介 Hough变换是图像处理中从图像中识别几何形状的基本方法之一.Hough变换的基本原理在 ...
- 深度解读 AlphaGo 算法原理
http://blog.csdn.net/songrotek/article/details/51065143 http://blog.csdn.net/dinosoft/article/detail ...
随机推荐
- F - Restoring the Expression CodeForces - 898F
字符串hash: base设置为10 枚举'='可能出现的位置,从1/2处开始到大概1/3处结束,当然大概的1/3不用计算,直接到最后就行,因为本题必然有解,输出直接结束即可. 根据'='号位置,' ...
- 多线程通信(wait和notify)
线程通信概念: 线程是操作系统中独立的个体,但这些个体如果不经过特殊的处理就不能成为一个整体,线程间的通信就成为整体的必用方式之一.当线程存在通信指挥,系统间的交互性会更强大,在提高CPU利用率的同时 ...
- WebApi2跨域问题及解决办法
跨域问题产生的原因 同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能.现在所有支持JavaScript的浏览器都会使用这个策略.所谓同源是指,域名,协议, ...
- 1到n的整数中,1出现的次数
参考链接:https://discuss.leetcode.com/topic/18054/4-lines-o-log-n-c-java-python 1到n的整数中,1出现的次数,如11中,1出现了 ...
- 使用json要导入什么包
json-lib-2.3-jdk15.jar commons-beanutils-1.7.0.jar commons-httpclient-3.1.jar commons-lang-2.3.jar c ...
- VS2015中C#版本6.0的新特性
[z]http://www.cnblogs.com/xszjk/articles/6417173.html [z]https://www.cnblogs.com/qixu/p/6047229.html ...
- 编码补充 daty 6
---恢复内容开始--- 1. 用id求内存地址 id 查询内存地址 name = 'alex' print(id(name)) li = [1,2,3] print(id(li)) 结果: 2. ...
- Ubuntu安装UFW防火墙
sudo apt-get install ufw 一般用户,只需如下设置:sudo apt-get install ufw sudo ufw enable sudo ufw default deny ...
- js阻止a标签默认事件的几种方法
方法/步骤 疑问 打开编辑器,新建html并加入a标签,如图所示,小编想点击a标签时执行pop函数同时禁止a标签的默认的href跳转,该如何阻止呢? 方法一 要阻止a标签跳转,可以改变href ...
- Svn Server 强制提交者输入注释信息
目的:在项目开发过程中,强制团队成员必须在提交前写上注释 环境简述:SVN服务器:Windows Server 2008 SVN版本:VisualSVN Ltd. 2.7.5 操作方法:在SVN的R ...