opencv笔记--Active contours
Active Contours 也称作 Snake,通过定义封闭区域曲线的能量函数,并使其最小化得到最终曲线。
Active Contours 被用作物体边界精确定位上,opencv 给出了一个实现,首先给出物体大致边界的外包围曲线作为初始曲线,然后通过迭代方式寻找邻域最小值,直到能量函数收敛或达到迭代次数停止。
由于能量函数不是严格的凸函数,故使用迭代方式可能无法收敛到正确位置。同时,该能量函数在平滑区域上迭代效果像气球一样不断缩小,直到遇到边缘区域才会产生反作用力,所以初始轮廓必须包围真实轮廓或者允许在真实轮廓内部且靠近真实轮廓。

首先给出能量函数的基本定义:
1)根据上图,在 xy 平面上定义曲线 C,使用参数 q 进行参数化
;
2)将曲线 C 分解为
与
函数,两个函数具有相同的定义域,其区域大致形状如上图;
3)根据上图,给出一些函数:
a. 
b. 
c. 
d. 
4)定义一个关于图像梯度的单调递减函数
,在图像平滑区域
趋近无穷大,在边缘区域
趋近零;
5)给出边缘能量函数
,解释如下:
a.
为不同积分分量的系数,该系数可以是一个固定值,也可以是一个与参数 q 相关的函数;
b. 第1项积分控制曲线的曲率,使曲线收缩为直线段;第2项积分控制曲线光滑度,避免曲线突变角点;前两项积分称作内部能量;
第3项积分使曲线项边缘方向靠近,该项积分称作外部能量;
6)给定初始曲线,在初始曲线的一个邻域内搜索最小能量值,并使用该最小能量值曲线作为新的搜索曲线,直到达到收敛条件为止;
opencv 中函数 CvSnakeImage 给出了实现,函数原型如下:
void cvSnakeImage( const IplImage* src, CvPoint* points, int length,
float *alpha, float *beta, float *gamma, int coeffUsage, CvSize win, CvTermCriteria criteria, int calc_gradient CV_DEFAULT(1) );
参数 :src 为原图像,
points 为Active Contours 的初始控制点,length 为控制点个数,
alpha, beta, gamma 为积分项对应的系数,可以是一个固定值或者关于参数 p 的函数,coeffUsage 表示参数类型(固定值或者参数 p 的函数),
win 表示迭代窗口尺寸,
criteria 表示停止条件,可以设置迭代次数与迭代精度,
calc_gradient 表示使用梯度还是使用灰度作为第3项积分输入;
以下给出实验代码及结果:
1 void UsingCvSnakeImage()
2 {
3 // Object
4 cv::Mat obj = cv::Mat::zeros(256, 256, CV_8UC1);
5 for (int y = 128 - 40; y < 128 + 40; ++y)
6 {
7 uchar *data = obj.ptr<uchar>(y);
8 for (int x = 128 - 40; x < 128 + 40; ++x)
9 data[x] = 128;
10 }
11
12 cv::imwrite("snake_1_obj.bmp", obj);
13
14 // initial contours
15 cv::Mat contour = cv::Mat::zeros(256, 256, CV_8UC1);
16 for (int y = 0; y < contour.rows; ++y)
17 {
18 int dy = (y - 98) * (y - 98);
19 uchar *data = contour.ptr<uchar>(y);
20 for (int x = 0; x < contour.cols; ++x)
21 {
22 int dx = (x - 128) * (x - 128);
23 if (dx + dy < 70 * 70)
24 data[x] = 255;
25 }
26 }
27
28 vector<vector<cv::Point>> contours;
29 cv::findContours(contour, contours, CV_RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);
30
31 cv::Mat obj_cpy;
32 obj.copyTo(obj_cpy);
33 contour.rowRange(0, contour.rows) = 0;
34 for (int i = 0; i < contours[0].size(); ++i)
35 {
36 cv::Point pt = contours[0][i];
37 contour.ptr<uchar>(pt.y)[pt.x] = 255;
38 obj_cpy.ptr<uchar>(pt.y)[pt.x] = 255;
39 }
40
41 cv::imwrite("snake_2_contour.bmp", obj_cpy);
42
43 // prepare parameters
44 IplImage *ipl_img = &obj.operator IplImage();
45 CvPoint *ipl_pts = new CvPoint[contours[0].size()];
46 for (int i = 0; i < contours[0].size(); ++i)
47 {
48 ipl_pts[i].x = contours[0][i].x;
49 ipl_pts[i].y = contours[0][i].y;
50 }
51
52 float alpha = .2;
53 float beta = .2;
54 float gamma = 1.;
55
56 CvSize ipl_sz;
57 ipl_sz.width = 5;
58 ipl_sz.height = 5;
59
60 CvTermCriteria ipl_criteria;
61 ipl_criteria.type = CV_TERMCRIT_ITER | CV_TERMCRIT_EPS;
62 ipl_criteria.max_iter = 1000;
63 ipl_criteria.epsilon = .1;
64
65 cvSnakeImage(ipl_img, ipl_pts, contours[0].size(), &alpha, &beta, &gamma, CV_VALUE, ipl_sz, ipl_criteria, 1);
66
67 // final contours
68 for (int i = 0; i < contours[0].size(); ++i)
69 {
70 if (i == 0)
71 cv::line(obj, cv::Point(ipl_pts[i].x, ipl_pts[i].y),
72 cv::Point(ipl_pts[contours[0].size() - 1].x, ipl_pts[contours[0].size() - 1].y), cv::Scalar(255), 2);
73 else
74 cv::line(obj, cv::Point(ipl_pts[i - 1].x, ipl_pts[i - 1].y),
75 cv::Point(ipl_pts[i].x, ipl_pts[i].y), cv::Scalar(255), 2);
76 }
77
78 cv::imwrite("snake_3_contour.bmp", obj);
79
80 delete[]ipl_pts;
81 }

参考资料 Active Contours: A Brief Review Serdar Kemal Balcı and Burak Acar
opencv笔记--Active contours的更多相关文章
- OpenCV笔记大集锦(转载)
整理了我所了解的有关OpenCV的学习笔记.原理分析.使用例程等相关的博文.排序不分先后,随机整理的.如果有好的资源,也欢迎介绍和分享. 1:OpenCV学习笔记 作者:CSDN数量:55篇博文网址: ...
- opencv笔记6:角点检测
time:2015年10月09日 星期五 23时11分58秒 # opencv笔记6:角点检测 update:从角点检测,学习图像的特征,这是后续图像跟踪.图像匹配的基础. 角点检测是什么鬼?前面一篇 ...
- opencv笔记5:频域和空域的一点理解
time:2015年10月06日 星期二 12时14分51秒 # opencv笔记5:频域和空域的一点理解 空间域和频率域 傅立叶变换是f(t)乘以正弦项的展开,正弦项的频率由u(其实是miu)的值决 ...
- opencv笔记4:模板运算和常见滤波操作
time:2015年10月04日 星期日 00时00分27秒 # opencv笔记4:模板运算和常见滤波操作 这一篇主要是学习模板运算,了解各种模板运算的运算过程和分类,理论方面主要参考<图像工 ...
- opencv笔记3:trackbar简单使用
time:2015年 10月 03日 星期六 13:54:17 CST # opencv笔记3:trackbar简单使用 当需要测试某变量的一系列取值取值会产生什么结果时,适合用trackbar.看起 ...
- opencv笔记2:图像ROI
time:2015年 10月 03日 星期六 12:03:45 CST # opencv笔记2:图像ROI ROI ROI意思是Region Of Interests,感兴趣区域,是一个图中的一个子区 ...
- opencv笔记1:opencv的基本模块,以及环境搭建
opencv笔记1:opencv的基本模块,以及环境搭建 安装系统 使用fedora22-workstation-x86_64 安装opencv sudo dnf install opencv-dev ...
- opencv笔记---contours
一 Contour Finding Contours使用 STL-style vector<> 表示,如 vector<cv::Point>, vector<cv::Po ...
- 查找并绘制轮廓[OpenCV 笔记XX]
好久没有更新了,原谅自己放了个假最近又在赶进度,所以...更新的内容是很靠后的第八章,因为最近工作要用就先跳了,后面会更新笔记编号...加油加油! 在二值图像中寻找轮廓 void cv::findCo ...
随机推荐
- centOS8安装java14
一.去官网下载相应的linux版本 二.通过xftp把下载下的文件传输到linux下指定目录 三.使用命令 rpm -ivh 安装(tar.gz 使用 tar zxvf 命令) 四.配置环境变量 ...
- centos 目录结构
bin -----存放命令的目录(bin目录是快捷方式)是/usr/bin的快捷方式 sbin ----只有root用户才能使用的命令 etc ----系统服务的配置文件 /usr/local --- ...
- Mysql高性能优化
一.背景 最近公司项目添加新功能,上线后发现有些功能的列表查询时间很久.原因是新功能用到旧功能的接口,而这些旧接口的 SQL 查询语句关联5,6张表且编写不够规范,导致 MySQL 在执行 SQL 语 ...
- IK 分词器
目录 IK 分词器-介绍 IK 分词器-安装 环境准备:Maven 安装 IK 分词器 IK 分词器-使用 IK 分词器-介绍 现有问题:ES 默认对中文分词并不友好,实际上是把中文进行了每个字的分词 ...
- Redis介绍一
一.五中数据类型 String: 字符串 Hash: 散列 List: 列表 Set: 集合 Sorted Set: 有序集合 Redis 发布订阅 Redis 发布订阅 (pub/sub) 是一种消 ...
- Fio使用和结果分析
感谢,参考自:https://blog.51cto.com/qixue/1906768: 官方说明文档,很有用:https://fio.readthedocs.io/en/latest/index.h ...
- C++ 基本类型的大小
C++的基本类型: char bool (unsigned) short (int) (unsigned) int (unsigned) long (int) (unsigned) long long ...
- 浅谈MySQL同步到ElasticSearch的几种方式及其优缺点
同步双写 优点:业务逻辑简单. 缺点: 硬编码,有需要写入mysql的地方都需要添加写入ES的代码: 业务强耦合: 存在双写失败丢数据风险: 性能较差:本来mysql的性能不是很高,再加一个ES,系统 ...
- 一种Django多租户解决方案
什么是多租户? 多租户技术或称多重租赁技术,简称SaaS,是一种软件架构技术,是实现如何在多用户环境下(此处的多用户一般是面向企业用户)共用相同的系统或程序组件,并且可确保各用户间数据的隔离性. 多租 ...
- /etc/crontab和crontab -e的区别
(1) /etc/crontab是系统级别的crontab,系统的设置等,这种方法只有root用户能用 crontab -e是用户级的crontab,会被写到 /var/spool/cron 目录下, ...