EmgnCv进行轮廓寻找和计算物体凸包
http://blog.csdn.net/qq_22033759/article/details/48029493
一、轮廓寻找
用的是FindContours函数,在CvInvoke中
不过需要用到这个VectorOfVectorOfPoint,来代替c++中的Vector
还有就是FindContours函数中的第三个参数hierarchy,不知道作用是什么,填入的只要是符合IOutputArray类型的都可以运行
代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using Emgu.CV.Util;
using Emgu.Util;
using Emgu.CV.UI;
namespace EmguCVHist
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Image<Bgr, byte> a = new Image<Bgr, byte>("153_140703112619_1.jpg");
Image<Gray, byte> b = new Image<Gray, byte>(a.Width, a.Height);
Image<Gray, byte> c = new Image<Gray, byte>(a.Width, a.Height);
Image<Bgr, byte> d = new Image<Bgr, byte>(a.Width, a.Height);
CvInvoke.Canny(a, b, 100, 60);
VectorOfVectorOfPoint con = new VectorOfVectorOfPoint();
CvInvoke.FindContours(b, con, c, RetrType.Ccomp, ChainApproxMethod.ChainApproxSimple);
for (int i = 0; i < con.Size; i++)
CvInvoke.DrawContours(d, con, i, new MCvScalar(255, 0, 255, 255),2);
imageBox1.Image = d;
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
二、凸包的计算
凸包的计算需要用到上面所求得的轮廓寻找的数据
ConvexHull函数的参数之前的不太一样,换成了PointF类型的,但所求的数据为VectorOfVectorOfPoint类型,所以就需要个转换,先把VectorOfVectorOfPoint转为Point的二维数组,在把二维数组转成PointF的二维数组,然后再挨个调用,
代码如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using Emgu.CV.Util;
using Emgu.Util;
using Emgu.CV.UI;
namespace EmguCVHist
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Image<Bgr, byte> a = new Image<Bgr, byte>("9660416_102608612175_2.jpg");
Image <Gray, byte> b = new Image<Gray, byte>(a.Width, a.Height);
Image<Gray, byte> c = new Image<Gray, byte>(a.Width, a.Height);
Image<Bgr, byte> d = new Image<Bgr, byte>(a.Width, a.Height);
CvInvoke.Canny(a, b, 100, 60);
VectorOfVectorOfPoint con = new VectorOfVectorOfPoint();
CvInvoke.FindContours(b, con, c, RetrType.Ccomp, ChainApproxMethod.ChainApproxSimple);
Point[][] con1 = con.ToArrayOfArray();
PointF[][] con2 = Array.ConvertAll<Point[], PointF[]>(con1, new Converter<Point[], PointF[]>(PointToPointF));
for (int i = 0; i < con.Size; i++)
{
PointF[] hull = CvInvoke.ConvexHull(con2[i], true);
for (int j = 0; j < hull.Length; j++)
{
Point p1 = new Point((int)(hull[j].X + 0.5), (int)(hull[j].Y + 0.5));
Point p2;
if (j == hull.Length - 1)
p2 = new Point((int)(hull[0].X + 0.5), (int)(hull[0].Y + 0.5));
else
p2 = new Point((int)(hull[j + 1].X + 0.5), (int)(hull[j + 1].Y + 0.5));
CvInvoke.Circle(d, p1, 3, new MCvScalar(0, 255, 255, 255), 6);
CvInvoke.Line(d, p1, p2, new MCvScalar(255, 255, 0, 255), 3);
}
}
for (int i = 0; i < con.Size; i++)
CvInvoke.DrawContours(d, con, i, new MCvScalar(255, 0, 255, 255), 2);
imageBox1.Image = a.ConcateVertical(d);
}
public static PointF[] PointToPointF(Point[] pf)
{
PointF[] aaa = new PointF[pf.Length];
int num = 0;
foreach(var point in pf)
{
aaa[num].X = (int)point.X;
aaa[num++].Y = (int)point.Y;
}
return aaa;
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
运行图:(之前那个图片由于会被分为好多块,所以换了张图片)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
2015-08-26 MVC执行顺序