C#:边界跟踪法
2023-09-08 本文已影响0人
大龙10
- EmguCV是将opencv封装的一个.net库,可以被VC++,VC#,VB.net调用。
EmguCV可以很好地连接C#与opencv,能够弥补opencv在gui这方面的不足。
一、Mat对象的像素操作
- 生成一个m8相同大小的全白图像
Scalar scalar = new Scalar(255, 255,255);
Mat coutour_img = new Mat(m8.Size(),MatType.CV_8UC1,scalar);
- Mat中不管是以At访问还是ptr访问,都是行优先 ,先Y轴后X轴(即先行后列)
二、边界跟踪法
- 边界跟踪法的函数
#region 轮廓追踪
protected void TraceContour(Mat imagedata,Mat contour_img)
{
int hei = imagedata.Rows;
int wid = imagedata.Cols;
int cn = imagedata.Channels(); //获取通道数
int start_i = 0;
int start_j = 0;
List<OpenCvSharp.Point> ContourPoints = new List<OpenCvSharp.Point>();
//寻找种子点
bool bfindstartpoint = false;
for (int row = 0; row < hei; row++)
for (int col = 0; col < wid; col++)
{
if (cn == 1) //如果是单通道
{
byte p = imagedata.At<byte>(row, col); //获取像素
if (p == 0)
{
bfindstartpoint = true;
start_i = row;
start_j = col;
break;
}
}
}
uiTextBox1.AppendText("i=" + start_i.ToString());
uiTextBox1.AppendText(",\t\n j=" + start_j.ToString());
//搜索方向
/*
* 0 1 2
* 7 + 3
* 6 5 4
*/
OpenCvSharp.Point pt = new OpenCvSharp.Point();
if (bfindstartpoint)
{
pt.X = start_i;
pt.Y = start_j;
contour_img.Set(pt.X, pt.Y, 0);
}
int[,] direction = new int[8, 2] { { -1, +1 }, { 0, +1 }, { +1, +1 }, { +1, 0 }, { +1, -1 }, { 0, -1 }, { -1, -1 }, { -1, 0 } };
int begindirect = 0;//从0开始顺时针搜索
int findstart = 0;
int cur_i = start_i;
int cur_j = start_j;
int findpoint = 0;
int i, j;
while (findstart == 0)
{
findpoint = 0;
while (findpoint == 0)
{
i = cur_i + direction[begindirect, 1];
j = cur_j + direction[begindirect, 0];
System.IO.File.AppendAllText("d:/my_trace.txt", "\t\n i=" + i.ToString() + ",j=" + j.ToString(), Encoding.Default);
if (j> wid) { return; }
byte p = imagedata.At<byte>(i, j); //获取像素
if (p == 0)
{
findpoint = 1;
cur_i = i;
cur_j = j;
if ((cur_i == start_i) && (cur_j == start_j)) findstart = 1;
contour_img.Set(cur_i, cur_j, 0);
begindirect -= 1;
if (begindirect == -1) begindirect = 7;
begindirect -= 1;
if (begindirect == -1) begindirect = 7;
}
else
{
begindirect += 1;
if (begindirect == 8) begindirect = 0;
}
}
}
}
}
#endregion
三、调用
private void uiButton8_Click(object sender, EventArgs e)
{
// 1) 读入彩色图像
// 2) 彩色图像灰度化
// 3) 图像二值化 uiButton6_Click 结果在dst
// 4)边界跟踪 结果在coutour_img
Mat m8 = new Mat();
dst.CopyTo(m8);
Scalar scalar = new Scalar(255, 255,255);
Mat coutour_img = new Mat(m8.Size(),MatType.CV_8UC1,scalar);
TraceContour(m8,coutour_img);
picBoxShowDel.Image = m8.ToBitmap();
pictureBox1.Image = coutour_img.ToBitmap();
}
运行结果