轮廓追踪与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 ...
随机推荐
- gcc for Windows 开发环境介绍
导读: 在Windows操作系统下的gcc 第一节 GCC家族概览 GCC是一个原本用于Unix-like系统下编程的编译器. 只是,如今GCC也有了很多Win32下的移植版本号.所以,或许对于很多W ...
- numpy tricks(二)—— 删除多维数组的行或列
numpy.delete numpy 下的多维数组,如果要删除其中的某些行,或某些列,不可以用置空的方式,进行设置: A[1, :] = None, ⇒ 会将 A 中的第一行数据全部置为 Nan 1. ...
- MKNetworkKit的断点续传SIDownloader下载
comefrom:http://cache.baiducontent.com/c?m=9f65cb4a8c8507ed4fece763105392230e54f73d6f8b9042238fce098 ...
- WPF中自动增加行(动画)的TextBox
原文:WPF中自动增加行(动画)的TextBox WPF中自动增加行(动画)的TextBox WPF中的Textbox控件是可以自动换行的,只要设置TextWrapping属性为"Wrap& ...
- uva 116 Unidirectional TSP【号码塔+打印路径】
主题: uva 116 Unidirectional TSP 意甲冠军:给定一个矩阵,当前格儿童值三个方向回格最小值和当前的和,就第一列的最小值并打印路径(同样则去字典序最小的). 分析:刚開始想错了 ...
- 修改NuGet packages目录路径
在*.sln文件同目录下新建配置文件nuget.config,内容为 <?xml version="1.0" encoding="utf-8"?> ...
- 三种方法解决 Failed to start LSB: Bring up/down networking 问题
感谢朋友支持本博客.欢迎共同探讨交流.因为能力和时间有限,错误之处在所难免.欢迎指正! 假设转载.请保留作者信息. 博客地址:http://blog.csdn.net/qq_21398167 原博文地 ...
- 手动安装huson插件的做法
作者:朱金灿 来源:http://blog.csdn.net/clever101 首先到jenkins-ci.org下载插件,地址为:http://updates.jenkins-ci.org/dow ...
- dropzone上传文件
先上张效果图吧 1.引入dropzone的js和css文件 2.html这里我用了一个form,当然你也可以直接用一个div,无论你用什么都要加上class="dropzone" ...
- Android 平台下Cordova 调用Activity插件开发
首先建立一个包名为package com.JiajiaCy.CallActivity; package com.JajaCy.CallActivity; import org.apache.cordo ...
