OpenCV是一个基于C/C++语言的开源跨平台图像处理函数库,可以运行在MacLinuxWindows操作系统平台,同时提供PythonRubyMATLAB等语言接口,应用于人机互动,物体识别,目标跟踪以及智能机器人。

        在UI自动化测试中无论使用专用测试工具还是开源测试框架,都会遇到开发自定义UI控件不可识别导致测试脚本无法实现自动化,以及测试脚本不容易实现调用多个应用程序在桌面上的交互。通过使用OpenCV图像处理算法,对桌面图像中的测试UI进行识别和定位则容易解决这些问题。
 
模版匹配
       使用模版匹配的方法可以定位需要测试的UI控件在桌面的坐标,从而发送相应的虚拟鼠标或者键盘事件进行操作。
实现步骤:
1. 获取桌面截图并保存为图像文件;
2. 使用模版匹配函数对桌面截图和测试UI模板进行处理;
void cvMatchTemplate( const CvArr* p_w_picpath, const CvArr* templ, CvArr* result, int method );
3. 获取最佳匹配值并得到测试UI在桌面的坐标值;
void cvMinMaxLoc( const CvArr* arr, double* min_val, double* max_val,
CvPoint* min_loc=NULL, CvPoint* max_loc=NULL, const CvArr* mask=NULL );
4. 发送鼠标或者键盘虚拟事件进行操作;
 
部分代码实现:
typedef struct targetRect{
int t_x;
int t_y;
int t_width;
int t_height;
}targetRect;
int get_match_p_w_picpath(targetRect* p_Rect){
   
cvMatchTemplate( desktopscreen, template, res, CV_TM_SQDIFF );
cvMinMaxLoc(res, &minval, &maxval, &minloc, &maxloc, 0 );  
p_Rect->t_x=minloc.x;
p_Rect->t_y=minloc.y;
p_Rect->t_width=tpl_width;
p_Rect->t_height=tpl_height;
}
 
目标识别
        对于UI变化的复杂情况,使用基于样本的学习的方法将测试UI可能的变化情况作为样本存储,对于产生新的样本获取相近的存储样本,从而得到匹配样本的相应值。
实现步骤:
1. 创建样本集合,将所有UI样本图片加入到这个集合。
CvMat* cvCreateMat( int rows, int cols, int type );
CvMat* cvGetRow( const CvArr* arr, CvMat* submat, int row );
void cvSet( CvArr* arr, CvScalar value, const CvArr* mask=NULL );
2. 训练样本;
bool CvKNearest::train( const CvMat* _train_data, const CvMat* _responses,
                        const CvMat* _sample_idx=0, bool is_regression=false,
                        int _max_k=32, bool _update_base=false );
3. 从桌面截图获取相近匹配样本的相应值;
float CvKNearest::find_nearest( const CvMat* _samples, int k, CvMat* results=0,
                                const float** neighbors=0, CvMat* neighbor_responses=0, CvMat* dist=0 ) const;
4. 判断新样本和测试UI样本的相近匹配率;
 
部分代码实现:
sampleData = cvCreateMat(sample_counts, sample_size, CV_32FC1);
sampleClasses = cvCreateMat(sample_counts, 1, CV_32FC1);
cvGetRow(sampleClasses, &sampleSet, sample_counts);
cvSet(&sampleSet, cvRealScalar(sample_counts));
cvGetRow(sampleData, &sampleSet, sample_counts);
knn=new CvKNearest(sampleData, sampleClasses, 0, false, K );
result=knn->find_nearest(sample,K,0,0,nearest,0);
 
相近匹配率:
for(int i=0, accuracy=0;i<K;i++){
if( nearest->data.fl[i] == result)
       accuracy++;
}
float pre_roti=100*((float)accuracy/(float)K);
 
         以上两种方法,可以通过桌面截图定位测试UI的坐标,而对于测试UI特征有变化的情况,则通过收集样本,然后确定相近特征的样本并获得相应的匹配值。
 
参考文章:
1.   OpenCV参考手册 http://www.opencv.org.cn/
3.   The baisc patter recognition and classification with OpenCV http://blog.damiles.com/2008/11/the-basic-patter-recognition-and-classification-with-opencv/