gpt4 book ai didi

c - openCV k-means 调用断言失败

转载 作者:太空宇宙 更新时间:2023-11-04 08:33:10 25 4
gpt4 key购买 nike

我已经从 openCV 源代码分发的示例文件夹中读取了 c++ 示例,并且,如果省略随机图片生成,kmeans 调用看起来非常简单——作者甚至没有分配中心/标签数组(你可以找到它 here ).但是,我不能在 C 中做同样的事情。如果我不分配标签,我会得到断言错误:

OpenCV Error: Assertion failed (labels.isContinuous() && labels.type() == CV_32S && (labels.cols == 1 || labels.rows == 1) && labels.cols + labels.rows - 1 == data.rows) in cvKMeans2, file /tmp/opencv-xiht/opencv-2.4.9/modules/core/src/matrix.cpp, line 3094

好的,我尝试创建空的 labels 矩阵,但断言消息根本没有改变。

IplImage* image = cvLoadImage("test.jpg", -1);
IplImage* normal = cvCreateImage(cvGetSize(image), IPL_DEPTH_32F, image->nChannels);
cvConvertScale(image, normal, 1/255.0, 0);
CvMat* points = cvCreateMat(image->width, image->height, CV_32F);
points->data.fl = normal->imageData;

CvMat* labels = cvCreateMat(1, points->cols, CV_32S);
CvMat* centers = NULL;

CvTermCriteria criteria = cvTermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 10, 1.0);

// KMEANS_PP_CENTERS is undefined
int KMEANS_PP_CENTERS = 2;
cvKMeans2(points, 4, labels, criteria, 3, NULL, KMEANS_PP_CENTERS, centers, 0);

让我发疯的事情:

CvMat* labels = cvCreateMat(1, points->cols, CV_32S);
int good = labels->type == CV_32S; // FALSE here

这显然是导致断言失败的一个(不确定是否是唯一的)问题。这应该如何工作?我不能使用 С++ API,因为整个应用程序都是纯 C 语言。

最佳答案

断言告诉你:

  1. type 必须是 CV_32S 这在您的代码中似乎是这种情况,也许您的 if 语句为 false 因为类型自动更改为 CV_32SC1?不知道...

  2. 您可以将每个点放在一行或一列中,因此 rows/cols 设置为 1 并且其他维度必须设置为 data.rows 表示 data 包含您要以每个点放置在一行中的格式聚类的点,导致 #points 行。所以你的错误似乎是 CvMat* labels = cvCreateMat(1, points->cols, CV_32S); 应该是 CvMat* labels = cvCreateMat(1, points->rows, CV_32S) ; 相反,使断言消失,但您对 points 的使用似乎在概念上是错误的。

您可能必须将您的点(您想要聚类)保存在具有n 行2 列 CV_32FC1 类型cvMat 中,或者1 col 并输入 CV_32FC2(也许两个版本都有效,也许只有一个,或者我可能根本错了)。

编辑:我写了一个适合我的简短代码片段:

// here create the data array where your input points will be hold:
CvMat* points = cvCreateMat( numberOfPoints , 2 /* 2D points*/ , CV_32F);

// this is a float array of the
float* pointsDataPtr = points->data.fl;
// fill the mat:
for(unsigned int r=0; r<samples.size(); ++r)
{
pointsDataPtr[2*r] = samples.at(r).x; // this is the x coordinate of your r-th point
pointsDataPtr[2*r+1] = samples.at(r).y; // this is the y coordinate of your r-th point
}


// this is the data array for the labels, which will be the output of the method.
CvMat* labels = cvCreateMat(1, points->rows, CV_32S);
// this is the quit criteria, which I did neither check nor modify, just used your version here.
CvTermCriteria criteria = cvTermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 10, 1.0);

// call the method for 2 cluster
cvKMeans2(points, 2, labels, criteria);

// now labels holds numberOfPoints labels which have either value 0 or 1 since we searched for 2 cluster

int* labelData = labels->data.i; // array to the labels
for(unsigned int r=0; r<samples.size(); ++r)
{
int labelOfPointR = labelData[r]; // this is the value of the label of point number r

// here I use c++ API to draw the points, do whatever else you want to do with the label information (in C API). I choose different color for different labels.
cv::Scalar outputColor;
switch(labelOfPointR)
{
case 0: outputColor = cv::Scalar(0,255,0); break;
case 1: outputColor = cv::Scalar(0,0,255); break;
default: outputColor = cv::Scalar(255,0,255); break; // this should never happen for 2 clusters...
}
cv::circle(outputMat, samples.at(r), 2, outputColor);
}

给我一​​些生成的点数据的结果:

enter image description here

也许您也需要这些中心,C API 为您提供了返回它们的选项,但没有检查它是如何工作的。

关于c - openCV k-means 调用断言失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27381241/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com