diff --git a/modules/viz/include/opencv2/viz/widgets.hpp b/modules/viz/include/opencv2/viz/widgets.hpp
index 44cb50074..455c96557 100644
--- a/modules/viz/include/opencv2/viz/widgets.hpp
+++ b/modules/viz/include/opencv2/viz/widgets.hpp
@@ -211,7 +211,6 @@ namespace cv
         {
         public:
             WImageOverlay(const Mat &image, const Rect &rect);
-
             void setImage(const Mat &image);
         };
 
diff --git a/modules/viz/src/shapes.cpp b/modules/viz/src/shapes.cpp
index 2067c5c9e..5dffbfa0e 100644
--- a/modules/viz/src/shapes.cpp
+++ b/modules/viz/src/shapes.cpp
@@ -616,21 +616,17 @@ cv::String cv::viz::WText::getText() const
 cv::viz::WImageOverlay::WImageOverlay(const Mat &image, const Rect &rect)
 {
     CV_Assert(!image.empty() && image.depth() == CV_8U);
-
     vtkSmartPointer<vtkImageMatSource> source = vtkSmartPointer<vtkImageMatSource>::New();
     source->SetImage(image);
 
-    vtkSmartPointer<vtkImageFlip> flip_filter = vtkSmartPointer<vtkImageFlip>::New();
-    flip_filter->SetInputConnection(source->GetOutputPort());
-    flip_filter->SetFilteredAxis(1);
-
-    // Scale the image based on the Rect
+    // Scale the image based on the Rect, and flip to match y-ais orientation
     vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
     transform->Scale(image.cols/(double)rect.width, image.rows/(double)rect.height, 1.0);
+    transform->RotateX(180);
 
     vtkSmartPointer<vtkImageReslice> image_reslice = vtkSmartPointer<vtkImageReslice>::New();
     image_reslice->SetResliceTransform(transform);
-    image_reslice->SetInputConnection(flip_filter->GetOutputPort());
+    image_reslice->SetInputConnection(source->GetOutputPort());
     image_reslice->SetOutputDimensionality(2);
     image_reslice->InterpolateOn();
     image_reslice->AutoCropOutputOn();
@@ -657,16 +653,29 @@ void cv::viz::WImageOverlay::setImage(const Mat &image)
 
     vtkImageMapper *mapper = vtkImageMapper::SafeDownCast(actor->GetMapper());
     CV_Assert("This widget does not support overlay image." && mapper);
+    \
+    Vec6i extent;
+    mapper->GetInput()->GetExtent(extent.val);
+    Size size(extent[1], extent[3]);
 
     // Create the vtk image and set its parameters based on input image
     vtkSmartPointer<vtkImageMatSource> source = vtkSmartPointer<vtkImageMatSource>::New();
     source->SetImage(image);
 
-    vtkSmartPointer<vtkImageFlip> flip_filter = vtkSmartPointer<vtkImageFlip>::New();
-    flip_filter->SetInputConnection(source->GetOutputPort());
-    flip_filter->SetFilteredAxis(1);
+    // Scale the image based on the Rect, and flip to match y-ais orientation
+    vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
+    transform->Scale(image.cols/(double)size.width, image.rows/(double)size.height, 1.0);
+    transform->RotateX(180);
 
-    mapper->SetInputConnection(flip_filter->GetOutputPort());
+    vtkSmartPointer<vtkImageReslice> image_reslice = vtkSmartPointer<vtkImageReslice>::New();
+    image_reslice->SetResliceTransform(transform);
+    image_reslice->SetInputConnection(source->GetOutputPort());
+    image_reslice->SetOutputDimensionality(2);
+    image_reslice->InterpolateOn();
+    image_reslice->AutoCropOutputOn();
+    image_reslice->Update();
+
+    mapper->SetInputConnection(image_reslice->GetOutputPort());
 }
 
 template<> cv::viz::WImageOverlay cv::viz::Widget::cast<cv::viz::WImageOverlay>()
diff --git a/modules/viz/test/tests_simple.cpp b/modules/viz/test/tests_simple.cpp
index 6bca25588..ff35bd416 100644
--- a/modules/viz/test/tests_simple.cpp
+++ b/modules/viz/test/tests_simple.cpp
@@ -221,17 +221,22 @@ TEST(Viz, DISABLED_show_camera_positions)
     viz.spin();
 }
 
-TEST(Viz, show_overlay_image)
+TEST(Viz, DISABLED_show_overlay_image)
 {
     Mat lena = imread(Path::combine(cvtest::TS::ptr()->get_data_path(), "lena.png"));
     Mat gray = make_gray(lena);
 
+    Size2d half_lsize = Size2d(lena.size()) * 0.5;
+
     Viz3d viz("show_overlay_image");
+    Size vsz = viz.getWindowSize();
+
     viz.showWidget("coos", WCoordinateSystem());
     viz.showWidget("cube", WCube());
-    viz.showWidget("img1", WImageOverlay(lena, Rect(Point(0, 400), Size2d(viz.getWindowSize()) * 0.5)));
-    viz.showWidget("img2", WImageOverlay(gray, Rect(Point(640, 0), Size2d(viz.getWindowSize()) * 0.5)));
-    viz.spin();
+    viz.showWidget("img1", WImageOverlay(lena, Rect(Point(10, 10), half_lsize)));
+    viz.showWidget("img2", WImageOverlay(gray, Rect(Point(vsz.width-10-lena.cols/2, 10), half_lsize)));
+    viz.showWidget("img3", WImageOverlay(gray, Rect(Point(10, vsz.height-10-lena.rows/2), half_lsize)));
+    viz.showWidget("img5", WImageOverlay(lena, Rect(Point(vsz.width-10-lena.cols/2, vsz.height-10-lena.rows/2), half_lsize)));
 
     int i = 0;
     while(!viz.wasStopped())
@@ -239,9 +244,7 @@ TEST(Viz, show_overlay_image)
         double a = ++i % 360;
         Vec3d pose(sin(a * CV_PI/180), 0.7, cos(a * CV_PI/180));
         viz.setViewerPose(makeCameraPose(pose * 3, Vec3d(0.0, 0.5, 0.0), Vec3d(0.0, 0.1, 0.0)));
-
         viz.getWidget("img1").cast<WImageOverlay>().setImage(lena * pow(sin(i*10*CV_PI/180) * 0.5 + 0.5, 1.0));
-        //viz.getWidget("img1").cast<WImageOverlay>().setImage(gray);
         viz.spinOnce(1, true);
     }
     //viz.spin();