opencv内存管理器2-cvSeqPartition聚类

本文介绍了OpenCV中CvSeq序列的拆分功能,特别是如何使用cvSeqPartition函数根据用户定义的标准进行拆分。在聚类过程中,该函数依据欧氏距离对随机生成的点进行分类,通过比较函数实现点之间的距离判断。拆分结果存储在labels参数中,表示每个元素所属的类别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.opencv的序列CvSeq中有一个函数可以按照用户设定的标准来拆分序列。


拆分操作需要申请新的内存用于存储结果,参数labels是指向序列的指针的指针,当函数调用结束时,参数labels中是一个整数序列,序列中的元素是跟序列seq中元素一一对应,这些参数的值从0开始递增,是拆分之后元素的类别的标志。is_euqal参数对应我们自己定义的比较函数,userdata为比较函数的参数。对随机生成的点进行模拟聚类,比较两个点之间的欧氏距离,小于特定的阈值时返回1.


源码:

#include "cxcore.h"
#include "highgui.h"
#include <stdio.h>

CvSeq* point_seq = 0;
IplImage* canvas = 0;
CvScalar* colors = 0;
int pos = 5;

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; //定义阈值为pos^2
	int i, class_count = cvSeqPartition(point_seq, 0, &labels, is_equal, &threshold);
	//对point_seq点序列拆分为等效的类,条件是(Ax-Bx)^2+(Ay-By)^2<=pos^2
	//含义为两点相差距离小于pos的属于一类
	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);
		cvWaitKey(0);
	}


}

int main(int argc, char** argv)
{
	CvMemStorage* storage = cvCreateMemStorage(0);//建立了一个存储器
	point_seq = cvCreateSeq(CV_32SC2, sizeof(CvSeq), sizeof(CvPoint), storage);
	//建立了一个32位整型序列
	CvRNG rng = cvRNG(0xffffffff);//初始化随机数生成器

	int width = 500, height = 500;//定义图像的长和宽
	int i, count = 100;//定义了两个计数器
	canvas = cvCreateImage(cvSize(width, height), 8, 3);
	//设置图像,大小为500*500,色深8,三通道

	colors = (CvScalar*)cvAlloc(count*sizeof(colors[0]));
	//分配1000个CvScalar大小的内存缓冲区
	for (i = 0; i < count; i++)
	{
		CvPoint pt;//设置一个点
		int icolor;//定义颜色标的
		pt.x = cvRandInt(&rng) % width;//随机产生点的x坐标
		pt.y = cvRandInt(&rng) % height;//随机产生点的y坐标
		cvSeqPush(point_seq, &pt);//添加这个点到序列的尾部
		icolor = cvRandInt(&rng) + 0xa0a0a0a0;
		//用随机的方法给颜色标的一个基准,后边加的那个数字是可以任意的。
		colors[i] = CV_RGB(icolor & 255, (icolor >> 8) & 255, (icolor >> 16) & 255);
		//把这个点的颜色完全写入标量容器colors中
	}

	cvNamedWindow("points", 1);//创建窗口
	cvCreateTrackbar("threshold", "points", &pos, 50, on_track);
	//建立拖动条,名称为threshold,窗口的名字叫points,创建初始化值取自pos,
	//回调函数名称为on_track
	on_track(pos);//监视拖动条的改变并处理之
	cvWaitKey(0);
	return 0;
}


结果:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值