egami
C++ Image Processing program
/homes/esi30/DCS339/coursework/src/Processes/convolution.cpp
Go to the documentation of this file.
00001 #include <memory>
00002 #include <sstream>
00003 #include <string>
00004 
00005 #include <gtkmm/image.h>
00006 #include <gtkmm/messagedialog.h>
00007 #include <gtkmm/stock.h>
00008 #include <gtkmm/radiobutton.h>
00009 #include <gtkmm/label.h>
00010 #include <gtkmm/entry.h>
00011 #include <gtkmm/table.h>
00012 
00013 #include "../display_unit.hpp"
00014 #include "../processing_page.hpp"
00015 #include "../processing_unit.hpp"
00016 #include "../utils.hpp"
00017 #include "convolution.hpp"
00018 
00019 namespace{
00020     class Config: public Gtk::Dialog {
00021         public:
00022             Config(): size("Size:"), dlabel("Divisor:"), threeb("3"), fiveb("5"), sevenb("7"), nineb("9"), threet(3,3), fivet(5,5), sevent(7, 7), ninet(9,9) {
00023                 set_resizable(false);
00024 
00025                 Gtk::RadioButton::Group group = threeb.get_group();
00026                 fiveb.set_group(group);
00027                 sevenb.set_group(group);
00028                 nineb.set_group(group);
00029 
00030                 threeb.set_active(true);
00031                 threeb.signal_clicked().connect(sigc::mem_fun(*this, &Config::on_three));
00032                 fiveb.signal_clicked().connect(sigc::mem_fun(*this, &Config::on_five));
00033                 sevenb.signal_clicked().connect(sigc::mem_fun(*this, &Config::on_seven));
00034                 nineb.signal_clicked().connect(sigc::mem_fun(*this, &Config::on_nine));
00035 
00036                 get_vbox()->pack_start(size);
00037                 get_vbox()->pack_start(threeb);
00038                 get_vbox()->pack_start(fiveb);
00039                 get_vbox()->pack_start(sevenb);
00040                 get_vbox()->pack_start(nineb);
00041 
00042                 for(unsigned char y=0; y<3; ++y)
00043                     for(unsigned char x=0; x<3; ++x){
00044                         Gtk::Entry &r=three[y][x];
00045                         r.set_text("0");
00046                         r.set_width_chars(3);
00047                         threet.attach(r, y, y+1, x, x+1);
00048                     }
00049 
00050                 for(unsigned char y=0; y<5; ++y)
00051                     for(unsigned char x=0; x<5; ++x){
00052                         Gtk::Entry &r=five[y][x];
00053                         r.set_text("0");
00054                         r.set_width_chars(3);
00055                         fivet.attach(r, y, y+1, x, x+1);
00056                     }
00057 
00058                 for(unsigned char y=0; y<7; ++y)
00059                     for(unsigned char x=0; x<7; ++x){
00060                         Gtk::Entry &r=seven[y][x];
00061                         r.set_text("0");
00062                         r.set_width_chars(3);
00063                         sevent.attach(r, y, y+1, x, x+1);
00064                     }
00065 
00066                 for(unsigned char y=0; y<9; ++y)
00067                     for(unsigned char x=0; x<9; ++x){
00068                         Gtk::Entry &r=nine[y][x];
00069                         r.set_text("0");
00070                         r.set_width_chars(3);
00071                         ninet.attach(r, y, y+1, x, x+1);
00072                     }
00073 
00074                 add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK);
00075                 add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
00076 
00077                 get_vbox()->pack_start(threet);
00078                 get_vbox()->pack_start(fivet);
00079                 get_vbox()->pack_start(sevent);
00080                 get_vbox()->pack_start(ninet);
00081 
00082                 get_vbox()->pack_start(dlabel);
00083                 divent.set_text("1");
00084                 divent.set_width_chars(3);
00085                 get_vbox()->pack_start(divent);
00086 
00087                 show_all_children();
00088                 on_three();
00089             }
00090 
00091             void on_three(){
00092                 threet.show_all();
00093                 fivet.hide();
00094                 sevent.hide();
00095                 ninet.hide();
00096             }
00097             void on_five(){
00098                 threet.hide();
00099                 fivet.show_all();
00100                 sevent.hide();
00101                 ninet.hide();
00102             }
00103             void on_seven(){
00104                 threet.hide();
00105                 fivet.hide();
00106                 sevent.show_all();
00107                 ninet.hide();
00108             }
00109             void on_nine(){
00110                 threet.hide();
00111                 fivet.hide();
00112                 sevent.hide();
00113                 ninet.show_all();
00114             }
00115 
00116             unsigned char size_a() const {
00117                 return threeb.get_active()?3:fiveb.get_active()?5:sevenb.get_active()?7:nineb.get_active()?9:0;
00118             }
00119 
00120             std::array<std::array<double, 3>, 3> get_3k() const {
00121                 std::array<std::array<double, 3>, 3> r;
00122                 for(unsigned char y=0; y<3; ++y)
00123                     for(unsigned char x=0; x<3; ++x){
00124                         std::stringstream ss;
00125                         ss << three[y][x].get_text();
00126                         if(!(ss >> r[y][x]))
00127                             throw std::runtime_error("Not a number");
00128                     }
00129                 return r;
00130             }
00131 
00132             std::array<std::array<double, 5>, 5> get_5k() const {
00133                 std::array<std::array<double, 5>, 5> r;
00134                 for(unsigned char y=0; y<5; ++y)
00135                     for(unsigned char x=0; x<5; ++x){
00136                         std::stringstream ss;
00137                         ss << five[y][x].get_text();
00138                         if(!(ss >> r[y][x]))
00139                             throw std::runtime_error("Not a number");
00140                     }
00141                 return r;
00142             }
00143 
00144             std::array<std::array<double, 7>, 7> get_7k() const {
00145                 std::array<std::array<double, 7>, 7> r;
00146                 for(unsigned char y=0; y<7; ++y)
00147                     for(unsigned char x=0; x<7; ++x){
00148                         std::stringstream ss;
00149                         ss << seven[y][x].get_text();
00150                         if(!(ss >> r[y][x]))
00151                             throw std::runtime_error("Not a number");
00152                     }
00153                 return r;
00154             }
00155 
00156             std::array<std::array<double, 9>, 9> get_9k() const {
00157                 std::array<std::array<double, 9>, 9> r;
00158                 for(unsigned char y=0; y<9; ++y)
00159                     for(unsigned char x=0; x<9; ++x){
00160                         std::stringstream ss;
00161                         ss << nine[y][x].get_text();
00162                         if(!(ss >> r[y][x]))
00163                             throw std::runtime_error("Not a number");
00164                     }
00165                 return r;
00166             }
00167 
00168             double get_d() const {
00169                 std::stringstream ss;
00170                 ss << divent.get_text();
00171                 double r;
00172                 ss >> r;
00173                 if(!r)
00174                     throw std::runtime_error("Divisor is 0");
00175                 return r;
00176             }
00177 
00178         private:
00179             Gtk::Label size, dlabel;
00180             Gtk::RadioButton threeb, fiveb, sevenb, nineb;
00181             Gtk::Table threet, fivet, sevent, ninet;
00182             std::array<std::array<Gtk::Entry, 3>, 3> three;
00183             std::array<std::array<Gtk::Entry, 5>, 5> five;
00184             std::array<std::array<Gtk::Entry, 7>, 7> seven;
00185             std::array<std::array<Gtk::Entry, 9>, 9> nine;
00186             Gtk::Entry divent;
00187     };
00188     
00189     Display_unit *impl(const Image_unit *in){
00190         Config c;
00191         if(c.run()!=Gtk::RESPONSE_OK)
00192             return nullptr;
00193         c.hide();
00194 
00195         switch(c.size_a()){
00196             case 3:
00197                 return apply<1>(in, c.get_3k(), c.get_d());
00198             case 5:
00199                 return apply<2>(in, c.get_5k(), c.get_d());
00200             case 7:
00201                 return apply<3>(in, c.get_7k(), c.get_d());
00202             case 9:
00203                 return apply<4>(in, c.get_9k(), c.get_d());
00204             default:
00205                 return nullptr;
00206         }
00207     }
00208 }
00209 
00210 namespace Processes{
00211     void convolution(){
00212         Gtk::Image icon(cmake_install_prefix+std::string("/share/egami/icons/generic.png"));
00213         std::shared_ptr<Processing_unit> pu(new Processing_unit(Processing(&impl), "Generic", icon, false));
00214         Processing_page::add_unit_to_page("Convolutions", pu);
00215     }
00216 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends