轮廓追踪与C#实现
原文:轮廓追踪与C#实现
轮廓追踪是图像处理中常见的方法,主要目的是追踪二值图像中目标物体的外轮廓,所得结果为单像素闭合轮廓。
流 程:
1. 确定种子点,即追踪的起始像素(如最左上方在轮廓上的像素点);
2. 以相应的追踪规则搜索外部轮廓点。
追踪规则:以种子点为起点,按某以确定方向(如顺时针)寻找与当前轮廓点相邻(8邻域)的轮廓点(第一个相邻),再以 此点为当前轮廓点按照前述方法搜索,直到最后搜索到 的点与种子点相同为止。
注 意:搜索过程中,下一次搜索的起始方向,是上一次搜索到当前像素方向的逆时针45度方向(如果搜索方向是顺时针)。如当前像素在上个轮廓像素的右邻域,那么当前像素可以从其右上角方向搜索,因为这时其上邻域必不是轮廓像素。这样做可以减少算法的计算量。
追踪过程如图1所示:其中红色点表示种子点,黑色点表示轮廓点,蓝色点表示目标物体内部点,搜索方向是顺时针。
我的代码中dircection是搜索方向,定义如下:
int[,] direction = new int[8, 2] { { -1, 0 }, { -1, +1 }, { 0, +1 }, { +1, +1 }, { +1, 0 }, { +1, -1 }, { 0, -1 }, { -1, -1 } };
在代码中的abrect是一个矩形对象,指的是追踪目标所在矩形,这是我原来代码中要用的东西,和这个算法没有关系。
图1.追踪过程图示
C#实现:
unsafe protected void TraceContour(byte* imagedata, int wid, int hei)
{
int stride = (wid + 3) / 4 * 4;
int offset = stride - wid; List<Point> ContourPoints = new List<Point>(); bool bfindstartpoint = false;
int ss = 0;
byte* p = null;
for (int i = 0; i < hei; i++)
{
imagedata[i * stride] = 0;
imagedata[i * stride + wid - 1] = 0;
}
for (int i = 0; i < wid; i++)
{
imagedata[i] = 0;
imagedata[(hei - 1) * stride + i] = 0;
}
//寻找种子点
for (int i = 1; i < hei - 1; i++)
{
p = imagedata + i * stride;
for (int j = 1; j < wid - 1; j++)
{
if (p[j] == 255 && (p[j + 1] + p[j - 1] + p[j - stride] + p[j + stride] + p[j + stride - 1] + p[stride + j + 1] + p[j - stride - 1] + p[j - stride + 1] != 0))
{
bfindstartpoint = true;
ss = i * stride + j;
break;
}
}
if (bfindstartpoint)
{
break;
}
} //寻找种子点失败
if (!bfindstartpoint)
return ; //搜索方向
/*
* 7 0 1
* 6 + 2
* 5 4 3
*/
int begindirect = 0;//从0开始顺时针搜索
int kk = ss;
int k = 0;
int bb = 0;
bool bfindpoint = false;
Point pt = new Point(); while (bfindstartpoint)
{
bfindpoint = false;
k = begindirect;
while (!bfindpoint)
{
bb = kk;
kk += (stride * direction[k, 0] + direction[k, 1]);
int ih = kk / stride;
int iw = kk % stride;
//如果只有一点会死循环
//如果超出边界
if (ih == hei || iw == wid || kk < ss || (kk >= stride * hei))
{
k++;
kk = bb;
if (k == 8)
k = 0;
}
else if (imagedata[kk] == 255)
{
//还原到原坐标系
pt.X = iw + abrect.X;
pt.Y = ih + abrect.Y;
ContourPoints.Add(pt);
if (kk == ss)
bfindstartpoint = false;
begindirect = (k + 7) % 8;//逆时针旋转45度
bfindpoint = true;
}
else
{
kk = bb;
k++;
if (k == 8)
k = 0;
}
}
}
}
轮廓追踪与C#实现的更多相关文章
- 简单的验证码识别(opecv)
opencv版本: 3.0.0 处理验证码: 纯数字验证码 (颜色不同,有噪音,和带有较多的划痕) 测试时间 : 一天+一晚 效果: 比较挫,可能是由于测试的图片是在太小了的缘故. 原理: 验证码 ...
- 基于OpenCV的车辆检测与追踪的实现
最近老师布置了一个作业,是做一个基于视频的车辆检测与追踪,用了大概两周的时间做了一个简单的,效果不是很理想,但抑制不住想把自己的一些认识写下来,这里就把一些网络上的博客整理一下分享给大家,希望帮助到大 ...
- Kinect 开发 —— 骨骼追踪进阶(上)
Kinect传感器核心只是发射红外线,并探测红外光反射,从而可以计算出视场范围内每一个像素的深度值.从深度数据中最先提取出来的是物体主体和形状,以及每一个像素点的游戏者索引信息.然后用这些形状信息来匹 ...
- 基于Cat的分布式调用追踪
Cat是美团点评出的一款APM工具,同类的产品也有不少,知名的开源产品如zipkin和pinpoint:国内收费的产品如oneapm.考虑到Cat在互联网公司的应用比较广,因此被纳入选型队列,我也有幸 ...
- Office 365 如何使用powershell查询邮件追踪
如何使用Powershell 对office365的邮件进行查询追踪 1. 首先链接到Exchange Online 管理上面 $UserCredential = Get-Credential $Se ...
- java性能调优及问题追踪--Btrace的使用
在生产环境中经常遇到格式各样的问题,如OOM或者莫名其妙的进程死掉.一般情况下是通过修改程序,添加打印日志:然后重新发布程序来完成.然而,这不仅麻烦,而且带来很多不可控的因素.有没有一种方式,在不修改 ...
- 追踪记录每笔业务操作数据改变的利器——SQLCDC
对于大部分企业应用来用,有一个基本的功能必不可少,那就是Audit Trail或者Audit Log,中文翻译为追踪检查.审核检查或者审核记录.我们采用Audit Trail记录每一笔业务操作的基本信 ...
- 2016-1-30 Servlet中Session管理(Sesssion追踪)
Session管理(Sesssion追踪)是Web应用程序开发中非常重要的一个主题.这是因为HTTP是无状态的,在默认情况下,Web服务器不知道一个HTTP请求是来自初次用户,还是来自之前已经访问过的 ...
- Metaio获取当前追踪的对象的方法
重写 onTrackingEvent获取TrackingValues集合,然后通过TrackingValues的state属性的isTrackingState()方法判断是否为追踪状态,或者直接使用s ...
随机推荐
- 【p094】道路游戏
Time Limit: 1 second Memory Limit: 128 MB [问题描述] 小新正在玩一个简单的电脑游戏. 游戏中有一条环形马路,马路上有n个机器人工厂,两个相邻机器人工厂之间由 ...
- vuex的简单例子和vue model组件
好久没用过vuex了,vuex官方示例的计算器counter是用的webpack打包了单文件组件,不方便回顾,今天把代码改成了html引人的方式,方便回顾 <!DOCTYPE html> ...
- BeforeFieldInit的小叙
BeforeFieldInit是什么 上片的文章中我们看到了有静态构造函数,和没有静态构造函数,代码的执行顺序有着显著的区别.然后,我们反编译了下代码,发现了在类中有一个BeforeFieldInit ...
- HTML:描述语义
一.HTML HTML:Hypertext Markup Launguage,超文本标记语言,是网页的就文件格式,用于描述网页语义. 二.HTML骨架 DTD手册:http://www.w3schoo ...
- zabbix 设备(自己的实践)
1. 下载源代码包 wget http://sourceforge.net/projects/zabbix/files/ 2. 解压 tar -zxvf zabbix-2.2.3.tar.gz 3. ...
- SWFTools PDF转换为SWF
前言 在iText 制作PDF这篇博文中只是简单的介绍了如何制作PDF,为了能让PDF在Web页面中显示,我还需要通过SWFTools工具将PDF文件转换为SWF文件,然后通过SWF文件显示在Web网 ...
- 2 DDD理论学习2 领域
一个领域本质上可以理解为就是一个问题域,只要是同一个领域,那问题域就相同. 所以,只要我们确定了系统所属的领域,那这个系统的核心业务,即要解决的关键问题.问题的范围边界就基本确定了. 领域首先要拆分成 ...
- Blend_技巧篇_导入PSD文件制作ToggleButton (Z)
原文:Blend_技巧篇_导入PSD文件制作ToggleButton (Z) 系统: Win7sp1 32位 IDE: Microsoft VisualStudio 2013 Ultimate Ble ...
- ValueStack和OGNL达到Struts2形式的数据存储原理
(1)最近学习struts相框,我们在快乐struts强大.为了便于使用转发,但不了解详细的内部数据存储: (2)网上找了很多关于struts数据存储的原理,但我还没有找到一个具体的解释,本书上找到了 ...
- 组态DNS、搜索域名和主机名
一个.组态DNS和搜索领域 特别配置DNS该文件是/etc/resolv.conf:同时,我们可以ifcfg-eth0网卡的配置和其他配置文件中指定的. 演示样本: [root@instructor ...
