fmll_som * fmll_som_init(const unsigned * N, const unsigned map_dim, const unsigned dim, double (* distance_w)(const double *, const double *, const unsigned), double (* distance)(const double *, const double *, const unsigned)) { int v; unsigned u, num, * tN; double ** w, ** coord; fmll_som * som = NULL; fmll_try; fmll_throw_null(som = fmll_alloc(sizeof(fmll_som), 1, 1)); som->w = som->coord = NULL; som->N = NULL; for(u = 0, num = 1; u < map_dim; u++) num *= N[u]; fmll_throw_if(! num); fmll_throw_null(w = som->w = (double **) fmll_alloc(sizeof(double), 2, num, dim)); fmll_throw_null(coord = som->coord = (double **) fmll_alloc(sizeof(double), 2, num, map_dim)); fmll_throw_null(tN = som->N = fmll_alloc(sizeof(unsigned), 1, map_dim)); som->num = num; som->map_dim = map_dim; som->dim = dim; som->distance_w = distance_w; som->distance = distance; memset(tN, 0, map_dim * sizeof(unsigned)); fmll_throw_if(fmll_math_matrix_init_fill(w, 0, num, dim)); for(u = 0; u < num; u++) { for(v = 0; v < map_dim; v++) coord[u][v] = tN[v]; for(v = map_dim - 1; v >= 0; v--) { if(++ tN[v] < N[v]) break; tN[v] = 0; } } memcpy(tN, N, map_dim * sizeof(unsigned)); fmll_catch; fmll_som_destroy(som); som = NULL; fmll_finally; return som; }
fmll_som * fmll_som_load(const char * fname_prefix, double (* distance_w)(const double *, const double *, const unsigned), double (* distance)(const double *, const double *, const unsigned)) { char node_name[4096]; int map_dim, dim; unsigned u, v, num, * N = NULL; double ** w; fmll_som * som = NULL; mxml_node_t * sub_sub_node, * sub_node, * node, * content_node, * main_node = NULL; fmll_try; fmll_throw_if(xml_load(fname_prefix, TYPE_SOM, & main_node, & content_node)); fmll_throw_if(xml_get_int(content_node, "map_dim", & map_dim)); fmll_throw_if(xml_get_int(content_node, "dim", & dim)); fmll_throw_null(N = fmll_alloc(sizeof(unsigned), 1, map_dim)); fmll_throw_null(node = mxmlFindElement(content_node, content_node, "N", NULL, NULL, MXML_DESCEND_FIRST)); for(u = 0, sub_node = mxmlFindElement(node, node, NULL, NULL, NULL, MXML_DESCEND_FIRST); u < map_dim; u++) { fmll_throw_null(sub_node); N[u] = sub_node->child->value.integer; sub_node = mxmlFindElement(sub_node, node, NULL, NULL, NULL, MXML_DESCEND); } fmll_throw_null(som = fmll_som_init(N, map_dim, dim, distance_w, distance)); fmll_throw_null(node = mxmlFindElement(content_node, content_node, "W", NULL, NULL, MXML_DESCEND_FIRST)); w = som->w; num = som->num; for(u = 0; u < num; u++) { sprintf(node_name, "w_%u", u); fmll_throw_null(sub_node = mxmlFindElement(node, node, node_name, NULL, NULL, MXML_DESCEND_FIRST)); for(v = 0, sub_sub_node = mxmlFindElement(sub_node, sub_node, NULL, NULL, NULL, MXML_DESCEND_FIRST); v < dim; v++) { w[u][v] = sub_sub_node->child->value.real; sub_sub_node = mxmlFindElement(sub_sub_node, sub_node, NULL, NULL, NULL, MXML_DESCEND); } } fmll_catch; fmll_som_destroy(som); som = NULL; fmll_finally; fmll_free(N); xml_destroy(main_node); return som; }
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; }