2010-06-27 3 views
2

Я пытаюсь написать пакет функций системы распознавания образов. Один шаг в алгоритме состоит в том, чтобы взять большее количество небольших патчей изображения (например, 7x7 или 11x11 пикселей) и попытаться сгруппировать их в группы, которые выглядят одинаково. Я получаю свои патчи с изображения, превращаю их в плагины с плавающей запятой в сером цвете, а затем пытаюсь заставить cvKMeans2 сгруппировать их для меня. Я думаю, что у меня возникают проблемы с форматированием входных данных, так что KMeans2 возвращает когерентные результаты. Раньше я использовал KMeans для кластеризации 2D и 3D, но кластер 49D, похоже, отличается от другого зверя.OpenCV 1.1 Кластеризация K-сред в высокоразмерных пространствах

Я продолжаю получать значения мусора для вектора возвращенных кластеров, так что, очевидно, это проблема с мусором/мусором. Кроме того, алгоритм работает быстрее, чем я полагаю, для такого огромного набора данных.

В приведенном ниже коде прямая memcpy - это только моя последняя попытка получить входные данные в правильном формате, я потратил некоторое время на использование встроенных функций OpenCV, но это сложно, когда ваш базовый тип - CV_32FC (49) ,

Может ли алгоритм KMeans OpenCV 1.1 поддерживать этот вид анализа высокого размера?

Кто-нибудь знает правильный метод копирования из изображений в матрицу ввода 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

Я наткнулся на эту статью и попробовал ее, так как она довольно похожа на мою проблему, и парень был наименее полезен. http://tech.groups.yahoo.com/group/OpenCV/message/59468 Это не сработало, поэтому я продолжу пробовать другие вещи. Я нахожусь в точке, где я буду искать альтернативный алгоритм. – kscottz

ответ

-1

Возможно, вы захотите зарегистрироваться http://bonsai.ims.u-tokyo.ac.jp/~mdehoon/software/cluster/ для другого кластера с открытым исходным кодом.

Использование тетсру, как это кажется подозреваемым, потому что когда вы делаете:

int rdsize = chunks.size()*CELL_SIZE*CELL_SIZE; 

Если CELL_SIZE и chunks.size() очень велики, вы создаете что-то большое в rdsize. Если это больше, чем наибольшее сохраняемое целое число, у вас может быть проблема.

Вы хотите изменить «куски» в этой функции? Я предполагаю, что вы не так, как это проблема K-mean.

Так что попробуйте передать ссылку на 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; 

иначе может быть утечка памяти здесь.

+0

Shuttle87, Хороший улов на целочисленном переполнении на rdsize. Сейчас это не проблема, но это будет позже. Что касается других небольших ошибок (т. Е. Не очистки, const-коррекции), я просто пытаюсь понять, работает ли это или нет, я обязательно переписал бы/очистил все, когда закончите. Я рассмотрю этот другой пакет кластеризации, который вы указали. – kscottz

+0

Мне просто пришло в голову, что если проблема с хранением данных является проблемой, это может также быть проблемой внутри внутренних частей библиотеки, которую вы используете. Возможно, есть некоторая ценность в публикации этого места в OpenCV, так как их библиотеки могут не поддерживать размер данных, которые вы используете. – shuttle87

+0

Я только вижу, что cvKMeans выполняет до трех измерений, и способ, которым вам нужно упаковывать данные, действительно неудобен. Я бы предположил, что входная матрица будет линейным представлением того, что sXd, где s - количество выборок, а d - размер точки. Во всяком случае, я пробовал около десяти разных подходов и ничего не работал, поэтому я использую алгоритм GPL KMeans, который я нашел в Интернете, и, похоже, он отлично работает. Я хотел бы найти что-то с более открытой лицензией. Я использую openCV некоторое время, но я не знаю открытого форума для вопросов. – kscottz

0

Хотя я не знаком с «сумкой функций», вы считали, что используете такие функции, как угловые детекторы и SIFT?

 Смежные вопросы

  • Нет связанных вопросов^_^