一:漫水填充算法(Floodfill)
漫水填充法是一种用特定的颜色填充联通区域,通过设置可连通像素的上下限以及连通方式来达到不同的填充效果的方法。漫水填充经常被用来标记或分离图像的一部分以便对其进行进一步处理或分析,也可以用来从输入图像获取掩码区域,掩码会加速处理过程,或只处理掩码指定的像素点,操作的结果总是某个连续的区域。
所谓漫水填充,简单来说,就是自动选中了和种子点相连的区域,接着将该区域替换成指定的颜色,这是个非常有用的功能,经常用来标记或者分离图像的一部分进行处理或分析.漫水填充也可以用来从输入图像获取掩码区域,掩码会加速处理过程,或者只处理掩码指定的像素点。
floodFill函数原型:
int floodFill(InputOutputArray image, Point seedPoint, Scalar newVal, Rect* rect=0, Scalar loDiff=Scalar(), Scalar upDiff=Scalar(), int flags=4 )
int floodFill(InputOutputArray image, InputOutputArray mask, Point seedPoint,Scalar newVal, Rect* rect=0, Scalar loDiff=Scalar(), Scalar upDiff=Scalar(), int flags=4
两种原型,除了第二个参数外,其他的参数都是共用的。
- 第一个参数,InputOutputArray类型的image, 输入/输出1通道或3通道,8位或浮点图像,具体参数由之后的参数具体指明。
- 第二个参数, InputOutputArray类型的mask,这是第二个版本的floodFill独享的参数,表示操作掩模,。它应该为单通道、8位、长和宽上都比输入图像 image 大两个像素点的图像。第二个版本的floodFill需要使用以及更新掩膜,所以这个mask参数我们一定要将其准备好并填在此处。需要注意的是,漫水填充不会填充掩膜mask的非零像素区域。例如,一个边缘检测算子的输出可以用来作为掩膜,以防止填充到边缘。同样的,也可以在多次的函数调用中使用同一个掩膜,以保证填充的区域不会重叠。另外需要注意的是,掩膜mask会比需填充的图像大,所以 mask 中与输入图像(x,y)像素点相对应的点的坐标为(x+1,y+1)。
- 第三个参数,Point类型的seedPoint,漫水填充算法的起始点。
- 第四个参数,Scalar类型的newVal,像素点被染色的值,即在重绘区域像素的新值。
- 第五个参数,Rect*类型的rect,有默认值0,一个可选的参数,用于设置floodFill函数将要重绘区域的最小边界矩形区域。
- 第六个参数,Scalar类型的loDiff,有默认值Scalar( ),表示当前观察像素值与其部件邻域像素值或者待加入该部件的种子像素之间的亮度或颜色之负差(lower brightness/color difference)的最大值。
- 第七个参数,Scalar类型的upDiff,有默认值Scalar( ),表示当前观察像素值与其部件邻域像素值或者待加入该部件的种子像素之间的亮度或颜色之正差(lower brightness/color difference)的最大值。
- 第八个参数,int类型的flags,操作标志符,
简单实例:
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
//-----------------------------------【main( )函数】--------------------------------------------
// 描述:控制台应用程序的入口函数,我们的程序从这里开始
//-----------------------------------------------------------------------------------------------
int main()
{
Mat src = imread("H:/final/fffff/1.jpg");
imshow("【原始图】", src);
Rect ccomp;//定义重绘区域的最小边界矩形区域
floodFill(src, Point(50, 300), Scalar(255, 255, 55), &ccomp, Scalar(20, 20, 20), Scalar(20, 20, 20));
imshow("【效果图】", src);
waitKey(0);
return 0;
}
补充知识:
SetMouseCallback函数为指定的窗口设置鼠标回调函数。
函数原型:
C++: void setMouseCallback(conststring& winname, MouseCallback onMouse, void* userdata=0 )
- 第一个参数,const string&类型的winname,为窗口的名字。
- 第二个参数,MouseCallback类型的onMouse,指定窗口里每次鼠标时间发生的时候,被调用的函数指针。这个函数的原型应该为voidFoo(int event, int x, int y, int flags, void* param);其中event是 CV_EVENT_*变量之一, x和y是鼠标指针在图像坐标系的坐标(不是窗口坐标系), flags是CV_EVENT_FLAG的组合, param是用户定义的传递到cvSetMouseCallback函数调用的参数。
- 第三个参数,void*类型的userdata,用户定义的传递到回调函数的参数,有默认值0。
二:特征点也就是角点检测
在图像处理和与计算机视觉领域,兴趣点(interest points),或称作关键点(keypoints)、特征点(feature points) 被大量用于解决物体识别,图像识别、图像匹配、视觉跟踪、三维重建等一系列的问题。我们不再观察整幅图,而是选择某些特殊的点,然后对他们进行局部有的放矢的分析。
图像特征类型可以被分为如下三种:
- <1>边缘
- <2>角点 (感兴趣关键点)
- <3>斑点(Blobs)(感兴趣区
其中,角点是个很特殊的存在。他们在图像中可以轻易地定位,同时,他们在人造物体场景,比如门、窗、桌等出随处可见。因为角点位于两条边缘的交点处,代表了两个边缘变化的方向上的点,,所以他们是可以精确定位的二维特征,甚至可以达到亚像素的精度。且其图像梯度有很高的变化,这种变化是可以用来帮助检测角点的。需要注意的是,角点与位于相同强度区域上的点不同,与物体轮廓上的点也不同,因为轮廓点难以在相同的其他物体上精确定位。
1.cornerHarris 函数
用于在OpenCV中运行Harris角点检测算子处理图像。
原型:
C++: void cornerHarris(InputArray src,OutputArray dst, int blockSize, int ksize, double k, intborderType=BORDER_DEFAULT )
- 第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可,且需为单通道8位或者浮点型图像。
- 第二个参数,OutputArray类型的dst,函数调用后的运算结果存在这里,即这个参数用于存放Harris角点检测的输出结果,和源图片有一样的尺寸和类型。
- 第三个参数,int类型的blockSize,表示邻域的大小,更多的详细信息在cornerEigenValsAndVecs()中有讲到。
- 第四个参数,int类型的ksize,表示Sobel()算子的孔径大小。
- 第五个参数,double类型的k,Harris参数。
- 第六个参数,int类型的borderType,图像像素的边界模式,注意它有默认值BORDER_DEFAULT。更详细的解释,参考borderInterpolate( )函数。
2.Threshold函数
对单通道数组应用固定阈值操作。该函数的典型应用是对灰度图像进行阈值操作得到二值图像。(另外,compare( )函数也可以达到此目的) 或者是去掉噪声,例如过滤很小或很大象素值的图像点。
原型:
C++: double threshold(InputArray src,OutputArray dst, double thresh, double maxval, int type)
- 第一个参数,InputArray类型的src,输入数组,填单通道 , 8或32位浮点类型的Mat即可。
- 第二个参数,OutputArray类型的dst,函数调用后的运算结果存在这里,即这个参数用于存放输出结果,且和第一个参数中的Mat变量有一样的尺寸和类型。
- 第三个参数,double类型的thresh,阈值的具体值。
- 第四个参数,double类型的maxval,当第五个参数阈值类型type取 CV_THRESH_BINARY 或CV_THRESH_BINARY_INV 阈值类型时的最大值.
- 第五个参数,int类型的type,阈值类型,。threshold( )函数支持的对图像取阈值的方法由其确定,
简单实例:
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/imgproc.hpp>
//-----------------------------------【命名空间声明部分】---------------------------------------
// 描述:包含程序所使用的命名空间
//-----------------------------------------------------------------------------------------------
using namespace cv;
int main()
{
//以灰度模式载入图像并显示
Mat srcImage = imread("1.jpg", 0);
imshow("原始图", srcImage);
//进行Harris角点检测找出角点
Mat cornerStrength;
cornerHarris(srcImage, cornerStrength, 2, 3, 0.01);
//对灰度图进行阈值操作,得到二值图并显示
Mat harrisCorner;
threshold(cornerStrength, harrisCorner, 0.00001, 255, THRESH_BINARY);
imshow("角点检测后的二值效果图", harrisCorner);
waitKey(0);
return 0;
}