void finish_metric_stats(int64_t output_num, float a1, float a2)
{
  int64_t i;
  if (metric_output) {
    fclose(metric_output);
    metric_output = NULL;
  }
  for (i=0; i<metric_mass_bins; i++) {
    _finish_metric_stats(&(sigma_x[i]));
    _finish_metric_stats(&(sigma_v[i]));
    _finish_metric_stats(&(sigma_vmax[i]));
    _finish_metric_stats(&(sigma_x_subs[i]));
    _finish_metric_stats(&(sigma_v_subs[i]));
    _finish_metric_stats(&(sigma_vmax_subs[i]));
    if (sigma_v_subs[i].count)
      sigma_v_subs[i].corr /= (double) sigma_v_subs[i].count;
    sigma_vmax[i].tol = sigma_vmax[i].sd;
    if (!sigma_vmax[i].tol) sigma_vmax[i].tol = 0.1;
    if (sigma_x[i].count && (sigma_x[i].sd*sigma_v[i].sd)>0) {
      sigma_x[i].corr /= (double) sigma_x[i].count;
      sigma_x[i].corr -= sigma_x[i].avg*sigma_v[i].avg;
      sigma_x[i].corr /= sigma_x[i].sd*sigma_v[i].sd;
    } else {
      sigma_x[i].corr = 0;
    }
    if (sigma_x_subs[i].count && (sigma_x_subs[i].sd*sigma_v_subs[i].sd)>0) {
      sigma_x_subs[i].corr /= (double) sigma_x_subs[i].count;
      sigma_x_subs[i].corr -= sigma_x_subs[i].avg*sigma_v_subs[i].avg;
      sigma_x_subs[i].corr /= sigma_x_subs[i].sd*sigma_v_subs[i].sd;
    } else {
      sigma_x_subs[i].corr = 0;
    }
  }

  //Propagate error calculations for bins with low counts
  propagate_statistics(sigma_x, 1, 20);
  propagate_statistics(sigma_v, 1, 20);
  propagate_statistics(sigma_vmax, 0, 100);
  for (i=1; i<metric_mass_bins; i++) {
    if (sigma_x[i].fixed || ((sigma_x[i].sd) > 0 && (sigma_x[i].count > 1))) continue;
    sigma_x[i] = sigma_x[i-1];
    if (!sigma_vmax[i].fixed) sigma_vmax[i] = sigma_vmax[i-1];
    sigma_v[i] = sigma_v[i-1];
    sigma_x[i].count = sigma_v[i].count = sigma_vmax[i].count = 1;
  }
  for (i=metric_mass_bins-2; i>=0; i--) {
    if (sigma_x[i].fixed || ((sigma_x[i].sd) > 0 && (sigma_x[i].count > 1))) continue;
    sigma_x[i] = sigma_x[i+1];
    if (!sigma_vmax[i].fixed) sigma_vmax[i] = sigma_vmax[i+1];
    sigma_v[i] = sigma_v[i+1];
    sigma_x[i].count = sigma_v[i].count = sigma_vmax[i].count = 1;
  }

  print_metric_stats(output_num, a1, a2);
}
示例#2
0
   bool corpus_tester::test(const char* pCmd_line)
   {
      console::printf("Command line:\n\"%s\"", pCmd_line);

      static const command_line_params::param_desc param_desc_array[] = 
      {
         { "corpus_test", 0, false },
         { "in", 1, true },
         { "deep", 0, false },
         { "alpha", 0, false },
         { "nomips", 0, false },
         { "perceptual", 0, false },
         { "endpointcaching", 0, false },
         { "multithreaded", 0, false },
         { "writehybrid", 0, false },
         { "nobadblocks", 0, false },
      };

      command_line_params cmd_line_params;
      if (!cmd_line_params.parse(pCmd_line, CRNLIB_ARRAY_SIZE(param_desc_array), param_desc_array, true))
         return false;

      double total_time1 = 0, total_time2 = 0;

      command_line_params::param_map_const_iterator it = cmd_line_params.begin();
      for ( ; it != cmd_line_params.end(); ++it)
      {
         if (it->first != "in")
            continue;
         if (it->second.m_values.empty())
         {
            console::error("Must follow /in parameter with a filename!\n");
            return false;
         }

         for (uint in_value_index = 0; in_value_index < it->second.m_values.size(); in_value_index++)
         {
            const dynamic_string& filespec = it->second.m_values[in_value_index];

            find_files file_finder;
            if (!file_finder.find(filespec.get_ptr(), find_files::cFlagAllowFiles | (cmd_line_params.has_key("deep") ? find_files::cFlagRecursive : 0)))
            {
               console::warning("Failed finding files: %s", filespec.get_ptr());
               continue;
            }

            if (file_finder.get_files().empty())
            {
               console::warning("No files found: %s", filespec.get_ptr());
               return false;
            }

            const find_files::file_desc_vec& files = file_finder.get_files();

            image_u8 o(4, 4), a(4, 4), b(4, 4);

            uint first_channel = 0;
            uint num_channels = 3;
            bool perceptual = cmd_line_params.get_value_as_bool("perceptual", false);
            if (perceptual)
            {
               first_channel = 0;
               num_channels = 0;
            }
            console::printf("Perceptual mode: %u", perceptual);

            for (uint file_index = 0; file_index < files.size(); file_index++)
            {
               const find_files::file_desc& file_desc = files[file_index];

               console::printf("-------- Loading image: %s", file_desc.m_fullname.get_ptr());

               image_u8 img;
               if (!image_utils::read_from_file(img, file_desc.m_fullname.get_ptr(), 0))
               {
                  console::warning("Failed loading image file: %s", file_desc.m_fullname.get_ptr());
                  continue;
               }

               if ((!cmd_line_params.has_key("alpha")) && img.is_component_valid(3))
               {
                  for (uint y = 0; y < img.get_height(); y++)
                     for (uint x = 0; x < img.get_width(); x++)
                        img(x, y).a = 255;

                  img.set_component_valid(3, false);
               }

               mipmapped_texture orig_tex;
               orig_tex.assign(crnlib_new<image_u8>(img));

               if (!cmd_line_params.has_key("nomips"))
               {
                  mipmapped_texture::generate_mipmap_params genmip_params;
                  genmip_params.m_srgb = true;

                  console::printf("Generating mipmaps");

                  if (!orig_tex.generate_mipmaps(genmip_params, false))
                  {
                     console::error("Mipmap generation failed!");
                     return false;
                  }
               }               

               console::printf("Compress 1");

               mipmapped_texture tex1(orig_tex);
               dxt_image::pack_params convert_params;
               convert_params.m_endpoint_caching = cmd_line_params.get_value_as_bool("endpointcaching", 0, false);
               convert_params.m_compressor = cCRNDXTCompressorCRN;
               convert_params.m_quality = cCRNDXTQualityNormal;
               convert_params.m_perceptual = perceptual;
               convert_params.m_num_helper_threads = cmd_line_params.get_value_as_bool("multithreaded", 0, true) ? (g_number_of_processors - 1) : 0;
               convert_params.m_pProgress_callback = progress_callback;
               timer t;
               t.start();
               if (!tex1.convert(PIXEL_FMT_ETC1, false, convert_params))
               {
                  console::error("Texture conversion failed!");
                  return false;
               }
               double time1 = t.get_elapsed_secs();
               total_time1 += time1;
               console::printf("Elapsed time: %3.3f", time1);

               console::printf("Compress 2");

               mipmapped_texture tex2(orig_tex);
               convert_params.m_endpoint_caching = false;
               convert_params.m_compressor = cCRNDXTCompressorCRN;
               convert_params.m_quality = cCRNDXTQualitySuperFast;
               t.start();
               if (!tex2.convert(PIXEL_FMT_ETC1, false, convert_params))
               {
                  console::error("Texture conversion failed!");
                  return false;
               }
               double time2 = t.get_elapsed_secs();
               total_time2 += time2;
               console::printf("Elapsed time: %3.3f", time2);

               image_u8 hybrid_img(img.get_width(), img.get_height());

               for (uint l = 0; l < orig_tex.get_num_levels(); l++)
               {
                  image_u8 orig_img, img1, img2;

                  image_u8* pOrig = orig_tex.get_level(0, l)->get_unpacked_image(orig_img, cUnpackFlagUncook | cUnpackFlagUnflip);
                  image_u8* pImg1 = tex1.get_level(0, l)->get_unpacked_image(img1, cUnpackFlagUncook | cUnpackFlagUnflip);
                  image_u8* pImg2 = tex2.get_level(0, l)->get_unpacked_image(img2, cUnpackFlagUncook | cUnpackFlagUnflip);

                  const uint num_blocks_x = pOrig->get_block_width(4);
                  const uint num_blocks_y = pOrig->get_block_height(4);

                  crnlib::vector<image_utils::error_metrics> metrics[2];

                  for (uint by = 0; by < num_blocks_y; by++)
                  {
                     for (uint bx = 0; bx < num_blocks_x; bx++)
                     {
                        pOrig->extract_block(o.get_ptr(), bx * 4, by * 4, 4, 4);
                        pImg1->extract_block(a.get_ptr(), bx * 4, by * 4, 4, 4);
                        pImg2->extract_block(b.get_ptr(), bx * 4, by * 4, 4, 4);

                        image_utils::error_metrics em1;
                        em1.compute(o, a, first_channel, num_channels);

                        image_utils::error_metrics em2;
                        em2.compute(o, b, first_channel, num_channels);

                        metrics[0].push_back(em1);
                        metrics[1].push_back(em2);

                        if (em1.mPeakSNR < em2.mPeakSNR)
                        {
                           add_bad_block(o);

                           hybrid_img.blit(bx * 4, by * 4, b);
                        }
                        else
                        {
                           hybrid_img.blit(bx * 4, by * 4, a);
                        }
                     }
                  }

                  if (cmd_line_params.has_key("writehybrid"))
                     image_utils::write_to_file("hybrid.tga", hybrid_img, image_utils::cWriteFlagIgnoreAlpha);

                  console::printf("---- Mip level: %u, Total blocks: %ux%u, %u", l, num_blocks_x, num_blocks_y, num_blocks_x * num_blocks_y);

                  console::printf("Compressor 1:");
                  print_metric_stats(metrics[0], num_blocks_x, num_blocks_y);

                  console::printf("Compressor 2:");
                  print_metric_stats(metrics[1], num_blocks_x, num_blocks_y);

                  console::printf("Compressor 1 vs. 2:");
                  print_comparative_metric_stats(cmd_line_params, metrics[0], metrics[1], num_blocks_x, num_blocks_y);

                  image_utils::error_metrics em;

                  em.compute(*pOrig, *pImg1, 0, perceptual ? 0 : 3);
                  em.print("Compressor 1: ");

                  em.compute(*pOrig, *pImg2, 0, perceptual ? 0 : 3);
                  em.print("Compressor 2: ");

                  em.compute(*pOrig, hybrid_img, 0, perceptual ? 0 : 3);
                  em.print("Best of Both: ");
               }
            }

         }  // file_index
      } 

      flush_bad_blocks();

      console::printf("Total times: %4.3f vs. %4.3f", total_time1, total_time2);

      return true;
   }