Генерация случайных чисел
Материал из CompVision
Содержание |
cvRNG
Инициализирует начальное состояние генератора случайных чисел.
CvRNG cvRNG(int64 seed=-1);
Параметр:seed – 64-битное значение для инициализации генератора случайных чисел.
Функция cvRNG() инициализирует генератор случайных чисел и возвращаетс состояние (RNG). Указатель на состояние RNG может быть передан функциям cvRandInt(), cvRandReal() and cvRandArr(). В данной реализации используется генератор "умножение с переносом".
cvRandArr
Заполняет массив случайными значениями и обновляет состояние RNG.
void cvRandArr(CvRNG* rng, CvArr* arr, int dist_type, CvScalar param1, CvScalar param2);
Параметры:
- rng - состояние RNG, инициализированное cvRNG ()
- arr - выходной массив
- dist_type -
Тип распределения
o CV_RAND_UNI - однородное распределение
o CV_RAND_NORMAL - нормальное или Гауссовское распределение
* param1 - первый параметр распределения. В случае однородного распределения это - нижняя (включительно) граница диапазона случайных чисел. В случае нормального распределения это - среднее значение случайных чисел.
* param2 - второй параметр распределения. В случае однородного распределения это - верхняя граница (исключительно) диапазона случайных чисел. В случае нормального распределения это - стандартное отклонение случайных чисел.
Функция cvRandArr () заполняет массив однородно или нормально распределенными случайными числами. В примере ниже, функция используется, чтобы добавить, несколько случайных чисел (нормальное распределение) с плавающей запятой в случайные ячейки двумерного массива.
/* сделаем на картинке шум */ CvRNG rng_state = cvRNG(0xffffffff); int i, pointCount = 1000; /* Выделяем массив координат точек */ CvMat* locations = cvCreateMat( pointCount, 1, CV_32SC2 ); /* arr значения случайных точек */ CvMat* values = cvCreateMat( pointCount, 1, CV_32FC1 ); CvSize size = cvGetSize( noisy_screen ); cvRandInit( &rng_state, 0, 1, /* используем параметры-заглушки, которые настроим позже */ 0xffffffff /* используем фиксированное значение для инициализации */, CV_RAND_UNI /* тип распределения - равномерное */ ); /* инициализация размещений */ cvRandArr( &rng_state, locations, CV_RAND_UNI, cvScalar(0,0,0,0), cvScalar(size.width,size.height,0,0) ); /* откорректируем RNG для выдачи нормально распределенных значений */ rng_state.disttype = CV_RAND_NORMAL; cvRandSetRange( &rng_state, 30 /* отклонение */, 100 /* средняя яркость точки */, -1 /* инициализировать все измерения */ ); /* генерировать значения */ cvRandArr( &rng_state, values, CV_RAND_NORMAL, cvRealScalar(100), // средняя интенсивность cvRealScalar(30) // отклонение интенсивности ); /* ставим точки */ for( i = 0; i < pointCount; i++ ) { CvPoint pt = *(CvPoint*)cvPtr1D( locations, i, 0 ); float value = *(float*)cvPtr1D( values, i, 0 ); *((float*)cvPtr2D( noisy_screen, pt.y, pt.x, 0 )) += value; } /* освобождаем временные массивы */ cvReleaseMat( &locations ); cvReleaseMat( &values ); /* RNG не нужно освобождать*/
cvRandInt
Возвращает 32-битное беззнаковое целое и обновляет состояние RNG.
unsigned cvRandInt(CvRNG* rng)
Параметр: rng - состояние RNG, инициализированное RandInit и, (необязательно) настроенный RandSetRange (хотя, последняя функция не затрагивает результат),
Функция cvRandInt () случайное (равномерное распределние) 32-разрядное целое число без знака и обновляет состояние RNG. Аналог функции rand() с тем различием, что rand() может генерировать числа от 0 до RAND_MAX. А RAND_MAX в зависимости от платформы может быть 2^16 или 2^32. cvRandInt() всегда работает с диапазоном 2^32.
Функция полезна для генерации скалярных случайных чисел, таких как точки, размеры патчей, индексы таблицы, и т.д., где целые числа определенного диапазона могут быть сгенерированы, используя операцию %. Вот пример от предыдущего обсуждения, перезаписанный, с использованием cvRandInt ():
/* цель та-же что и предыдущего проекта */ CvRNG rnggstate = cvRNG(0xffffffff); int i, pointCount = 1000; /* ... - никаких массивов здест не выделяется */ CvSize size = cvGetSize( noisygscreen ); /* сделаем буфер для нормально распределенных чисел для уменьшения call overhead */ #define bufferSize 16 float normalValueBuffer[bufferSize]; CvMat normalValueMat = cvMat( bufferSize, 1, CVg32F, normalValueBuffer ); int valuesLeft = 0; for( i = 0; i < pointCount; i++ ) { CvPoint pt; /* generate random point */ pt.x = cvRandInt( &rnggstate ) % size.width; pt.y = cvRandInt( &rnggstate ) % size.height; if( valuesLeft <= 0 ) { /* если буфер пуст - заполняем его нормально распределенными значениями */ cvRandArr( &rnggstate, &normalValueMat, CV\_RAND\_NORMAL, cvRealScalar(100), cvRealScalar(30) ); valuesLeft = bufferSize; } *((float*)cvPtr2D( noisygscreen, pt.y, pt.x, 0 ) = normalValueBuffer[--valuesLeft]; } /* здесь не нужно освобождать normalValueMat т.к. и заголовок матрицы и ее данные находятся в стеке. Это обычный и эффективный метод работы с маленькими массивами. */
cvRandReal
Возвращает число с плавающей точкой в диапазоне от 0 до 1 (не включая единицу) и обновляет состояние RNG.
double cvRandReal(CvRNG* rng);
Параметр: состояние RNG, инициализированное cvRNG ().