diff --git a/cmake/OpenCVExtraTargets.cmake b/cmake/OpenCVExtraTargets.cmake index e766f7a603..4b9a078423 100644 --- a/cmake/OpenCVExtraTargets.cmake +++ b/cmake/OpenCVExtraTargets.cmake @@ -1,17 +1,22 @@ # ---------------------------------------------------------------------------- # Uninstall target, for "make uninstall" # ---------------------------------------------------------------------------- -CONFIGURE_FILE( - "${OpenCV_SOURCE_DIR}/cmake/templates/cmake_uninstall.cmake.in" - "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" - @ONLY) +if(NOT TARGET uninstall) # avoid conflicts with parent projects + configure_file( + "${OpenCV_SOURCE_DIR}/cmake/templates/cmake_uninstall.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" + @ONLY + ) -ADD_CUSTOM_TARGET(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") -if(ENABLE_SOLUTION_FOLDERS) - set_target_properties(uninstall PROPERTIES FOLDER "CMakeTargets") + add_custom_target(uninstall + COMMAND "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" + ) + + if(ENABLE_SOLUTION_FOLDERS) + set_target_properties(uninstall PROPERTIES FOLDER "CMakeTargets") + endif() endif() - # ---------------------------------------------------------------------------- # target building all OpenCV modules # ---------------------------------------------------------------------------- diff --git a/cmake/templates/cmake_uninstall.cmake.in b/cmake/templates/cmake_uninstall.cmake.in index 0e63d705cd..ef23c3d2d2 100644 --- a/cmake/templates/cmake_uninstall.cmake.in +++ b/cmake/templates/cmake_uninstall.cmake.in @@ -1,25 +1,28 @@ # ----------------------------------------------- # File that provides "make uninstall" target # We use the file 'install_manifest.txt' +# +# Details: https://gitlab.kitware.com/cmake/community/-/wikis/FAQ#can-i-do-make-uninstall-with-cmake # ----------------------------------------------- -IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") - MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") -ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") -FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) -STRING(REGEX REPLACE "\n" ";" files "${files}") -FOREACH(file ${files}) - MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") - IF(EXISTS "$ENV{DESTDIR}${file}") - EXEC_PROGRAM( - "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" - OUTPUT_VARIABLE rm_out - RETURN_VALUE rm_retval - ) - IF(NOT "${rm_retval}" STREQUAL 0) - MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") - ENDIF(NOT "${rm_retval}" STREQUAL 0) - ELSE(EXISTS "$ENV{DESTDIR}${file}") - MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") - ENDIF(EXISTS "$ENV{DESTDIR}${file}") -ENDFOREACH(file) +if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt") + message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_BINARY_DIR@/install_manifest.txt\"") +endif() + +file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files) +string(REGEX REPLACE "\n" ";" files "${files}") +foreach(file ${files}) + message(STATUS "Uninstalling $ENV{DESTDIR}${file}") + if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + exec_program( + "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval + ) + if(NOT "${rm_retval}" STREQUAL 0) + message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}") + endif() + else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}") + message(STATUS "File $ENV{DESTDIR}${file} does not exist.") + endif() +endforeach() diff --git a/doc/faq.markdown b/doc/faq.markdown index 3bf574ae2d..92e5b62709 100644 --- a/doc/faq.markdown +++ b/doc/faq.markdown @@ -1,23 +1,4 @@ Frequently Asked Questions {#faq} ========================== -- **What is InputArray?** - - It can be seen that almost all OpenCV functions receive InputArray type. - What is it, and how can I understand the actual input types of parameters? - - - This is the proxy class for passing read-only input arrays into OpenCV functions. - - Inside a function you should use cv::_InputArray::getMat() method to construct -a matrix header for the array (without copying data). cv::_InputArray::kind() can be used to distinguish Mat from vector<> etc. -but normally it is not needed. - - for more information see cv::_InputArray - -- **Which is more efficient, use contourArea() or count number of ROI non-zero pixels?** - - In a case where you only want relative areas, which one is faster to compute: - calculate a contour area or count the number of ROI non-zero pixels? - - cv::contourArea() uses Green formula (http://en.wikipedia.org/wiki/Green's_theorem) to compute the area, therefore its complexity is O(contour_number_of_vertices). Counting non-zero pixels in the ROI is O(roi_width*roi_height) algorithm, i.e. much slower. Note, however, that because of finite, and quite low, resolution of the raster grid, the two algorithms will give noticeably different results. For large and square-like contours the error will be minimal. For small and/or oblong contours the error can be quite large. +Compatibility page. FAQ migrated to the project [wiki](https://github.com/opencv/opencv/wiki/FAQ). diff --git a/modules/dnn/src/tensorflow/tf_importer.cpp b/modules/dnn/src/tensorflow/tf_importer.cpp index c741446717..ca4b8dbe9d 100644 --- a/modules/dnn/src/tensorflow/tf_importer.cpp +++ b/modules/dnn/src/tensorflow/tf_importer.cpp @@ -1402,9 +1402,17 @@ void TFImporter::populateNet(Net dstNet) netInputsNames.push_back(name); layer_id[name] = 0; } + tensorflow::TensorShapeProto shape; if (hasLayerAttr(layer, "shape")) + shape = getLayerAttr(layer, "shape").shape(); + else if (hasLayerAttr(layer, "_output_shapes")) + { + tensorflow::AttrValue_ListValue list = getLayerAttr(layer, "_output_shapes").list(); + if (list.shape_size()) + shape = list.shape()[0]; + } + if (shape.dim_size()) { - const tensorflow::TensorShapeProto& shape = getLayerAttr(layer, "shape").shape(); MatShape dims(shape.dim_size()); for (int i = 0; i < dims.size(); ++i) dims[i] = shape.dim(i).size(); @@ -1868,8 +1876,31 @@ void TFImporter::populateNet(Net dstNet) connect(layer_id, dstNet, parsePin(layer.input(1)), id, 0); data_layouts[name] = DATA_LAYOUT_UNKNOWN; } - else if (type == "ResizeNearestNeighbor" || type == "ResizeBilinear") + else if (type == "ResizeNearestNeighbor" || type == "ResizeBilinear" || type == "FusedResizeAndPadConv2D") { + std::string convWeights = ""; + if (type == "FusedResizeAndPadConv2D") + { + // input: "mul_1" + // input: "decoder/ResizeBilinear/size" + // input: "decoder/decoder_conv0/Conv2D_dummy_paddings" + // input: "decoder/decoder_conv0/weights" + CV_CheckEQ(layer.input_size(), 4, "Number of input for FusedResizeAndPadConv2D"); + + Mat paddings = getTensorContent(getConstBlob(layer, value_id, 2)); + CV_CheckEQ(countNonZero(paddings), 0, "Unsupported mode"); + + convWeights = layer.input(3); + layer.mutable_input()->DeleteSubrange(2, 2); + name = name + "/resize"; + + if (hasLayerAttr(layer, "resize_align_corners")) + { + layer.mutable_attr()->insert( + ::google::protobuf::MapPair("align_corners", + getLayerAttr(layer, "resize_align_corners"))); + } + } if (layer.input_size() == 2) { Mat outSize = getTensorContent(getConstBlob(layer, value_id, 1)); @@ -1901,6 +1932,17 @@ void TFImporter::populateNet(Net dstNet) layer_id[name] = id; connect(layer_id, dstNet, parsePin(layer.input(0)), id, 0); + + // Step back to add convolution + if (type == "FusedResizeAndPadConv2D") + { + tensorflow::NodeDef* conv = net.mutable_node(li); + conv->clear_input(); + conv->add_input(name); + conv->add_input(convWeights); + conv->set_op("Conv2D"); + li -= 1; + } } else if (type == "L2Normalize") { diff --git a/modules/dnn/test/test_tf_importer.cpp b/modules/dnn/test/test_tf_importer.cpp index 395f751683..285da55ba0 100644 --- a/modules/dnn/test/test_tf_importer.cpp +++ b/modules/dnn/test/test_tf_importer.cpp @@ -891,6 +891,11 @@ TEST_P(Test_TensorFlow_layers, resize_nearest_neighbor) runTensorFlowNet("keras_upsampling2d"); } +TEST_P(Test_TensorFlow_layers, fused_resize_conv) +{ + runTensorFlowNet("fused_resize_conv"); +} + TEST_P(Test_TensorFlow_layers, slice) { if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && diff --git a/modules/highgui/src/window_winrt.cpp b/modules/highgui/src/window_winrt.cpp index 4bd3e1ab23..1572929b90 100644 --- a/modules/highgui/src/window_winrt.cpp +++ b/modules/highgui/src/window_winrt.cpp @@ -33,7 +33,7 @@ #include #include #include -#include +#include "window_winrt_bridge.hpp" #define CV_WINRT_NO_GUI_ERROR( funcname ) \ { \ @@ -281,4 +281,4 @@ double cvGetModeWindow_WinRT(const char* name) { CV_IMPL int cvStartWindowThread() { CV_WINRT_NO_GUI_ERROR("cvStartWindowThread"); return CV_StsNotImplemented; -} \ No newline at end of file +}