一、图像运算
cpp
Mat src, src1, src2, dst;
// 图像运算 加 减 乘 除
cv::add(src1, src2, dst); // 相加:src1+src2
cv::scaleAdd(src1, 1.0, src2, dst); // 相加:1.0*src1+src2
cv::addWeighted(src1, 0.3, src2, 0.7, 0.0, dst); // 相加:0.3*src1+0.7*src2
cv::subtract(src1, src2, dst); // 相减:src1-src2
cv::subtract(cv::Scalar(255), src, dst); // 相减:255-src
cv::subtract(src, cv::Scalar(128), dst); // 相减:src-128
cv::multiply(src1, src2, dst, 1.0); // 相乘:src1*src2*1.0
cv::mulTransposed(src, dst, true); // 相乘:true:src'*src false:src*src'
cv::divide(src1, src2, dst, 1.0); // 相除:src1/src2
cv::divide(255.0, src, dst); // 相除:255.0/src
二、按位运算
cpp
// 按位运算 与 或 非 异或
cv::bitwise_and(src1, src2, dst); // 按位与操作 1&1=1 1&0=0 0&1=0 0&0=0
cv::bitwise_or(src1, src2, dst); // 按位或操作 1|1=1 1|0=1 0|1=1 0|0=0
cv::bitwise_not(src, dst); // 按位非操作 ~1=0 ~0=1
cv::bitwise_xor(src1, src2, dst); // 按位异或操作 1xor1=0 1xor0=1 0xor1=1 0xor0=1
cv::bitwise_and(src, cv::Scalar(255), dst);
三、函数运算
cpp
// 绝对值 开方 指数 对数 幂次方
dst = cv::abs(src); // 元素绝对值
cv::sqrt(src, dst); // 元素开方 x^(0.5)
cv::exp(src, dst); // 元素指数 e^x
cv::log(src, dst); // 元素自然对数 In(x)
cv::pow(src, 5, dst); // 元素p次幂 x^5
四、像素比较
cpp
// 较大值 较小值
cv::max(src1, src2, dst); // 两图像较大值
cv::max(src, cv::Scalar(0), dst); // 取较大值
cv::min(src1, src2, dst); // 两图像较小值
cv::min(src, cv::Scalar(255), dst); // 取较小值
// 像素比较,匹配标记255,否则0,输入src为单通道
// CMP_EQ:= CMP_GT:> CMP_GE:>= CMP_LT:< CMP_LE:<= CMP_NE:!=
cv::compare(src1, src2, dst, cv::CMP_EQ);
cv::compare(src, cv::Scalar(9), dst, cv::CMP_EQ);
cv::compare(cv::Scalar(9), src, dst, cv::CMP_EQ);
cv::Point posOutlier; // [0.0, 256.0)
bool flagRange = cv::checkRange(src, true, &posOutlier, 0.0, 256.0); // 检查值是否在范围内
// 输入为单通道/多通道, 输出为单通道二值图像; 区间为闭区间
Mat maskInRange;
cv::inRange(gray, cv::Scalar(0), cv::Scalar(255), maskInRange); // 相当于阈值分割
cv::inRange(color, cv::Scalar(0,0,0), cv::Scalar(9,9,9), maskInRange); // 多通道之间取交集
五、通道操作
cpp
// 通道合并 通道分离
vector<Mat> mats;
Mat grays[3] = { gray, gray, gray };
cv::merge(mats, dst); // 合并
cv::merge(grays, 3, dst); // 合并
cv::split(dst, mats); // 分离
cv::split(dst, grays); // 分离
int fromTo[] = { 0, 0 };
cv::mixChannels(&src, 1, &src, 1, fromTo, 1); // 通道重组
六、矩阵相关
cpp
// 矩阵相关
double det = cv::determinant(src); // 行列式
cv::Scalar trace = cv::trace(src); // 计算矩阵的迹
double norm1 = cv::norm(src, cv::NORM_L2); // 矩阵范数
double norm2 = cv::norm(src1, src2, cv::NORM_L2); // 矩阵范数
int cntNonZero = cv::countNonZero(src); // 非零元素个数
cv::transpose(src, dst); // 转置
cv::completeSymm(src, false); // 上三角复制到下三角,使之对称
cv::invert(src, dst, cv::DECOMP_LU); // 矩阵求逆或伪逆
cv::normalize(src, dst, 0.0, 1.0, cv::NORM_MINMAX); // 映射到指定范围内
Mat mtx = Mat::ones(100, 100, CV_8UC1);
cv::setIdentity(mtx, cv::Scalar(255)); // 对角线元素设置为指定值,其他为0
// 输入为浮点型对称方阵 输出特征值为向量 特征向量为矩阵
Mat eigenvalues, eigenvectors;
cv::eigen(src, eigenvalues, eigenvectors);
// 协方差矩阵和均值
Mat dstCovar, dstMean;
cv::calcCovarMatrix(src, dstCovar, dstMean, 0, 6);
七、极值坐标
cpp
// 寻找图像中灰度值最大最小位置 输入为单通道
double minV, maxV;
int minIdx[2], maxIdx[2];
cv::Point minLoc, maxLoc;
cv::minMaxIdx(src, &minV, &maxV, minIdx, maxIdx);
cv::minMaxLoc(src, &minV, &maxV, &minLoc, &maxLoc);
八、矩阵变换
cpp
/* 透视变换 */
Mat m33 = Mat::zeros(3, 3, CV_32FC1);
cv::perspectiveTransform(src, dst, m33); // 投影变换 3*3/4*4变换矩阵
/* 线性变换 */
Mat m22 = Mat::zeros(2, 2, CV_32FC1);
cv::transform(src, dst, m22); // 任意线性变换 2*2/2*3变换矩阵
/* 仿射变换 透视变换 */
cv::warpAffine(src, dst, m23, src.size()); // m23 为2*3变换矩阵
cv::warpPerspective(src, dst, m33, src.size()); // m33为3*3变换矩阵
perspectiveTransform / transform:变换矩阵与通道向量的乘积作为结果通道向量。
warpAffine / warpPerspective:矩阵坐标位置变换。
九、其他算子
cpp
// 矩阵求解
Mat lhs, rhs, dstSolve; // n*n n*1 n*1 lhs*dstSolve=rhs
cv::solve(lhs, rhs, dstSolve, cv::DECOMP_LU); // 求解线性系统
Mat coeffs, dstRoots; // coeffs 4*1
cv::solveCubic(coeffs, dstRoots); // 三次多项式实根
cv::solvePoly(coeffs, dstRoots); // 任意多项式的根
cv::sort(src, dst, cv::SORT_EVERY_ROW + SORT_ASCENDING); // 分别对每行或列排序
cv::sortIdx(src, dst, cv::SORT_EVERY_ROW + SORT_ASCENDING); // 排序索引
cv::flip(src, dst, 0); // 绕x轴或y轴旋转 >0:y-flip 0:x-flip <0:both
// 广义矩阵乘法
cv::gemm(src1, src2, 1.0, src, 1.0, dst, cv::GEMM_1_T + cv::GEMM_3_T); // dst=1.0*src1'*src2+1.0*src
// 幅值、角度相关
Mat dstMagnitude, dstAngle;
cv::cartToPolar(src, src, dstMagnitude, dstAngle); // 直角坐标系转为极坐标系
Mat dstx, dsty;
cv::polarToCart(dstMagnitude, dstAngle, dstx, dsty); // 极坐标中计算笛卡尔坐标
cv::magnitude(src, src, dstMagnitude); // 计算直角坐标系转换成极坐标系的幅值
Mat dstPhase;
cv::phase(src, src, dstPhase, false); // 对二维矢量场计算笛卡尔-极坐标转换的方位角
Mat vecMat1, vecMat2, dstIcovar;
cv::Mahalanobis(vecMat1, vecMat2, dstIcovar); // 计算两个向量的马氏距离