egami
C++ Image Processing program
|
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 }