Cxcore其它混合函数
Wikipedia,自由的百科全书
[编辑]
CheckArr
检查输入数组的每一个元素是否是合法值
int cvCheckArr( const CvArr* arr, int flags=0,
double min_val=0, double max_val=0);
#define cvCheckArray cvCheckArr
- arr
- 待检查数组
- flags
- 操作标志, 0 或者下面值的组合:
- CV_CHECK_RANGE - 如果设置这个标志, 函数检查数组的每一个值是否在范围 [minVal,maxVal) 以内;否则,它只检查每一个元素是否是 NaN 或者 ±Inf。
- CV_CHECK_QUIET - 设置这个标志后, 如果一个元素是非法值的或者越界时,函数不会产生错误。
- min_val
- 有效值范围的闭下边界。只有当 CV_CHECK_RANGE 被设置的时候它才有作用。
- max_val
- 有效值范围的开上边界。只有当 CV_CHECK_RANGE 被设置的时候它才有作用。
函数 cvCheckArr 检查每一个数组元素是否是 NaN 或者 ±Inf。如果 CV_CHECK_RANGE 被设定, 它将检查每一个元素是否大于等于 minVal 并且小于maxVal。如果检查成功函数返回非零值,例如,所有元素都是合法的并且在范围内,如果检查失败则返回 0 。 在后一种情况下如果 CV_CHECK_QUIET 标志没有被设定,函数将报出运行错误。
[编辑]
KMeans2
按照给定的类别数目对样本集合进行聚类
void cvKMeans2( const CvArr* samples, int cluster_count,
CvArr* labels, CvTermCriteria termcrit );
- samples
- 输入样本的浮点矩阵,每个样本一行。
- cluster_count
- 所给定的聚类数目
- labels
- 输出整数向量:每个样本对应的类别标识
- termcrit
- 指定聚类的最大迭代次数和/或精度(两次迭代引起的聚类中心的移动距离)
函数 cvKMeans2 执行 k-means 算法 搜索 cluster_count 个类别的中心并对样本进行分类,输出 labels(i) 为样本 i 的类别标识。
例子. 用 k-means 对高斯分布的随机样本进行聚类
#include "cxcore.h"
#include "highgui.h"
int main( int argc, char** argv )
{
#define MAX_CLUSTERS 5
CvScalar color_tab[MAX_CLUSTERS];
IplImage* img = cvCreateImage( cvSize( 500, 500 ), 8, 3 );
CvRNG rng = cvRNG(0xffffffff);
color_tab[0] = CV_RGB(255,0,0);
color_tab[1] = CV_RGB(0,255,0);
color_tab[2] = CV_RGB(100,100,255);
color_tab[3] = CV_RGB(255,0,255);
color_tab[4] = CV_RGB(255,255,0);
cvNamedWindow( "clusters", 1 );
for(;;)
{
int k, cluster_count = cvRandInt(&rng)%MAX_CLUSTERS + 1;
int i, sample_count = cvRandInt(&rng)%1000 + 1;
CvMat* points = cvCreateMat( sample_count, 1, CV_32FC2 );
CvMat* clusters = cvCreateMat( sample_count, 1, CV_32SC1 );
/* generate random sample from multigaussian distribution */
for( k = 0; k < cluster_count; k++ )
{
CvPoint center;
CvMat point_chunk;
center.x = cvRandInt(&rng)%img->width;
center.y = cvRandInt(&rng)%img->height;
cvGetRows( points, &point_chunk, k*sample_count/cluster_count,
k == cluster_count - 1 ? sample_count : (k+1)*sample_count/cluster_count );
cvRandArr( &rng, &point_chunk, CV_RAND_NORMAL,
cvScalar(center.x,center.y,0,0),
cvScalar(img->width/6, img->height/6,0,0) );
}
/* shuffle samples */
for( i = 0; i < sample_count/2; i++ )
{
CvPoint2D32f* pt1 = (CvPoint2D32f*)points->data.fl + cvRandInt(&rng)%sample_count;
CvPoint2D32f* pt2 = (CvPoint2D32f*)points->data.fl + cvRandInt(&rng)%sample_count;
CvPoint2D32f temp;
CV_SWAP( *pt1, *pt2, temp );
}
cvKMeans2( points, cluster_count, clusters,
cvTermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0 ));
cvZero( img );
for( i = 0; i < sample_count; i++ )
{
CvPoint2D32f pt = ((CvPoint2D32f*)points->data.fl)[i];
int cluster_idx = clusters->data.i[i];
cvCircle( img, cvPointFrom32f(pt), 2, color_tab[cluster_idx], CV_FILLED );
}
cvReleaseMat( &points );
cvReleaseMat( &clusters );
cvShowImage( "clusters", img );
int key = cvWaitKey(0);
if( key == 27 ) // 'ESC'
break;
}
}
[编辑]
SeqPartition
拆分序列为等效的类
typedef int (CV_CDECL* CvCmpFunc)(const void* a, const void* b, void* userdata);
int cvSeqPartition( const CvSeq* seq, CvMemStorage* storage, CvSeq** labels,
CvCmpFunc is_equal, void* userdata );
- seq
- 划分序列
- storage
- 存储序列的等效类的存储器,如果为空, 函数用 seq->storage 存储输出标签。
- labels
- 输出参数。指向序列指针的指针,这个序列存储以0为开始的输入序列元素的标签。
- is_equal
- 比较函数指针。如果两个特殊元素是来自同一个类,那这个比较函数返回非零值,否则返回 0 。划分算法用比较函数的传递闭包得到等价类。
- userdata
- 直接传递给 is_equal 函数的指针。
函数 cvSeqPartition 执行二次方程算法为拆分集合为一个或者更多的等效类。 函数返回等效类的数目。
例子:拆分二维点集。
#include "cxcore.h"
#include "highgui.h"
#include <stdio.h>
CvSeq* point_seq = 0;
IplImage* canvas = 0;
CvScalar* colors = 0;
int pos = 10;
int is_equal( const void* _a, const void* _b, void* userdata )
{
CvPoint a = *(const CvPoint*)_a;
CvPoint b = *(const CvPoint*)_b;
double threshold = *(double*)userdata;
return (double)(a.x - b.x)*(a.x - b.x) + (double)(a.y - b.y)*(a.y - b.y) <= threshold;
}
void on_track( int pos )
{
CvSeq* labels = 0;
double threshold = pos*pos;
int i, class_count = cvSeqPartition( point_seq, 0, &labels, is_equal, &threshold );
printf("%4d classes\n", class_count );
cvZero( canvas );
for( i = 0; i < labels->total; i++ )
{
CvPoint pt = *(CvPoint*)cvGetSeqElem( point_seq, i );
CvScalar color = colors[*(int*)cvGetSeqElem( labels, i )];
cvCircle( canvas, pt, 1, color, -1 );
}
cvShowImage( "points", canvas );
}
int main( int argc, char** argv )
{
CvMemStorage* storage = cvCreateMemStorage(0);
point_seq = cvCreateSeq( CV_32SC2, sizeof(CvSeq), sizeof(CvPoint), storage );
CvRNG rng = cvRNG(0xffffffff);
int width = 500, height = 500;
int i, count = 1000;
canvas = cvCreateImage( cvSize(width,height), 8, 3 );
colors = (CvScalar*)cvAlloc( count*sizeof(colors[0]) );
for( i = 0; i < count; i++ )
{
CvPoint pt;
int icolor;
pt.x = cvRandInt( &rng ) % width;
pt.y = cvRandInt( &rng ) % height;
cvSeqPush( point_seq, &pt );
icolor = cvRandInt( &rng ) | 0x00404040;
colors[i] = CV_RGB(icolor & 255, (icolor >> 8)&255, (icolor >> 16)&255);
}
cvNamedWindow( "points", 1 );
cvCreateTrackbar( "threshold", "points", &pos, 50, on_track );
on_track(pos);
cvWaitKey(0);
return 0;
}


