Merge pull request #2744 from jet47:kmeans-fix
This commit is contained in:
commit
118b27f5b4
@ -2691,16 +2691,18 @@ double cv::kmeans( InputArray _data, int K,
|
||||
int flags, OutputArray _centers )
|
||||
{
|
||||
const int SPP_TRIALS = 3;
|
||||
Mat data = _data.getMat();
|
||||
bool isrow = data.rows == 1 && data.channels() > 1;
|
||||
int N = !isrow ? data.rows : data.cols;
|
||||
int dims = (!isrow ? data.cols : 1)*data.channels();
|
||||
int type = data.depth();
|
||||
Mat data0 = _data.getMat();
|
||||
bool isrow = data0.rows == 1 && data0.channels() > 1;
|
||||
int N = !isrow ? data0.rows : data0.cols;
|
||||
int dims = (!isrow ? data0.cols : 1)*data0.channels();
|
||||
int type = data0.depth();
|
||||
|
||||
attempts = std::max(attempts, 1);
|
||||
CV_Assert( data.dims <= 2 && type == CV_32F && K > 0 );
|
||||
CV_Assert( data0.dims <= 2 && type == CV_32F && K > 0 );
|
||||
CV_Assert( N >= K );
|
||||
|
||||
Mat data(N, dims, CV_32F, data0.data, isrow ? dims * sizeof(float) : static_cast<size_t>(data0.step));
|
||||
|
||||
_bestLabels.create(N, 1, CV_32S, -1, true);
|
||||
|
||||
Mat _labels, best_labels = _bestLabels.getMat();
|
||||
|
@ -2512,6 +2512,15 @@ TEST(Core_SVD, flt)
|
||||
|
||||
// TODO: eigenvv, invsqrt, cbrt, fastarctan, (round, floor, ceil(?)),
|
||||
|
||||
enum
|
||||
{
|
||||
MAT_N_DIM_C1,
|
||||
MAT_N_1_CDIM,
|
||||
MAT_1_N_CDIM,
|
||||
MAT_N_DIM_C1_NONCONT,
|
||||
MAT_N_1_CDIM_NONCONT,
|
||||
VECTOR
|
||||
};
|
||||
|
||||
class CV_KMeansSingularTest : public cvtest::BaseTest
|
||||
{
|
||||
@ -2519,7 +2528,7 @@ public:
|
||||
CV_KMeansSingularTest() {}
|
||||
~CV_KMeansSingularTest() {}
|
||||
protected:
|
||||
void run(int)
|
||||
void run(int inVariant)
|
||||
{
|
||||
int i, iter = 0, N = 0, N0 = 0, K = 0, dims = 0;
|
||||
Mat labels;
|
||||
@ -2531,20 +2540,70 @@ protected:
|
||||
for( iter = 0; iter < maxIter; iter++ )
|
||||
{
|
||||
ts->update_context(this, iter, true);
|
||||
dims = rng.uniform(1, MAX_DIM+1);
|
||||
dims = rng.uniform(inVariant == MAT_1_N_CDIM ? 2 : 1, MAX_DIM+1);
|
||||
N = rng.uniform(1, MAX_POINTS+1);
|
||||
N0 = rng.uniform(1, MAX(N/10, 2));
|
||||
K = rng.uniform(1, N+1);
|
||||
|
||||
Mat data0(N0, dims, CV_32F);
|
||||
rng.fill(data0, RNG::UNIFORM, -1, 1);
|
||||
if (inVariant == VECTOR)
|
||||
{
|
||||
dims = 2;
|
||||
|
||||
Mat data(N, dims, CV_32F);
|
||||
for( i = 0; i < N; i++ )
|
||||
data0.row(rng.uniform(0, N0)).copyTo(data.row(i));
|
||||
std::vector<cv::Point2f> data0(N0);
|
||||
rng.fill(data0, RNG::UNIFORM, -1, 1);
|
||||
|
||||
kmeans(data, K, labels, TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS, 30, 0),
|
||||
5, KMEANS_PP_CENTERS);
|
||||
std::vector<cv::Point2f> data(N);
|
||||
for( i = 0; i < N; i++ )
|
||||
data[i] = data0[rng.uniform(0, N0)];
|
||||
|
||||
kmeans(data, K, labels, TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS, 30, 0),
|
||||
5, KMEANS_PP_CENTERS);
|
||||
}
|
||||
else
|
||||
{
|
||||
Mat data0(N0, dims, CV_32F);
|
||||
rng.fill(data0, RNG::UNIFORM, -1, 1);
|
||||
|
||||
Mat data;
|
||||
|
||||
switch (inVariant)
|
||||
{
|
||||
case MAT_N_DIM_C1:
|
||||
data.create(N, dims, CV_32F);
|
||||
for( i = 0; i < N; i++ )
|
||||
data0.row(rng.uniform(0, N0)).copyTo(data.row(i));
|
||||
break;
|
||||
|
||||
case MAT_N_1_CDIM:
|
||||
data.create(N, 1, CV_32FC(dims));
|
||||
for( i = 0; i < N; i++ )
|
||||
memcpy(data.ptr(i), data0.ptr(rng.uniform(0, N0)), dims * sizeof(float));
|
||||
break;
|
||||
|
||||
case MAT_1_N_CDIM:
|
||||
data.create(1, N, CV_32FC(dims));
|
||||
for( i = 0; i < N; i++ )
|
||||
memcpy(data.data + i * dims * sizeof(float), data0.ptr(rng.uniform(0, N0)), dims * sizeof(float));
|
||||
break;
|
||||
|
||||
case MAT_N_DIM_C1_NONCONT:
|
||||
data.create(N, dims + 5, CV_32F);
|
||||
data = data(Range(0, N), Range(0, dims));
|
||||
for( i = 0; i < N; i++ )
|
||||
data0.row(rng.uniform(0, N0)).copyTo(data.row(i));
|
||||
break;
|
||||
|
||||
case MAT_N_1_CDIM_NONCONT:
|
||||
data.create(N, 3, CV_32FC(dims));
|
||||
data = data.colRange(0, 1);
|
||||
for( i = 0; i < N; i++ )
|
||||
memcpy(data.ptr(i), data0.ptr(rng.uniform(0, N0)), dims * sizeof(float));
|
||||
break;
|
||||
}
|
||||
|
||||
kmeans(data, K, labels, TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS, 30, 0),
|
||||
5, KMEANS_PP_CENTERS);
|
||||
}
|
||||
|
||||
Mat hist(K, 1, CV_32S, Scalar(0));
|
||||
for( i = 0; i < N; i++ )
|
||||
@ -2568,7 +2627,19 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
TEST(Core_KMeans, singular) { CV_KMeansSingularTest test; test.safe_run(); }
|
||||
TEST(Core_KMeans, singular) { CV_KMeansSingularTest test; test.safe_run(MAT_N_DIM_C1); }
|
||||
|
||||
CV_ENUM(KMeansInputVariant, MAT_N_DIM_C1, MAT_N_1_CDIM, MAT_1_N_CDIM, MAT_N_DIM_C1_NONCONT, MAT_N_1_CDIM_NONCONT, VECTOR)
|
||||
|
||||
typedef testing::TestWithParam<KMeansInputVariant> Core_KMeans_InputVariants;
|
||||
|
||||
TEST_P(Core_KMeans_InputVariants, singular)
|
||||
{
|
||||
CV_KMeansSingularTest test;
|
||||
test.safe_run(GetParam());
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(AllVariants, Core_KMeans_InputVariants, KMeansInputVariant::all());
|
||||
|
||||
TEST(CovariationMatrixVectorOfMat, accuracy)
|
||||
{
|
||||
|
@ -33,7 +33,7 @@ int main( int /*argc*/, char** /*argv*/ )
|
||||
{
|
||||
int k, clusterCount = rng.uniform(2, MAX_CLUSTERS+1);
|
||||
int i, sampleCount = rng.uniform(1, 1001);
|
||||
Mat points(sampleCount, 2, CV_32F), labels;
|
||||
Mat points(sampleCount, 1, CV_32FC2), labels;
|
||||
|
||||
clusterCount = MIN(clusterCount, sampleCount);
|
||||
Mat centers;
|
||||
|
Loading…
x
Reference in New Issue
Block a user