From 462d516743bf9bc5d6fc8eabe1a250828e6b8bae Mon Sep 17 00:00:00 2001 From: Anatoly Baksheev Date: Fri, 10 Jan 2014 00:31:27 +0400 Subject: [PATCH] added test for camera positions, slightly refactored the widgets --- modules/viz/src/shapes.cpp | 140 ++++++++++++++++---------------------- modules/viz/test/tests_simple.cpp | 27 ++++++++ 2 files changed, 86 insertions(+), 81 deletions(-) diff --git a/modules/viz/src/shapes.cpp b/modules/viz/src/shapes.cpp index f4b68a9..422ea9b 100644 --- a/modules/viz/src/shapes.cpp +++ b/modules/viz/src/shapes.cpp @@ -622,29 +622,29 @@ cv::viz::WImageOverlay::WImageOverlay(const Mat &image, const Rect &rect) ConvertToVtkImage::convert(image, vtk_image); // Need to flip the image as the coordinates are different in OpenCV and VTK - vtkSmartPointer flipFilter = vtkSmartPointer::New(); - flipFilter->SetFilteredAxis(1); // Vertical flip - flipFilter->SetInputConnection(vtk_image->GetProducerPort()); - flipFilter->Update(); + vtkSmartPointer flip_filter = vtkSmartPointer::New(); + flip_filter->SetFilteredAxis(1); // Vertical flip + flip_filter->SetInputConnection(vtk_image->GetProducerPort()); + flip_filter->Update(); // Scale the image based on the Rect vtkSmartPointer transform = vtkSmartPointer::New(); - transform->Scale(double(image.cols)/rect.width,double(image.rows)/rect.height,1.0); + transform->Scale(image.cols/(double)rect.width, image.rows/(double)rect.height, 1.0); vtkSmartPointer image_reslice = vtkSmartPointer::New(); image_reslice->SetResliceTransform(transform); - image_reslice->SetInputConnection(flipFilter->GetOutputPort()); + image_reslice->SetInputConnection(flip_filter->GetOutputPort()); image_reslice->SetOutputDimensionality(2); image_reslice->InterpolateOn(); image_reslice->AutoCropOutputOn(); - vtkSmartPointer imageMapper = vtkSmartPointer::New(); - imageMapper->SetInputConnection(image_reslice->GetOutputPort()); - imageMapper->SetColorWindow(255); // OpenCV color - imageMapper->SetColorLevel(127.5); + vtkSmartPointer image_mapper = vtkSmartPointer::New(); + image_mapper->SetInputConnection(image_reslice->GetOutputPort()); + image_mapper->SetColorWindow(255); // OpenCV color + image_mapper->SetColorLevel(127.5); vtkSmartPointer actor = vtkSmartPointer::New(); - actor->SetMapper(imageMapper); + actor->SetMapper(image_mapper); actor->SetPosition(rect.x, rect.y); WidgetAccessor::setProp(*this, actor); @@ -820,11 +820,33 @@ namespace cv { namespace viz { namespace { struct CameraPositionUtils { - static void projectImage(double fovy, double far_end_height, const Mat &image, - double scale, const Color &color, vtkSmartPointer actor) + static vtkSmartPointer createFrustum(double aspect_ratio, double fovy, double scale) { - // Create a camera vtkSmartPointer camera = vtkSmartPointer::New(); + camera->SetViewAngle(fovy); + camera->SetPosition(0.0, 0.0, 0.0); + camera->SetViewUp(0.0, 1.0, 0.0); + camera->SetFocalPoint(0.0, 0.0, 1.0); + camera->SetClippingRange(1e-9, scale); + + double planes_array[24]; + camera->GetFrustumPlanes(aspect_ratio, planes_array); + + vtkSmartPointer planes = vtkSmartPointer::New(); + planes->SetFrustumPlanes(planes_array); + + vtkSmartPointer frustumSource = vtkSmartPointer::New(); + frustumSource->SetPlanes(planes); + + vtkSmartPointer extract_edges = vtkSmartPointer::New(); + extract_edges->SetInputConnection(frustumSource->GetOutputPort()); + extract_edges->Update(); + + return extract_edges->GetOutput(); + } + + static vtkSmartPointer projectImage(double fovy, double far_end_height, const Mat &image, double scale, const Color &color) + { float aspect_ratio = float(image.cols)/float(image.rows); // Create the vtk image @@ -832,66 +854,47 @@ namespace cv { namespace viz { namespace ConvertToVtkImage::convert(image, vtk_image); // Adjust a pixel of the vtk_image - vtk_image->SetScalarComponentFromDouble(0, image.rows-1, 0, 0, color[2]); - vtk_image->SetScalarComponentFromDouble(0, image.rows-1, 0, 1, color[1]); - vtk_image->SetScalarComponentFromDouble(0, image.rows-1, 0, 2, color[0]); - - // Need to flip the image as the coordinates are different in OpenCV and VTK - vtkSmartPointer flipFilter = vtkSmartPointer::New(); - flipFilter->SetFilteredAxis(1); // Vertical flip - flipFilter->SetInputConnection(vtk_image->GetProducerPort()); - flipFilter->Update(); + if(image.channels() == 1) + { + double gray = color[2] * 0.299 + color[1] * 0.578 + color[0] * 0.144; + vtk_image->SetScalarComponentFromDouble(0, 0, 0, 0, gray); + } + else + { + vtk_image->SetScalarComponentFromDouble(0, 0, 0, 0, color[2]); + vtk_image->SetScalarComponentFromDouble(0, 0, 0, 1, color[1]); + vtk_image->SetScalarComponentFromDouble(0, 0, 0, 2, color[0]); + } Vec3d plane_center(0.0, 0.0, scale); vtkSmartPointer plane = vtkSmartPointer::New(); - plane->SetCenter(plane_center[0], plane_center[1], plane_center[2]); + plane->SetCenter(plane_center.val); plane->SetNormal(0.0, 0.0, 1.0); vtkSmartPointer transform = vtkSmartPointer::New(); transform->PreMultiply(); - transform->Translate(plane_center[0], plane_center[1], plane_center[2]); + transform->Translate(plane_center.val); transform->Scale(far_end_height*aspect_ratio, far_end_height, 1.0); transform->RotateY(180.0); transform->Translate(-plane_center[0], -plane_center[1], -plane_center[2]); // Apply the texture vtkSmartPointer texture = vtkSmartPointer::New(); - texture->SetInputConnection(flipFilter->GetOutputPort()); + texture->SetInputConnection(vtk_image->GetProducerPort()); - vtkSmartPointer texturePlane = vtkSmartPointer::New(); - texturePlane->SetInputConnection(plane->GetOutputPort()); + vtkSmartPointer texture_plane = vtkSmartPointer::New(); + texture_plane->SetInputConnection(plane->GetOutputPort()); vtkSmartPointer transform_filter = vtkSmartPointer::New(); + transform_filter->SetInputConnection(texture_plane->GetOutputPort()); transform_filter->SetTransform(transform); - transform_filter->SetInputConnection(texturePlane->GetOutputPort()); - transform_filter->Update(); - - // Create frustum - camera->SetViewAngle(fovy); - camera->SetPosition(0.0, 0.0, 0.0); - camera->SetViewUp(0.0, 1.0, 0.0); - camera->SetFocalPoint(0.0, 0.0, 1.0); - camera->SetClippingRange(0.01, scale); - double planesArray[24]; - camera->GetFrustumPlanes(aspect_ratio, planesArray); - - vtkSmartPointer planes = vtkSmartPointer::New(); - planes->SetFrustumPlanes(planesArray); - - vtkSmartPointer frustumSource = - vtkSmartPointer::New(); - frustumSource->SetPlanes(planes); - frustumSource->Update(); - - vtkSmartPointer filter = vtkSmartPointer::New(); - filter->SetInputConnection(frustumSource->GetOutputPort()); - filter->Update(); + vtkSmartPointer frustum = createFrustum(aspect_ratio, fovy, scale); // Frustum needs to be textured or else it can't be combined with image vtkSmartPointer frustum_texture = vtkSmartPointer::New(); - frustum_texture->SetInputConnection(filter->GetOutputPort()); + frustum_texture->SetInputConnection(frustum->GetProducerPort()); // Texture mapping with only one pixel from the image to have constant color frustum_texture->SetSRange(0.0, 0.0); frustum_texture->SetTRange(0.0, 0.0); @@ -903,35 +906,12 @@ namespace cv { namespace viz { namespace vtkSmartPointer planeMapper = vtkSmartPointer::New(); planeMapper->SetInputConnection(appendFilter->GetOutputPort()); + vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(planeMapper); actor->SetTexture(texture); - } - static vtkSmartPointer createFrustum(double aspect_ratio, double fovy, double scale) - { - vtkSmartPointer camera = vtkSmartPointer::New(); - camera->SetViewAngle(fovy); - camera->SetPosition(0.0, 0.0, 0.0); - camera->SetViewUp(0.0, 1.0, 0.0); - camera->SetFocalPoint(0.0, 0.0, 1.0); - camera->SetClippingRange(1e-9, scale); - - double planesArray[24]; - camera->GetFrustumPlanes(aspect_ratio, planesArray); - - vtkSmartPointer planes = vtkSmartPointer::New(); - planes->SetFrustumPlanes(planesArray); - - vtkSmartPointer frustumSource = vtkSmartPointer::New(); - frustumSource->SetPlanes(planes); - - vtkSmartPointer extract_edges = vtkSmartPointer::New(); - extract_edges->SetInputConnection(frustumSource->GetOutputPort()); - extract_edges->Update(); - - return extract_edges->GetOutput(); + return actor; } - }; }}} @@ -994,8 +974,7 @@ cv::viz::WCameraPosition::WCameraPosition(const Matx33d &K, const Mat &image, do double fovy = 2.0 * atan2(c_y, f_y) * 180.0 / CV_PI; double far_end_height = 2.00 * c_y * scale / f_y; - vtkSmartPointer actor = vtkSmartPointer::New(); - CameraPositionUtils::projectImage(fovy, far_end_height, image, scale, color, actor); + vtkSmartPointer actor = CameraPositionUtils::projectImage(fovy, far_end_height, image, scale, color); WidgetAccessor::setProp(*this, actor); } @@ -1005,8 +984,7 @@ cv::viz::WCameraPosition::WCameraPosition(const Vec2d &fov, const Mat &image, do double fovy = fov[1] * 180.0 / CV_PI; double far_end_height = 2.0 * scale * tan(fov[1] * 0.5); - vtkSmartPointer actor = vtkSmartPointer::New(); - CameraPositionUtils::projectImage(fovy, far_end_height, image, scale, color, actor); + vtkSmartPointer actor = CameraPositionUtils::projectImage(fovy, far_end_height, image, scale, color); WidgetAccessor::setProp(*this, actor); } diff --git a/modules/viz/test/tests_simple.cpp b/modules/viz/test/tests_simple.cpp index 4fd0dc4..4f37f32 100644 --- a/modules/viz/test/tests_simple.cpp +++ b/modules/viz/test/tests_simple.cpp @@ -199,6 +199,33 @@ TEST(Viz, DISABLED_show_trajectory_reposition) } + +TEST(Viz, show_camera_positions) +{ + Mat lena = imread(Path::combine(cvtest::TS::ptr()->get_data_path(), "lena.png")); + Mat chs[3]; split(lena, chs); + Mat gray = 0.114 * chs[0] + 0.58 * chs[1] + 0.3 * chs[2]; + + Matx33d K(1024.0, 0.0, 320.0, 0.0, 1024.0, 240.0, 0.0, 0.0, 1.0); + + Affine3d poses[2]; + for(int i = 0; i < 2; ++i) + { + Vec3d pose = 5 * Vec3d(sin(3.14 + 2.7 + i*60 * CV_PI/180), 0.4 - i*0.3, cos(3.14 + 2.7 + i*60 * CV_PI/180)); + poses[i] = makeCameraPose(pose, Vec3d(0.0, 0.0, 0.0), Vec3d(0.0, -0.1, 0.0)); + } + + Viz3d viz("show_camera_positions"); + viz.showWidget("sphe", WSphere(Point3d(0,0,0), 1.0)); + viz.showWidget("coos", WCoordinateSystem(1.5)); + viz.showWidget("pos1", WCameraPosition(0.75), poses[0]); + viz.showWidget("pos2", WCameraPosition(Vec2d(0.78, 0.78), lena, 2.2, Color::green()), poses[0]); + + viz.showWidget("pos3", WCameraPosition(0.75), poses[1]); + viz.showWidget("pos4", WCameraPosition(K, gray, 3, Color::indigo()), poses[1]); + viz.spin(); +} + TEST(Viz, DISABLED_spin_twice_____________________________TODO_UI_BUG) { Mesh mesh = Mesh::load(get_dragon_ply_file_path()); -- 2.7.4