int fmll_som_so_kohonen(fmll_som * som, const double ** vec, const unsigned vec_num, const double beta_0, double (* next_beta)(const double), const double gamma_mult, const double gamma_add, double (* neighbor)(const fmll_som *, const double, const double, const unsigned, const unsigned)) { int ret = 0; const unsigned num = som->num, dim = som->dim; unsigned u, v, q, index_winner; double beta_gamma, beta = beta_0, ** w = som->w; fmll_try; fmll_throw_if(beta_0 < 0 || beta_0 > 1); fmll_throw_if(neighbor == & fmll_som_neighbor_radial && (gamma_mult < 0 || gamma_mult > 1)); fmll_throw_if(neighbor == & fmll_som_neighbor_radial && (gamma_add < 0)); while(beta < 1.0000001) { fmll_print("Self - organization: beta == %.7lf\n", beta); for(u = 0; u < vec_num; u++) { index_winner = fmll_som_run(som, vec[u]); if(neighbor == & fmll_som_neighbor_wta) for(q = 0; q < dim; q++) w[index_winner][q] += beta * (vec[u][q] - w[index_winner][q]); else for(v = 0; v < num; v++) { beta_gamma = beta * neighbor(som, gamma_mult, gamma_add, index_winner, v); for(q = 0; q < dim; q++) w[v][q] += beta_gamma * (vec[u][q] - w[v][q]); } } beta = (* next_beta)(beta); } fmll_catch; ret = -1; fmll_finally; return ret; }
int main(const int argc, const char * argv[]) { const unsigned base = 256 * 256 * 256; unsigned u, v, q, cur, index_winner, N[4]; double param[2], ** vec; IplImage * src, * dst_1, * dst_2, * dst_3, * dst_4; CvSize size; CvScalar pixel; fmll_random * rnd; fmll_som * som; /* ############################################################################ */ if(argc != 6) { /* У C90 "проблемы" с максимальной длиной строки кода */ printf("\nДемонстрация самоорганизующейся карты.\n\n"); printf("Запуск программы:\n\n"); printf("ex_som IMAGE_SRC IMAGE_1 IMAGE_2 IMAGE_3 IMAGE_4\n\n"); printf("Где:\n\n"); printf("\tIMAGE_SRC - путь и имя файла с исходным изображением;\n"); printf("\tIMAGE_1 - путь и имя файла, в который будет сохранено первое результирующее изображение;\n"); printf("\tIMAGE_2 - путь и имя файла, в который будет сохранено второе результирующее изображение;\n"); printf("\tIMAGE_3 - путь и имя файла, в который будет сохранено третье результирующее изображение;\n"); printf("\tIMAGE_4 - путь и имя файла, в который будет сохранено четвертое результирующее изображение.\n\n"); return -1; } /* ############################################################################ */ src = cvLoadImage(argv[1], CV_LOAD_IMAGE_COLOR); size = cvGetSize(src); dst_1 = cvCreateImage(size, IPL_DEPTH_8U, 3); dst_2 = cvCreateImage(size, IPL_DEPTH_8U, 3); dst_3 = cvCreateImage(size, IPL_DEPTH_8U, 3); dst_4 = cvCreateImage(size, IPL_DEPTH_8U, 3); /* N[0] = 5; N[1] = 5; N[2] = 5; N[3] = 5; */ N[0] = 4; N[1] = 3; N[2] = 3; N[3] = 3; vec = (double **) fmll_alloc(sizeof(double), 2, size.height * size.width, 3); for(v = 0, q = 0; v < size.height; v++) for(u = 0; u < size.width; u++, q++) { pixel = cvGet2D(src, v, u); vec[q][0] = pixel.val[0]; vec[q][1] = pixel.val[1]; vec[q][2] = pixel.val[2]; } param[0] = 0; param[1] = 256; rnd = fmll_random_init(FMLL_RANDOM_ALGORITHM_LCG, FMLL_RANDOM_DISTRIBUTION_UNIFORM, param, time(NULL)); som = fmll_som_init(N, 4, 3, & fmll_distance_euclid, & fmll_distance_square_euclid); fmll_som_weight_init_random(som, rnd); fmll_som_so_kohonen(som, (const double **) vec, size.height * size.width, 0, & fmll_timing_next_beta_step_plus_0_1, 0.8, 0.002, & fmll_som_neighbor_wta); for(v = 0; v < som->num; v++) printf("%u = [%f, %f, %f]\n", v, som->w[v][0], som->w[v][1], som->w[v][2]); for(v = 0, q = 0; v < size.height; v++) for(u = 0; u < size.width; u++, q++) { index_winner = fmll_som_run(som, vec[q]); pixel.val[0] = som->w[index_winner][0]; pixel.val[1] = som->w[index_winner][1]; pixel.val[2] = som->w[index_winner][2]; cvSet2D(dst_1, v, u, pixel); cur = (base / ((double) som->num + 7)) * index_winner; pixel.val[0] = (cur & 0xFF0000) >> 16; pixel.val[1] = (cur & 0xFF00) >> 8; pixel.val[2] = cur & 0xFF; cvSet2D(dst_2, v, u, pixel); } fmll_som_save(som, "som"); fmll_som_destroy(som); som = NULL; if( (som = fmll_som_load("som", & fmll_distance_euclid, & fmll_distance_euclid)) != NULL ) { fmll_som_save(som, "som_2"); for(v = 0, q = 0; v < size.height; v++) for(u = 0; u < size.width; u++, q++) { index_winner = fmll_som_run(som, vec[q]); pixel.val[0] = som->w[index_winner][0]; pixel.val[1] = som->w[index_winner][1]; pixel.val[2] = som->w[index_winner][2]; cvSet2D(dst_3, v, u, pixel); cur = (base / (double) som->num) * index_winner; pixel.val[0] = (cur & 0xFF0000) >> 16; pixel.val[1] = (cur & 0xFF00) >> 8; pixel.val[2] = cur & 0xFF; cvSet2D(dst_4, v, u, pixel); } }
Mat Kohonen::getFrame(Mat parFrame) { int map_dim=2;//размерность карты unsigned N[map_dim]; unsigned u, v, q, index_winner; N[0] = 7;//количество нейронов в каждом слое N[1] = 7; //определение константы для вывода каждого класса определенным цветом uint32_t A=1; for (int i=0;i<map_dim; i++) { A*=N[i];//подсчет общего числа нейрнов } A=0xFFFFFF/A; fmll_som * som; Mat resultFrame; resultFrame.create(parFrame.rows, parFrame.cols,CV_8UC3); Mat frameFromUnsigned; frameFromUnsigned.create(parFrame.rows, parFrame.cols,CV_32S); Vec3b pixel; double ** vec; //инициализация векторного пространства значениями яркости изображения vec = (double **) fmll_alloc(sizeof(double), 2, parFrame.rows * parFrame.cols, 3); som = fmll_som_load(somFilename.c_str(),& fmll_distance_euclid, & fmll_distance_euclid); for(v = 0, q = 0; v < parFrame.rows; v++) for(u = 0; u < parFrame.cols; u++, q++) { pixel=parFrame.at<Vec3b>(v,u); vec[q][0] = pixel[0] / 255.; vec[q][1] = pixel[1] / 255.; vec[q][2] = pixel[2] / 255.; } //загрузка карты из xml if(som == NULL) { fmll_random * rnd; double param[2]; param[0] = 0; param[1] = 0.01; //инициализация датчика случайных чисел rnd = fmll_random_init(FMLL_RANDOM_ALGORITHM_LCG, FMLL_RANDOM_DISTRIBUTION_UNIFORM, param, time(NULL)); //иницилизация нейронной карты som = fmll_som_init(N, map_dim, 3, & fmll_distance_euclid, & fmll_distance_euclid);//(1)расстояние между векторами, 2)расстояние между нейронами.(2)не исп.,т.к. алгоритм WTA) //иницилизация весов синапсов нейронов карты случайными числами fmll_som_weight_init_random(som, rnd); cout<<"don't load"<<endl; //обучение нейронной карты fmll_som_so_kohonen(som, (const double **) vec, parFrame.rows * parFrame.cols, 0.3, & fmll_timing_next_beta_step_plus_0_1, 0.8, 0.002, & fmll_som_neighbor_wta); if (fmll_som_save(som,somFilename.c_str())!=0) { cout<<"Ошибка сохранения Som в Xml"<<endl; } fmll_random_destroy(rnd); } for(v = 0, q = 0; v < parFrame.rows; v++) { for(u = 0; u < parFrame.cols; u++, q++) { index_winner = fmll_som_run(som, vec[q]); uint32_t color=A*index_winner; pixel[0]=0x0000FF&color; pixel[1]=(0x00FF00&color)>>8; pixel[2]=(0xFF0000&color)>>16; //pixel[0] = som->w[index_winner][0]; //pixel[1] = som->w[index_winner][1]; //pixel[2] = som->w[index_winner][2]; resultFrame.at<Vec3b>(v,u)=pixel; frameFromUnsigned.at<uint32_t>(v,u)=color; //cout<<color<<" "; } //cout<<endl; } fmll_free(vec); imshow( "kohonen", resultFrame ); fmll_som_destroy(som); return frameFromUnsigned; }