00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "yuv_viewer_gui.h"
00024
00025 #include <fvutils/color/colorspaces.h>
00026 #include <fvutils/draw/drawer.h>
00027
00028 #include <cmath>
00029 #include <cstring>
00030 #include <iomanip>
00031 #include <sstream>
00032
00033 #define M_2xPI (2*M_PI)
00034 using namespace fawkes;
00035 using namespace firevision;
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 YuvViewerGtkWindow::YuvViewerGtkWindow(BaseObjectType* cobject,
00048 const Glib::RefPtr<Gnome::Glade::Xml> ref_xml)
00049 : Gtk::Window(cobject)
00050 {
00051 ref_xml->get_widget("yuv_vp", __yuv_vp);
00052 ref_xml->get_widget("cur_vp", __cur_vp);
00053 ref_xml->get_widget("seg_vp", __seg_vp);
00054 ref_xml->get_widget("y_scale", __y_scale);
00055 ref_xml->get_widget("u_value", __u_value);
00056 ref_xml->get_widget("v_value", __v_value);
00057 ref_xml->get_widget("y_res", __y_res);
00058 ref_xml->get_widget("u_res", __u_res);
00059 ref_xml->get_widget("v_res", __v_res);
00060
00061 __yuv_widget = Gtk::manage(new ImageWidget(256, 256));
00062 __cur_widget = Gtk::manage(new ImageWidget( 60, 40));
00063 __seg_widget = Gtk::manage(new ImageWidget(256, 256));
00064
00065 __y_scale->signal_value_changed().connect(sigc::mem_fun(*this, &YuvViewerGtkWindow::on_y_value_changed));
00066 __y_res->signal_value_changed().connect(sigc::mem_fun(*this, &YuvViewerGtkWindow::on_y_res_changed));
00067 __u_res->signal_value_changed().connect(sigc::mem_fun(*this, &YuvViewerGtkWindow::on_uv_res_changed));
00068 __v_res->signal_value_changed().connect(sigc::mem_fun(*this, &YuvViewerGtkWindow::on_uv_res_changed));
00069
00070 __yuv_vp->signal_button_press_event().connect(sigc::mem_fun(*this, &YuvViewerGtkWindow::on_click_on_yuv));
00071 __yuv_vp->signal_motion_notify_event().connect(sigc::mem_fun(*this, &YuvViewerGtkWindow::on_mouse_over_yuv));
00072 __yuv_vp->add(*__yuv_widget);
00073 __cur_vp->add(*__cur_widget);
00074 __seg_vp->add(*__seg_widget);
00075
00076
00077 memset(__cur_buffer + 60 * 40, 128, 60 * 40);
00078 memset(__seg_buffer, 128, 256 * 256);
00079 on_y_value_changed();
00080 on_uv_res_changed();
00081 calc_seg();
00082 show_all_children();
00083 }
00084
00085
00086 YuvViewerGtkWindow::~YuvViewerGtkWindow()
00087 {
00088 }
00089
00090
00091
00092
00093
00094 bool
00095 YuvViewerGtkWindow::on_click_on_yuv(GdkEventButton *event)
00096 {
00097 GdkEventMotion mot;
00098 mot.x = event->x;
00099 mot.y = event->y;
00100 return on_mouse_over_yuv(&mot);
00101 }
00102
00103
00104
00105
00106
00107 bool
00108 YuvViewerGtkWindow::on_mouse_over_yuv(GdkEventMotion *event)
00109 {
00110 unsigned int u = std::max(0, std::min(255, (int)event->x));
00111 unsigned int v = 255 - std::max(0, std::min(255, (int)event->y));
00112
00113 __u_value->set_text(convert_float2str(u, 0));
00114 __v_value->set_text(convert_float2str(v, 0));
00115 memset(__cur_buffer + 60 * 40, u, 60 * 20);
00116 memset(__cur_buffer + 60 * 60, v, 60 * 20);
00117 __cur_widget->show(YUV422_PLANAR, __cur_buffer);
00118
00119 return true;
00120 }
00121
00122
00123 void
00124 YuvViewerGtkWindow::on_y_value_changed()
00125 {
00126 unsigned int y = round(__y_scale->get_value());
00127 memset(__yuv_buffer, y, 256 * 256);
00128 memset(__cur_buffer, y, 60 * 40);
00129
00130 Drawer d;
00131 d.set_buffer(__yuv_buffer, 256, 256);
00132 d.set_color(YUV_t::black());
00133 d.draw_line(127, 127, 0, 64);
00134 d.draw_line(127, 127, 64, 0);
00135
00136 d.draw_line(128, 127, 192, 0);
00137 d.draw_line(128, 127, 255, 64);
00138
00139 d.draw_line(128, 128, 192, 255);
00140 d.draw_line(128, 128, 255, 192);
00141
00142 d.draw_line(127, 128, 0, 192);
00143 d.draw_line(127, 128, 64, 255);
00144
00145 __yuv_widget->show(YUV422_PLANAR, __yuv_buffer);
00146 __cur_widget->show(YUV422_PLANAR, __cur_buffer);
00147 }
00148
00149
00150 void
00151 YuvViewerGtkWindow::on_y_res_changed()
00152 {
00153 unsigned int r = round(__y_res->get_value());
00154
00155 if (r == 0) {
00156 __y_scale->set_value(127);
00157 __y_scale->set_range(127, 128);
00158 }
00159 else {
00160 __y_scale->set_range(0, 255);
00161 __y_scale->set_increments(255.f / (pow(2, r) - 1), 0);
00162 }
00163 }
00164
00165 void
00166 YuvViewerGtkWindow::on_uv_res_changed()
00167 {
00168 unsigned char *yuv_u = __yuv_buffer + 256 * 256;
00169 unsigned char *yuv_v = yuv_u + 256 * 256 / 2;
00170 unsigned int u_div = 256 / (int)pow(2, __u_res->get_value());
00171 unsigned int v_div = 256 / (int)pow(2, __v_res->get_value());
00172
00173 for (unsigned int v = 0; v < 256; ++v) {
00174 memset((yuv_v + v * 128), ((255 - v) / v_div) * v_div, 128);
00175
00176 for (unsigned int u = 0; u < 128; ++u) {
00177 yuv_u[v * 128 + u] = (u * 2 / u_div) * u_div;
00178 }
00179 }
00180
00181 on_y_value_changed();
00182 }
00183
00184
00185
00186
00187
00188
00189
00190 Glib::ustring
00191 YuvViewerGtkWindow::convert_float2str(float f, unsigned int width)
00192 {
00193 #if GLIBMM_MAJOR_VERSION > 2 || ( GLIBMM_MAJOR_VERSION == 2 && GLIBMM_MINOR_VERSION >= 16 )
00194 return Glib::ustring::format(std::fixed, std::setprecision(width), f);
00195 #else
00196 std::ostringstream ss;
00197 ss << std::fixed << std::setprecision(width);
00198 ss << f;
00199
00200 return Glib::locale_to_utf8(ss.str());
00201 #endif
00202 }
00203
00204
00205 void
00206 YuvViewerGtkWindow::calc_seg()
00207 {
00208 YUV_t c;
00209 unsigned char *seg_u = __seg_buffer + 256 * 256;
00210 unsigned char *seg_v = seg_u + 256 * 256 / 2;
00211
00212 float a1 = atan2f(64, 128);
00213 float a2 = atan2f(128, 64);
00214 float a3 = atan2f(128, -64);
00215 float a4 = atan2f(64, -128);
00216 float a5 = atan2f(-64, -128) + M_2xPI;
00217 float a6 = atan2f(-128, -64) + M_2xPI;
00218 float a7 = atan2f(-128, 64) + M_2xPI;
00219 float a8 = atan2f(-64, 128) + M_2xPI;
00220
00221 for (int u = 0; u < 256; ++u) {
00222 float du = u - 128;
00223
00224 for (int v = 255; v >= 0; --v) {
00225 float dv = v - 128;
00226
00227 if (!du) {
00228 if (dv > 0) YUV_t::red();
00229 else c = YUV_t::gray();
00230 }
00231 else {
00232 float a = atan2f(dv, du);
00233 if (a < 0) a += M_2xPI;
00234
00235 if (a >= a1 && a < a2) c = YUV_t::magenta();
00236 else if (a >= a2 && a < a3) c = YUV_t::red();
00237 else if (a >= a3 && a < a4) c = YUV_t::orange();
00238 else if (a >= a4 && a < a5) c = YUV_t::yellow();
00239 else if (a >= a5 && a < a6) c = YUV_t::green();
00240 else if (a >= a6 && a < a7) c = YUV_t::gray();
00241 else if (a >= a7 && a < a8) c = YUV_t::cyan();
00242 else c = YUV_t::blue();
00243 }
00244
00245 unsigned int addr = ((255 - v) * 256 + u) / 2;
00246 seg_u[addr] = c.U;
00247 seg_v[addr] = c.V;
00248 }
00249 }
00250
00251 __seg_widget->show(YUV422_PLANAR, __seg_buffer);
00252 }