一些函数
1、计算两个颜色向量的距离
return abs(color1[0]-color2[0])+
abs(color1[1]-color2[1])+
abs(color1[2]-color2[2]);
// Or:
return static_cast<int>(cv::norm<int,3>(cv::Vec3i(color[0]-color2[0],color[1]-color2[1],color[2]-color2[2])));
// Or:
cv::Vec3b dist;
cv::absdiff(color,color2,dist);
return cv::sum(dist)[0];
2、cv::absdiff函数
cv::absdiff(image,target,dist)
//cv::absdiff(image,cv::Scalar(target),dist)
//前两个为输入数组,后一个为输出数组
absdiff 函数计算图像的像素与标量值之间差距的绝对值。该函数的第二个参数也可以不用标量值,而是改用另一幅图像,这样就可以逐个像素地计算差距。因此两幅图像的尺寸必须相同。
3、cv::saturate_cast模板函数
在计算输出像素的值时,我们调用了 cv::saturate_cast 模板函数,并传入运算结果。这是因为计算像素的数学表达式的结果经常超出允许的范围(即小于 0 或大于 255)。使用这个函数可把结果调整到 8 位无符号数的范围内,具体做法是把小于 0 的数值调整为 0,大于 255 的数值调整为 255——这就是 cv::saturate_cast函数的作用。此外,如果输入参数是浮点数,就会得到最接近的整数。可以在调用这个函数时显式地指定其他数据类型,以确保结果在该数据类型定义的范围之内。
4、cv::Scalar(a,b,c)
对于三通道彩色图像,需要使用 cv::Scalar(a,b,c)来指定三个数值,分别对像素的每个通道赋值。
cv::Scalar(0)//所有入口初始为0
5、cv::filter2D
鉴于滤波是图像处理中的常见操作,OpenCV 专门为此定义了一个函数,即 cv::filter2D。要使用这个函数,只需要定义一个内核(以矩阵的形式),调用函数并传入图像和内核,即可返回滤波后的图像。因此,使用这个函数重新定义锐化函数非常容易:
void sharpen2D(const cv::Mat &image, cv::Mat &result) {
// 构造内核(所有入口都初始化为 0)
cv::Mat kernel(3,3,CV_32F,cv::Scalar(0));
// 对内核赋值
kernel.at<float>(1,1)= 5.0;
kernel.at<float>(0,1)= -1.0;
kernel.at<float>(2,1)= -1.0;
kernel.at<float>(1,0)= -1.0;
kernel.at<float>(1,2)= -1.0;
// 对图像滤波
cv::filter2D(image,result,image.depth(),kernel);
}
这种实现方式得到的结果与前面的完全相同(执行效率也相同)。如果处理的是彩色图像,三个通道可以应用同一个内核。注意,使用大内核的 filter2D 函数是特别有利的,因为这时它使用了更高效的算法。
6、cv::split 函数
以使用 cv::split 函数,将图像的三个通道分别复制到三个 cv::Mat 实例中。
// 创建三幅图像的向量
std::vector<cv::Mat> planes;
// 将一个三通道图像分割为三个单通道图像
cv::split(image1,planes);
7、cv::merge 函数
// 创建三幅图像的向量
std::vector<cv::Mat> planes;
// 将一个三通道图像分割为三个单通道图像
cv::split(image1,planes);
// 加到蓝色通道上
planes[0]+= image2;
// 将三个单通道图像合并为一个三通道图像
cv::merge(planes,result);
这里的 cv::merge 函数用三个单通道图像创建一个彩色图像。
8、cv::remap
// 应用映射参数
cv::remap(image, // 源图像
result, // 目标图像
srcX, // x 映射
srcY, // y 映射
cv::INTER_LINEAR); // 填补方法,插值法
}
9、迭代器
// 取得迭代器
cv::Mat_<cv::Vec3b>::const_iterator it= image.begin<cv::Vec3b>();
cv::Mat_<cv::Vec3b>::const_iterator itend= image.end<cv::Vec3b>();
cv::Mat_<uchar>::iterator itout= result.begin<uchar>();
10、cv::threshold
cv::threshold(output, // 相同的输入/输出图像
output,
maxDist, // 阈值(必须<256)
255, // 最大值
cv::THRESH_BINARY_INV); // 阈值化模式
用 cv::threshold 函数创建一个二值图像。这个函数通常用于将所有像素与某个阈值(第三个参数)进行比较,并且在常规阈值化模式(cv::THRESH_BINARY)下,将所有大于指定阈值的像素赋值为预定的最大值(第四个参数),将其他像素赋值为 0。这里使用相反的模式(cv::THRESH_BINARY_INV)把小于或等于阈值的像素赋值为预定的最大值。此外还有 cv::THRESH_TOZERO 和cv::THRESH_TOZERO_INV 模式,它们使大于或小于阈值的像素保持不变。
11、cv::floodFill
如要从图中提取出蓝天,可以执行以下语句:
cv::floodFill(image, // 输入/输出图像
cv::Point(100, 50), // 起始点
cv::Scalar(255, 255, 255), // 填充颜色
(cv::Rect*)0, // 填充区域的边界矩形
cv::Scalar(35, 35, 35), // 偏差的最小/最大阈值
cv::Scalar(35, 35, 35), // 正差阈值,两个阈值通常相等
cv::FLOODFILL_FIXED_RANGE); // 与起始点像素比较
图像中亚像素(100, 50)所处的位置是天空。函数会检查所有的相邻像素,颜色接近的像素会被重绘成第三个参数指定的新颜色。为了判断颜色是否接近,需要分别定义比参考色更高或更低的值作为阈值。这里使用固定范围模式,即所有像素都与亚像素的颜色进行对比,默认模式是将每个像素与和它邻近的像素进行对比。
12、cv::grabCut
cv::Mat result; // 分割结果(四种可能的值)
cv::Mat bgModel,fgModel; // 模型(内部使用)
// GrabCut 分割算法
cv::grabCut(image, // 输入图像
result, // 分割结果
rectangle, // 包含前景的矩形
bgModel,fgModel, // 模型
5, // 迭代次数
cv::GC_INIT_WITH_RECT); // 使用矩形
注意,我们在函数的中用 cv::GC_INIT_WITH_RECT 标志作为最后一个参数,表示将使用带边框的矩形模型。输入/输出的分割图像可以是以下四个值之一。
cv::GC_BGD:这个值表示明确属于背景的像素(例如本例中矩形之外的像素)。
cv::GC_FGD:这个值表示明确属于前景的像素(本例中没有这种像素)。
cv::GC_PR_BGD:这个值表示可能属于背景的像素。
cv::GC_PR_FGD:这个值表示可能属于前景的像素(即本例中矩形之内像素的初始值)。
通过提取值为 cv::GC_PR_FGD 的像素,可得到包含分割信息的二值图像,实现代码为:
// 取得标记为“可能属于前景”的像素
cv::compare(result,cv::GC_PR_FGD,result,cv::CMP_EQ);
// 生成输出图像
cv::Mat foreground(image.size(),CV_8UC3,cv::Scalar(255,255,255));
image.copyTo(foreground, result); // 不复制背景像素
13、 cv::cvtColor
// 转换成 Lab 色彩空间
cv::cvtColor(image, converted, CV_BGR2Lab);
14、cv::cvtColor
// 转换成 HSV 色彩空间
cv::Mat hsv;
cv::cvtColor(image, hsv, CV_BGR2HSV);