CV_EXPORTS_W void findContours(
InputOutputArray image, //输入图像,数据类型为 CV_8U 的单通道灰度图像或者二值化图像
OutputArrayOfArrays contours, //检测到的轮廓,每个轮廓中存放着像素的坐标
OutputArray hierarchy, //轮廓结构关系描述向量
int mode, //轮廓检测模式标志
int method, //轮廓逼近方法标志
Point offset = Point() //每个轮廓点移动的可选偏移量。这个参数主要用在从 ROI 图像中找出轮廓并基于整个图像分析轮廓的场景中。
);
该函数主要用于检测图像中的轮廓信息,并输出各个轮廓之间的结构信息。
该函数的第一个参数是待检测轮廓的输入图像,从理论上讲,检测图像轮廓需要是二值化图像,但是该函数会将非零相似视为1,0像素保持不变,因此该参数能够接受非二值化的灰度图像。 由于该函数默认二值化操作不能保持图像主要的内容,因此常需要对图像进行预处理,利用 threshold 函数或者 adaptiveThreshold 函数根据需求进行二值化。
该函数第二个参数用于存放检测到的轮廓,数据类型为 vector
该函数第三个参数用于存放各个轮廓之间的结构信息,数据类型为 vector,数据的尺寸与检测到的轮廓数目相同,每个轮廓结构信息中第一个数据表示同层下一个轮廓索引,第二个数据表示同层上一个轮廓索引,第三个数据表示下一层第一个子轮廓索引,第四个数据表示上层父轮廓索引。
该函数第四个参数是轮廓检测模式的标志。
该函数的第五个参数是选择轮廓逼近方法的标志。
该函数的最后一个参数是每个轮廓点移动的可选偏移量。
mode 轮廓检测模式标志
CV_RETR_EXTERNAL 0 只检测最外层轮廓
CV_RETR_LIST 1 提取所有轮廓,并且放置在 list 中。检测的轮廓不建立等级关系
CV_RETR_CCOMP 2 提取所有轮廓,并且将其组织为双层结构。顶层为连通域的外围边界,次层为孔的内层边界
CV_RETR_TREE 3 提取所有轮廓,并重新建立网状的轮廓结构
CV_RETR_FLOODFILL 4
CV_CHAIN_CODE 0
CV_CHAIN_APPROX_NONE 1 获取每个轮廓的每个像素,相邻两个点的像素位置相差1
CV_CHAIN_APPROX_SIMPLE 2 压缩水平方向、垂直方向和对角线方向的像素,只保留该方向的终点坐标
CV_CHAIN_APPROX_TC89_L1 3
CV_CHAIN_APPROX_TC89_KCOS 4
CV_LINK_RUNS 5
CV_EXPORTS_W void drawContours(
InputOutputArray image, //绘制轮廓的目标图像
InputArrayOfArrays contours, //所有将要绘制的轮廓
int contourIdx, //要绘制的轮廓数目,如果是负数,那么绘制所有的轮廓
const Scalar& color, //绘制轮廓的颜色
int thickness = 1, //绘制轮廓的线条粗细。如果参数为负数,那么绘制轮廓的内部。默认参数值为 1。
int lineType = LINE_8, //边界线的连续类型,可以选择的参数在下方给出,默认参数值为 LINE_8
InputArray hierarchy = noArray(), //可选的结构关系信息,默认值为 noArray
int maxLevel = INT_MAX, //表示绘制轮廓的最大等级,默认值为 INT_MAX
Point offset = Point() //可选的轮廓偏移参数,按指定的移动距离绘制所有的轮廓
);
该函数用于绘制 findContours 函数检测到的图像轮廓。
lineType
FILLED = -1,
LINE_4 = 4, 4连通线型
LINE_8 = 8, 8连通线型
LINE_AA = 16 抗锯齿线型
OpenCV并没有专门用于图像旋转的函数,二是通过图像的仿射变换实现图像的旋转。
实现图像的旋转,首先需要确定旋转角度和旋转中心,之后确定旋转矩阵,最终通过仿射变换实现图像旋转。
针对这个流程,OpenCV提供了 getRotationMatrix2D 函数用于计算旋转矩阵,提供了 warpAffine 函数用于实现图像的仿射变换。
CV_EXPORTS_W Mat getRotationMatrix2D(
Point2f center, //图像旋转的中心位置
double angle, //图像旋转的角度,单位为度,正值为逆时针旋转
double scale //两个轴的比例因子,可以实现旋转过程中的图像缩放,不缩放则输入 1
)
该函数输入旋转角度和旋转中心,返回图像旋转矩阵,返回值的数据类型为 mat 类,是一个 2x3 的矩阵。如果我们已知图像旋转矩阵,那么可以自己生成旋转矩阵而不调用该函数。
在确定旋转矩阵后,通过 warpAffine 函数进行放射变换,就可以实现图像的旋转
仿射变换就是图像的旋转、平移和缩放操作的统称,可以表示为线性变换和平移变换的叠加。仿射变换的数学表示是先乘以一个线性变换矩阵再加上一个平移向量,其中线性变换矩阵为2x2的矩阵,平移向量为 2x1的向量。
CV_EXPORTS_W void warpAffine(
InputArray src, //输入图像
OutputArray dst, //仿射变换后输出图像,与 src 数据类型相同,尺寸与 dsize 相同
InputArray M, //2x3的变换矩阵
Size dsize, //输出图像的尺寸
int flags = INTER_LINEAR, //插值方法标志,可选参数在下方
int borderMode = BORDER_CONSTANT, //像素边界外推方法的标志
const Scalar& borderValue = Scalar() //填充边界使用的数值,默认情况下为 0
);
参数设置
INTER_NEAREST = 0, 最近邻插算法
INTER_LINEAR = 1, 双线性插值法
INTER_CUBIC = 2, 双三次插值法
INTER_AREA = 3, 使用像素区域关系重新采样,首选用于图像缩小,图像放大时效果与 INTER_NEAREST 相似
INTER_LANCZOS4 = 4, Lanczos 插值法
INTER_MAX = 7, 用掩码进行插值
WARP_FILL_OUTLIERS = 8, 填充所有输出图像的像素,如果部分像素落在输入图像的边界外,则他们的值设定为 fillval
WARP_INVERSE_MAP = 16 设置M输出图像到输入图像的反变换
BORDER_CONSTANT = 0, //!< `iiiiii|abcdefgh|iiiiiii` with some specified `i`
BORDER_REPLICATE = 1, //!< `aaaaaa|abcdefgh|hhhhhhh`
BORDER_REFLECT = 2, //!< `fedcba|abcdefgh|hgfedcb`
BORDER_WRAP = 3, //!< `cdefgh|abcdefgh|abcdefg`
BORDER_REFLECT_101 = 4, //!< `gfedcb|abcdefgh|gfedcba`
BORDER_TRANSPARENT = 5, //!< `uvwxyz|absdefgh|ijklmno`
BORDER_REFLECT101 = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101
BORDER_DEFAULT = BORDER_REFLECT_101, //!< same as BORDER_REFLECT_101
BORDER_ISOLATED = 16 //!< do not look outside of ROI
逆转仿射变换
CV_EXPORTS_W void invertAffineTransform(
InputArray M, //原始仿射变换
OutputArray iM //输出反向仿射变换
);
CV_EXPORTS_W void transform(
InputArray src, //待变换数组
OutputArray dst, //变换后数组
InputArray m //M矩阵
);