egami
C++ Image Processing program
/homes/esi30/DCS339/coursework/src/Processes/histogram.cpp
Go to the documentation of this file.
00001 #include <memory>
00002 #include <array>
00003 #include <algorithm>
00004 #include <string>
00005 #include <vector>
00006 
00007 #include <gtkmm/image.h>
00008 #include <gtkmm/dialog.h>
00009 #include <gtkmm/spinbutton.h>
00010 #include <gtkmm/checkbutton.h>
00011 #include <gtkmm/label.h>
00012 #include <gtkmm/enums.h>
00013 #include <gtkmm/stock.h>
00014 
00015 #include "../display_unit.hpp"
00016 #include "../processing_page.hpp"
00017 #include "../processing_unit.hpp"
00018 #include "../utils.hpp"
00019 #include "../progress.hpp"
00020 #include "order_statistic.hpp"
00021 
00022 namespace{
00023     class Config: public Gtk::Dialog {
00024         public:
00025             Config(): adj(Gtk::Adjustment::create(1, 1, 32, 1, 5)), tt("Precision:"), bt(adj), rb("Red"), gb("Green"), bb("Blue") {
00026                 set_resizable(false);
00027 
00028                 rb.set_active(true);
00029                 gb.set_active(true);
00030                 bb.set_active(true);
00031 
00032                 get_vbox()->pack_start(tt);
00033                 get_vbox()->pack_start(bt);
00034                 get_vbox()->pack_start(rb);
00035                 get_vbox()->pack_start(gb);
00036                 get_vbox()->pack_start(bb);
00037 
00038                 add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
00039                 add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
00040 
00041                 show_all_children();
00042             }
00043 
00044             unsigned precision() const {
00045                 return bt.get_value();
00046             }
00047 
00048             bool r_a() const { return rb.get_active(); }
00049             bool g_a() const { return gb.get_active(); }
00050             bool b_a() const { return bb.get_active(); }
00051 
00052         private:
00053             Glib::RefPtr<Gtk::Adjustment> adj;
00054             Gtk::Label tt;
00055             Gtk::SpinButton bt;
00056             Gtk::CheckButton rb, gb, bb;
00057     };
00058 
00059     Display_unit *impl(const Image_unit *in){
00060         Config config;
00061         if(config.run()!=Gtk::RESPONSE_OK)
00062             return nullptr;
00063         config.hide();
00064 
00065         std::vector<unsigned> red_norm(1+255/config.precision(), 0), green_norm(1+255/config.precision(), 0), blue_norm(1+255/config.precision(), 0);
00066 
00067         for(auto pixel: *in){
00068             red_norm[pixel.r/config.precision()]++;
00069             green_norm[pixel.g/config.precision()]++;
00070             blue_norm[pixel.b/config.precision()]++;
00071         }
00072 
00073         std::array<unsigned, 256> red_hist{{}}, green_hist{{}}, blue_hist{{}};
00074         unsigned max=1;
00075         for(unsigned short i=0; i<256; ++i){
00076             if(config.r_a()) red_hist[i]=red_norm[i/config.precision()];
00077             if(config.g_a()) green_hist[i]=green_norm[i/config.precision()];
00078             if(config.b_a()) blue_hist[i]=blue_norm[i/config.precision()];
00079             max=std::max(max, std::max(red_hist[i], std::max(green_hist[i], blue_hist[i])));
00080         }
00081 
00082         Image_unit *out(new Image_unit(in, 257, 258, false));
00083         for(auto pixel: *out)
00084             pixel = {0};
00085 
00086         for(unsigned short i=0; i<256; ++i){
00087             if(config.r_a())
00088                 for(unsigned j=0; j<red_hist[i]/static_cast<double>(max)*255; ++j)
00089                     out->red(255-j, 1+i, 255);
00090             if(config.g_a())
00091                 for(unsigned j=0; j<green_hist[i]/static_cast<double>(max)*255; ++j)
00092                     out->green(255-j, 1+i, 255);
00093             if(config.b_a())
00094                 for(unsigned j=0; j<blue_hist[i]/static_cast<double>(max)*255; ++j)
00095                     out->blue(255-j, 1+i, 255);
00096         }
00097         return out;
00098     }
00099 }
00100 
00101 namespace Processes{
00102     void histogram(){
00103         Gtk::Image icon(cmake_install_prefix+std::string("/share/egami/icons/histogram.png"));
00104         std::shared_ptr<Processing_unit> pu(new Processing_unit(Processing(&impl), "Histogram", icon, true));
00105         Processing_page::add_unit_to_page("Colours", pu);
00106     }
00107 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends