00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00040 #include <pcl_visualization/common/image_widget_wx.h>
00041 #include <pcl_visualization/common/float_image_utils.h>
00042
00043 #include <iostream>
00044 using std::cout;
00045 using std::cerr;
00046
00047 IMPLEMENT_APP_NO_MAIN (wxApp)
00048
00049 void
00050 pcl_visualization::ImageWidgetWX::spinOnce ()
00051 {
00052 if (wxTheApp != NULL)
00053 wxTheApp->Yield (true);
00054
00055
00056
00057
00058
00059 }
00060
00061 void
00062 pcl_visualization::ImageWidgetWX::spin ()
00063 {
00064 wxTheApp->OnRun ();
00065 }
00066
00067 pcl_visualization::ImageWidgetWX::ImageWidgetWX () : keepAspectRatio (true), visualize_selected_point (false),
00068 print_selected_point(false),
00069 image_frame (NULL), image_data (NULL)
00070 {
00071
00072 if (wxTheApp == NULL)
00073 {
00074
00075 int fake_argc = 0;
00076 char** fake_argv = NULL;
00077 wxEntryStart(fake_argc, fake_argv);
00078 }
00079 else
00080 {
00081
00082 }
00083 }
00084
00085 pcl_visualization::ImageWidgetWX::~ImageWidgetWX ()
00086 {
00087
00088 if (image_frame != NULL)
00089 {
00090 image_frame->parentImageWidget = NULL;
00091 image_frame->Close (true);
00092
00093 }
00094 free (image_data);
00095 }
00096
00097 void
00098 pcl_visualization::ImageWidgetWX::reset ()
00099 {
00100 mouse_click_happened = false;
00101 last_clicked_point_x = -1.0f;
00102 last_clicked_point_y = -1.0f;
00103 if (image_frame==NULL)
00104 image_frame = new ImageFrame (this);
00105 image_frame->image_panel->markedPoints.clear ();
00106 image_frame->image_panel->lines.clear ();
00107 }
00108
00109
00110
00111
00112
00113
00114 void
00115 pcl_visualization::ImageWidgetWX::setSize (int width, int height)
00116 {
00117 int original_width = image_frame->image_panel->image->GetWidth (),
00118 original_height = image_frame->image_panel->image->GetHeight ();
00119
00120 if (width <= 0 && height <= 0)
00121 {
00122 width = original_width;
00123 height=original_height;
00124 }
00125 else if (width <= 0)
00126 {
00127 width = lrint(float(original_width) * float(height)/float(original_height));
00128 }
00129 else if (height <= 0)
00130 {
00131 height = lrint(float(original_height) * float(width)/float(original_width));
00132 }
00133
00134 image_frame->SetSize (wxSize (width, height));
00135 }
00136
00137 void
00138 pcl_visualization::ImageWidgetWX::setRGBImage (const unsigned char* data,
00139 unsigned int width, unsigned int height, const char* name)
00140 {
00141
00142 reset ();
00143
00144 if (width==0 || height==0)
00145 {
00146 std::cerr << __PRETTY_FUNCTION__ << ": image has size 0.\n";
00147 return;
00148 }
00149
00150 unsigned int arraySize = 3*width*height;
00151 if (data == NULL) arraySize=0;
00152
00153 image_data = (unsigned char*)realloc(image_data, arraySize);
00154 memcpy (image_data, data, arraySize);
00155
00156 image_frame->updateImage (image_data, width, height);
00157 image_frame->SetTitle (wxString (name, wxConvUTF8));
00158 image_frame->image_panel->resizeImage ();
00159 image_frame->Refresh ();
00160 image_frame->Show ();
00161 }
00162
00163 void
00164 pcl_visualization::ImageWidgetWX::setName (const std::string& name)
00165 {
00166 image_frame->SetTitle (wxString (name.c_str(), wxConvUTF8));
00167
00168 }
00169
00170 void
00171 pcl_visualization::ImageWidgetWX::setFloatImage (const float* float_image, unsigned int width, unsigned int height,
00172 const char* name, float min_value, float max_value, bool grayscale)
00173 {
00174 unsigned char* rgb_image = FloatImageUtils::getVisualImage (float_image, width, height,
00175 min_value, max_value, grayscale);
00176 setRGBImage (rgb_image, width, height, name);
00177 delete[] rgb_image;
00178 }
00179
00180 void
00181 pcl_visualization::ImageWidgetWX::setAngleImage (const float* angle_image, unsigned int width, unsigned int height,
00182 const char* name)
00183 {
00184 unsigned char* rgb_image = FloatImageUtils::getVisualAngleImage (angle_image, width, height);
00185 setRGBImage (rgb_image, width, height, name);
00186 delete[] rgb_image;
00187 }
00188
00189 void
00190 pcl_visualization::ImageWidgetWX::setHalfAngleImage (const float* angle_image, unsigned int width,
00191 unsigned int height, const char* name)
00192 {
00193 unsigned char* rgb_image = FloatImageUtils::getVisualHalfAngleImage (angle_image, width, height);
00194 setRGBImage (rgb_image, width, height, name);
00195 delete[] rgb_image;
00196 }
00197
00198 void
00199 pcl_visualization::ImageWidgetWX::informAboutImageFrameDestruction ()
00200 {
00201
00202 image_frame = NULL;
00203 }
00204
00205 void
00206 pcl_visualization::ImageWidgetWX::markPoint (float x, float y, const wxPen* color, const wxBrush* background)
00207 {
00208 image_frame->image_panel->markedPoints.push_back (ImagePoint (x,y, color, background));
00209 }
00210
00211 void
00212 pcl_visualization::ImageWidgetWX::markLine (float x1, float y1, float x2, float y2, const wxPen* color)
00213 {
00214 image_frame->image_panel->lines.push_back (ImageLine (x1, y1, x2, y2, color));
00215 }
00216
00217 bool
00218 pcl_visualization::ImageWidgetWX::isShown () const
00219 {
00220 if (image_frame==NULL) return false;
00221 return image_frame->IsShown ();
00222 }
00223
00224 void
00225 pcl_visualization::ImageWidgetWX::addPixelClickedHandler (PixelClickedHandler pixel_clicked_handler)
00226 {
00227 image_frame->image_panel->pixel_clicked_handlers.push_back (pixel_clicked_handler);
00228 }
00229
00230 void
00231 pcl_visualization::ImageWidgetWX::show (bool show_widget)
00232 {
00233 if (image_frame != NULL)
00234 image_frame->Show (show_widget);
00235 }
00236
00237
00238
00239
00240
00241
00242
00243 pcl_visualization::ImageWidgetWX::ImageFrame::ImageFrame (ImageWidgetWX* parentImageWidget) :
00244 wxFrame (NULL, wxID_ANY, wxString (__func__, wxConvUTF8), wxPoint (50, 50), wxSize (800, 600)),
00245 parentImageWidget (parentImageWidget)
00246 {
00247 image_panel = new ImagePanel (this);
00248
00249
00250
00251 }
00252
00253 pcl_visualization::ImageWidgetWX::ImageFrame::~ImageFrame()
00254 {
00255
00256 if (parentImageWidget != NULL)
00257 parentImageWidget->informAboutImageFrameDestruction ();
00258
00259 }
00260
00261 BEGIN_EVENT_TABLE (pcl_visualization::ImageWidgetWX::ImageFrame, wxFrame)
00262
00263 EVT_SIZE (pcl_visualization::ImageWidgetWX::ImageFrame::OnSize)
00264 EVT_CLOSE (pcl_visualization::ImageWidgetWX::ImageFrame::OnClose)
00265 END_EVENT_TABLE ()
00266
00267 void
00268 pcl_visualization::ImageWidgetWX::ImageFrame::OnSize(wxSizeEvent& event)
00269 {
00270
00271 Fit ();
00272 event.Skip ();
00273 }
00274
00275 void
00276 pcl_visualization::ImageWidgetWX::ImageFrame::OnClose (wxCloseEvent& event)
00277 {
00278
00279
00280 event.Skip ();
00281 }
00282
00283 void
00284 pcl_visualization::ImageWidgetWX::ImageFrame::updateImage (unsigned char* data,
00285 unsigned int width, unsigned int height)
00286 {
00287
00288
00289
00290 delete image_panel->image;
00291 image_panel->image = NULL;
00292
00293 if (data == NULL) return;
00294
00295 bool letWxDeleteIt = false;
00296 image_panel->image = new wxImage (width, height, data, !letWxDeleteIt);
00297 }
00298
00299
00300
00301
00302
00303
00304 BEGIN_EVENT_TABLE (pcl_visualization::ImageWidgetWX::ImagePanel, wxPanel)
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314 EVT_LEFT_UP (pcl_visualization::ImageWidgetWX::ImagePanel::mouseReleased)
00315 EVT_PAINT (pcl_visualization::ImageWidgetWX::ImagePanel::paintEvent)
00316 EVT_SIZE (pcl_visualization::ImageWidgetWX::ImagePanel::OnSize)
00317 END_EVENT_TABLE ()
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328 pcl_visualization::ImageWidgetWX::ImagePanel::ImagePanel (wxFrame* parent) : wxPanel (parent), image (NULL),
00329 scaledWidth (0), scaledHeight (0)
00330 {
00331 }
00332
00333 pcl_visualization::ImageWidgetWX::ImagePanel::~ImagePanel ()
00334 {
00335
00336 }
00337
00338
00339
00340
00341
00342
00343 void
00344 pcl_visualization::ImageWidgetWX::ImagePanel::paintEvent (wxPaintEvent & evt)
00345 {
00346
00347
00348 wxPaintDC dc (this);
00349 render (dc);
00350 }
00351
00352 void
00353 pcl_visualization::ImageWidgetWX::ImagePanel::mouseReleased (wxMouseEvent& event)
00354 {
00355
00356 float clicked_pixel_x = (float)event.m_x * (float)image->GetWidth ()/(float)scaledWidth -0.5f,
00357 clicked_pixel_y = (float)event.m_y * (float)image->GetHeight ()/(float)scaledHeight -0.5f;
00358 getParentImageWidget()->mouse_click_happened = true;
00359 getParentImageWidget()->last_clicked_point_x = clicked_pixel_x;
00360 getParentImageWidget()->last_clicked_point_y = clicked_pixel_y;
00361
00362
00363
00364 if (getParentImageWidget()->print_selected_point)
00365 cout << "ImageWidgetWX: Clicked image point is " << clicked_pixel_x<<", "<<clicked_pixel_y<<".\n";
00366
00367 for (unsigned int i = 0; i < pixel_clicked_handlers.size(); ++i)
00368 pixel_clicked_handlers[i] (clicked_pixel_x, clicked_pixel_y);
00369 Refresh ();
00370 }
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381 void
00382 pcl_visualization::ImageWidgetWX::ImagePanel::paintNow ()
00383 {
00384
00385 wxClientDC dc (this);
00386 render (dc);
00387 }
00388
00389
00390
00391
00392
00393
00394 void
00395 pcl_visualization::ImageWidgetWX::ImagePanel::render (wxDC& dc)
00396 {
00397
00398 if (image==NULL) return;
00399
00400 int newWidth, newHeight;
00401 dc.GetSize (&newWidth, &newHeight);
00402
00403 if (newWidth != scaledWidth || newHeight != scaledHeight)
00404 {
00405 resizeImage (newWidth, newHeight);
00406 }
00407 dc.DrawBitmap (resized_, 0, 0, false);
00408
00409 int circleSize = 4;
00410 for (unsigned int i = 0; i < markedPoints.size (); ++i)
00411 {
00412 const ImagePoint& point = markedPoints.at (i);
00413 dc.SetPen (*point.color);
00414 dc.SetBrush (*point.background);
00415 dc.DrawEllipse (lrint ((point.x+0.5f)*scaledWidth / image->GetWidth ())-0.5f*circleSize,
00416 lrint ((point.y+0.5f)*scaledHeight / image->GetHeight ())-0.5f*circleSize, circleSize, circleSize);
00417 }
00418
00419 for (unsigned int i = 0; i < lines.size (); ++i)
00420 {
00421 const ImageLine& line = lines.at (i);
00422 wxPoint points_array[2];
00423 points_array[0].x = lrint ((line.x1+0.5f)*scaledWidth / image->GetWidth ());
00424 points_array[0].y = lrint ((line.y1+0.5f)*scaledHeight / image->GetHeight ());
00425 points_array[1].x = lrint((line.x2+0.5f)*scaledWidth / image->GetWidth ());
00426 points_array[1].y = lrint((line.y2+0.5f)*scaledHeight / image->GetHeight ());
00427 wxPen pen(*line.color);
00428 pen.SetWidth(3);
00429 dc.SetPen(pen);
00430 dc.DrawLines (2, points_array);
00431 }
00432
00433 if (getParentImageWidget()->visualize_selected_point)
00434 {
00435 int selected_x = getParentImageWidget()->last_clicked_point_x,
00436 selected_y = getParentImageWidget()->last_clicked_point_y;
00437 if (selected_x >= 0 && selected_y >= 0)
00438 {
00439 wxPen pen(*wxGREEN, 2);
00440 dc.SetPen (pen);
00441 dc.CrossHair (lrint((selected_x+0.5f)*scaledWidth / image->GetWidth ()),
00442 lrint((selected_y+0.5f)*scaledHeight / image->GetHeight ()));
00443 }
00444 }
00445 }
00446
00447
00448
00449
00450
00451 void
00452 pcl_visualization::ImageWidgetWX::ImagePanel::OnSize (wxSizeEvent& event)
00453 {
00454 event.Skip ();
00455 if (getParentImageWidget ()->keepAspectRatio)
00456 {
00457 float aspectRatio = (float)image->GetWidth () / (float)image->GetHeight ();
00458 SetSize (wxDefaultCoord, wxDefaultCoord, event.GetSize ().GetWidth (),
00459 lrint((float)event.GetSize ().GetWidth () / aspectRatio));
00460 }
00461 Refresh ();
00462 }
00463
00464 void
00465 pcl_visualization::ImageWidgetWX::ImagePanel::resizeImage (int newWidth, int newHeight)
00466 {
00467 if (newWidth<=0 || newHeight<=0)
00468 this->GetSize (&newWidth, &newHeight);
00469
00470 resized_ = wxBitmap (image->Scale (newWidth, newHeight));
00471
00472 scaledWidth = newWidth;
00473 scaledHeight = newHeight;
00474
00475 }
00476