opencv API (个人笔记)
注:个人笔记:最主要的是记录一些学习中遇到的问题,知识点较碎,编辑也不优美。但持续记录、持续更新、持续分享。有问题可以留言交流。
此文也参考一些其他资料,都已附加源链接不再单谢;本文可以转载但需表明出处。
本文链接:https://blog.csdn.net/zaibeijixing/article/details/80971208
本文链接:https://blog.csdn.net/zaibeijixing/article/details/80971208
- 【1】 graphcut ---> grabcut ---> onecut,发展。
grabcut分割算法 https://www.cnblogs.com/mikewolf2002/p/3330390.html mask解释
- 【2】多用于人脸68点
特征点提取方法。
ASM(Active Shape Model)是指主观形状模型,即通过形状模型 对 目标物体进行抽象。ASM 是一种 基于点分布模型(Point Distribution Model, PDM)的算法。在PDM中,外形相似的物体,例如 人脸、人手、心脏等的几何形状可以通过若干关键特征点(landmarks)的坐标依次串联形成一个形状向量来表示。【https://www.cnblogs.com/Anita9002/p/7094535.html】
【https://blog.csdn.net/linolzhang/article/details/55271815 https://blog.csdn.net/linolzhang/article/details/55274035 】
【https://blog.csdn.net/cbl709/article/details/46239571 https://blog.csdn.net/carson2005/article/details/8194317】
基于ASM的人脸 通常通过 标定好的68个关键特征点 来进行描述:
ASM算法 分为 训练过程 和 搜索过程。
• AAM
AAM 称为 主动外观模型(Active Appearance Model),AAM是在ASM的基础上,进一步对纹理(将人脸图像变换到平均形状 而得到的形状无关图像)进行统计建模,并将形状和纹理两个统计模型进一步融合为 外观模型。可以理解为:
Appreance = Shape + Texture
AAM 在对形状和纹理特征统一量纲后,建模和搜索过程和ASM基本相同。
• CLM
CLM 是有约束的局部模型(Constrained Local Model),它通过初始化平均脸的位置,然后让每个平均脸上的特征点在其邻域位置上进行搜索匹配来完成人脸点检测。前面讲到的ASM也属于CLM的一种。
CLM分别继承 ASM和AAM的优点,在ASM的效率 与 AAM的效果之间做了平衡。抛弃了AAM的全局纹理方法,在ASM的基础上,通过特征点周围的局部纹理Patch,提高了ASM仅仅依靠灰度 带来的匹配问题,引用一张老掉牙的图 说明原理。
• SDM
SDM 全名是 Supervised Descent Method,中文叫监督下降方法。
SDM 方法提出的背景就是为了更好的解决非线性优化问题,那么什么是非线性优化问题呢?非线性优化问题 就是约束条件或者目标函数是非线性的。
学界通常使用二阶导数的方法进行优化,比如牛顿法。
非线性最优化问题 通常有 2个难点:
(1)函数(方程)可能不可微,或者参数无法估计;
(2)Hessian不正定,或者维度太高导致计算量过大;
[源码 stASM 2013 http://www.milbo.users.sonic.net/stasm/download.html https://github.com/juan-cardelino/stasm]
图像旋转 好 https://blog.csdn.net/qianqing13579/article/details/52504089
- 【3】resize
/************************************************************************/
/*
OpenCV图像缩放使用的函数是:resize
void resize(InputArray src, OutputArray dst, Size dsize, double fx=0, double fy=0, int interpolation=INTER_LINEAR )
参数含义:
InputArray src -原图像
OutputArray dst -输出图像
Size dsize -目标图像的大小
double fx=0 -在x轴上的缩放比例
double fy=0 -在y轴上的缩放比例
int interpolation -插值方式,有以下四种方式
INTER_NN -最近邻插值
INTER_LINEAR -双线性插值 (缺省使用)
INTER_AREA -使用象素关系重采样,当图像缩小时候,该方法可以避免波纹出现。当图像放大时,类似于 INTER_NN 方法。
INTER_CUBIC -立方插值。
说明:dsize与fx和fy必须不能同时为零
resize(src, dst, Size(), 0.5, 0.5, interpolation);
resize(src, dst, dst.size(), 0, 0, interpolation);
*/
/************************************************************************/
resize(img, img, Size(img.cols / 2, img.rows / 2), 0, 0, INTER_LINEAR);
resize(img, img, Size(), 1.3, 0.4, INTER_LINEAR);
- 【4】 mat类型的图像,用cvRectangle时报错显示[不存在"cv::Mat"到"CvArr **"的适当转换函数];换成rectangle()函数时正确。
Mat img;
const CvArr* s=(CvArr*)&img;
上面就可以了,CvArr是Mat的虚基类,所有直接强制转换就可以了
主要C是大写。
- 【5】threshold() 和adaptiveThreshold()
一幅图像包括目标物体、背景还有噪声,要想从多值的数字图像中直接提取出目标物体,常用的方法就是设定一个阈值T,用T将图像的数据分成两部分:大于T的像素群和小于T的像素群。这是研究灰度变换的最特殊的方法,称为图像的二值化(Binarization)。
(1)threshold()的本质是找到一个确定值作为阈值,处理,全局阈值。
double cv::threshold(
cv::InputArray src, // 输入图像
cv::OutputArray dst, // 输出图像
double thresh, // 阈值
double maxValue, // 向上最大值
int thresholdType // 阈值化操作的类型
);
阈值类型:
效果显示:
(2)adaptiveThreshold() 自适应阈值化能够根据图像不同区域亮度分布的,改变阈值,即多个阈值。
当同一幅图像上的不同部分的具有不同亮度时。这种情况下我们需要采用自适应阈值。此时的阈值是根据图像上的每一个小区域计算与其对应的阈值。因此在同一幅图像上的不同区域采用的是不同的阈值,从而使我们能在亮度不同的情况下得到更好的结果。
通过计算每个像素周围bxb大小像素块的加权均值并减去常量C得到。其中,b由blockSize给出,大小必须为奇数;如果使用平均的方法,则所有像素周围的权值相同;如果使用高斯的方法,则(x,y)周围的像素的权值则根据其到中心点的距离通过高斯方程得到。
void cv::adaptiveThreshold(
cv::InputArray src, // 输入图像
cv::OutputArray dst, // 输出图像
double maxValue, // 向上最大值
int adaptiveMethod, // 自适应方法,平均或高斯
int thresholdType // 阈值化类型
int blockSize, // 块大小
double C // 常量
);
阈值类型有两种:即cv::ADAPTIVE_THRESH_MEAN_C(平均)和cv::ADAPTIVE_THRESH_GAUSSIAN_C(高斯)。
- 【6】 Mat <—> IplImage
1、将Mat转换为IplImage
//! converts header to IplImage; no data is copied
operator IplImage() const;
举例:Mat img;
IplImage *src;
src=&IplImage(img);
2、将IplImage转换为Mat
//! converts old-style IplImage to the new matrix; the data is not copied by default
Mat(const IplImage* img, bool copyData=false);
- 【7】OpenCV —— 画图 、 文字 及 属性。
可以绘制的图形有直线、矩形、多边形、圆、椭圆。以及一个写文本的函数puttext
https://blog.csdn.net/gdfsg/article/details/50867809
关于画图中的LineTypes参数(可选4,8,LINE_AA三种)。如果画水平竖直线完全没差别。当画斜线时,显示区别。具体如下:
// 三条线依次向下
line(img_01, Point(10, 10), Point(25, 18), 0, 1, 4);
line(img_01, Point(10, 17), Point(25, 25), 0, 1, 8);
line(img_01, Point(10, 23), Point(25, 29), 0, 1, LINE_AA);
图01 线型 图02 4邻域 图03 8邻域
看图,LineTypes参数中的4,8,LINE_AA代表点的邻域连接方式。4邻域,必须此点上下左右相连;8邻域,此点8个方向相连;LINE_AA,抗锯齿,从图上大约看出边缘利用较暗像素模糊一点,基本没啥用。
4、8邻域的线端点即是线的两端;LINE_AA线两端颜色中间颜色的是端点,浅色的那个是效果点。
LineTypes总结:三个参数是线点的邻域连接方式,只在斜线上表现差异。一般用8邻域即可。参考https://zhidao.baidu.com/question/427970238676959132.html
- 【8】霍夫直线
看了一些网页,这个最清晰直观。https://www.cnblogs.com/cheermyang/p/5348820.html
其中,r为直线L到原点的距离;θ为直线 L与x轴正方向的夹角,根据上式,直线L 上不同的点在参数平面r-θ中被变换为一簇相交于t点的正弦曲线。显然,若能确定参数平面中的t点,就实现了直线检测。在实际计算中,根据图像空间中的数据点计算Hough 参数空间中的正弦曲线轨迹,在参数平面上进行二维统计,选取峰值。该峰值就是图像空间中一条直线的参数,从而实现了图像空间中的直线检测。
记录个优化后的hough圆 http://www.opencv.org.cn/forum.php?mod=viewthread&tid=34096&extra=&page=1
以下为具体步骤以及实现:
1. 彩色图像RBG->灰度图Gray
(opencv上需要注意颜色空间是RGB还是BGR,CImg中RGB分别对应0,1,2通道)
2. 去噪(高斯核)
3. 边缘提取(梯度算子、拉普拉斯算子、canny; 此处实现用sobel)
4. 二值化(判断此处是否为边缘点,就看灰度值==255)
5. 映射到霍夫空间(此处准备两个容器,一个CImg用来展示hough-space概况,一个数组hough-space用来储存voting的值,因为投票过程往往有某个极大值超过255,多达几千,不能直接用灰度图来记录投票信息)
6. 取局部极大值,设定阈值,过滤干扰直线
7. 绘制直线、标定角点
可以转载分享,但需在文章开头注明本文原始链接:https://blog.csdn.net/zaibeijixing/article/details/80971208
可以转载分享,但需在文章开头注明本文原始链接:https://blog.csdn.net/zaibeijixing/article/details/80971208