我一直在为返回的集群向量获取垃圾值,所以很明显这是垃圾输入/垃圾输出类型问题。此外,该算法运行速度比我认为应该如此庞大的数据集。
在下面的代码中,直接memcpy只是我最近尝试以正确的格式获取输入数据,我花了一些时间使用内置的OpenCV函数,但是当你的基类型是CV_32FC(49)时这很难。
OpenCV 1.1的KMeans算法能否支持这种高维分析?
有人知道从图像复制到K-Means输入矩阵的正确方法吗?
有人能指出我可以使用的免费非GPL KMeans算法吗?
这不是最好的代码,因为我只是想让事情立即发挥作用:
std::vector<int> DoKMeans(std::vector<IplImage *>& chunks){
// the size of one image patch, CELL_SIZE = 7
int chunk_size = CELL_SIZE*CELL_SIZE*sizeof(float);
// create the input data, CV_32FC(49) is 7x7 float object (I think)
CvMat* data = cvCreateMat(chunks.size(),1,CV_32FC(49) );
// Create a temporary vector to hold our data
// we'll copy into the matrix for KMeans
int rdsize = chunks.size()*CELL_SIZE*CELL_SIZE;
float * rawdata = new float[rdsize];
// Go through each image chunk and copy the
// pixel values into the raw data array.
vector<IplImage*>::iterator iter;
int k = 0;
for( iter = chunks.begin(); iter != chunks.end(); ++iter )
{
for( int i =0; i < CELL_SIZE; i++)
{
for( int j=0; j < CELL_SIZE; j++)
{
CvScalar val;
val = cvGet2D(*iter,i,j);
rawdata[k] = (float)val.val[0];
k++;
}
}
}
// Copy the data into the CvMat for KMeans
// I have tried various methods, but this is just the latest.
memcpy( data->data.ptr,rawdata,rdsize*sizeof(float));
// Create the output array
CvMat* results = cvCreateMat(chunks.size(),1,CV_32SC1);
// Do KMeans
int r = cvKMeans2(data, 128,results, cvTermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 1000, 0.1));
// Copy the grouping information to our output vector
vector<int> retVal;
for( int y = 0; y < chunks.size(); y++ )
{
CvScalar cvs = cvGet1D(results, y);
int g = (int)cvs.val[0];
retVal.push_back(g);
}
return retVal;}
提前致谢!
答案 0 :(得分:0)
虽然我不熟悉“功能包”,您是否考虑过使用角点探测器和SIFT等功能点?
答案 1 :(得分:-1)
您可能希望查看http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster/其他开源群集程序包。
使用像这样的memcpy似乎很可疑,因为当你这样做时:
int rdsize = chunks.size()*CELL_SIZE*CELL_SIZE;
如果CELL_SIZE和chunks.size()非常大,那么你在rdsize中创建了一些大的东西。如果这大于最大可存储整数,则可能会出现问题。
你想在这个功能中改变“块”吗? 我猜你没有,因为这是一个K-means问题。
所以尝试通过引用传递给const。 (一般来说,这就是你想要做的事情)
所以代替:
std::vector<int> DoKMeans(std::vector<IplImage *>& chunks)
它将是:
std::vector<int> DoKMeans(const std::vector<IplImage *>& chunks)
同样在这种情况下,最好使用static_cast而不是旧的c样式转换。 (例如static_cast(变量)而不是(float)变量)。
您也可以删除“rawdata”:
float * rawdata = new float[rdsize];
可以删除:
delete[] rawdata;
否则你可能会在这里泄漏记忆。