typename DownhillSimplexMethod< DIM >::Converged DownhillSimplexMethod< DIM >::optimize( const ParamsT& initial ) { assert( m_refl > 0.0 ); assert( m_exp > 1.0 ); assert( m_exp > m_refl ); assert( 0 < m_contr && m_contr < 1 ); assert( 0 < m_shri && m_shri < 1 ); assert( m_initFactor > 0.0 ); // Prepare optimization m_iterations = 0; createInitials( initial ); Converged conv = CONVERGED_NO; Step next = STEP_START; while( next != STEP_EXIT ) { switch( next ) { case STEP_START: order(); conv = converged(); if( conv != CONVERGED_NO ) { next = STEP_EXIT; break; } ++m_iterations; centroid(); next = STEP_REFLECTION; break; case STEP_REFLECTION: next = reflection(); break; case STEP_EXPANSION: next = expansion(); break; case STEP_CONTRACTION: next = contraction(); break; case STEP_SHRINKAGE: next = shrinkage(); break; default: std::cerr << "Undefined control flow!"; next = STEP_EXIT; break; } } return conv; }
int bm3d (char* const infile, // name of input file char* const kind, // kind of shrinkage (ht, wnr, avg) int const block_size, // size of internal processed blocks int const block_step, // step size between blocks int const sigma, // standard deviation of noise int const max_blocks, // maximum number of block in one 3D array int const h_search, // horizontal width of search window int const v_search, // vertical width of search window double const th_2d, // threshold for the 2D transformation double const tau_match, // match value for block-matching double const th_3d, // threshold for the 3D transformtaion int const block_marking) { // indicates the action of block marking png_img img; // noisy input image png_img org; // temporary image for marking the blocks FILE* log = 0; // log-file for all kinds of messages char logfile[30]; // name of the log-file including path char path[30]; // universally used path-name char prefix[20]; // universally used prefix-name char pure_name[30]; int h_search_true; // true value of horizontal search window size after validation int v_search_true; // true value of vertical search window size after validation list_t y_list = 0; // list of groups of the y-channel list_t u_list = 0; // list of groups of the u-channel list_t v_list = 0; // list of groups of the v-channel clock_t start, end; // time variables for counting durations double time; // ---------------------------------------------------------------------- // OPEN LOG-FILE FOR WRITING // ---------------------------------------------------------------------- // obtain filename without path and extension if (exclude_extension(infile, pure_name) != 0) { return 1; } sprintf (logfile, "log/log_%s_%s[%d].txt", pure_name, kind, sigma); log = fopen (logfile, "a"); if (log == NULL) { generate_error ("Unable to open log-file for writing ..."); return 1; } // ---------------------------------------------------------------------- // INPUT READING AND VALIDATION // ---------------------------------------------------------------------- // read input image if (png_read(&img, infile) != 0) { return 1; } // read temporary image if (png_read(&org, infile) != 0) { return 1; } // control color type if (img.color != PNG_COLOR_TYPE_RGB) { generate_error ("Wrong color type..."); return 1; } // control number of channels if (img.channels != 3) { generate_error ("Wrong number of channels..."); return 1; } // ---------------------------------------------------------------------- // PARAMETER VALIDATION // ---------------------------------------------------------------------- // verify kind of shrinkage if (strcmp(kind, "none") && strcmp(kind, "avg") && strcmp(kind, "ht") && strcmp(kind, "wnr")) { generate_error ("Unknown kind of shrinkage..."); return 1; } // verify block size if ((block_size!=7) && (block_size!=9) && (block_size!=11) && (block_size!=13)) { generate_error ("Wrong value for block size...\nValid values: 7, 9, 11, 13"); return 1; } // verify block step if ((block_step<5) || (block_step>15)) { generate_error ("Block step is out of valid Range...\nValid range: 5..15"); return 1; } // control search window dimensions h_search_true = ((h_search > img.width) || (h_search <= 0)) ? img.width : h_search; v_search_true = ((v_search > img.height) || (v_search <= 0)) ? img.height : v_search; // ---------------------------------------------------------------------- // PRINTING OF STATUS INFORMATION // ---------------------------------------------------------------------- fprintf (log, "-------------------------------------------------------------------------\n"); fprintf (log, "-------------------------------------------------------------------------\n"); fprintf (log, "[INFO] ... image dimensions: %dx%d\n", img.width, img.height); fprintf (log, "[INFO] ... kind of shrinkage: %s\n", kind); fprintf (log, "[INFO] ... block size: %d\n", block_size); fprintf (log, "[INFO] ... block step: %d\n", block_step); fprintf (log, "[INFO] ... sigma: %d\n", sigma); fprintf (log, "[INFO] ... maximum number of blocks: %d\n", max_blocks); fprintf (log, "[INFO] ... horizontal search window size: %d\n", h_search_true); fprintf (log, "[INFO] ... vertical search window size: %d\n", v_search_true); fprintf (log, "[INFO] ... threshold 2D: %f\n", th_2d); fprintf (log, "[INFO] ... tau-match 2D: %f\n", tau_match); fprintf (log, "[INFO] ... threshold 3D: %f\n", th_3d); fprintf (log, "[INFO] ... block marking: %s\n\n", block_marking ? "yes" : "no"); // ---------------------------------------------------------------------- // COLORSPACE CONVERSION & WRITEBACK // ---------------------------------------------------------------------- printf ("[INFO] ... launch of color conversion...\n"); rgb2yuv (&img); // write output image if (png_write(&img, "img/yuv/", "noisy_yuv", 0) != 0) { return 1; } printf ("[INFO] ... end of color conversion...\n\n"); fprintf (log, "[INFO] ... converted colorspace of input image to YUV...\n\n"); // ---------------------------------------------------------------------- // IMAGE-TO-ARRAY CONVERSION // ---------------------------------------------------------------------- printf ("[INFO] ... launch of printing image as three separate value arrays...\n"); printf ("[INFO] ... ... luminance channel...\n"); img2array (&img, 0, "img/", "y_channel_before"); printf ("[INFO] ... ... chrominance channel 1...\n"); img2array (&img, 1, "img/", "u_channel_before"); printf ("[INFO] ... ... chrominance channel 2...\n"); img2array (&img, 2, "img/", "v_channel_before"); printf ("[INFO] ... end of printing arrays...\n\n"); fprintf (log, "[INFO] ... printed every intput channel as array of values...\n\n"); // ---------------------------------------------------------------------- // BLOCK-MATCHING // ---------------------------------------------------------------------- printf ("[INFO] ... launch of block-matching...\n"); printf ("[INFO] ... ... luminance channel...\n"); start = clock(); if (block_matching(&img, &org, block_size, block_step, sigma, h_search_true, v_search_true, th_2d, tau_match, 0, block_marking, &y_list) != 0) { return 1; } printf ("[INFO] ... end of block-matching...\n\n"); end = clock(); time = (end - start) / (double)CLOCKS_PER_SEC; fprintf (log, "[INFO] ... block-matching accomplished...\n"); fprintf (log, "[INFO] ... ... elapsed time: %f\n", time); fprintf (log, "[INFO] ... ... number of groups in list: %d\n\n", list_length(&y_list)); // print recognized groups to file sprintf (path, "grp/org/%s/y/", kind); if (print_list(y_list, path, "group") != 0) { return 1; } // trim groups to maximal number of blocks printf ("[INFO] ... trimming groups to maximum size...\n\n"); if (trim_list(&y_list, max_blocks) != 0) { return 1; } fprintf (log, "[INFO] ... trimmed groups to maximum size of blocks...\n\n"); // obtain the pixel values from the u- and v-channel of the image printf ("[INFO] ... extracting blocks from chrominance channels...\n"); printf ("[INFO] ... ... chrominance channel 1...\n"); if (get_chrom(&img, &y_list, &u_list, 1)) { return 1; } printf ("[INFO] ... ... chrominance channel 2...\n\n"); if (get_chrom(&img, &y_list, &v_list, 2)) { return 1; } fprintf (log, "[INFO] ... extracted values from chrominance channels...\n\n"); // print trimmed groups to file sprintf (path, "grp/trm/%s/y/", kind); if (print_list(y_list, path, "group") != 0) { return 1; } sprintf (path, "grp/trm/%s/u/", kind); if (print_list(u_list, path, "group") != 0) { return 1; } sprintf (path, "grp/trm/%s/v/", kind); if (print_list(v_list, path, "group") != 0) { return 1; } // ---------------------------------------------------------------------- // IMAGE-DENOISING // ---------------------------------------------------------------------- printf ("[INFO] ... launch of shrinkage...\n"); start = clock(); printf ("[INFO] ... ... luminance channel...\n"); if (shrinkage(kind, &y_list, sigma, th_3d, 0) != 0) { return 1; } // printf ("[INFO] ... ... chrominance channel 1...\n"); // if (shrinkage(kind, &u_list, sigma, th_3d, 1) != 0) { // return 1; // } // printf ("[INFO] ... ... chrominance channel 2...\n"); // if (shrinkage(kind, &v_list, sigma, th_3d, 1) != 0) { // return 1; // } printf ("[INFO] ... end of shrinkage...\n\n"); end = clock(); time = (end - start) / (double)CLOCKS_PER_SEC; fprintf (log, "[INFO] ... accomplished shrinkage...\n"); fprintf (log, "[INFO] ... ... elapsed time: %f\n\n", time); sprintf (path, "grp/est/%s/y/", kind); if (print_list(y_list, path, "group") != 0) { return 1; } sprintf (path, "grp/est/%s/u/", kind); if (print_list(u_list, path, "group") != 0) { return 1; } sprintf (path, "grp/est/%s/v/", kind); if (print_list(v_list, path, "group") != 0) { return 1; } // ---------------------------------------------------------------------- // AGGREGATION // ---------------------------------------------------------------------- printf ("[INFO] ... launch of aggregation...\n"); start = clock(); printf ("[INFO] ... ... luminance channel...\n"); if (aggregate(kind, &img, &y_list, 0) != 0) { return 1; } // printf ("[INFO] ... chrominance channel 1...\n"); // if (aggregate(kind, &img, &u_list, 1) != 0) { // return 1; // } // printf ("[INFO] ... chrominance channel 2...\n"); // if (aggregate(kind, &img, &v_list, 2) != 0) { // return 1; // } printf ("[INFO] ... end of aggregation...\n\n"); end = clock(); time = (end - start) / (double)CLOCKS_PER_SEC; fprintf (log, "[INFO] ... accomplished aggregation...\n"); fprintf (log, "[INFO] ... ... elapsed time: %f\n\n", time); // ---------------------------------------------------------------------- // IMAGE-TO-ARRAY CONVERSION // ---------------------------------------------------------------------- printf ("[INFO] ... launch of printing image as three separate value arrays...\n"); printf ("[INFO] ... ... luminance channel...\n"); img2array (&img, 0, "img/", "y_channel_after"); printf ("[INFO] ... ... chrominance channel 1...\n"); img2array (&img, 1, "img/", "u_channel_after"); printf ("[INFO] ... ... chrominance channel 2...\n"); img2array (&img, 2, "img/", "v_channel_after"); printf ("[INFO] ... end of printing arrays...\n\n"); // ---------------------------------------------------------------------- // COLORSPACE CONVERSION & WRITEBACK // ---------------------------------------------------------------------- printf ("[INFO] ... launch of color conversion...\n"); yuv2rgb (&img); sprintf (prefix, "denoised_rgb_%s_%s", pure_name, kind); // write output image if (png_write(&img, "img/rgb/", prefix, sigma) != 0) { return 1; } printf ("[INFO] ... end of color conversion...\n\n"); fprintf (log, "[INFO] ... converted colorspace of output image to RGB...\n\n"); fprintf (log, "[INFO] ... PSNR after denoising: %fdB\n", get_snr(&org, &img)); fprintf (log, "-------------------------------------------------------------------------\n"); fprintf (log, "-------------------------------------------------------------------------\n\n\n"); // ---------------------------------------------------------------------- // FREEING DYNAMICALY ALLOCATED MEMORY // ---------------------------------------------------------------------- free_list (&y_list); free_list (&u_list); free_list (&v_list); png_free_mem (&img); png_free_mem (&org); fclose (log); return 0; }