轮廓追踪与C#实现
来源:互联网 发布:贴吧推广软件 编辑:程序博客网 时间:2024/05/16 17:48
轮廓追踪是图像处理中常见的方法,主要目的是追踪二值图像中目标物体的外轮廓,所得结果为单像素闭合轮廓。
流 程:
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#实现
- 轮廓追踪与连通区域检测
- 实现图像的矩形与轮廓
- 认识C#的轮廓
- c# 追踪settings 文件
- c# 追踪settings 文件
- 基于OpenCV的车辆检测与追踪的实现
- 基于OpenCV的车辆检测与追踪的实现
- 边界追踪中有关轮廓信息统计的函数
- 链码表追踪二值图像的最外层轮廓
- 八部追踪法提取小圆点轮廓计算中心坐标
- opencv轮廓提取与轮廓拟合
- 视频播放与轮廓
- 视频与轮廓2
- 轮廓 - 内存与序列
- 追踪导弹的实现
- 追踪TCP_IP实现过程
- opencv实现运动追踪
- jsp中控制数字显示格式的代码
- C_无符号数和有符号数的左移和右移
- 《深入浅出数字信号处理》目录
- linux top的解释
- 10个很有用但是IE浏览器不支持的CSS属性
- 轮廓追踪与C#实现
- 如何隐藏table的左/右/上/下边框
- Sql Server中的CharIndex函数
- VC_16位色和24位色转换宏
- linux驱动current,引用当前进程,及task_struct
- android.intent.action.MAIN与android.intent.category 决定哪个activity最先执行
- Linux中vi编辑器的用法
- MongoDB学习笔记
- 黑马程序员-treeMap根据值排序