第四章 细说highGUI
1.OpenCV与用户界面GUI的交互都在HighGUI中,里面主要有图像的显示,键盘鼠标相应函数的交互,以及窗口的设置,改变等,这一部分主要掌握的函数有:
cvNamedWindow(const char* name,int flags=CV_WINDOW_AUTOSIZE);
cvDestroyWindow();
cvDestroyAllWindows();
cvResizeWindow();
cvMoveWindow();
cvShowImage();
cvSaveImage();
//所有句柄的窗口处理都由封装好的以上函数完成,也可以通过下面的函数访问:
cvGetWindowName();
cvGetWindowHandle();//还有其他的函数,类推。
//下面是响应交互的函数:
char c=cvWaitKey();//键盘响应
//鼠标响应,和键盘不同,鼠标响应必须有回调函数并注册,有格式要求:
void CvMouseCallBack(int event,int x,int y,int flags,void* param);//通过选取不同的event来设置鼠标响应P113
void cvSetMouseCallback(const char* windowName,CvMouseCallback onMOuse,void *param=NULL);//例子P114
//滑动条,也必须有回调函数。
int cvCreateTracker();
void CvTrackbarCallback();
cvGetTrackbarPos();//滑动条的设置
cvSetTrackbarPos();
注意:OpenCV中没有按钮,但是可以用滑动条(0,1)来实现按钮的功能,书上P123有例子。
另外一个重要的图像格式转化函数 从vConvertImage();
第五章 图像处理
前面讲了GUI,以及图像的载入和保存,从本章开始将介绍图像处理,获取图像的特征。
1)平滑:
cvSmooth(const CvArr* src,CvArr* dst,int smoothtype=CV_GAUSSIAN,int param=3);
//其中,smoothtype有五种类型:简单模糊,简单无放缩模糊,高斯模糊,中值模糊,双边滤波。
//CV_BLUR(均值)、CV_MEDIAN(中值、图像变化比较大)、CV_GAUSS(常用,效果比较好、但是在边缘处不太好),
//CV_BILATE-RAL(双边滤波:采用高斯加权,边缘处理比较好,但较费时)
//cvSmooth、cvErode()、cvDilate()处理后,输入输出的图像大小是一样大的,因为在OpenCV处理时,边缘创造了“虚拟”像素。
2)膨胀和腐蚀
膨胀和腐蚀:将图像与核进行卷积,核可以任意大小,膨胀是求局部核内最大值的操作,腐蚀是求局部核内最小值操作,结果一般是:膨胀将图像增亮(轮廓变粗),腐蚀变暗(变细)。经常将图像先经过 二值化处理,在进行膨胀或者腐蚀。函数如下:
cvErode(IplImage* src,IplImage* dst,IplConvKernel* B=NULL,int iterations=1);//填补凹孔,连通相邻区域
cvDilate(IplImage* src,IplImage* dst,IplConvKernel* B=NULL,int iterations=1);//消除凸起,去斑点
自定义核:
<span style="white-space:pre"> </span>IplConvKernel* cvCreateStructuringElementEx(int cols,int rows,int anchor_x,int anchor_y,int shape,int *values=NULL);
void cvReleaseStructuringElement(IplConvKernel** element);//删除自定义核
3)更通用形态学
在处理布尔图像或者图像掩码,以上形态学操作就够了,然而在处理灰度或者彩色图像时,需要额外的操作,函数如下:
void cvMorphologyEx(const CvArr* src,CvArr* dst,CvArr* temp,IplConvKernel* element,int operation,int iteration=1);
//其中operation指定该函数具体操作:开、闭运算,形态学梯度,“礼帽”,“黑帽”。
//开操作:先腐蚀后膨胀,结果:除去小的明亮区域,且剩下的明亮区域被隔绝。(闭操作相反)
//“礼帽”=原图 - 原图的开操作 ,结果:突出亮的斑点;“黑帽”=原图-原图的闭操作,结果:选出暗的区域(黑色区域变亮,分割出来)
漫水填充和改变图像大小:
void cvFloodFill();//能设置种子点,及要修改的像素值的区间,一般能处理连通区域。
void cvResize();//放缩图像的大小,ROI也会进行放缩,可选择插值方法。
//最近邻插值,原理直观,但是效果不好,
//线性插值(领域2x2范围距离作为加权求取):双线性内插值法计算量大,但缩放后图像质量高,但是高频受损(边缘)
//三次卷积和三次样条法能够克服以上两种算法的不足,计算精度高,但是更复杂。
金字塔分为Gauss金字塔和拉普拉斯金字塔:
void cvPyrDown();// Gauss金字塔,原理:先gauss模糊,然后再降采样,删除偶数行列,所以图像大小要能被2整除
void cvPyrUp();//Laplase金字塔,原理:先新增偶数行列为零,然后用拉普拉斯卷积对新增的行列求其近似的像素(gauss和拉普拉斯不是逆操作)
void cvPyrSegmentation();//金字塔分割,建立“父--子”之间的关系,分割后可以对其区域进行访问:P154页
4)阈值处理
分为单一阈值,和自适应阈值:
void cvThreshold();//单一阈值。
void cvAdaptiveThreshold();//源图像和目标图像不能一样。
//自适应阈值,原理:计算bXb区域内加权平均,然后减去一个常数得到自适应阈值,效果较好。