chore: import upstream snapshot with attribution
@@ -0,0 +1,333 @@
|
||||
set(the_description "High-level GUI")
|
||||
|
||||
if(ANDROID)
|
||||
ocv_add_module(highgui opencv_imgproc OPTIONAL opencv_imgcodecs opencv_videoio WRAP python)
|
||||
else()
|
||||
ocv_add_module(highgui opencv_imgproc OPTIONAL opencv_imgcodecs opencv_videoio WRAP python java)
|
||||
endif()
|
||||
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/cmake/plugin.cmake)
|
||||
|
||||
set(tgts "PRIVATE")
|
||||
|
||||
set(highgui_hdrs
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/precomp.hpp
|
||||
)
|
||||
|
||||
set(highgui_srcs
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/backend.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/window.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/roiSelector.cpp
|
||||
)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# CMake file for highgui. See root CMakeLists.txt
|
||||
# Some parts taken from version of Hartmut Seichter, HIT Lab NZ.
|
||||
# Jose Luis Blanco, 2008
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
if(DEFINED WINRT AND NOT DEFINED ENABLE_WINRT_MODE_NATIVE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /ZW")
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
ocv_include_directories(${ZLIB_INCLUDE_DIRS})
|
||||
list(APPEND HIGHGUI_LIBRARIES ${ZLIB_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if(HAVE_WEBP)
|
||||
add_definitions(-DHAVE_WEBP)
|
||||
endif()
|
||||
|
||||
file(GLOB highgui_ext_hdrs
|
||||
"${CMAKE_CURRENT_LIST_DIR}/include/opencv2/*.hpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/include/opencv2/${name}/*.hpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/include/opencv2/${name}/*.h")
|
||||
|
||||
# Removing WinRT API headers by default
|
||||
list(REMOVE_ITEM highgui_ext_hdrs "${CMAKE_CURRENT_LIST_DIR}/include/opencv2/${name}/highgui_winrt.hpp")
|
||||
|
||||
set(OPENCV_HIGHGUI_BUILTIN_BACKEND "")
|
||||
|
||||
if(WITH_FRAMEBUFFER AND HAVE_FRAMEBUFFER)
|
||||
set(OPENCV_HIGHGUI_BUILTIN_BACKEND "FB")
|
||||
add_definitions(-DHAVE_FRAMEBUFFER)
|
||||
list(APPEND highgui_srcs ${CMAKE_CURRENT_LIST_DIR}/src/window_framebuffer.cpp)
|
||||
list(APPEND highgui_hdrs ${CMAKE_CURRENT_LIST_DIR}/src/window_framebuffer.hpp)
|
||||
if(HAVE_FRAMEBUFFER_XVFB)
|
||||
add_definitions(-DHAVE_FRAMEBUFFER_XVFB)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_WAYLAND AND HAVE_WAYLAND)
|
||||
set(OPENCV_HIGHGUI_BUILTIN_BACKEND "Wayland")
|
||||
add_definitions(-DHAVE_WAYLAND)
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
if (HAVE_WAYLAND_PROTOCOLS)
|
||||
ocv_wayland_generate(
|
||||
${WAYLAND_PROTOCOLS_BASE}/stable/xdg-shell/xdg-shell.xml
|
||||
xdg-shell-client-protocol)
|
||||
endif()
|
||||
|
||||
list(APPEND highgui_srcs
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/window_wayland.cpp
|
||||
${WAYLAND_PROTOCOL_SOURCES}
|
||||
)
|
||||
list(APPEND HIGHGUI_LIBRARIES "${WAYLAND_CLIENT_LINK_LIBRARIES};${WAYLAND_CURSOR_LINK_LIBRARIES};${XKBCOMMON_LINK_LIBRARIES}")
|
||||
|
||||
if(HAVE_WAYLAND_EGL)
|
||||
if(WAYLAND_EGL_LIBRARIES)
|
||||
list(APPEND HIGHGUI_LIBRARIES "${WAYLAND_EGL_LIBRARIES}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
ocv_module_include_directories(${WAYLAND_CLIENT_INCLUDE_DIRS} ${XKBCOMMON_INCLUDE_DIRS})
|
||||
elseif(HAVE_QT)
|
||||
set(OPENCV_HIGHGUI_BUILTIN_BACKEND "QT${QT_VERSION_MAJOR}")
|
||||
add_definitions(-DHAVE_QT)
|
||||
|
||||
if(QT_VERSION_MAJOR GREATER 4)
|
||||
# "Automoc" doesn't work properly with opencv_world build, use QT<ver>_WRAP_CPP() directly
|
||||
#set(CMAKE_AUTOMOC ON)
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
if(QT_VERSION_MAJOR EQUAL 6)
|
||||
add_definitions(-DHAVE_QT6) # QGLWidget deprecated for QT6, use this preprocessor to adjust window_QT.[h,cpp]
|
||||
QT6_ADD_RESOURCES(_RCC_OUTFILES ${CMAKE_CURRENT_LIST_DIR}/src/window_QT.qrc)
|
||||
QT6_WRAP_CPP(_MOC_OUTFILES ${CMAKE_CURRENT_LIST_DIR}/src/window_QT.h)
|
||||
elseif(QT_VERSION_MAJOR EQUAL 5)
|
||||
QT5_ADD_RESOURCES(_RCC_OUTFILES ${CMAKE_CURRENT_LIST_DIR}/src/window_QT.qrc)
|
||||
QT5_WRAP_CPP(_MOC_OUTFILES ${CMAKE_CURRENT_LIST_DIR}/src/window_QT.h)
|
||||
else()
|
||||
message(FATAL_ERROR "Unsupported QT version: ${QT_VERSION_MAJOR}")
|
||||
endif()
|
||||
|
||||
list(APPEND highgui_srcs
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/window_QT.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/window_QT.h
|
||||
${_MOC_OUTFILES}
|
||||
${_RCC_OUTFILES})
|
||||
|
||||
set(qt_deps Core Gui Widgets Test Concurrent)
|
||||
if(HAVE_QT_OPENGL)
|
||||
add_definitions(-DHAVE_QT_OPENGL)
|
||||
# QOpenGLWidget requires Qt6 package component OpenGLWidgets
|
||||
if(QT_VERSION_MAJOR GREATER 5)
|
||||
list(APPEND qt_deps OpenGLWidgets)
|
||||
endif()
|
||||
list(APPEND qt_deps OpenGL)
|
||||
if(OPENGL_LIBRARIES)
|
||||
list(APPEND HIGHGUI_LIBRARIES "${OPENGL_LIBRARIES}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
foreach(dt_dep ${qt_deps})
|
||||
link_libraries(${Qt${QT_VERSION_MAJOR}${dt_dep}})
|
||||
include_directories(${Qt${QT_VERSION_MAJOR}${dt_dep}_INCLUDE_DIRS})
|
||||
list(APPEND HIGHGUI_LIBRARIES ${Qt${QT_VERSION_MAJOR}${dt_dep}_LIBRARIES})
|
||||
endforeach()
|
||||
else()
|
||||
ocv_assert(QT_VERSION_MAJOR EQUAL 4)
|
||||
if(HAVE_QT_OPENGL)
|
||||
set(QT_USE_QTOPENGL TRUE)
|
||||
if(OPENGL_LIBRARIES)
|
||||
list(APPEND HIGHGUI_LIBRARIES "${OPENGL_LIBRARIES}")
|
||||
endif()
|
||||
endif()
|
||||
include(${QT_USE_FILE})
|
||||
|
||||
QT4_ADD_RESOURCES(_RCC_OUTFILES ${CMAKE_CURRENT_LIST_DIR}/src/window_QT.qrc)
|
||||
QT4_WRAP_CPP(_MOC_OUTFILES ${CMAKE_CURRENT_LIST_DIR}/src/window_QT.h)
|
||||
|
||||
list(APPEND HIGHGUI_LIBRARIES ${QT_LIBRARIES})
|
||||
list(APPEND highgui_srcs ${CMAKE_CURRENT_LIST_DIR}/src/window_QT.cpp ${_MOC_OUTFILES} ${_RCC_OUTFILES})
|
||||
ocv_check_flag_support(CXX -Wno-missing-declarations _have_flag "")
|
||||
if(${_have_flag})
|
||||
set_source_files_properties(${_RCC_OUTFILES} PROPERTIES COMPILE_FLAGS -Wno-missing-declarations)
|
||||
endif()
|
||||
endif()
|
||||
elseif(WINRT)
|
||||
set(OPENCV_HIGHGUI_BUILTIN_BACKEND "WINRT")
|
||||
if(NOT WINRT_8_0)
|
||||
# Dependencies used by the implementation referenced
|
||||
# below are not available on WinRT 8.0.
|
||||
# Enabling it for WiRT 8.1+ only.
|
||||
|
||||
# WinRT 8.1+ detected. Adding WinRT API header.
|
||||
message(STATUS " ${name}: WinRT detected. Adding WinRT API header")
|
||||
list(APPEND highgui_ext_hdrs "${CMAKE_CURRENT_LIST_DIR}/include/opencv2/${name}/highgui_winrt.hpp")
|
||||
|
||||
|
||||
list(APPEND highgui_srcs
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/window_winrt.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/window_winrt_bridge.cpp)
|
||||
list(APPEND highgui_hdrs
|
||||
${CMAKE_CURRENT_LIST_DIR}/src/window_winrt_bridge.hpp)
|
||||
endif()
|
||||
|
||||
# libraries below are neither available nor required
|
||||
# on ARM devices and/or Windows Phone
|
||||
if(WINRT_PHONE OR (OpenCV_ARCH STREQUAL "ARM"))
|
||||
list(REMOVE_ITEM HIGHGUI_LIBRARIES "comctl32" "gdi32" "ole32" "setupapi")
|
||||
if(WINRT_PHONE)
|
||||
message(STATUS " ${name}: Windows Phone detected")
|
||||
elseif(OpenCV_ARCH STREQUAL "ARM")
|
||||
message(STATUS " ${name}: ARM detected")
|
||||
if(WINRT_STORE)
|
||||
list(REMOVE_ITEM HIGHGUI_LIBRARIES "ws2_32")
|
||||
message(STATUS " ${name}: Removing 'ws2_32.lib'")
|
||||
endif()
|
||||
endif()
|
||||
message(STATUS " ${name}: Removing 'comctl32.lib, gdi32.lib, ole32.lib, setupapi.lib'")
|
||||
message(STATUS " ${name}: Leaving '${HIGHGUI_LIBRARIES}'")
|
||||
endif()
|
||||
elseif(HAVE_COCOA)
|
||||
set(OPENCV_HIGHGUI_BUILTIN_BACKEND "COCOA")
|
||||
add_definitions(-DHAVE_COCOA)
|
||||
list(APPEND highgui_srcs ${CMAKE_CURRENT_LIST_DIR}/src/window_cocoa.mm)
|
||||
list(APPEND HIGHGUI_LIBRARIES "-framework Cocoa")
|
||||
endif()
|
||||
|
||||
if(TARGET ocv.3rdparty.win32ui)
|
||||
if("win32ui" IN_LIST HIGHGUI_PLUGIN_LIST OR HIGHGUI_PLUGIN_LIST STREQUAL "all")
|
||||
ocv_create_builtin_highgui_plugin(opencv_highgui_win32 ocv.3rdparty.win32ui "window_w32.cpp")
|
||||
elseif(NOT OPENCV_HIGHGUI_BUILTIN_BACKEND)
|
||||
set(OPENCV_HIGHGUI_BUILTIN_BACKEND "WIN32UI")
|
||||
list(APPEND highgui_srcs ${CMAKE_CURRENT_LIST_DIR}/src/window_w32.cpp)
|
||||
list(APPEND tgts ocv.3rdparty.win32ui)
|
||||
if(HAVE_OPENGL AND OPENGL_LIBRARIES)
|
||||
list(APPEND tgts "${OPENGL_LIBRARIES}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(TARGET ocv.3rdparty.gtk3 OR TARGET ocv.3rdparty.gtk2)
|
||||
if(TARGET ocv.3rdparty.gtk3 AND NOT WITH_GTK_2_X)
|
||||
set(__gtk_dependency "ocv.3rdparty.gtk3")
|
||||
else()
|
||||
set(__gtk_dependency "ocv.3rdparty.gtk2")
|
||||
endif()
|
||||
if(
|
||||
NOT HIGHGUI_PLUGIN_LIST STREQUAL "all"
|
||||
AND NOT "gtk" IN_LIST HIGHGUI_PLUGIN_LIST
|
||||
AND NOT "gtk2" IN_LIST HIGHGUI_PLUGIN_LIST
|
||||
AND NOT "gtk3" IN_LIST HIGHGUI_PLUGIN_LIST
|
||||
AND NOT OPENCV_HIGHGUI_BUILTIN_BACKEND
|
||||
)
|
||||
if(__gtk_dependency STREQUAL "ocv.3rdparty.gtk3")
|
||||
set(OPENCV_HIGHGUI_BUILTIN_BACKEND "GTK3")
|
||||
if(OPENGL_LIBRARIES)
|
||||
list(APPEND HIGHGUI_LIBRARIES "${OPENGL_LIBRARIES}")
|
||||
endif()
|
||||
elseif(__gtk_dependency STREQUAL "ocv.3rdparty.gtk2")
|
||||
set(OPENCV_HIGHGUI_BUILTIN_BACKEND "GTK2")
|
||||
else()
|
||||
set(OPENCV_HIGHGUI_BUILTIN_BACKEND "GTK")
|
||||
endif()
|
||||
list(APPEND highgui_srcs ${CMAKE_CURRENT_LIST_DIR}/src/window_gtk.cpp)
|
||||
list(APPEND tgts ${__gtk_dependency})
|
||||
if(TARGET ocv.3rdparty.gtkglext
|
||||
AND __gtk_dependency STREQUAL "ocv.3rdparty.gtk2"
|
||||
AND NOT OPENCV_GTK_DISABLE_GTKGLEXT
|
||||
)
|
||||
list(APPEND tgts ocv.3rdparty.gtkglext)
|
||||
if(TARGET ocv.3rdparty.gtk_opengl
|
||||
AND __gtk_dependency STREQUAL "ocv.3rdparty.gtk2"
|
||||
AND NOT OPENCV_GTK_DISABLE_OPENGL
|
||||
)
|
||||
list(APPEND tgts ocv.3rdparty.gtk_opengl)
|
||||
endif()
|
||||
endif()
|
||||
elseif("gtk" IN_LIST HIGHGUI_PLUGIN_LIST)
|
||||
ocv_create_builtin_highgui_plugin(opencv_highgui_gtk ${__gtk_dependency} "window_gtk.cpp")
|
||||
if(TARGET ocv.3rdparty.gtkglext)
|
||||
ocv_target_link_libraries(opencv_highgui_gtk ocv.3rdparty.gtkglext)
|
||||
endif()
|
||||
else()
|
||||
if(TARGET ocv.3rdparty.gtk3 AND ("gtk3" IN_LIST HIGHGUI_PLUGIN_LIST OR HIGHGUI_PLUGIN_LIST STREQUAL "all"))
|
||||
ocv_create_builtin_highgui_plugin(opencv_highgui_gtk3 ocv.3rdparty.gtk3 "window_gtk.cpp")
|
||||
if(TARGET ocv.3rdparty.gtkglext)
|
||||
ocv_target_link_libraries(opencv_highgui_gtk3 ocv.3rdparty.gtkglext)
|
||||
endif()
|
||||
endif()
|
||||
if(TARGET ocv.3rdparty.gtk2 AND ("gtk2" IN_LIST HIGHGUI_PLUGIN_LIST OR HIGHGUI_PLUGIN_LIST STREQUAL "all"))
|
||||
ocv_create_builtin_highgui_plugin(opencv_highgui_gtk2 ocv.3rdparty.gtk2 "window_gtk.cpp")
|
||||
if(TARGET ocv.3rdparty.gtkglext)
|
||||
ocv_target_link_libraries(opencv_highgui_gtk2 ocv.3rdparty.gtkglext)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT OPENCV_HIGHGUI_BUILTIN_BACKEND)
|
||||
set(OPENCV_HIGHGUI_BUILTIN_BACKEND "NONE")
|
||||
endif()
|
||||
message(STATUS "highgui: using builtin backend: ${OPENCV_HIGHGUI_BUILTIN_BACKEND}")
|
||||
set(OPENCV_HIGHGUI_BUILTIN_BACKEND "${OPENCV_HIGHGUI_BUILTIN_BACKEND}" PARENT_SCOPE) # informational
|
||||
|
||||
if(TRUE)
|
||||
# these variables are set by 'ocv_append_build_options(HIGHGUI ...)'
|
||||
foreach(P ${HIGHGUI_INCLUDE_DIRS})
|
||||
ocv_include_directories(${P})
|
||||
endforeach()
|
||||
|
||||
foreach(P ${HIGHGUI_LIBRARY_DIRS})
|
||||
link_directories(${P})
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
if(tgts STREQUAL "PRIVATE")
|
||||
set(tgts "")
|
||||
endif()
|
||||
|
||||
ocv_install_used_external_targets(${tgts})
|
||||
|
||||
source_group("Src" FILES ${highgui_srcs} ${highgui_hdrs})
|
||||
source_group("Include" FILES ${highgui_ext_hdrs})
|
||||
ocv_set_module_sources(HEADERS ${highgui_ext_hdrs} SOURCES ${highgui_srcs} ${highgui_hdrs})
|
||||
ocv_module_include_directories()
|
||||
|
||||
ocv_create_module(${HIGHGUI_LIBRARIES})
|
||||
|
||||
macro(ocv_highgui_configure_target)
|
||||
if(APPLE)
|
||||
add_apple_compiler_options(${the_module})
|
||||
endif()
|
||||
|
||||
if(MSVC AND NOT BUILD_SHARED_LIBS AND BUILD_WITH_STATIC_CRT)
|
||||
set_target_properties(${the_module} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:atlthunk.lib /NODEFAULTLIB:atlsd.lib /NODEFAULTLIB:libcmt.lib /DEBUG")
|
||||
endif()
|
||||
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wno-deprecated-declarations)
|
||||
endmacro()
|
||||
|
||||
if(NOT BUILD_opencv_world)
|
||||
ocv_highgui_configure_target()
|
||||
endif()
|
||||
|
||||
ocv_add_accuracy_tests(${tgts})
|
||||
#ocv_add_perf_tests(${tgts})
|
||||
|
||||
if(HIGHGUI_ENABLE_PLUGINS)
|
||||
ocv_target_compile_definitions(${the_module} PRIVATE ENABLE_PLUGINS)
|
||||
if(TARGET opencv_test_highgui)
|
||||
ocv_target_compile_definitions(opencv_test_highgui PRIVATE ENABLE_PLUGINS)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
ocv_target_link_libraries(${the_module} LINK_PRIVATE ${tgts})
|
||||
|
||||
# generate module configuration
|
||||
set(CONFIG_STR "// Auto-generated file
|
||||
#define OPENCV_HIGHGUI_BUILTIN_BACKEND_STR \"${OPENCV_HIGHGUI_BUILTIN_BACKEND}\"
|
||||
")
|
||||
if(OPENCV_HIGHGUI_BUILTIN_BACKEND STREQUAL "NONE")
|
||||
set(CONFIG_STR "${CONFIG_STR}
|
||||
#define OPENCV_HIGHGUI_WITHOUT_BUILTIN_BACKEND 1
|
||||
")
|
||||
endif()
|
||||
|
||||
ocv_update_file("${CMAKE_CURRENT_BINARY_DIR}/opencv_highgui_config.hpp" "${CONFIG_STR}")
|
||||
@@ -0,0 +1,14 @@
|
||||
# --- FB ---
|
||||
set(HAVE_FRAMEBUFFER ON)
|
||||
if(WITH_FRAMEBUFFER_XVFB)
|
||||
try_compile(HAVE_FRAMEBUFFER_XVFB
|
||||
"${CMAKE_CURRENT_BINARY_DIR}"
|
||||
"${OpenCV_SOURCE_DIR}/cmake/checks/framebuffer.cpp")
|
||||
if(HAVE_FRAMEBUFFER_XVFB)
|
||||
message(STATUS "Check virtual framebuffer - done")
|
||||
else()
|
||||
message(STATUS
|
||||
"Check virtual framebuffer - failed\n"
|
||||
"Please install the xorg-x11-proto-devel or x11proto-dev package\n")
|
||||
endif()
|
||||
endif()
|
||||
@@ -0,0 +1,49 @@
|
||||
# --- GTK ---
|
||||
ocv_clear_vars(HAVE_GTK HAVE_GTK2 HAVE_GTK3 HAVE_GTKGLEXT)
|
||||
if(WITH_GTK)
|
||||
if(NOT WITH_GTK_2_X)
|
||||
ocv_check_modules(GTK3 gtk+-3.0)
|
||||
if(HAVE_GTK3)
|
||||
ocv_add_external_target(gtk3 "${GTK3_INCLUDE_DIRS}" "${GTK3_LIBRARIES}" "HAVE_GTK3;HAVE_GTK")
|
||||
set(HAVE_GTK TRUE)
|
||||
endif()
|
||||
endif()
|
||||
if((PROJECT_NAME STREQUAL "OpenCV" AND HIGHGUI_ENABLE_PLUGINS) OR NOT HAVE_GTK3)
|
||||
ocv_check_modules(GTK2 gtk+-2.0)
|
||||
if(HAVE_GTK2)
|
||||
set(MIN_VER_GTK "2.18.0")
|
||||
if(GTK2_VERSION VERSION_LESS MIN_VER_GTK)
|
||||
message(FATAL_ERROR "GTK support requires a minimum version of ${MIN_VER_GTK} (${GTK2_VERSION} found)")
|
||||
else()
|
||||
ocv_add_external_target(gtk2 "${GTK2_INCLUDE_DIRS}" "${GTK2_LIBRARIES}" "HAVE_GTK2;HAVE_GTK")
|
||||
set(HAVE_GTK TRUE)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
if((WITH_OPENGL OR HAVE_OPENGL) AND (HAVE_GTK2 OR HAVE_GTK3))
|
||||
if(HAVE_GTK2)
|
||||
ocv_check_modules(GTKGLEXT gtkglext-1.0)
|
||||
if(HAVE_GTKGLEXT)
|
||||
# HACK for https://github.com/opencv/opencv/issues/20850
|
||||
# pkg-config reports some include directories that do not exist. Just filter them out.
|
||||
set(GTKGLEXT_INCLUDE_DIRS_EXISTS "")
|
||||
foreach(p ${GTKGLEXT_INCLUDE_DIRS})
|
||||
if (EXISTS "${p}")
|
||||
list(APPEND GTKGLEXT_INCLUDE_DIRS_EXISTS "${p}")
|
||||
endif()
|
||||
endforeach()
|
||||
ocv_add_external_target(gtkglext "${GTKGLEXT_INCLUDE_DIRS}" "${GTKGLEXT_LIBRARIES}" "HAVE_GTKGLEXT")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
elseif(HAVE_GTK)
|
||||
ocv_add_external_target(gtk "${GTK_INCLUDE_DIRS}" "${GTK_LIBRARIES}" "${GTK_DEFINES};HAVE_GTK")
|
||||
endif()
|
||||
|
||||
if(WITH_OPENGL)
|
||||
find_package(OpenGL QUIET)
|
||||
if(OPENGL_FOUND)
|
||||
set(HAVE_OPENGL TRUE)
|
||||
ocv_add_external_target(gtk_opengl "${OPENGL_INCLUDE_DIRS}" "${OPENGL_LIBRARIES}" "HAVE_OPENGL")
|
||||
endif()
|
||||
endif()
|
||||
@@ -0,0 +1,41 @@
|
||||
# --- Wayland ---
|
||||
macro(ocv_wayland_generate protocol_file output_file)
|
||||
add_custom_command(OUTPUT ${output_file}.h
|
||||
COMMAND ${WAYLAND_SCANNER_EXECUTABLE} client-header < ${protocol_file} > ${output_file}.h
|
||||
DEPENDS ${protocol_file})
|
||||
add_custom_command(OUTPUT ${output_file}.c
|
||||
COMMAND ${WAYLAND_SCANNER_EXECUTABLE} private-code < ${protocol_file} > ${output_file}.c
|
||||
DEPENDS ${protocol_file})
|
||||
list(APPEND WAYLAND_PROTOCOL_SOURCES ${output_file}.h ${output_file}.c)
|
||||
endmacro()
|
||||
|
||||
ocv_clear_vars(HAVE_WAYLAND_CLIENT HAVE_WAYLAND_CURSOR HAVE_XKBCOMMON HAVE_WAYLAND_PROTOCOLS HAVE_WAYLAND_EGL)
|
||||
if(WITH_WAYLAND)
|
||||
ocv_check_modules(WAYLAND_CLIENT wayland-client)
|
||||
if(WAYLAND_CLIENT_FOUND)
|
||||
set(HAVE_WAYLAND_CLIENT ON)
|
||||
endif()
|
||||
ocv_check_modules(WAYLAND_CURSOR wayland-cursor)
|
||||
if(WAYLAND_CURSOR_FOUND)
|
||||
set(HAVE_WAYLAND_CURSOR ON)
|
||||
endif()
|
||||
ocv_check_modules(XKBCOMMON xkbcommon)
|
||||
if(XKBCOMMON_FOUND)
|
||||
set(HAVE_XKBCOMMON ON)
|
||||
endif()
|
||||
ocv_check_modules(WAYLAND_PROTOCOLS wayland-protocols>=1.13)
|
||||
if(HAVE_WAYLAND_PROTOCOLS)
|
||||
pkg_get_variable(WAYLAND_PROTOCOLS_BASE wayland-protocols pkgdatadir)
|
||||
find_host_program(WAYLAND_SCANNER_EXECUTABLE NAMES wayland-scanner REQUIRED)
|
||||
endif()
|
||||
|
||||
if(HAVE_WAYLAND_CLIENT AND HAVE_WAYLAND_CURSOR AND HAVE_XKBCOMMON AND HAVE_WAYLAND_PROTOCOLS)
|
||||
set(HAVE_WAYLAND TRUE)
|
||||
endif()
|
||||
|
||||
# WAYLAND_EGL is option
|
||||
ocv_check_modules(WAYLAND_EGL wayland-egl)
|
||||
if(WAYLAND_EGL_FOUND)
|
||||
set(HAVE_WAYLAND_EGL ON)
|
||||
endif()
|
||||
endif()
|
||||
@@ -0,0 +1,15 @@
|
||||
#--- Win32 UI ---
|
||||
ocv_clear_vars(HAVE_WIN32UI)
|
||||
if(WITH_WIN32UI)
|
||||
try_compile(HAVE_WIN32UI
|
||||
"${CMAKE_CURRENT_BINARY_DIR}"
|
||||
"${OpenCV_SOURCE_DIR}/cmake/checks/win32uitest.cpp"
|
||||
CMAKE_FLAGS "-DLINK_LIBRARIES:STRING=user32;gdi32")
|
||||
if(HAVE_WIN32UI)
|
||||
set(__libs "user32" "gdi32")
|
||||
if(OpenCV_ARCH STREQUAL "ARM64")
|
||||
list(APPEND __libs "comdlg32" "advapi32")
|
||||
endif()
|
||||
ocv_add_external_target(win32ui "" "${__libs}" "HAVE_WIN32UI")
|
||||
endif()
|
||||
endif()
|
||||
@@ -0,0 +1,48 @@
|
||||
if(PROJECT_NAME STREQUAL "OpenCV")
|
||||
set(ENABLE_PLUGINS_DEFAULT ON)
|
||||
if(EMSCRIPTEN OR IOS OR WINRT)
|
||||
set(ENABLE_PLUGINS_DEFAULT OFF)
|
||||
endif()
|
||||
set(HIGHGUI_PLUGIN_LIST "" CACHE STRING "List of GUI backends to be compiled as plugins (gtk, gtk2/gtk3, qt, win32 or special value 'all')")
|
||||
set(HIGHGUI_ENABLE_PLUGINS "${ENABLE_PLUGINS_DEFAULT}" CACHE BOOL "Allow building and using of GUI plugins")
|
||||
mark_as_advanced(HIGHGUI_PLUGIN_LIST HIGHGUI_ENABLE_PLUGINS)
|
||||
|
||||
string(REPLACE "," ";" HIGHGUI_PLUGIN_LIST "${HIGHGUI_PLUGIN_LIST}") # support comma-separated list (,) too
|
||||
string(TOLOWER "${HIGHGUI_PLUGIN_LIST}" HIGHGUI_PLUGIN_LIST)
|
||||
if(NOT HIGHGUI_ENABLE_PLUGINS)
|
||||
if(HIGHGUI_PLUGIN_LIST)
|
||||
message(WARNING "HighGUI: plugins are disabled through HIGHGUI_ENABLE_PLUGINS, so HIGHGUI_PLUGIN_LIST='${HIGHGUI_PLUGIN_LIST}' is ignored")
|
||||
set(HIGHGUI_PLUGIN_LIST "")
|
||||
endif()
|
||||
else()
|
||||
# Make virtual plugins target
|
||||
if(NOT TARGET opencv_highgui_plugins)
|
||||
add_custom_target(opencv_highgui_plugins ALL)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#
|
||||
# Detect available dependencies
|
||||
#
|
||||
|
||||
if(NOT PROJECT_NAME STREQUAL "OpenCV")
|
||||
include(FindPkgConfig)
|
||||
endif()
|
||||
|
||||
macro(add_backend backend_id cond_var)
|
||||
if(${cond_var})
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/detect_${backend_id}.cmake")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
add_backend("gtk" WITH_GTK)
|
||||
add_backend("win32ui" WITH_WIN32UI)
|
||||
add_backend("wayland" WITH_WAYLAND)
|
||||
add_backend("framebuffer" WITH_FRAMEBUFFER)
|
||||
|
||||
# TODO cocoa
|
||||
# TODO qt
|
||||
# TODO opengl
|
||||
|
||||
# FIXIT: move content of cmake/OpenCVFindLibsGUI.cmake here (need to resolve CMake scope issues)
|
||||
@@ -0,0 +1,61 @@
|
||||
function(ocv_create_builtin_highgui_plugin name target)
|
||||
|
||||
ocv_debug_message("ocv_create_builtin_highgui_plugin(${ARGV})")
|
||||
|
||||
if(NOT TARGET ${target})
|
||||
message(FATAL_ERROR "${target} does not exist!")
|
||||
endif()
|
||||
if(NOT OpenCV_SOURCE_DIR)
|
||||
message(FATAL_ERROR "OpenCV_SOURCE_DIR must be set to build the plugin!")
|
||||
endif()
|
||||
|
||||
message(STATUS "HighGUI: add builtin plugin '${name}'")
|
||||
|
||||
foreach(src ${ARGN})
|
||||
list(APPEND sources "${CMAKE_CURRENT_LIST_DIR}/src/${src}")
|
||||
endforeach()
|
||||
|
||||
add_library(${name} MODULE ${sources})
|
||||
target_include_directories(${name} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
target_compile_definitions(${name} PRIVATE BUILD_PLUGIN)
|
||||
target_link_libraries(${name} PRIVATE ${target})
|
||||
|
||||
foreach(mod opencv_highgui
|
||||
opencv_core
|
||||
opencv_imgproc
|
||||
opencv_imgcodecs
|
||||
opencv_videoio # TODO remove this dependency
|
||||
)
|
||||
ocv_target_link_libraries(${name} LINK_PRIVATE ${mod})
|
||||
ocv_target_include_directories(${name} "${OPENCV_MODULE_${mod}_LOCATION}/include")
|
||||
endforeach()
|
||||
|
||||
if(WIN32)
|
||||
set(OPENCV_PLUGIN_VERSION "${OPENCV_DLLVERSION}" CACHE STRING "")
|
||||
if(CMAKE_CXX_SIZEOF_DATA_PTR EQUAL 8)
|
||||
set(OPENCV_PLUGIN_ARCH "_64" CACHE STRING "")
|
||||
else()
|
||||
set(OPENCV_PLUGIN_ARCH "" CACHE STRING "")
|
||||
endif()
|
||||
else()
|
||||
set(OPENCV_PLUGIN_VERSION "" CACHE STRING "")
|
||||
set(OPENCV_PLUGIN_ARCH "" CACHE STRING "")
|
||||
endif()
|
||||
|
||||
set_target_properties(${name} PROPERTIES
|
||||
CXX_STANDARD 11
|
||||
CXX_VISIBILITY_PRESET hidden
|
||||
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
|
||||
OUTPUT_NAME "${name}${OPENCV_PLUGIN_VERSION}${OPENCV_PLUGIN_ARCH}"
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
set_target_properties(${name} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH})
|
||||
install(TARGETS ${name} OPTIONAL LIBRARY DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT plugins)
|
||||
else()
|
||||
install(TARGETS ${name} OPTIONAL LIBRARY DESTINATION ${OPENCV_LIB_INSTALL_PATH} COMPONENT plugins)
|
||||
endif()
|
||||
|
||||
add_dependencies(opencv_highgui_plugins ${name})
|
||||
|
||||
endfunction()
|
||||
@@ -0,0 +1,39 @@
|
||||
#include "opencv2/highgui.hpp"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int value = 50;
|
||||
int value2 = 0;
|
||||
|
||||
namedWindow("main1",WINDOW_NORMAL);
|
||||
namedWindow("main2",WINDOW_AUTOSIZE | WINDOW_GUI_NORMAL);
|
||||
createTrackbar( "track1", "main1", &value, 255, NULL);
|
||||
|
||||
String nameb1 = "button1";
|
||||
String nameb2 = "button2";
|
||||
|
||||
createButton(nameb1,callbackButton,&nameb1,QT_CHECKBOX,1);
|
||||
createButton(nameb2,callbackButton,NULL,QT_CHECKBOX,0);
|
||||
createTrackbar( "track2", NULL, &value2, 255, NULL);
|
||||
createButton("button5",callbackButton1,NULL,QT_RADIOBOX,0);
|
||||
createButton("button6",callbackButton2,NULL,QT_RADIOBOX,1);
|
||||
|
||||
setMouseCallback( "main2",on_mouse,NULL );
|
||||
|
||||
Mat img1 = imread("files/flower.jpg");
|
||||
VideoCapture video;
|
||||
video.open("files/hockey.avi");
|
||||
|
||||
Mat img2,img3;
|
||||
while( waitKey(33) != 27 )
|
||||
{
|
||||
img1.convertTo(img2,-1,1,value);
|
||||
video >> img3;
|
||||
|
||||
imshow("main1",img2);
|
||||
imshow("main2",img3);
|
||||
}
|
||||
|
||||
destroyAllWindows();
|
||||
return 0;
|
||||
}
|
||||
|
After Width: | Height: | Size: 371 KiB |
@@ -0,0 +1,830 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef OPENCV_HIGHGUI_HPP
|
||||
#define OPENCV_HIGHGUI_HPP
|
||||
|
||||
#include "opencv2/core.hpp"
|
||||
#ifdef HAVE_OPENCV_IMGCODECS
|
||||
#include "opencv2/imgcodecs.hpp"
|
||||
#endif
|
||||
#ifdef HAVE_OPENCV_VIDEOIO
|
||||
#include "opencv2/videoio.hpp"
|
||||
#endif
|
||||
|
||||
/**
|
||||
@defgroup highgui High-level GUI
|
||||
|
||||
While OpenCV was designed for use in full-scale applications and can be used within functionally
|
||||
rich UI frameworks (such as Qt\*, WinForms\*, or Cocoa\*) or without any UI at all, sometimes there
|
||||
it is required to try functionality quickly and visualize the results. This is what the HighGUI
|
||||
module has been designed for.
|
||||
|
||||
It provides easy interface to:
|
||||
|
||||
- Create and manipulate windows that can display images and "remember" their content (no need to
|
||||
handle repaint events from OS).
|
||||
- Add trackbars to the windows, handle simple mouse events as well as keyboard commands.
|
||||
|
||||
@{
|
||||
@defgroup highgui_window_flags Flags related creating and manipulating HighGUI windows and mouse events
|
||||
@defgroup highgui_opengl OpenGL support
|
||||
@defgroup highgui_qt Qt New Functions
|
||||
|
||||

|
||||
|
||||
This figure explains new functionality implemented with Qt\* GUI. The new GUI provides a statusbar,
|
||||
a toolbar, and a control panel. The control panel can have trackbars and buttonbars attached to it.
|
||||
If you cannot see the control panel, press Ctrl+P or right-click any Qt window and select **Display
|
||||
properties window**.
|
||||
|
||||
- To attach a trackbar, the window name parameter must be NULL.
|
||||
|
||||
- To attach a buttonbar, a button must be created. If the last bar attached to the control panel
|
||||
is a buttonbar, the new button is added to the right of the last button. If the last bar
|
||||
attached to the control panel is a trackbar, or the control panel is empty, a new buttonbar is
|
||||
created. Then, a new button is attached to it.
|
||||
|
||||
See below the example used to generate the figure:
|
||||
|
||||
@include highgui_qt.cpp
|
||||
|
||||
@defgroup highgui_winrt WinRT support
|
||||
|
||||
This figure explains new functionality implemented with WinRT GUI. The new GUI provides an Image control,
|
||||
and a slider panel. Slider panel holds trackbars attached to it.
|
||||
|
||||
Sliders are attached below the image control. Every new slider is added below the previous one.
|
||||
|
||||
See below the example used to generate the figure:
|
||||
@code
|
||||
void sample_app::MainPage::ShowWindow()
|
||||
{
|
||||
static cv::String windowName("sample");
|
||||
cv::winrt_initContainer(this->cvContainer);
|
||||
cv::namedWindow(windowName); // not required
|
||||
|
||||
cv::Mat image = cv::imread("Assets/sample.jpg");
|
||||
cv::Mat converted = cv::Mat(image.rows, image.cols, CV_8UC4);
|
||||
cv::cvtColor(image, converted, COLOR_BGR2BGRA);
|
||||
cv::imshow(windowName, converted); // this will create window if it hasn't been created before
|
||||
|
||||
int state = 42;
|
||||
cv::TrackbarCallback callback = [](int pos, void* userdata)
|
||||
{
|
||||
if (pos == 0) {
|
||||
cv::destroyWindow(windowName);
|
||||
}
|
||||
};
|
||||
cv::TrackbarCallback callbackTwin = [](int pos, void* userdata)
|
||||
{
|
||||
if (pos >= 70) {
|
||||
cv::destroyAllWindows();
|
||||
}
|
||||
};
|
||||
cv::createTrackbar("Sample trackbar", windowName, &state, 100, callback);
|
||||
cv::createTrackbar("Twin brother", windowName, &state, 100, callbackTwin);
|
||||
}
|
||||
@endcode
|
||||
@}
|
||||
*/
|
||||
|
||||
///////////////////////// graphical user interface //////////////////////////
|
||||
namespace cv
|
||||
{
|
||||
|
||||
//! @addtogroup highgui
|
||||
//! @{
|
||||
|
||||
//! @addtogroup highgui_window_flags
|
||||
//! @{
|
||||
|
||||
//! Flags for cv::namedWindow
|
||||
enum WindowFlags {
|
||||
WINDOW_NORMAL = 0x00000000, //!< the user can resize the window (no constraint) / also use to switch a fullscreen window to a normal size.
|
||||
WINDOW_AUTOSIZE = 0x00000001, //!< the user cannot resize the window, the size is constrainted by the image displayed.
|
||||
WINDOW_OPENGL = 0x00001000, //!< window with opengl support.
|
||||
|
||||
WINDOW_FULLSCREEN = 1, //!< change the window to fullscreen.
|
||||
WINDOW_FREERATIO = 0x00000100, //!< the image expends as much as it can (no ratio constraint).
|
||||
WINDOW_KEEPRATIO = 0x00000000, //!< the ratio of the image is respected.
|
||||
WINDOW_GUI_EXPANDED=0x00000000, //!< status bar and tool bar
|
||||
WINDOW_GUI_NORMAL = 0x00000010, //!< old fashious way
|
||||
};
|
||||
|
||||
//! Flags for cv::setWindowProperty / cv::getWindowProperty
|
||||
enum WindowPropertyFlags {
|
||||
WND_PROP_FULLSCREEN = 0, //!< fullscreen property (can be WINDOW_NORMAL or WINDOW_FULLSCREEN).
|
||||
WND_PROP_AUTOSIZE = 1, //!< autosize property (can be WINDOW_NORMAL or WINDOW_AUTOSIZE).
|
||||
WND_PROP_ASPECT_RATIO = 2, //!< window's aspect ration (can be set to WINDOW_FREERATIO or WINDOW_KEEPRATIO).
|
||||
WND_PROP_OPENGL = 3, //!< opengl support.
|
||||
WND_PROP_VISIBLE = 4, //!< checks whether the window exists and is visible
|
||||
WND_PROP_TOPMOST = 5, //!< property to toggle normal window being topmost or not
|
||||
WND_PROP_VSYNC = 6 //!< enable or disable VSYNC (in OpenGL mode)
|
||||
};
|
||||
|
||||
//! Mouse Events see cv::MouseCallback
|
||||
enum MouseEventTypes {
|
||||
EVENT_MOUSEMOVE = 0, //!< indicates that the mouse pointer has moved over the window.
|
||||
EVENT_LBUTTONDOWN = 1, //!< indicates that the left mouse button is pressed.
|
||||
EVENT_RBUTTONDOWN = 2, //!< indicates that the right mouse button is pressed.
|
||||
EVENT_MBUTTONDOWN = 3, //!< indicates that the middle mouse button is pressed.
|
||||
EVENT_LBUTTONUP = 4, //!< indicates that left mouse button is released.
|
||||
EVENT_RBUTTONUP = 5, //!< indicates that right mouse button is released.
|
||||
EVENT_MBUTTONUP = 6, //!< indicates that middle mouse button is released.
|
||||
EVENT_LBUTTONDBLCLK = 7, //!< indicates that left mouse button is double clicked.
|
||||
EVENT_RBUTTONDBLCLK = 8, //!< indicates that right mouse button is double clicked.
|
||||
EVENT_MBUTTONDBLCLK = 9, //!< indicates that middle mouse button is double clicked.
|
||||
EVENT_MOUSEWHEEL = 10,//!< positive and negative values mean forward and backward scrolling, respectively.
|
||||
EVENT_MOUSEHWHEEL = 11 //!< positive and negative values mean right and left scrolling, respectively.
|
||||
};
|
||||
|
||||
//! Mouse Event Flags see cv::MouseCallback
|
||||
enum MouseEventFlags {
|
||||
EVENT_FLAG_LBUTTON = 1, //!< indicates that the left mouse button is down.
|
||||
EVENT_FLAG_RBUTTON = 2, //!< indicates that the right mouse button is down.
|
||||
EVENT_FLAG_MBUTTON = 4, //!< indicates that the middle mouse button is down.
|
||||
EVENT_FLAG_CTRLKEY = 8, //!< indicates that CTRL Key is pressed.
|
||||
EVENT_FLAG_SHIFTKEY = 16,//!< indicates that SHIFT Key is pressed.
|
||||
EVENT_FLAG_ALTKEY = 32 //!< indicates that ALT Key is pressed.
|
||||
};
|
||||
|
||||
//! @} highgui_window_flags
|
||||
|
||||
//! @addtogroup highgui_qt
|
||||
//! @{
|
||||
|
||||
//! Qt font weight
|
||||
enum QtFontWeights {
|
||||
QT_FONT_LIGHT = 25, //!< Weight of 25
|
||||
QT_FONT_NORMAL = 50, //!< Weight of 50
|
||||
QT_FONT_DEMIBOLD = 63, //!< Weight of 63
|
||||
QT_FONT_BOLD = 75, //!< Weight of 75
|
||||
QT_FONT_BLACK = 87 //!< Weight of 87
|
||||
};
|
||||
|
||||
//! Qt font style
|
||||
enum QtFontStyles {
|
||||
QT_STYLE_NORMAL = 0, //!< Normal font.
|
||||
QT_STYLE_ITALIC = 1, //!< Italic font.
|
||||
QT_STYLE_OBLIQUE = 2 //!< Oblique font.
|
||||
};
|
||||
|
||||
//! Qt "button" type
|
||||
enum QtButtonTypes {
|
||||
QT_PUSH_BUTTON = 0, //!< Push button.
|
||||
QT_CHECKBOX = 1, //!< Checkbox button.
|
||||
QT_RADIOBOX = 2, //!< Radiobox button.
|
||||
QT_NEW_BUTTONBAR = 1024 //!< Button should create a new buttonbar
|
||||
};
|
||||
|
||||
//! @} highgui_qt
|
||||
|
||||
/** @brief Callback function for mouse events. see cv::setMouseCallback
|
||||
@param event one of the cv::MouseEventTypes constants.
|
||||
@param x The x-coordinate of the mouse event.
|
||||
@param y The y-coordinate of the mouse event.
|
||||
@param flags one of the cv::MouseEventFlags constants.
|
||||
@param userdata The optional parameter.
|
||||
*/
|
||||
typedef void (*MouseCallback)(int event, int x, int y, int flags, void* userdata);
|
||||
|
||||
/** @brief Callback function for Trackbar see cv::createTrackbar
|
||||
@param pos current position of the specified trackbar.
|
||||
@param userdata The optional parameter.
|
||||
*/
|
||||
typedef void (*TrackbarCallback)(int pos, void* userdata);
|
||||
|
||||
/** @brief Callback function defined to be called every frame. See cv::setOpenGlDrawCallback
|
||||
@param userdata The optional parameter.
|
||||
*/
|
||||
typedef void (*OpenGlDrawCallback)(void* userdata);
|
||||
|
||||
/** @brief Callback function for a button created by cv::createButton
|
||||
@param state current state of the button. It could be -1 for a push button, 0 or 1 for a check/radio box button.
|
||||
@param userdata The optional parameter.
|
||||
*/
|
||||
typedef void (*ButtonCallback)(int state, void* userdata);
|
||||
|
||||
/** @brief Creates a window.
|
||||
|
||||
The function namedWindow creates a window that can be used as a placeholder for images and
|
||||
trackbars. Created windows are referred to by their names.
|
||||
|
||||
If a window with the same name already exists, the function does nothing.
|
||||
|
||||
You can call cv::destroyWindow or cv::destroyAllWindows to close the window and de-allocate any associated
|
||||
memory usage. For a simple program, you do not really have to call these functions because all the
|
||||
resources and windows of the application are closed automatically by the operating system upon exit.
|
||||
|
||||
@note Qt backend supports additional flags:
|
||||
- **WINDOW_NORMAL or WINDOW_AUTOSIZE:** WINDOW_NORMAL enables you to resize the
|
||||
window, whereas WINDOW_AUTOSIZE adjusts automatically the window size to fit the
|
||||
displayed image (see imshow ), and you cannot change the window size manually.
|
||||
- **WINDOW_FREERATIO or WINDOW_KEEPRATIO:** WINDOW_FREERATIO adjusts the image
|
||||
with no respect to its ratio, whereas WINDOW_KEEPRATIO keeps the image ratio.
|
||||
- **WINDOW_GUI_NORMAL or WINDOW_GUI_EXPANDED:** WINDOW_GUI_NORMAL is the old way to draw the window
|
||||
without statusbar and toolbar, whereas WINDOW_GUI_EXPANDED is a new enhanced GUI.
|
||||
By default, flags == WINDOW_AUTOSIZE | WINDOW_KEEPRATIO | WINDOW_GUI_EXPANDED
|
||||
|
||||
@param winname Name of the window in the window caption that may be used as a window identifier.
|
||||
@param flags Flags of the window. The supported flags are: (cv::WindowFlags)
|
||||
*/
|
||||
CV_EXPORTS_W void namedWindow(const String& winname, int flags = WINDOW_AUTOSIZE);
|
||||
|
||||
/** @brief Destroys the specified window.
|
||||
|
||||
The function destroyWindow destroys the window with the given name.
|
||||
|
||||
@param winname Name of the window to be destroyed.
|
||||
*/
|
||||
CV_EXPORTS_W void destroyWindow(const String& winname);
|
||||
|
||||
/** @brief Destroys all of the HighGUI windows.
|
||||
|
||||
The function destroyAllWindows destroys all of the opened HighGUI windows.
|
||||
*/
|
||||
CV_EXPORTS_W void destroyAllWindows();
|
||||
|
||||
|
||||
/** @brief HighGUI backend used.
|
||||
|
||||
The function returns HighGUI backend name used: could be COCOA, GTK2/3, QT, WAYLAND or WIN32.
|
||||
Returns empty string if there is no available UI backend.
|
||||
*/
|
||||
CV_EXPORTS_W const std::string currentUIFramework();
|
||||
|
||||
|
||||
CV_EXPORTS_W int startWindowThread();
|
||||
|
||||
/** @brief Similar to #waitKey, but returns full key code.
|
||||
|
||||
@note Key code is implementation specific and depends on used backend: QT/GTK/Win32/etc
|
||||
|
||||
*/
|
||||
CV_EXPORTS_W int waitKeyEx(int delay = 0);
|
||||
|
||||
/** @brief Waits for a pressed key.
|
||||
|
||||
The function waitKey waits for a key event infinitely (when \f$\texttt{delay}\leq 0\f$ ) or for delay
|
||||
milliseconds, when it is positive. Since the OS has a minimum time between switching threads, the
|
||||
function will not wait exactly delay ms, it will wait at least delay ms, depending on what else is
|
||||
running on your computer at that time. It returns the code of the pressed key or -1 if no key was
|
||||
pressed before the specified time had elapsed. To check for a key press but not wait for it, use
|
||||
#pollKey.
|
||||
|
||||
@note The functions #waitKey and #pollKey are the only methods in HighGUI that can fetch and handle
|
||||
GUI events, so one of them needs to be called periodically for normal event processing unless
|
||||
HighGUI is used within an environment that takes care of event processing.
|
||||
|
||||
@note The function only works if there is at least one HighGUI window created and the window is
|
||||
active. If there are several HighGUI windows, any of them can be active.
|
||||
|
||||
@param delay Delay in milliseconds. 0 is the special value that means "forever".
|
||||
*/
|
||||
CV_EXPORTS_W int waitKey(int delay = 0);
|
||||
|
||||
/** @brief Polls for a pressed key.
|
||||
|
||||
The function pollKey polls for a key event without waiting. It returns the code of the pressed key
|
||||
or -1 if no key was pressed since the last invocation. To wait until a key was pressed, use #waitKey.
|
||||
|
||||
@note The functions #waitKey and #pollKey are the only methods in HighGUI that can fetch and handle
|
||||
GUI events, so one of them needs to be called periodically for normal event processing unless
|
||||
HighGUI is used within an environment that takes care of event processing.
|
||||
|
||||
@note The function only works if there is at least one HighGUI window created and the window is
|
||||
active. If there are several HighGUI windows, any of them can be active.
|
||||
*/
|
||||
CV_EXPORTS_W int pollKey();
|
||||
|
||||
/** @brief Displays an image in the specified window.
|
||||
|
||||
The function imshow displays an image in the specified window. If the window was created with the
|
||||
cv::WINDOW_AUTOSIZE flag, the image is shown with its original size, however it is still limited by the screen resolution.
|
||||
Otherwise, the image is scaled to fit the window. The function may scale the image, depending on its depth:
|
||||
|
||||
- If the image is 8-bit unsigned, it is displayed as is.
|
||||
- If the image is 16-bit unsigned, the pixels are divided by 256. That is, the
|
||||
value range [0,255\*256] is mapped to [0,255].
|
||||
- If the image is 32-bit or 64-bit floating-point, the pixel values are multiplied by 255. That is, the
|
||||
value range [0,1] is mapped to [0,255].
|
||||
- 32-bit integer images are not processed anymore due to ambiguouty of required transform.
|
||||
Convert to 8-bit unsigned matrix using a custom preprocessing specific to image's context.
|
||||
|
||||
If window was created with OpenGL support, cv::imshow also support ogl::Buffer , ogl::Texture2D and
|
||||
cuda::GpuMat as input.
|
||||
|
||||
If the window was not created before this function, it is assumed creating a window with cv::WINDOW_AUTOSIZE.
|
||||
|
||||
If you need to show an image that is bigger than the screen resolution, you will need to call namedWindow("", WINDOW_NORMAL) before the imshow.
|
||||
|
||||
@note This function should be followed by a call to cv::waitKey or cv::pollKey to perform GUI
|
||||
housekeeping tasks that are necessary to actually show the given image and make the window respond
|
||||
to mouse and keyboard events. Otherwise, it won't display the image and the window might lock up.
|
||||
For example, **waitKey(0)** will display the window infinitely until any keypress (it is suitable
|
||||
for image display). **waitKey(25)** will display a frame and wait approximately 25 ms for a key
|
||||
press (suitable for displaying a video frame-by-frame). To remove the window, use cv::destroyWindow.
|
||||
|
||||
@note [__Windows Backend Only__] Pressing Ctrl+C will copy the image to the clipboard. Pressing Ctrl+S will show a dialog to save the image.
|
||||
@note [__Wayland Backend Only__] Supoorting format is extended.
|
||||
- If the image is 8-bit signed, the pixels are biased by 128. That is, the
|
||||
value range [-128,127] is mapped to [0,255].
|
||||
- If the image is 16-bit signed, the pixels are divided by 256 and biased by 128. That is, the
|
||||
value range [-32768,32767] is mapped to [0,255].
|
||||
|
||||
@param winname Name of the window.
|
||||
@param mat Image to be shown.
|
||||
*/
|
||||
CV_EXPORTS_W void imshow(const String& winname, InputArray mat);
|
||||
|
||||
/** @brief Resizes the window to the specified size
|
||||
|
||||
@note The specified window size is for the image area. Toolbars are not counted.
|
||||
Only windows created without cv::WINDOW_AUTOSIZE flag can be resized.
|
||||
|
||||
@param winname Window name.
|
||||
@param width The new window width.
|
||||
@param height The new window height.
|
||||
*/
|
||||
CV_EXPORTS_W void resizeWindow(const String& winname, int width, int height);
|
||||
|
||||
/** @overload
|
||||
@param winname Window name.
|
||||
@param size The new window size.
|
||||
*/
|
||||
CV_EXPORTS_W void resizeWindow(const String& winname, const cv::Size& size);
|
||||
|
||||
/** @brief Moves the window to the specified position
|
||||
|
||||
@param winname Name of the window.
|
||||
@param x The new x-coordinate of the window.
|
||||
@param y The new y-coordinate of the window.
|
||||
|
||||
@note [__Wayland Backend Only__] This function is not supported by the Wayland protocol limitation.
|
||||
*/
|
||||
CV_EXPORTS_W void moveWindow(const String& winname, int x, int y);
|
||||
|
||||
/** @brief Changes parameters of a window dynamically.
|
||||
|
||||
The function setWindowProperty enables changing properties of a window.
|
||||
|
||||
@param winname Name of the window.
|
||||
@param prop_id Window property to edit. The supported operation flags are: (cv::WindowPropertyFlags)
|
||||
@param prop_value New value of the window property. The supported flags are: (cv::WindowFlags)
|
||||
|
||||
@note [__Wayland Backend Only__] This function is not supported.
|
||||
*/
|
||||
CV_EXPORTS_W void setWindowProperty(const String& winname, int prop_id, double prop_value);
|
||||
|
||||
/** @brief Updates window title
|
||||
@param winname Name of the window.
|
||||
@param title New title.
|
||||
*/
|
||||
CV_EXPORTS_W void setWindowTitle(const String& winname, const String& title);
|
||||
|
||||
/** @brief Provides parameters of a window.
|
||||
|
||||
The function getWindowProperty returns properties of a window.
|
||||
|
||||
@param winname Name of the window.
|
||||
@param prop_id Window property to retrieve. The following operation flags are available: (cv::WindowPropertyFlags)
|
||||
|
||||
@sa setWindowProperty
|
||||
|
||||
@note [__Wayland Backend Only__] This function is not supported.
|
||||
*/
|
||||
CV_EXPORTS_W double getWindowProperty(const String& winname, int prop_id);
|
||||
|
||||
/** @brief Provides rectangle of image in the window.
|
||||
|
||||
The function getWindowImageRect returns the client screen coordinates, width and height of the image rendering area.
|
||||
|
||||
@param winname Name of the window.
|
||||
|
||||
@sa resizeWindow moveWindow
|
||||
|
||||
@note [__Wayland Backend Only__] This function is not supported by the Wayland protocol limitation.
|
||||
*/
|
||||
CV_EXPORTS_W Rect getWindowImageRect(const String& winname);
|
||||
|
||||
/** @example samples/cpp/create_mask.cpp
|
||||
This program demonstrates using mouse events and how to make and use a mask image (black and white) .
|
||||
*/
|
||||
/** @brief Sets mouse handler for the specified window
|
||||
|
||||
@param winname Name of the window.
|
||||
@param onMouse Callback function for mouse events. See OpenCV samples on how to specify and use the callback.
|
||||
@param userdata The optional parameter passed to the callback.
|
||||
*/
|
||||
CV_EXPORTS void setMouseCallback(const String& winname, MouseCallback onMouse, void* userdata = 0);
|
||||
|
||||
/** @brief Gets the mouse-wheel motion delta, when handling mouse-wheel events cv::EVENT_MOUSEWHEEL and
|
||||
cv::EVENT_MOUSEHWHEEL.
|
||||
|
||||
For regular mice with a scroll-wheel, delta will be a multiple of 120. The value 120 corresponds to
|
||||
a one notch rotation of the wheel or the threshold for action to be taken and one such action should
|
||||
occur for each delta. Some high-precision mice with higher-resolution freely-rotating wheels may
|
||||
generate smaller values.
|
||||
|
||||
For cv::EVENT_MOUSEWHEEL positive and negative values mean forward and backward scrolling,
|
||||
respectively. For cv::EVENT_MOUSEHWHEEL, where available, positive and negative values mean right and
|
||||
left scrolling, respectively.
|
||||
|
||||
@note Mouse-wheel events are currently supported only on Windows and Cocoa.
|
||||
|
||||
@param flags The mouse callback flags parameter.
|
||||
*/
|
||||
CV_EXPORTS int getMouseWheelDelta(int flags);
|
||||
|
||||
/** @brief Allows users to select a ROI on the given image.
|
||||
|
||||
The function creates a window and allows users to select a ROI using the mouse.
|
||||
Controls: use `space` or `enter` to finish selection, use key `c` to cancel selection (function will return the zero cv::Rect).
|
||||
|
||||
@param windowName name of the window where selection process will be shown.
|
||||
@param img image to select a ROI.
|
||||
@param showCrosshair if true crosshair of selection rectangle will be shown.
|
||||
@param fromCenter if true center of selection will match initial mouse position. In opposite case a corner of
|
||||
selection rectangle will correspont to the initial mouse position.
|
||||
@param printNotice if true a notice to select ROI or cancel selection will be printed in console.
|
||||
@return selected ROI or empty rect if selection canceled.
|
||||
|
||||
@note The function sets it's own mouse callback for specified window using cv::setMouseCallback(windowName, ...).
|
||||
After finish of work an empty callback will be set for the used window.
|
||||
*/
|
||||
CV_EXPORTS_W Rect selectROI(const String& windowName, InputArray img, bool showCrosshair = true, bool fromCenter = false, bool printNotice = true);
|
||||
|
||||
/** @overload
|
||||
*/
|
||||
CV_EXPORTS_W Rect selectROI(InputArray img, bool showCrosshair = true, bool fromCenter = false, bool printNotice = true);
|
||||
|
||||
/** @brief Allows users to select multiple ROIs on the given image.
|
||||
|
||||
The function creates a window and allows users to select multiple ROIs using the mouse.
|
||||
Controls: use `space` or `enter` to finish current selection and start a new one,
|
||||
use `esc` to terminate multiple ROI selection process.
|
||||
|
||||
@param windowName name of the window where selection process will be shown.
|
||||
@param img image to select a ROI.
|
||||
@param boundingBoxes selected ROIs.
|
||||
@param showCrosshair if true crosshair of selection rectangle will be shown.
|
||||
@param fromCenter if true center of selection will match initial mouse position. In opposite case a corner of
|
||||
selection rectangle will correspont to the initial mouse position.
|
||||
@param printNotice if true a notice to select ROI or cancel selection will be printed in console.
|
||||
|
||||
@note The function sets it's own mouse callback for specified window using cv::setMouseCallback(windowName, ...).
|
||||
After finish of work an empty callback will be set for the used window.
|
||||
*/
|
||||
CV_EXPORTS_W void selectROIs(const String& windowName, InputArray img,
|
||||
CV_OUT std::vector<Rect>& boundingBoxes, bool showCrosshair = true, bool fromCenter = false, bool printNotice = true);
|
||||
|
||||
/** @brief Creates a trackbar and attaches it to the specified window.
|
||||
|
||||
The function createTrackbar creates a trackbar (a slider or range control) with the specified name
|
||||
and range, assigns a variable value to be a position synchronized with the trackbar and specifies
|
||||
the callback function onChange to be called on the trackbar position change. The created trackbar is
|
||||
displayed in the specified window winname.
|
||||
|
||||
@note [__Qt Backend Only__] winname can be empty if the trackbar should be attached to the
|
||||
control panel.
|
||||
|
||||
Clicking the label of each trackbar enables editing the trackbar values manually.
|
||||
|
||||
@param trackbarname Name of the created trackbar.
|
||||
@param winname Name of the window that will contain the trackbar.
|
||||
@param value Pointer to the integer value that will be changed by the trackbar.
|
||||
Pass `nullptr` if the value pointer is not used. In this case, manually handle
|
||||
the trackbar position in the callback function.
|
||||
@param count Maximum position of the trackbar.
|
||||
@param onChange Pointer to the function to be called every time the slider changes position.
|
||||
This function should have the prototype void Foo(int, void\*);, where the first parameter is
|
||||
the trackbar position, and the second parameter is the user data (see the next parameter).
|
||||
If the callback is a nullptr, no callbacks are called, but the trackbar's value will still be
|
||||
updated automatically.
|
||||
@param userdata Optional user data that is passed to the callback.
|
||||
@note If the `value` pointer is `nullptr`, the trackbar position must be manually managed.
|
||||
Call the callback function manually with the desired initial value to avoid runtime warnings.
|
||||
@see \ref tutorial_trackbar
|
||||
*/
|
||||
CV_EXPORTS int createTrackbar(const String& trackbarname, const String& winname,
|
||||
int* value, int count,
|
||||
TrackbarCallback onChange = 0,
|
||||
void* userdata = 0);
|
||||
|
||||
/** @brief Returns the trackbar position.
|
||||
|
||||
The function returns the current position of the specified trackbar.
|
||||
|
||||
@note [__Qt Backend Only__] winname can be empty if the trackbar is attached to the control
|
||||
panel.
|
||||
|
||||
@param trackbarname Name of the trackbar.
|
||||
@param winname Name of the window that is the parent of the trackbar.
|
||||
*/
|
||||
CV_EXPORTS_W int getTrackbarPos(const String& trackbarname, const String& winname);
|
||||
|
||||
/** @brief Sets the trackbar position.
|
||||
|
||||
The function sets the position of the specified trackbar in the specified window.
|
||||
|
||||
@note [__Qt Backend Only__] winname can be empty if the trackbar is attached to the control
|
||||
panel.
|
||||
|
||||
@param trackbarname Name of the trackbar.
|
||||
@param winname Name of the window that is the parent of trackbar.
|
||||
@param pos New position.
|
||||
*/
|
||||
CV_EXPORTS_W void setTrackbarPos(const String& trackbarname, const String& winname, int pos);
|
||||
|
||||
/** @brief Sets the trackbar maximum position.
|
||||
|
||||
The function sets the maximum position of the specified trackbar in the specified window.
|
||||
|
||||
@note [__Qt Backend Only__] winname can be empty if the trackbar is attached to the control
|
||||
panel.
|
||||
|
||||
@param trackbarname Name of the trackbar.
|
||||
@param winname Name of the window that is the parent of trackbar.
|
||||
@param maxval New maximum position.
|
||||
*/
|
||||
CV_EXPORTS_W void setTrackbarMax(const String& trackbarname, const String& winname, int maxval);
|
||||
|
||||
/** @brief Sets the trackbar minimum position.
|
||||
|
||||
The function sets the minimum position of the specified trackbar in the specified window.
|
||||
|
||||
@note [__Qt Backend Only__] winname can be empty if the trackbar is attached to the control
|
||||
panel.
|
||||
|
||||
@param trackbarname Name of the trackbar.
|
||||
@param winname Name of the window that is the parent of trackbar.
|
||||
@param minval New minimum position.
|
||||
*/
|
||||
CV_EXPORTS_W void setTrackbarMin(const String& trackbarname, const String& winname, int minval);
|
||||
|
||||
//! @addtogroup highgui_opengl OpenGL support
|
||||
//! @{
|
||||
|
||||
/** @brief Displays OpenGL 2D texture in the specified window.
|
||||
|
||||
@param winname Name of the window.
|
||||
@param tex OpenGL 2D texture data.
|
||||
*/
|
||||
CV_EXPORTS void imshow(const String& winname, const ogl::Texture2D& tex);
|
||||
|
||||
/** @brief Sets a callback function to be called to draw on top of displayed image.
|
||||
|
||||
The function setOpenGlDrawCallback can be used to draw 3D data on the window. See the example of
|
||||
callback function below:
|
||||
@code
|
||||
void on_opengl(void* param)
|
||||
{
|
||||
glLoadIdentity();
|
||||
|
||||
glTranslated(0.0, 0.0, -1.0);
|
||||
|
||||
glRotatef( 55, 1, 0, 0 );
|
||||
glRotatef( 45, 0, 1, 0 );
|
||||
glRotatef( 0, 0, 0, 1 );
|
||||
|
||||
static const int coords[6][4][3] = {
|
||||
{ { +1, -1, -1 }, { -1, -1, -1 }, { -1, +1, -1 }, { +1, +1, -1 } },
|
||||
{ { +1, +1, -1 }, { -1, +1, -1 }, { -1, +1, +1 }, { +1, +1, +1 } },
|
||||
{ { +1, -1, +1 }, { +1, -1, -1 }, { +1, +1, -1 }, { +1, +1, +1 } },
|
||||
{ { -1, -1, -1 }, { -1, -1, +1 }, { -1, +1, +1 }, { -1, +1, -1 } },
|
||||
{ { +1, -1, +1 }, { -1, -1, +1 }, { -1, -1, -1 }, { +1, -1, -1 } },
|
||||
{ { -1, -1, +1 }, { +1, -1, +1 }, { +1, +1, +1 }, { -1, +1, +1 } }
|
||||
};
|
||||
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
glColor3ub( i*20, 100+i*10, i*42 );
|
||||
glBegin(GL_QUADS);
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
glVertex3d(0.2 * coords[i][j][0], 0.2 * coords[i][j][1], 0.2 * coords[i][j][2]);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
@endcode
|
||||
|
||||
@param winname Name of the window.
|
||||
@param onOpenGlDraw Pointer to the function to be called every frame. This function should be
|
||||
prototyped as void Foo(void\*) .
|
||||
@param userdata Pointer passed to the callback function.(__Optional__)
|
||||
*/
|
||||
CV_EXPORTS void setOpenGlDrawCallback(const String& winname, OpenGlDrawCallback onOpenGlDraw, void* userdata = 0);
|
||||
|
||||
/** @brief Sets the specified window as current OpenGL context.
|
||||
|
||||
@param winname Name of the window.
|
||||
*/
|
||||
CV_EXPORTS void setOpenGlContext(const String& winname);
|
||||
|
||||
/** @brief Force window to redraw its context and call draw callback ( See cv::setOpenGlDrawCallback ).
|
||||
|
||||
@param winname Name of the window.
|
||||
*/
|
||||
CV_EXPORTS void updateWindow(const String& winname);
|
||||
|
||||
//! @} highgui_opengl
|
||||
|
||||
//! @addtogroup highgui_qt
|
||||
//! @{
|
||||
|
||||
/** @brief QtFont available only for Qt. See cv::fontQt
|
||||
*/
|
||||
struct QtFont
|
||||
{
|
||||
const char* nameFont; //!< Name of the font
|
||||
Scalar color; //!< Color of the font. Scalar(blue_component, green_component, red_component[, alpha_component])
|
||||
int font_face; //!< See cv::QtFontStyles
|
||||
const int* ascii; //!< font data and metrics
|
||||
const int* greek;
|
||||
const int* cyrillic;
|
||||
float hscale, vscale;
|
||||
float shear; //!< slope coefficient: 0 - normal, >0 - italic
|
||||
int thickness; //!< See cv::QtFontWeights
|
||||
float dx; //!< horizontal interval between letters
|
||||
int line_type; //!< PointSize
|
||||
};
|
||||
|
||||
/** @brief Creates the font to draw a text on an image.
|
||||
|
||||
The function fontQt creates a cv::QtFont object. This cv::QtFont is not compatible with putText .
|
||||
|
||||
A basic usage of this function is the following: :
|
||||
@code
|
||||
QtFont font = fontQt("Times");
|
||||
addText( img1, "Hello World !", Point(50,50), font);
|
||||
@endcode
|
||||
|
||||
@param nameFont Name of the font. The name should match the name of a system font (such as
|
||||
*Times*). If the font is not found, a default one is used.
|
||||
@param pointSize Size of the font. If not specified, equal zero or negative, the point size of the
|
||||
font is set to a system-dependent default value. Generally, this is 12 points.
|
||||
@param color Color of the font in BGRA where A = 255 is fully transparent. Use the macro CV_RGB
|
||||
for simplicity.
|
||||
@param weight Font weight. Available operation flags are : cv::QtFontWeights You can also specify a positive integer for better control.
|
||||
@param style Font style. Available operation flags are : cv::QtFontStyles
|
||||
@param spacing Spacing between characters. It can be negative or positive.
|
||||
*/
|
||||
CV_EXPORTS QtFont fontQt(const String& nameFont, int pointSize = -1,
|
||||
Scalar color = Scalar::all(0), int weight = QT_FONT_NORMAL,
|
||||
int style = QT_STYLE_NORMAL, int spacing = 0);
|
||||
|
||||
/** @brief Draws a text on the image.
|
||||
|
||||
The function addText draws *text* on the image *img* using a specific font *font* (see example cv::fontQt
|
||||
)
|
||||
|
||||
@param img 8-bit 3-channel image where the text should be drawn.
|
||||
@param text Text to write on an image.
|
||||
@param org Point(x,y) where the text should start on an image.
|
||||
@param font Font to use to draw a text.
|
||||
*/
|
||||
CV_EXPORTS void addText( const Mat& img, const String& text, Point org, const QtFont& font);
|
||||
|
||||
/** @brief Draws a text on the image.
|
||||
|
||||
@param img 8-bit 3-channel image where the text should be drawn.
|
||||
@param text Text to write on an image.
|
||||
@param org Point(x,y) where the text should start on an image.
|
||||
@param nameFont Name of the font. The name should match the name of a system font (such as
|
||||
*Times*). If the font is not found, a default one is used.
|
||||
@param pointSize Size of the font. If not specified, equal zero or negative, the point size of the
|
||||
font is set to a system-dependent default value. Generally, this is 12 points.
|
||||
@param color Color of the font in BGRA where A = 255 is fully transparent.
|
||||
@param weight Font weight. Available operation flags are : cv::QtFontWeights You can also specify a positive integer for better control.
|
||||
@param style Font style. Available operation flags are : cv::QtFontStyles
|
||||
@param spacing Spacing between characters. It can be negative or positive.
|
||||
*/
|
||||
CV_EXPORTS_W void addText(const Mat& img, const String& text, Point org, const String& nameFont, int pointSize = -1, Scalar color = Scalar::all(0),
|
||||
int weight = QT_FONT_NORMAL, int style = QT_STYLE_NORMAL, int spacing = 0);
|
||||
|
||||
/** @brief Displays a text on a window image as an overlay for a specified duration.
|
||||
|
||||
The function displayOverlay displays useful information/tips on top of the window for a certain
|
||||
amount of time *delayms*. The function does not modify the image, displayed in the window, that is,
|
||||
after the specified delay the original content of the window is restored.
|
||||
|
||||
@param winname Name of the window.
|
||||
@param text Overlay text to write on a window image.
|
||||
@param delayms The period (in milliseconds), during which the overlay text is displayed. If this
|
||||
function is called before the previous overlay text timed out, the timer is restarted and the text
|
||||
is updated. If this value is zero, the text never disappears.
|
||||
*/
|
||||
CV_EXPORTS_W void displayOverlay(const String& winname, const String& text, int delayms = 0);
|
||||
|
||||
/** @brief Displays a text on the window statusbar during the specified period of time.
|
||||
|
||||
The function displayStatusBar displays useful information/tips on top of the window for a certain
|
||||
amount of time *delayms* . This information is displayed on the window statusbar (the window must be
|
||||
created with the CV_GUI_EXPANDED flags).
|
||||
|
||||
@param winname Name of the window.
|
||||
@param text Text to write on the window statusbar.
|
||||
@param delayms Duration (in milliseconds) to display the text. If this function is called before
|
||||
the previous text timed out, the timer is restarted and the text is updated. If this value is
|
||||
zero, the text never disappears.
|
||||
*/
|
||||
CV_EXPORTS_W void displayStatusBar(const String& winname, const String& text, int delayms = 0);
|
||||
|
||||
/** @brief Saves parameters of the specified window.
|
||||
|
||||
The function saveWindowParameters saves size, location, flags, trackbars value, zoom and panning
|
||||
location of the window windowName.
|
||||
|
||||
@param windowName Name of the window.
|
||||
*/
|
||||
CV_EXPORTS void saveWindowParameters(const String& windowName);
|
||||
|
||||
/** @brief Loads parameters of the specified window.
|
||||
|
||||
The function loadWindowParameters loads size, location, flags, trackbars value, zoom and panning
|
||||
location of the window windowName.
|
||||
|
||||
@param windowName Name of the window.
|
||||
*/
|
||||
CV_EXPORTS void loadWindowParameters(const String& windowName);
|
||||
|
||||
CV_EXPORTS int startLoop(int (*pt2Func)(int argc, char *argv[]), int argc, char* argv[]);
|
||||
|
||||
CV_EXPORTS void stopLoop();
|
||||
|
||||
/** @brief Attaches a button to the control panel.
|
||||
|
||||
The function createButton attaches a button to the control panel. Each button is added to a
|
||||
buttonbar to the right of the last button. A new buttonbar is created if nothing was attached to the
|
||||
control panel before, or if the last element attached to the control panel was a trackbar or if the
|
||||
QT_NEW_BUTTONBAR flag is added to the type.
|
||||
|
||||
See below various examples of the cv::createButton function call: :
|
||||
@code
|
||||
createButton("",callbackButton);//create a push button "button 0", that will call callbackButton.
|
||||
createButton("button2",callbackButton,NULL,QT_CHECKBOX,0);
|
||||
createButton("button3",callbackButton,&value);
|
||||
createButton("button5",callbackButton1,NULL,QT_RADIOBOX);
|
||||
createButton("button6",callbackButton2,NULL,QT_PUSH_BUTTON,1);
|
||||
createButton("button6",callbackButton2,NULL,QT_PUSH_BUTTON|QT_NEW_BUTTONBAR);// create a push button in a new row
|
||||
@endcode
|
||||
|
||||
@param bar_name Name of the button.
|
||||
@param on_change Pointer to the function to be called every time the button changes its state.
|
||||
This function should be prototyped as void Foo(int state,\*void); . *state* is the current state
|
||||
of the button. It could be -1 for a push button, 0 or 1 for a check/radio box button.
|
||||
@param userdata Pointer passed to the callback function.
|
||||
@param type Optional type of the button. Available types are: (cv::QtButtonTypes)
|
||||
@param initial_button_state Default state of the button. Use for checkbox and radiobox. Its
|
||||
value could be 0 or 1. (__Optional__)
|
||||
*/
|
||||
CV_EXPORTS int createButton( const String& bar_name, ButtonCallback on_change,
|
||||
void* userdata = 0, int type = QT_PUSH_BUTTON,
|
||||
bool initial_button_state = false);
|
||||
|
||||
//! @} highgui_qt
|
||||
|
||||
//! @} highgui
|
||||
|
||||
} // cv
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,48 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifdef __OPENCV_BUILD
|
||||
#error this is a compatibility header which should not be used inside the OpenCV library
|
||||
#endif
|
||||
|
||||
#include "opencv2/highgui.hpp"
|
||||
@@ -0,0 +1,251 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of Intel Corporation may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef OPENCV_HIGHGUI_H
|
||||
#define OPENCV_HIGHGUI_H
|
||||
|
||||
#include "opencv2/core/core_c.h"
|
||||
#include "opencv2/imgproc/imgproc_c.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/** @addtogroup highgui_c
|
||||
@{
|
||||
*/
|
||||
|
||||
/****************************************************************************************\
|
||||
* Basic GUI functions *
|
||||
\****************************************************************************************/
|
||||
//YV
|
||||
//-----------New for Qt
|
||||
/* For font */
|
||||
enum { CV_FONT_LIGHT = 25,//QFont::Light,
|
||||
CV_FONT_NORMAL = 50,//QFont::Normal,
|
||||
CV_FONT_DEMIBOLD = 63,//QFont::DemiBold,
|
||||
CV_FONT_BOLD = 75,//QFont::Bold,
|
||||
CV_FONT_BLACK = 87 //QFont::Black
|
||||
};
|
||||
|
||||
enum { CV_STYLE_NORMAL = 0,//QFont::StyleNormal,
|
||||
CV_STYLE_ITALIC = 1,//QFont::StyleItalic,
|
||||
CV_STYLE_OBLIQUE = 2 //QFont::StyleOblique
|
||||
};
|
||||
/* ---------*/
|
||||
|
||||
//for color cvScalar(blue_component, green_component, red_component[, alpha_component])
|
||||
//and alpha= 0 <-> 0xFF (not transparent <-> transparent)
|
||||
CVAPI(CvFont) cvFontQt(const char* nameFont, int pointSize CV_DEFAULT(-1), CvScalar color CV_DEFAULT(cvScalarAll(0)), int weight CV_DEFAULT(CV_FONT_NORMAL), int style CV_DEFAULT(CV_STYLE_NORMAL), int spacing CV_DEFAULT(0));
|
||||
|
||||
CVAPI(void) cvAddText(const CvArr* img, const char* text, CvPoint org, CvFont *arg2);
|
||||
|
||||
CVAPI(void) cvDisplayOverlay(const char* name, const char* text, int delayms CV_DEFAULT(0));
|
||||
CVAPI(void) cvDisplayStatusBar(const char* name, const char* text, int delayms CV_DEFAULT(0));
|
||||
|
||||
CVAPI(void) cvSaveWindowParameters(const char* name);
|
||||
CVAPI(void) cvLoadWindowParameters(const char* name);
|
||||
CVAPI(int) cvStartLoop(int (*pt2Func)(int argc, char *argv[]), int argc, char* argv[]);
|
||||
CVAPI(void) cvStopLoop( void );
|
||||
|
||||
typedef void (CV_CDECL *CvButtonCallback)(int state, void* userdata);
|
||||
enum {CV_PUSH_BUTTON = 0, CV_CHECKBOX = 1, CV_RADIOBOX = 2};
|
||||
CVAPI(int) cvCreateButton( const char* button_name CV_DEFAULT(NULL),CvButtonCallback on_change CV_DEFAULT(NULL), void* userdata CV_DEFAULT(NULL) , int button_type CV_DEFAULT(CV_PUSH_BUTTON), int initial_button_state CV_DEFAULT(0));
|
||||
//----------------------
|
||||
|
||||
|
||||
/* this function is used to set some external parameters in case of X Window */
|
||||
CVAPI(int) cvInitSystem( int argc, char** argv );
|
||||
|
||||
CVAPI(int) cvStartWindowThread( void );
|
||||
|
||||
// --------- YV ---------
|
||||
enum
|
||||
{
|
||||
//These 3 flags are used by cvSet/GetWindowProperty
|
||||
CV_WND_PROP_FULLSCREEN = 0, //to change/get window's fullscreen property
|
||||
CV_WND_PROP_AUTOSIZE = 1, //to change/get window's autosize property
|
||||
CV_WND_PROP_ASPECTRATIO= 2, //to change/get window's aspectratio property
|
||||
CV_WND_PROP_OPENGL = 3, //to change/get window's opengl support
|
||||
CV_WND_PROP_VISIBLE = 4,
|
||||
|
||||
//These 2 flags are used by cvNamedWindow and cvSet/GetWindowProperty
|
||||
CV_WINDOW_NORMAL = 0x00000000, //the user can resize the window (no constraint) / also use to switch a fullscreen window to a normal size
|
||||
CV_WINDOW_AUTOSIZE = 0x00000001, //the user cannot resize the window, the size is constrainted by the image displayed
|
||||
CV_WINDOW_OPENGL = 0x00001000, //window with opengl support
|
||||
|
||||
//Those flags are only for Qt
|
||||
CV_GUI_EXPANDED = 0x00000000, //status bar and tool bar
|
||||
CV_GUI_NORMAL = 0x00000010, //old fashious way
|
||||
|
||||
//These 3 flags are used by cvNamedWindow and cvSet/GetWindowProperty
|
||||
CV_WINDOW_FULLSCREEN = 1,//change the window to fullscreen
|
||||
CV_WINDOW_FREERATIO = 0x00000100,//the image expends as much as it can (no ratio constraint)
|
||||
CV_WINDOW_KEEPRATIO = 0x00000000//the ration image is respected.
|
||||
};
|
||||
|
||||
/* create window */
|
||||
CVAPI(int) cvNamedWindow( const char* name, int flags CV_DEFAULT(CV_WINDOW_AUTOSIZE) );
|
||||
|
||||
/* Set and Get Property of the window */
|
||||
CVAPI(void) cvSetWindowProperty(const char* name, int prop_id, double prop_value);
|
||||
CVAPI(double) cvGetWindowProperty(const char* name, int prop_id);
|
||||
|
||||
/* display image within window (highgui windows remember their content) */
|
||||
CVAPI(void) cvShowImage( const char* name, const CvArr* image );
|
||||
|
||||
/* resize/move window */
|
||||
CVAPI(void) cvResizeWindow( const char* name, int width, int height );
|
||||
CVAPI(void) cvMoveWindow( const char* name, int x, int y );
|
||||
|
||||
|
||||
/* destroy window and all the trackers associated with it */
|
||||
CVAPI(void) cvDestroyWindow( const char* name );
|
||||
|
||||
CVAPI(void) cvDestroyAllWindows(void);
|
||||
|
||||
/* get native window handle (HWND in case of Win32 and Widget in case of X Window) */
|
||||
CVAPI(void*) cvGetWindowHandle( const char* name );
|
||||
|
||||
/* get name of highgui window given its native handle */
|
||||
CVAPI(const char*) cvGetWindowName( void* window_handle );
|
||||
|
||||
|
||||
typedef void (CV_CDECL *CvTrackbarCallback)(int pos);
|
||||
|
||||
/* create trackbar and display it on top of given window, set callback */
|
||||
CVAPI(int) cvCreateTrackbar( const char* trackbar_name, const char* window_name,
|
||||
int* value, int count, CvTrackbarCallback on_change CV_DEFAULT(NULL));
|
||||
|
||||
typedef void (CV_CDECL *CvTrackbarCallback2)(int pos, void* userdata);
|
||||
|
||||
CVAPI(int) cvCreateTrackbar2( const char* trackbar_name, const char* window_name,
|
||||
int* value, int count, CvTrackbarCallback2 on_change,
|
||||
void* userdata CV_DEFAULT(0));
|
||||
|
||||
/* retrieve or set trackbar position */
|
||||
CVAPI(int) cvGetTrackbarPos( const char* trackbar_name, const char* window_name );
|
||||
CVAPI(void) cvSetTrackbarPos( const char* trackbar_name, const char* window_name, int pos );
|
||||
CVAPI(void) cvSetTrackbarMax(const char* trackbar_name, const char* window_name, int maxval);
|
||||
CVAPI(void) cvSetTrackbarMin(const char* trackbar_name, const char* window_name, int minval);
|
||||
|
||||
enum
|
||||
{
|
||||
CV_EVENT_MOUSEMOVE =0,
|
||||
CV_EVENT_LBUTTONDOWN =1,
|
||||
CV_EVENT_RBUTTONDOWN =2,
|
||||
CV_EVENT_MBUTTONDOWN =3,
|
||||
CV_EVENT_LBUTTONUP =4,
|
||||
CV_EVENT_RBUTTONUP =5,
|
||||
CV_EVENT_MBUTTONUP =6,
|
||||
CV_EVENT_LBUTTONDBLCLK =7,
|
||||
CV_EVENT_RBUTTONDBLCLK =8,
|
||||
CV_EVENT_MBUTTONDBLCLK =9,
|
||||
CV_EVENT_MOUSEWHEEL =10,
|
||||
CV_EVENT_MOUSEHWHEEL =11
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CV_EVENT_FLAG_LBUTTON =1,
|
||||
CV_EVENT_FLAG_RBUTTON =2,
|
||||
CV_EVENT_FLAG_MBUTTON =4,
|
||||
CV_EVENT_FLAG_CTRLKEY =8,
|
||||
CV_EVENT_FLAG_SHIFTKEY =16,
|
||||
CV_EVENT_FLAG_ALTKEY =32
|
||||
};
|
||||
|
||||
|
||||
#define CV_GET_WHEEL_DELTA(flags) ((short)((flags >> 16) & 0xffff)) // upper 16 bits
|
||||
|
||||
typedef void (CV_CDECL *CvMouseCallback )(int event, int x, int y, int flags, void* param);
|
||||
|
||||
/* assign callback for mouse events */
|
||||
CVAPI(void) cvSetMouseCallback( const char* window_name, CvMouseCallback on_mouse,
|
||||
void* param CV_DEFAULT(NULL));
|
||||
|
||||
/* wait for key event infinitely (delay<=0) or for "delay" milliseconds */
|
||||
CVAPI(int) cvWaitKey(int delay CV_DEFAULT(0));
|
||||
|
||||
// OpenGL support
|
||||
|
||||
typedef void (CV_CDECL *CvOpenGlDrawCallback)(void* userdata);
|
||||
CVAPI(void) cvSetOpenGlDrawCallback(const char* window_name, CvOpenGlDrawCallback callback, void* userdata CV_DEFAULT(NULL));
|
||||
|
||||
CVAPI(void) cvSetOpenGlContext(const char* window_name);
|
||||
CVAPI(void) cvUpdateWindow(const char* window_name);
|
||||
|
||||
|
||||
/****************************************************************************************\
|
||||
|
||||
* Obsolete functions/synonyms *
|
||||
\****************************************************************************************/
|
||||
|
||||
#define cvAddSearchPath(path)
|
||||
#define cvvInitSystem cvInitSystem
|
||||
#define cvvNamedWindow cvNamedWindow
|
||||
#define cvvShowImage cvShowImage
|
||||
#define cvvResizeWindow cvResizeWindow
|
||||
#define cvvDestroyWindow cvDestroyWindow
|
||||
#define cvvCreateTrackbar cvCreateTrackbar
|
||||
#define cvvAddSearchPath cvAddSearchPath
|
||||
#define cvvWaitKey(name) cvWaitKey(0)
|
||||
#define cvvWaitKeyEx(name,delay) cvWaitKey(delay)
|
||||
#define HG_AUTOSIZE CV_WINDOW_AUTOSIZE
|
||||
#define set_preprocess_func cvSetPreprocessFuncWin32
|
||||
#define set_postprocess_func cvSetPostprocessFuncWin32
|
||||
|
||||
#if defined _WIN32
|
||||
|
||||
CVAPI(void) cvSetPreprocessFuncWin32_(const void* callback);
|
||||
CVAPI(void) cvSetPostprocessFuncWin32_(const void* callback);
|
||||
#define cvSetPreprocessFuncWin32(callback) cvSetPreprocessFuncWin32_((const void*)(callback))
|
||||
#define cvSetPostprocessFuncWin32(callback) cvSetPostprocessFuncWin32_((const void*)(callback))
|
||||
|
||||
#endif
|
||||
|
||||
/** @} highgui_c */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,48 @@
|
||||
// highgui (UX) support for Windows Runtime
|
||||
|
||||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// (3 - clause BSD License)
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that
|
||||
// the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
|
||||
// following disclaimer.
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
|
||||
// following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or
|
||||
// promote products derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
// PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING
|
||||
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
using namespace Windows::UI::Xaml::Controls;
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
//! @addtogroup highgui_winrt
|
||||
//! @{
|
||||
|
||||
/********************************** WinRT Specific API *************************************************/
|
||||
|
||||
/** @brief Initializes container component that will be used to hold generated window content.
|
||||
|
||||
@param container Container (Panel^) reference that will be used to hold generated window content: controls and image.
|
||||
|
||||
@note
|
||||
Must be called to assign WinRT container that will hold created windows content.
|
||||
*/
|
||||
CV_EXPORTS void winrt_initContainer(::Windows::UI::Xaml::Controls::Panel^ container);
|
||||
|
||||
//! @} videoio_winrt
|
||||
|
||||
} // cv
|
||||
@@ -0,0 +1,186 @@
|
||||
package org.opencv.highgui;
|
||||
|
||||
import org.opencv.core.Mat;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.KeyListener;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBufferByte;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* This class was designed for use in Java applications
|
||||
* to recreate the OpenCV HighGui functionalities.
|
||||
*/
|
||||
public final class HighGui {
|
||||
|
||||
// Constants for namedWindow
|
||||
public final static int WINDOW_NORMAL = ImageWindow.WINDOW_NORMAL;
|
||||
public final static int WINDOW_AUTOSIZE = ImageWindow.WINDOW_AUTOSIZE;
|
||||
|
||||
// Control Variables
|
||||
public static int n_closed_windows = 0;
|
||||
public static int pressedKey = -1;
|
||||
public static CountDownLatch latch = new CountDownLatch(1);
|
||||
|
||||
// Windows Map
|
||||
public static Map<String, ImageWindow> windows = new HashMap<String, ImageWindow>();
|
||||
|
||||
public static void namedWindow(String winname) {
|
||||
namedWindow(winname, HighGui.WINDOW_AUTOSIZE);
|
||||
}
|
||||
|
||||
public static void namedWindow(String winname, int flag) {
|
||||
ImageWindow newWin = new ImageWindow(winname, flag);
|
||||
if (windows.get(winname) == null) windows.put(winname, newWin);
|
||||
}
|
||||
|
||||
public static void imshow(String winname, Mat img) {
|
||||
if (img.empty()) {
|
||||
throw new IllegalArgumentException("Image is empty");
|
||||
} else {
|
||||
ImageWindow tmpWindow = windows.get(winname);
|
||||
if (tmpWindow == null) {
|
||||
ImageWindow newWin = new ImageWindow(winname, img);
|
||||
windows.put(winname, newWin);
|
||||
} else {
|
||||
tmpWindow.setMat(img);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Image toBufferedImage(Mat m) {
|
||||
int type = BufferedImage.TYPE_BYTE_GRAY;
|
||||
|
||||
if (m.channels() > 1) {
|
||||
type = BufferedImage.TYPE_3BYTE_BGR;
|
||||
}
|
||||
BufferedImage image = new BufferedImage(m.cols(), m.rows(), type);
|
||||
final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
|
||||
m.get(0, 0, targetPixels);
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
public static JFrame createJFrame(String title, int flag) {
|
||||
JFrame frame = new JFrame(title);
|
||||
|
||||
frame.addWindowListener(new java.awt.event.WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(java.awt.event.WindowEvent windowEvent) {
|
||||
n_closed_windows++;
|
||||
if (n_closed_windows == windows.size()) latch.countDown();
|
||||
}
|
||||
});
|
||||
|
||||
frame.addKeyListener(new KeyListener() {
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e) {
|
||||
pressedKey = e.getKeyCode();
|
||||
latch.countDown();
|
||||
}
|
||||
});
|
||||
|
||||
if (flag == WINDOW_AUTOSIZE) frame.setResizable(false);
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
public static void waitKey(){
|
||||
waitKey(0);
|
||||
}
|
||||
|
||||
public static int waitKey(int delay) {
|
||||
// Reset control values
|
||||
latch = new CountDownLatch(1);
|
||||
n_closed_windows = 0;
|
||||
pressedKey = -1;
|
||||
|
||||
// If there are no windows to be shown return
|
||||
if (windows.isEmpty()) {
|
||||
throw new IllegalStateException("No windows created. Call imshow() first");
|
||||
}
|
||||
|
||||
// Remove the unused windows
|
||||
Iterator<Map.Entry<String,
|
||||
ImageWindow>> iter = windows.entrySet().iterator();
|
||||
while (iter.hasNext()) {
|
||||
Map.Entry<String,
|
||||
ImageWindow> entry = iter.next();
|
||||
ImageWindow win = entry.getValue();
|
||||
if (win.alreadyUsed) {
|
||||
iter.remove();
|
||||
win.frame.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
// (if) Create (else) Update frame
|
||||
for (ImageWindow win : windows.values()) {
|
||||
|
||||
if (win.img != null) {
|
||||
|
||||
ImageIcon icon = new ImageIcon(toBufferedImage(win.img));
|
||||
|
||||
if (win.lbl == null) {
|
||||
JFrame frame = createJFrame(win.name, win.flag);
|
||||
JLabel lbl = new JLabel(icon);
|
||||
win.setFrameLabelVisible(frame, lbl);
|
||||
} else {
|
||||
win.lbl.setIcon(icon);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException("No image set for window: \"" + win.name + "\". Call imshow() first");
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (delay == 0) {
|
||||
latch.await();
|
||||
} else {
|
||||
latch.await(delay, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
|
||||
// Set all windows as already used
|
||||
for (ImageWindow win : windows.values())
|
||||
win.alreadyUsed = true;
|
||||
|
||||
return pressedKey;
|
||||
}
|
||||
|
||||
public static void destroyWindow(String winname) {
|
||||
ImageWindow tmpWin = windows.get(winname);
|
||||
if (tmpWin != null) windows.remove(winname);
|
||||
}
|
||||
|
||||
public static void destroyAllWindows() {
|
||||
windows.clear();
|
||||
}
|
||||
|
||||
public static void resizeWindow(String winname, int width, int height) {
|
||||
ImageWindow tmpWin = windows.get(winname);
|
||||
if (tmpWin != null) tmpWin.setNewDimension(width, height);
|
||||
}
|
||||
|
||||
public static void moveWindow(String winname, int x, int y) {
|
||||
ImageWindow tmpWin = windows.get(winname);
|
||||
if (tmpWin != null) tmpWin.setNewPosition(x, y);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
package org.opencv.highgui;
|
||||
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.Size;
|
||||
import org.opencv.imgproc.Imgproc;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* This class was designed to create and manipulate
|
||||
* the Windows to be used by the HighGui class.
|
||||
*/
|
||||
public final class ImageWindow {
|
||||
|
||||
public final static int WINDOW_NORMAL = 0;
|
||||
public final static int WINDOW_AUTOSIZE = 1;
|
||||
|
||||
public String name;
|
||||
public Mat img = null;
|
||||
public Boolean alreadyUsed = false;
|
||||
public Boolean imgToBeResized = false;
|
||||
public Boolean windowToBeResized = false;
|
||||
public Boolean positionToBeChanged = false;
|
||||
public JFrame frame = null;
|
||||
public JLabel lbl = null;
|
||||
public int flag;
|
||||
public int x = -1;
|
||||
public int y = -1;
|
||||
public int width = -1;
|
||||
public int height = -1;
|
||||
|
||||
public ImageWindow(String name, Mat img) {
|
||||
this.name = name;
|
||||
this.img = img;
|
||||
this.flag = WINDOW_NORMAL;
|
||||
}
|
||||
|
||||
public ImageWindow(String name, int flag) {
|
||||
this.name = name;
|
||||
this.flag = flag;
|
||||
}
|
||||
|
||||
public static Size keepAspectRatioSize(int original_width, int original_height, int bound_width, int bound_height) {
|
||||
|
||||
int new_width = original_width;
|
||||
int new_height = original_height;
|
||||
|
||||
if (original_width > bound_width) {
|
||||
new_width = bound_width;
|
||||
new_height = (new_width * original_height) / original_width;
|
||||
}
|
||||
|
||||
if (new_height > bound_height) {
|
||||
new_height = bound_height;
|
||||
new_width = (new_height * original_width) / original_height;
|
||||
}
|
||||
|
||||
return new Size(new_width, new_height);
|
||||
}
|
||||
|
||||
public void setMat(Mat img) {
|
||||
|
||||
this.img = img;
|
||||
this.alreadyUsed = false;
|
||||
|
||||
if (imgToBeResized) {
|
||||
resizeImage();
|
||||
imgToBeResized = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setFrameLabelVisible(JFrame frame, JLabel lbl) {
|
||||
this.frame = frame;
|
||||
this.lbl = lbl;
|
||||
|
||||
if (windowToBeResized) {
|
||||
lbl.setPreferredSize(new Dimension(width, height));
|
||||
windowToBeResized = false;
|
||||
}
|
||||
|
||||
if (positionToBeChanged) {
|
||||
frame.setLocation(x, y);
|
||||
positionToBeChanged = false;
|
||||
}
|
||||
|
||||
frame.add(lbl);
|
||||
frame.pack();
|
||||
frame.setVisible(true);
|
||||
}
|
||||
|
||||
public void setNewDimension(int width, int height) {
|
||||
|
||||
if (this.width != width || this.height != height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
if (img != null) {
|
||||
resizeImage();
|
||||
} else {
|
||||
imgToBeResized = true;
|
||||
}
|
||||
|
||||
if (lbl != null) {
|
||||
lbl.setPreferredSize(new Dimension(width, height));
|
||||
} else {
|
||||
windowToBeResized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setNewPosition(int x, int y) {
|
||||
if (this.x != x || this.y != y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
|
||||
if (frame != null) {
|
||||
frame.setLocation(x, y);
|
||||
} else {
|
||||
positionToBeChanged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void resizeImage() {
|
||||
if (flag == WINDOW_NORMAL) {
|
||||
Size tmpSize = keepAspectRatioSize(img.width(), img.height(), width, height);
|
||||
Imgproc.resize(img, img, tmpSize, 0, 0, Imgproc.INTER_LINEAR_EXACT);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
if [ -z $1 ] ; then
|
||||
echo "$0 <destination directory>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
OCV="$( cd "${DIR}/../../../.." >/dev/null 2>&1 && pwd )"
|
||||
mkdir -p "${1}" # Docker creates non-existed mounts with 'root' owner, lets ensure that dir exists under the current user to avoid "Permission denied" problem
|
||||
DST="$( cd "$1" >/dev/null 2>&1 && pwd )"
|
||||
CFG=${2:-Release}
|
||||
|
||||
do_build()
|
||||
{
|
||||
TAG=$1
|
||||
D=$2
|
||||
F=$3
|
||||
shift 3
|
||||
docker build \
|
||||
--build-arg http_proxy \
|
||||
--build-arg https_proxy \
|
||||
$@ \
|
||||
-t $TAG \
|
||||
-f "${D}/${F}" \
|
||||
"${D}"
|
||||
}
|
||||
|
||||
do_run()
|
||||
{
|
||||
TAG=$1
|
||||
shift 1
|
||||
docker run \
|
||||
-it \
|
||||
--rm \
|
||||
-v "${OCV}":/opencv:ro \
|
||||
-v "${DST}":/dst \
|
||||
-e CFG=$CFG \
|
||||
--user $(id -u):$(id -g) \
|
||||
$TAG \
|
||||
"$@"
|
||||
}
|
||||
|
||||
build_gtk2_ubuntu()
|
||||
{
|
||||
VER=$1
|
||||
shift 1
|
||||
TAG=opencv_highgui_ubuntu_gtk2_builder:${VER}
|
||||
do_build $TAG "${DIR}/plugin_gtk" Dockerfile-ubuntu-gtk2 --build-arg VER=${VER}
|
||||
do_run $TAG /opencv/modules/highgui/misc/plugins/plugin_gtk/build.sh /dst gtk2_ubuntu${VER} ${CFG} "$@"
|
||||
|
||||
}
|
||||
|
||||
build_gtk3_ubuntu()
|
||||
{
|
||||
VER=$1
|
||||
shift 1
|
||||
TAG=opencv_highgui_ubuntu_gtk3_builder:${VER}
|
||||
do_build $TAG "${DIR}/plugin_gtk" Dockerfile-ubuntu-gtk3 --build-arg VER=${VER}
|
||||
do_run $TAG /opencv/modules/highgui/misc/plugins/plugin_gtk/build.sh /dst gtk3_ubuntu${VER} ${CFG} "$@"
|
||||
}
|
||||
|
||||
echo "OpenCV: ${OCV}"
|
||||
echo "Destination: ${DST}"
|
||||
|
||||
build_gtk2_ubuntu 16.04
|
||||
build_gtk2_ubuntu 16.04 -DOPENCV_PLUGIN_NAME=opencv_highgui_gtk2-opengl_ubuntu16.04 -DWITH_OPENGL=ON -DWITH_GTK_2_X=ON
|
||||
build_gtk2_ubuntu 18.04
|
||||
build_gtk3_ubuntu 18.04
|
||||
build_gtk3_ubuntu 20.04
|
||||
@@ -0,0 +1,52 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(opencv_highgui_gtk)
|
||||
|
||||
get_filename_component(OpenCV_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../../.." ABSOLUTE)
|
||||
include("${OpenCV_SOURCE_DIR}/cmake/OpenCVPluginStandalone.cmake")
|
||||
|
||||
# scan dependencies
|
||||
set(WITH_GTK ON)
|
||||
include("${OpenCV_SOURCE_DIR}/modules/highgui/cmake/init.cmake")
|
||||
|
||||
if(NOT HAVE_GTK)
|
||||
message(FATAL_ERROR "GTK: NO")
|
||||
endif()
|
||||
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wno-deprecated-declarations)
|
||||
|
||||
set(OPENCV_PLUGIN_DEPS core imgproc imgcodecs)
|
||||
if(TARGET ocv.3rdparty.gtk3)
|
||||
set(__deps ocv.3rdparty.gtk3)
|
||||
elseif(TARGET ocv.3rdparty.gtk2)
|
||||
set(__deps ocv.3rdparty.gtk2)
|
||||
elseif(TARGET ocv.3rdparty.gtk)
|
||||
set(__deps ocv.3rdparty.gtk)
|
||||
else()
|
||||
message(FATAL_ERROR "Missing dependency target for GTK libraries")
|
||||
endif()
|
||||
ocv_create_plugin(highgui "opencv_highgui_gtk" "${__deps}" "GTK" "src/window_gtk.cpp")
|
||||
if(WITH_OPENGL)
|
||||
if(HAVE_GTK2
|
||||
AND TARGET ocv.3rdparty.gtkglext
|
||||
AND TARGET ocv.3rdparty.gtk_opengl
|
||||
AND NOT OPENCV_GTK_DISABLE_GTKGLEXT
|
||||
AND NOT OPENCV_GTK_DISABLE_OPENGL
|
||||
)
|
||||
message(STATUS "OpenGL: YES")
|
||||
target_link_libraries(${OPENCV_PLUGIN_NAME} PRIVATE
|
||||
ocv.3rdparty.gtkglext ocv.3rdparty.gtk_opengl
|
||||
)
|
||||
else()
|
||||
message(WARNING "OpenGL dependencies are not available!")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(HAVE_GTK3)
|
||||
message(STATUS "GTK3+: ver ${GTK3_VERSION}")
|
||||
elseif(HAVE_GTK3)
|
||||
message(STATUS "GTK2+: ver ${GTK2_VERSION}")
|
||||
elseif(DEFINED GTK_VERSION)
|
||||
message(STATUS "GTK+: ver ${GTK_VERSION}")
|
||||
else()
|
||||
message(STATUS "GTK+: YES")
|
||||
endif()
|
||||
@@ -0,0 +1,28 @@
|
||||
ARG VER
|
||||
FROM ubuntu:$VER
|
||||
|
||||
RUN \
|
||||
apt-get update && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||
pkg-config \
|
||||
cmake \
|
||||
g++ \
|
||||
ninja-build \
|
||||
&& \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN \
|
||||
apt-get update && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||
libgtk2.0-dev \
|
||||
&& \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN \
|
||||
apt-get update && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||
libgtkglext1-dev \
|
||||
&& \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /tmp
|
||||
@@ -0,0 +1,21 @@
|
||||
ARG VER
|
||||
FROM ubuntu:$VER
|
||||
|
||||
RUN \
|
||||
apt-get update && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||
pkg-config \
|
||||
cmake \
|
||||
g++ \
|
||||
ninja-build \
|
||||
&& \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN \
|
||||
apt-get update && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||
libgtk-3-dev \
|
||||
&& \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /tmp
|
||||
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
|
||||
OPENCV_PLUGIN_DESTINATION=$1
|
||||
OPENCV_PLUGIN_NAME=opencv_highgui_$2
|
||||
CMAKE_BUILD_TYPE=${3:-Release}
|
||||
|
||||
shift 3 || true
|
||||
|
||||
set -x
|
||||
cmake -GNinja \
|
||||
-DOPENCV_PLUGIN_NAME=${OPENCV_PLUGIN_NAME} \
|
||||
-DOPENCV_PLUGIN_DESTINATION=${OPENCV_PLUGIN_DESTINATION} \
|
||||
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} \
|
||||
"$@" \
|
||||
$DIR
|
||||
|
||||
ninja -v
|
||||
@@ -0,0 +1,181 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
#include "precomp.hpp"
|
||||
#include "backend.hpp"
|
||||
|
||||
#include <opencv2/core/utils/configuration.private.hpp>
|
||||
#include <opencv2/core/utils/logger.defines.hpp>
|
||||
#ifdef NDEBUG
|
||||
#define CV_LOG_STRIP_LEVEL CV_LOG_LEVEL_DEBUG + 1
|
||||
#else
|
||||
#define CV_LOG_STRIP_LEVEL CV_LOG_LEVEL_VERBOSE + 1
|
||||
#endif
|
||||
#include <opencv2/core/utils/logger.hpp>
|
||||
|
||||
|
||||
#include "registry.hpp"
|
||||
#include "registry.impl.hpp"
|
||||
|
||||
#include "plugin_api.hpp"
|
||||
#include "plugin_wrapper.impl.hpp"
|
||||
|
||||
|
||||
namespace cv { namespace highgui_backend {
|
||||
|
||||
UIBackend::~UIBackend()
|
||||
{
|
||||
// nothing
|
||||
}
|
||||
|
||||
UIWindowBase::~UIWindowBase()
|
||||
{
|
||||
// nothing
|
||||
}
|
||||
|
||||
UIWindow::~UIWindow()
|
||||
{
|
||||
// nothing
|
||||
}
|
||||
|
||||
UITrackbar::~UITrackbar()
|
||||
{
|
||||
// nothing
|
||||
}
|
||||
|
||||
static
|
||||
std::string& getUIBackendName()
|
||||
{
|
||||
static std::string g_backendName = toUpperCase(cv::utils::getConfigurationParameterString("OPENCV_UI_BACKEND", ""));
|
||||
return g_backendName;
|
||||
}
|
||||
|
||||
static bool g_initializedUIBackend = false;
|
||||
|
||||
static
|
||||
std::shared_ptr<UIBackend> createUIBackend()
|
||||
{
|
||||
const std::string& name = getUIBackendName();
|
||||
bool isKnown = false;
|
||||
const auto& backends = getBackendsInfo();
|
||||
if (!name.empty())
|
||||
{
|
||||
CV_LOG_INFO(NULL, "UI: requested backend name: " << name);
|
||||
}
|
||||
for (size_t i = 0; i < backends.size(); i++)
|
||||
{
|
||||
const auto& info = backends[i];
|
||||
if (!name.empty())
|
||||
{
|
||||
if (name != info.name)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
isKnown = true;
|
||||
}
|
||||
try
|
||||
{
|
||||
CV_LOG_DEBUG(NULL, "UI: trying backend: " << info.name << " (priority=" << info.priority << ")");
|
||||
if (!info.backendFactory)
|
||||
{
|
||||
CV_LOG_DEBUG(NULL, "UI: factory is not available (plugins require filesystem support): " << info.name);
|
||||
continue;
|
||||
}
|
||||
std::shared_ptr<UIBackend> backend = info.backendFactory->create();
|
||||
if (!backend)
|
||||
{
|
||||
CV_LOG_VERBOSE(NULL, 0, "UI: not available: " << info.name);
|
||||
continue;
|
||||
}
|
||||
CV_LOG_INFO(NULL, "UI: using backend: " << info.name << " (priority=" << info.priority << ")");
|
||||
g_initializedUIBackend = true;
|
||||
getUIBackendName() = info.name;
|
||||
return backend;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
CV_LOG_WARNING(NULL, "UI: can't initialize " << info.name << " backend: " << e.what());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
CV_LOG_WARNING(NULL, "UI: can't initialize " << info.name << " backend: Unknown C++ exception");
|
||||
}
|
||||
}
|
||||
if (name.empty())
|
||||
{
|
||||
CV_LOG_DEBUG(NULL, "UI: fallback on builtin code: " OPENCV_HIGHGUI_BUILTIN_BACKEND_STR);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!isKnown)
|
||||
CV_LOG_INFO(NULL, "UI: unknown backend: " << name);
|
||||
}
|
||||
g_initializedUIBackend = true;
|
||||
return std::shared_ptr<UIBackend>();
|
||||
}
|
||||
|
||||
static inline
|
||||
std::shared_ptr<UIBackend> createDefaultUIBackend()
|
||||
{
|
||||
CV_LOG_DEBUG(NULL, "UI: Initializing backend...");
|
||||
return createUIBackend();
|
||||
}
|
||||
|
||||
std::shared_ptr<UIBackend>& getCurrentUIBackend()
|
||||
{
|
||||
static std::shared_ptr<UIBackend> g_currentUIBackend = createDefaultUIBackend();
|
||||
return g_currentUIBackend;
|
||||
}
|
||||
|
||||
void setUIBackend(const std::shared_ptr<UIBackend>& api)
|
||||
{
|
||||
getCurrentUIBackend() = api;
|
||||
}
|
||||
|
||||
bool setUIBackend(const std::string& backendName)
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
|
||||
std::string backendName_u = toUpperCase(backendName);
|
||||
if (g_initializedUIBackend)
|
||||
{
|
||||
// ... already initialized
|
||||
if (getUIBackendName() == backendName_u)
|
||||
{
|
||||
CV_LOG_INFO(NULL, "UI: backend is already activated: " << (backendName.empty() ? "builtin(legacy)" : backendName));
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ... re-create new
|
||||
CV_LOG_DEBUG(NULL, "UI: replacing backend...");
|
||||
getUIBackendName() = backendName_u;
|
||||
getCurrentUIBackend() = createUIBackend();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// ... no backend exists, just specify the name (initialization is triggered by getCurrentUIBackend() call)
|
||||
getUIBackendName() = backendName_u;
|
||||
}
|
||||
std::shared_ptr<UIBackend> api = getCurrentUIBackend();
|
||||
if (!api)
|
||||
{
|
||||
if (!backendName.empty())
|
||||
{
|
||||
CV_LOG_WARNING(NULL, "UI: backend is not available: " << backendName << " (using builtin legacy code)");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_LOG_WARNING(NULL, "UI: switched to builtin code (legacy)");
|
||||
}
|
||||
}
|
||||
if (!backendName_u.empty())
|
||||
{
|
||||
CV_Assert(backendName_u == getUIBackendName()); // data race?
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}} // namespace cv::highgui_backend
|
||||
@@ -0,0 +1,140 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
#ifndef OPENCV_HIGHGUI_BACKEND_HPP
|
||||
#define OPENCV_HIGHGUI_BACKEND_HPP
|
||||
|
||||
#include <memory>
|
||||
#include <map>
|
||||
|
||||
namespace cv { namespace highgui_backend {
|
||||
|
||||
class CV_EXPORTS UIWindowBase
|
||||
{
|
||||
public:
|
||||
typedef std::shared_ptr<UIWindowBase> Ptr;
|
||||
typedef std::weak_ptr<UIWindowBase> WeakPtr;
|
||||
|
||||
virtual ~UIWindowBase();
|
||||
|
||||
virtual const std::string& getID() const = 0; // internal name, used for logging
|
||||
|
||||
virtual bool isActive() const = 0;
|
||||
|
||||
virtual void destroy() = 0;
|
||||
}; // UIWindowBase
|
||||
|
||||
class UITrackbar;
|
||||
|
||||
class CV_EXPORTS UIWindow : public UIWindowBase
|
||||
{
|
||||
public:
|
||||
virtual ~UIWindow();
|
||||
|
||||
virtual void imshow(InputArray image) = 0;
|
||||
|
||||
virtual double getProperty(int prop) const = 0;
|
||||
virtual bool setProperty(int prop, double value) = 0;
|
||||
|
||||
virtual void resize(int width, int height) = 0;
|
||||
virtual void move(int x, int y) = 0;
|
||||
|
||||
virtual Rect getImageRect() const = 0;
|
||||
|
||||
virtual void setTitle(const std::string& title) = 0;
|
||||
|
||||
virtual void setMouseCallback(MouseCallback onMouse, void* userdata /*= 0*/) = 0;
|
||||
|
||||
//TODO: handle both keys and mouse events (both with mouse coordinates)
|
||||
//virtual void setInputCallback(InputCallback onInputEvent, void* userdata /*= 0*/) = 0;
|
||||
|
||||
virtual std::shared_ptr<UITrackbar> createTrackbar(
|
||||
const std::string& name,
|
||||
int count,
|
||||
TrackbarCallback onChange /*= 0*/,
|
||||
void* userdata /*= 0*/
|
||||
) = 0;
|
||||
|
||||
virtual std::shared_ptr<UITrackbar> findTrackbar(const std::string& name) = 0;
|
||||
|
||||
#if 0 // QT only
|
||||
virtual void displayOverlay(const std::string& text, int delayms = 0) = 0;
|
||||
virtual void displayStatusBar(const std::string& text, int delayms /*= 0*/) = 0;
|
||||
virtual int createButton(
|
||||
const std::string& bar_name, ButtonCallback on_change,
|
||||
void* userdata = 0, int type /*= QT_PUSH_BUTTON*/,
|
||||
bool initial_button_state /*= false*/
|
||||
) = 0;
|
||||
// addText, QtFont stuff
|
||||
#endif
|
||||
|
||||
#if 0 // OpenGL
|
||||
virtual void imshow(const ogl::Texture2D& tex) = 0;
|
||||
virtual void setOpenGlDrawCallback(OpenGlDrawCallback onOpenGlDraw, void* userdata = 0) = 0;
|
||||
virtual void setOpenGlContext() = 0;
|
||||
virtual void updateWindow() = 0;
|
||||
#endif
|
||||
|
||||
}; // UIWindow
|
||||
|
||||
|
||||
class CV_EXPORTS UITrackbar : public UIWindowBase
|
||||
{
|
||||
public:
|
||||
virtual ~UITrackbar();
|
||||
|
||||
virtual int getPos() const = 0;
|
||||
virtual void setPos(int pos) = 0;
|
||||
|
||||
virtual cv::Range getRange() const = 0;
|
||||
virtual void setRange(const cv::Range& range) = 0;
|
||||
}; // UITrackbar
|
||||
|
||||
|
||||
class CV_EXPORTS UIBackend
|
||||
{
|
||||
public:
|
||||
virtual ~UIBackend();
|
||||
|
||||
virtual void destroyAllWindows() = 0;
|
||||
|
||||
// namedWindow
|
||||
virtual std::shared_ptr<UIWindow> createWindow(
|
||||
const std::string& winname,
|
||||
int flags
|
||||
) = 0;
|
||||
|
||||
virtual int waitKeyEx(int delay /*= 0*/) = 0;
|
||||
virtual int pollKey() = 0;
|
||||
virtual const std::string getName() const = 0;
|
||||
};
|
||||
|
||||
std::shared_ptr<UIBackend>& getCurrentUIBackend();
|
||||
void setUIBackend(const std::shared_ptr<UIBackend>& api);
|
||||
bool setUIBackend(const std::string& backendName);
|
||||
|
||||
#ifndef BUILD_PLUGIN
|
||||
|
||||
#ifdef HAVE_WIN32UI
|
||||
std::shared_ptr<UIBackend> createUIBackendWin32UI();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GTK
|
||||
std::shared_ptr<UIBackend> createUIBackendGTK();
|
||||
#endif
|
||||
|
||||
#if 0 // TODO: defined HAVE_QT
|
||||
std::shared_ptr<UIBackend> createUIBackendQT();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FRAMEBUFFER
|
||||
std::shared_ptr<UIBackend> createUIBackendFramebuffer();
|
||||
#endif
|
||||
|
||||
#endif // BUILD_PLUGIN
|
||||
|
||||
} // namespace highgui_backend
|
||||
|
||||
} // namespace cv
|
||||
|
||||
#endif // OPENCV_HIGHGUI_BACKEND_HPP
|
||||
@@ -0,0 +1,48 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#ifndef OPENCV_UI_FACTORY_HPP
|
||||
#define OPENCV_UI_FACTORY_HPP
|
||||
|
||||
#include "backend.hpp"
|
||||
|
||||
namespace cv { namespace highgui_backend {
|
||||
|
||||
class IUIBackendFactory
|
||||
{
|
||||
public:
|
||||
virtual ~IUIBackendFactory() {}
|
||||
virtual std::shared_ptr<cv::highgui_backend::UIBackend> create() const = 0;
|
||||
};
|
||||
|
||||
|
||||
class StaticBackendFactory CV_FINAL: public IUIBackendFactory
|
||||
{
|
||||
protected:
|
||||
std::function<std::shared_ptr<cv::highgui_backend::UIBackend>(void)> create_fn_;
|
||||
|
||||
public:
|
||||
StaticBackendFactory(std::function<std::shared_ptr<cv::highgui_backend::UIBackend>(void)>&& create_fn)
|
||||
: create_fn_(create_fn)
|
||||
{
|
||||
// nothing
|
||||
}
|
||||
|
||||
~StaticBackendFactory() CV_OVERRIDE {}
|
||||
|
||||
std::shared_ptr<cv::highgui_backend::UIBackend> create() const CV_OVERRIDE
|
||||
{
|
||||
return create_fn_();
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// PluginUIBackendFactory is implemented in plugin_wrapper
|
||||
//
|
||||
|
||||
std::shared_ptr<IUIBackendFactory> createPluginUIBackendFactory(const std::string& baseName);
|
||||
|
||||
}} // namespace
|
||||
|
||||
#endif // OPENCV_UI_FACTORY_HPP
|
||||
|
After Width: | Height: | Size: 832 B |
|
After Width: | Height: | Size: 799 B |
|
After Width: | Height: | Size: 522 B |
|
After Width: | Height: | Size: 531 B |
|
After Width: | Height: | Size: 561 B |
|
After Width: | Height: | Size: 761 B |
|
After Width: | Height: | Size: 536 B |
|
After Width: | Height: | Size: 688 B |
|
After Width: | Height: | Size: 579 B |
|
After Width: | Height: | Size: 914 B |
|
After Width: | Height: | Size: 674 B |
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -0,0 +1 @@
|
||||
Icons for Google Material Design: https://github.com/google/material-design-icons/
|
||||
@@ -0,0 +1,72 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#ifndef UI_PLUGIN_API_HPP
|
||||
#define UI_PLUGIN_API_HPP
|
||||
|
||||
#include <opencv2/core/cvdef.h>
|
||||
#include <opencv2/core/llapi/llapi.h>
|
||||
|
||||
#include "backend.hpp"
|
||||
|
||||
#if !defined(BUILD_PLUGIN)
|
||||
|
||||
/// increased for backward-compatible changes, e.g. add new function
|
||||
/// Caller API <= Plugin API -> plugin is fully compatible
|
||||
/// Caller API > Plugin API -> plugin is not fully compatible, caller should use extra checks to use plugins with older API
|
||||
#define API_VERSION 0 // preview
|
||||
|
||||
/// increased for incompatible changes, e.g. remove function argument
|
||||
/// Caller ABI == Plugin ABI -> plugin is compatible
|
||||
/// Caller ABI > Plugin ABI -> plugin is not compatible, caller should use shim code to use old ABI plugins (caller may know how lower ABI works, so it is possible)
|
||||
/// Caller ABI < Plugin ABI -> plugin can't be used (plugin should provide interface with lower ABI to handle that)
|
||||
#define ABI_VERSION 0 // preview
|
||||
|
||||
#else // !defined(BUILD_PLUGIN)
|
||||
|
||||
#if !defined(ABI_VERSION) || !defined(API_VERSION)
|
||||
#error "Plugin must define ABI_VERSION and API_VERSION before including plugin_api.hpp"
|
||||
#endif
|
||||
|
||||
#endif // !defined(BUILD_PLUGIN)
|
||||
|
||||
typedef cv::highgui_backend::UIBackend* CvPluginUIBackend;
|
||||
|
||||
struct OpenCV_UI_Plugin_API_v0_0_api_entries
|
||||
{
|
||||
/** @brief Get backend API instance
|
||||
|
||||
@param[out] handle pointer on backend API handle
|
||||
|
||||
@note API-CALL 1, API-Version == 0
|
||||
*/
|
||||
CvResult (CV_API_CALL *getInstance)(CV_OUT CvPluginUIBackend* handle) CV_NOEXCEPT;
|
||||
}; // OpenCV_UI_Plugin_API_v0_0_api_entries
|
||||
|
||||
typedef struct OpenCV_UI_Plugin_API_v0
|
||||
{
|
||||
OpenCV_API_Header api_header;
|
||||
struct OpenCV_UI_Plugin_API_v0_0_api_entries v0;
|
||||
} OpenCV_UI_Plugin_API_v0;
|
||||
|
||||
#if ABI_VERSION == 0 && API_VERSION == 0
|
||||
typedef OpenCV_UI_Plugin_API_v0 OpenCV_UI_Plugin_API;
|
||||
#else
|
||||
#error "Not supported configuration: check ABI_VERSION/API_VERSION"
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_PLUGIN
|
||||
extern "C" {
|
||||
|
||||
CV_PLUGIN_EXPORTS
|
||||
const OpenCV_UI_Plugin_API* CV_API_CALL opencv_ui_plugin_init_v0
|
||||
(int requested_abi_version, int requested_api_version, void* reserved /*NULL*/) CV_NOEXCEPT;
|
||||
|
||||
} // extern "C"
|
||||
#else // BUILD_PLUGIN
|
||||
typedef const OpenCV_UI_Plugin_API* (CV_API_CALL *FN_opencv_ui_plugin_init_t)
|
||||
(int requested_abi_version, int requested_api_version, void* reserved /*NULL*/);
|
||||
#endif // BUILD_PLUGIN
|
||||
|
||||
#endif // UI_PLUGIN_API_HPP
|
||||
@@ -0,0 +1,294 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
//
|
||||
// Not a standalone header, part of backend.cpp
|
||||
//
|
||||
|
||||
//==================================================================================================
|
||||
// Dynamic backend implementation
|
||||
|
||||
#include "opencv2/core/utils/plugin_loader.private.hpp"
|
||||
|
||||
namespace cv { namespace impl {
|
||||
|
||||
using namespace cv::highgui_backend;
|
||||
|
||||
#if OPENCV_HAVE_FILESYSTEM_SUPPORT && defined(ENABLE_PLUGINS)
|
||||
|
||||
using namespace cv::plugin::impl; // plugin_loader.hpp
|
||||
|
||||
class PluginUIBackend CV_FINAL: public std::enable_shared_from_this<PluginUIBackend>
|
||||
{
|
||||
protected:
|
||||
void initPluginAPI()
|
||||
{
|
||||
const char* init_name = "opencv_ui_plugin_init_v0";
|
||||
FN_opencv_ui_plugin_init_t fn_init = reinterpret_cast<FN_opencv_ui_plugin_init_t>(lib_->getSymbol(init_name));
|
||||
if (fn_init)
|
||||
{
|
||||
CV_LOG_DEBUG(NULL, "Found entry: '" << init_name << "'");
|
||||
for (int supported_api_version = API_VERSION; supported_api_version >= 0; supported_api_version--)
|
||||
{
|
||||
plugin_api_ = fn_init(ABI_VERSION, supported_api_version, NULL);
|
||||
if (plugin_api_)
|
||||
break;
|
||||
}
|
||||
if (!plugin_api_)
|
||||
{
|
||||
CV_LOG_INFO(NULL, "UI: plugin is incompatible (can't be initialized): " << lib_->getName());
|
||||
return;
|
||||
}
|
||||
// NB: force strict minor version check (ABI is not preserved for now)
|
||||
if (!checkCompatibility(plugin_api_->api_header, ABI_VERSION, API_VERSION, true))
|
||||
{
|
||||
plugin_api_ = NULL;
|
||||
return;
|
||||
}
|
||||
CV_LOG_INFO(NULL, "UI: plugin is ready to use '" << plugin_api_->api_header.api_description << "'");
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_LOG_INFO(NULL, "UI: plugin is incompatible, missing init function: '" << init_name << "', file: " << lib_->getName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool checkCompatibility(const OpenCV_API_Header& api_header, unsigned int abi_version, unsigned int api_version, bool checkMinorOpenCVVersion)
|
||||
{
|
||||
if (api_header.opencv_version_major != CV_VERSION_MAJOR)
|
||||
{
|
||||
CV_LOG_ERROR(NULL, "UI: wrong OpenCV major version used by plugin '" << api_header.api_description << "': " <<
|
||||
cv::format("%d.%d, OpenCV version is '" CV_VERSION "'", api_header.opencv_version_major, api_header.opencv_version_minor))
|
||||
return false;
|
||||
}
|
||||
if (!checkMinorOpenCVVersion)
|
||||
{
|
||||
// no checks for OpenCV minor version
|
||||
}
|
||||
else if (api_header.opencv_version_minor != CV_VERSION_MINOR)
|
||||
{
|
||||
CV_LOG_ERROR(NULL, "UI: wrong OpenCV minor version used by plugin '" << api_header.api_description << "': " <<
|
||||
cv::format("%d.%d, OpenCV version is '" CV_VERSION "'", api_header.opencv_version_major, api_header.opencv_version_minor))
|
||||
return false;
|
||||
}
|
||||
CV_LOG_DEBUG(NULL, "UI: initialized '" << api_header.api_description << "': built with "
|
||||
<< cv::format("OpenCV %d.%d (ABI/API = %d/%d)",
|
||||
api_header.opencv_version_major, api_header.opencv_version_minor,
|
||||
api_header.min_api_version, api_header.api_version)
|
||||
<< ", current OpenCV version is '" CV_VERSION "' (ABI/API = " << abi_version << "/" << api_version << ")"
|
||||
);
|
||||
if (api_header.min_api_version != abi_version) // future: range can be here
|
||||
{
|
||||
// actually this should never happen due to checks in plugin's init() function
|
||||
CV_LOG_ERROR(NULL, "UI: plugin is not supported due to incompatible ABI = " << api_header.min_api_version);
|
||||
return false;
|
||||
}
|
||||
if (api_header.api_version != api_version)
|
||||
{
|
||||
CV_LOG_INFO(NULL, "UI: NOTE: plugin is supported, but there is API version mismath: "
|
||||
<< cv::format("plugin API level (%d) != OpenCV API level (%d)", api_header.api_version, api_version));
|
||||
if (api_header.api_version < api_version)
|
||||
{
|
||||
CV_LOG_INFO(NULL, "UI: NOTE: some functionality may be unavailable due to lack of support by plugin implementation");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
std::shared_ptr<cv::plugin::impl::DynamicLib> lib_;
|
||||
const OpenCV_UI_Plugin_API* plugin_api_;
|
||||
|
||||
PluginUIBackend(const std::shared_ptr<cv::plugin::impl::DynamicLib>& lib)
|
||||
: lib_(lib)
|
||||
, plugin_api_(NULL)
|
||||
{
|
||||
initPluginAPI();
|
||||
}
|
||||
|
||||
std::shared_ptr<cv::highgui_backend::UIBackend> create() const
|
||||
{
|
||||
CV_Assert(plugin_api_);
|
||||
|
||||
CvPluginUIBackend instancePtr = NULL;
|
||||
|
||||
if (plugin_api_->v0.getInstance)
|
||||
{
|
||||
if (CV_ERROR_OK == plugin_api_->v0.getInstance(&instancePtr))
|
||||
{
|
||||
CV_Assert(instancePtr);
|
||||
// TODO C++20 "aliasing constructor"
|
||||
return std::shared_ptr<cv::highgui_backend::UIBackend>(instancePtr, [](cv::highgui_backend::UIBackend*){}); // empty deleter
|
||||
}
|
||||
}
|
||||
return std::shared_ptr<cv::highgui_backend::UIBackend>();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class PluginUIBackendFactory CV_FINAL: public IUIBackendFactory
|
||||
{
|
||||
public:
|
||||
std::string baseName_;
|
||||
std::shared_ptr<PluginUIBackend> backend;
|
||||
bool initialized;
|
||||
public:
|
||||
PluginUIBackendFactory(const std::string& baseName)
|
||||
: baseName_(baseName)
|
||||
, initialized(false)
|
||||
{
|
||||
// nothing, plugins are loaded on demand
|
||||
}
|
||||
|
||||
std::shared_ptr<cv::highgui_backend::UIBackend> create() const CV_OVERRIDE
|
||||
{
|
||||
if (!initialized)
|
||||
{
|
||||
const_cast<PluginUIBackendFactory*>(this)->initBackend();
|
||||
}
|
||||
if (backend)
|
||||
return backend->create();
|
||||
return std::shared_ptr<cv::highgui_backend::UIBackend>();
|
||||
}
|
||||
protected:
|
||||
void initBackend()
|
||||
{
|
||||
AutoLock lock(getInitializationMutex());
|
||||
try
|
||||
{
|
||||
if (!initialized)
|
||||
loadPlugin();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
CV_LOG_INFO(NULL, "UI: exception during plugin loading: " << baseName_ << ". SKIP");
|
||||
}
|
||||
initialized = true;
|
||||
}
|
||||
void loadPlugin();
|
||||
};
|
||||
|
||||
static
|
||||
std::vector<FileSystemPath_t> getPluginCandidates(const std::string& baseName)
|
||||
{
|
||||
using namespace cv::utils;
|
||||
using namespace cv::utils::fs;
|
||||
const std::string baseName_l = toLowerCase(baseName);
|
||||
const std::string baseName_u = toUpperCase(baseName);
|
||||
const FileSystemPath_t baseName_l_fs = toFileSystemPath(baseName_l);
|
||||
std::vector<FileSystemPath_t> paths;
|
||||
// TODO OPENCV_PLUGIN_PATH
|
||||
const std::vector<std::string> paths_ = getConfigurationParameterPaths("OPENCV_CORE_PLUGIN_PATH", std::vector<std::string>());
|
||||
if (paths_.size() != 0)
|
||||
{
|
||||
for (size_t i = 0; i < paths_.size(); i++)
|
||||
{
|
||||
paths.push_back(toFileSystemPath(paths_[i]));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FileSystemPath_t binaryLocation;
|
||||
if (getBinLocation(binaryLocation))
|
||||
{
|
||||
binaryLocation = getParent(binaryLocation);
|
||||
#ifndef CV_UI_PLUGIN_SUBDIRECTORY
|
||||
paths.push_back(binaryLocation);
|
||||
#else
|
||||
paths.push_back(binaryLocation + toFileSystemPath("/") + toFileSystemPath(CV_UI_PLUGIN_SUBDIRECTORY_STR));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
const std::string default_expr = libraryPrefix() + "opencv_highgui_" + baseName_l + "*" + librarySuffix();
|
||||
const std::string plugin_expr = getConfigurationParameterString((std::string("OPENCV_UI_PLUGIN_") + baseName_u).c_str(), default_expr.c_str());
|
||||
std::vector<FileSystemPath_t> results;
|
||||
#ifdef _WIN32
|
||||
FileSystemPath_t moduleName = toFileSystemPath(libraryPrefix() + "opencv_highgui_" + baseName_l + librarySuffix());
|
||||
if (plugin_expr != default_expr)
|
||||
{
|
||||
moduleName = toFileSystemPath(plugin_expr);
|
||||
results.push_back(moduleName);
|
||||
}
|
||||
for (const FileSystemPath_t& path : paths)
|
||||
{
|
||||
results.push_back(path + L"\\" + moduleName);
|
||||
}
|
||||
results.push_back(moduleName);
|
||||
#else
|
||||
CV_LOG_DEBUG(NULL, "UI: " << baseName << " plugin's glob is '" << plugin_expr << "', " << paths.size() << " location(s)");
|
||||
for (const std::string& path : paths)
|
||||
{
|
||||
if (path.empty())
|
||||
continue;
|
||||
std::vector<std::string> candidates;
|
||||
cv::glob(utils::fs::join(path, plugin_expr), candidates);
|
||||
// Prefer candisates with higher versions
|
||||
// TODO: implemented accurate versions-based comparator
|
||||
std::sort(candidates.begin(), candidates.end(), std::greater<std::string>());
|
||||
CV_LOG_DEBUG(NULL, " - " << path << ": " << candidates.size());
|
||||
copy(candidates.begin(), candidates.end(), back_inserter(results));
|
||||
}
|
||||
#endif
|
||||
CV_LOG_DEBUG(NULL, "Found " << results.size() << " plugin(s) for " << baseName);
|
||||
return results;
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENCV_IMGCODECS // NB: require loading of imgcodecs module
|
||||
static void* g_imwrite = (void*)imwrite;
|
||||
#endif
|
||||
|
||||
void PluginUIBackendFactory::loadPlugin()
|
||||
{
|
||||
#ifdef HAVE_OPENCV_IMGCODECS
|
||||
CV_Assert(g_imwrite);
|
||||
#endif
|
||||
for (const FileSystemPath_t& plugin : getPluginCandidates(baseName_))
|
||||
{
|
||||
auto lib = std::make_shared<cv::plugin::impl::DynamicLib>(plugin);
|
||||
if (!lib->isLoaded())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
try
|
||||
{
|
||||
auto pluginBackend = std::make_shared<PluginUIBackend>(lib);
|
||||
if (!pluginBackend)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (pluginBackend->plugin_api_ == NULL)
|
||||
{
|
||||
CV_LOG_ERROR(NULL, "UI: no compatible plugin API for backend: " << baseName_ << " in " << toPrintablePath(plugin));
|
||||
continue;
|
||||
}
|
||||
// NB: we are going to use UI backend, so prevent automatic library unloading
|
||||
lib->disableAutomaticLibraryUnloading();
|
||||
backend = pluginBackend;
|
||||
return;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
CV_LOG_WARNING(NULL, "UI: exception during plugin initialization: " << toPrintablePath(plugin) << ". SKIP");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // OPENCV_HAVE_FILESYSTEM_SUPPORT && defined(ENABLE_PLUGINS)
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace highgui_backend {
|
||||
|
||||
std::shared_ptr<IUIBackendFactory> createPluginUIBackendFactory(const std::string& baseName)
|
||||
{
|
||||
#if OPENCV_HAVE_FILESYSTEM_SUPPORT && defined(ENABLE_PLUGINS)
|
||||
return std::make_shared<impl::PluginUIBackendFactory>(baseName);
|
||||
#else
|
||||
CV_UNUSED(baseName);
|
||||
return std::shared_ptr<IUIBackendFactory>();
|
||||
#endif
|
||||
}
|
||||
|
||||
}} // namespace
|
||||
@@ -0,0 +1,196 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of Intel Corporation may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __HIGHGUI_H_
|
||||
#define __HIGHGUI_H_
|
||||
|
||||
#if defined(__OPENCV_BUILD) && defined(BUILD_PLUGIN)
|
||||
#undef __OPENCV_BUILD // allow public API only
|
||||
#endif
|
||||
|
||||
#include "opencv2/highgui.hpp"
|
||||
#if !defined(BUILD_PLUGIN)
|
||||
#include "opencv_highgui_config.hpp" // generated by CMake
|
||||
#endif
|
||||
|
||||
#include "opencv2/core/utility.hpp"
|
||||
#if defined(__OPENCV_BUILD)
|
||||
#include "opencv2/core/private.hpp"
|
||||
#include "opencv2/core/utils/configuration.private.hpp"
|
||||
#endif
|
||||
|
||||
#include "opencv2/imgproc.hpp"
|
||||
#include "opencv2/imgproc/imgproc_c.h"
|
||||
#include "opencv2/highgui/highgui_c.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#if defined _WIN32 || defined WINCE
|
||||
#include <windows.h>
|
||||
#undef small
|
||||
#undef min
|
||||
#undef max
|
||||
#undef abs
|
||||
#endif
|
||||
|
||||
/* Errors */
|
||||
#define HG_OK 0 /* Don't bet on it! */
|
||||
#define HG_BADNAME -1 /* Bad window or file name */
|
||||
#define HG_INITFAILED -2 /* Can't initialize HigHGUI */
|
||||
#define HG_WCFAILED -3 /* Can't create a window */
|
||||
#define HG_NULLPTR -4 /* The null pointer where it should not appear */
|
||||
#define HG_BADPARAM -5
|
||||
|
||||
#define __BEGIN__ __CV_BEGIN__
|
||||
#define __END__ __CV_END__
|
||||
#define EXIT __CV_EXIT__
|
||||
|
||||
#define CV_WINDOW_MAGIC_VAL 0x00420042
|
||||
#define CV_TRACKBAR_MAGIC_VAL 0x00420043
|
||||
|
||||
//Yannick Verdie 2010, Max Kostin 2015
|
||||
void cvSetModeWindow_W32(const char* name, double prop_value);
|
||||
void cvSetModeWindow_GTK(const char* name, double prop_value);
|
||||
void cvSetModeWindow_COCOA(const char* name, double prop_value);
|
||||
void cvSetModeWindow_WinRT(const char* name, double prop_value);
|
||||
|
||||
CvRect cvGetWindowRect_W32(const char* name);
|
||||
CvRect cvGetWindowRect_GTK(const char* name);
|
||||
CvRect cvGetWindowRect_COCOA(const char* name);
|
||||
CvRect cvGetWindowRect_WAYLAND(const char* name);
|
||||
|
||||
double cvGetModeWindow_W32(const char* name);
|
||||
double cvGetModeWindow_GTK(const char* name);
|
||||
double cvGetModeWindow_COCOA(const char* name);
|
||||
double cvGetModeWindow_WinRT(const char* name);
|
||||
|
||||
double cvGetPropWindowAutoSize_W32(const char* name);
|
||||
double cvGetPropWindowAutoSize_GTK(const char* name);
|
||||
|
||||
double cvGetRatioWindow_W32(const char* name);
|
||||
double cvGetRatioWindow_GTK(const char* name);
|
||||
|
||||
double cvGetOpenGlProp_W32(const char* name);
|
||||
double cvGetOpenGlProp_GTK(const char* name);
|
||||
|
||||
double cvGetPropVisible_W32(const char* name);
|
||||
double cvGetPropVisible_COCOA(const char* name);
|
||||
|
||||
double cvGetPropTopmost_W32(const char* name);
|
||||
double cvGetPropTopmost_COCOA(const char* name);
|
||||
|
||||
void cvSetPropTopmost_W32(const char* name, const bool topmost);
|
||||
void cvSetPropTopmost_COCOA(const char* name, const bool topmost);
|
||||
|
||||
double cvGetPropVsync_W32(const char* name);
|
||||
void cvSetPropVsync_W32(const char* name, const bool enabled);
|
||||
|
||||
void setWindowTitle_W32(const cv::String& name, const cv::String& title);
|
||||
void setWindowTitle_GTK(const cv::String& name, const cv::String& title);
|
||||
void setWindowTitle_QT(const cv::String& name, const cv::String& title);
|
||||
void setWindowTitle_COCOA(const cv::String& name, const cv::String& title);
|
||||
void setWindowTitle_WAYLAND(const cv::String& name, const cv::String& title);
|
||||
|
||||
int pollKey_W32();
|
||||
|
||||
//for QT
|
||||
#if defined (HAVE_QT)
|
||||
CvRect cvGetWindowRect_QT(const char* name);
|
||||
double cvGetModeWindow_QT(const char* name);
|
||||
void cvSetModeWindow_QT(const char* name, double prop_value);
|
||||
|
||||
double cvGetPropWindow_QT(const char* name);
|
||||
void cvSetPropWindow_QT(const char* name,double prop_value);
|
||||
|
||||
double cvGetRatioWindow_QT(const char* name);
|
||||
void cvSetRatioWindow_QT(const char* name,double prop_value);
|
||||
|
||||
double cvGetOpenGlProp_QT(const char* name);
|
||||
double cvGetPropVisible_QT(const char* name);
|
||||
#endif
|
||||
|
||||
inline void convertToShow(const cv::Mat &src, cv::Mat &dst, bool toRGB = true)
|
||||
{
|
||||
const int src_depth = src.depth();
|
||||
CV_Assert(src_depth != CV_16F && src_depth != CV_32S);
|
||||
cv::Mat tmp;
|
||||
switch(src_depth)
|
||||
{
|
||||
case CV_8U:
|
||||
tmp = src;
|
||||
break;
|
||||
case CV_8S:
|
||||
cv::convertScaleAbs(src, tmp, 1, 127);
|
||||
break;
|
||||
case CV_16S:
|
||||
cv::convertScaleAbs(src, tmp, 1/255., 127);
|
||||
break;
|
||||
case CV_16U:
|
||||
cv::convertScaleAbs(src, tmp, 1/255.);
|
||||
break;
|
||||
case CV_32F:
|
||||
case CV_64F: // assuming image has values in range [0, 1)
|
||||
src.convertTo(tmp, CV_8U, 255., 0.);
|
||||
break;
|
||||
}
|
||||
cv::cvtColor(tmp, dst, toRGB ? cv::COLOR_BGR2RGB : cv::COLOR_BGRA2BGR, dst.channels());
|
||||
}
|
||||
|
||||
inline void convertToShow(const cv::Mat &src, const CvMat* arr, bool toRGB = true)
|
||||
{
|
||||
cv::Mat dst = cv::cvarrToMat(arr);
|
||||
convertToShow(src, dst, toRGB);
|
||||
CV_Assert(dst.data == arr->data.ptr);
|
||||
}
|
||||
|
||||
|
||||
namespace cv {
|
||||
|
||||
CV_EXPORTS Mutex& getWindowMutex();
|
||||
static inline Mutex& getInitializationMutex() { return getWindowMutex(); }
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif /* __HIGHGUI_H_ */
|
||||
@@ -0,0 +1,25 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#ifndef OPENCV_HIGHGUI_REGISTRY_HPP
|
||||
#define OPENCV_HIGHGUI_REGISTRY_HPP
|
||||
|
||||
#include "factory.hpp"
|
||||
|
||||
namespace cv { namespace highgui_backend {
|
||||
|
||||
struct BackendInfo
|
||||
{
|
||||
int priority; // 1000-<index*10> - default builtin priority
|
||||
// 0 - disabled (OPENCV_UI_PRIORITY_<name> = 0)
|
||||
// >10000 - prioritized list (OPENCV_UI_PRIORITY_LIST)
|
||||
std::string name;
|
||||
std::shared_ptr<IUIBackendFactory> backendFactory;
|
||||
};
|
||||
|
||||
const std::vector<BackendInfo>& getBackendsInfo();
|
||||
|
||||
}} // namespace
|
||||
|
||||
#endif // OPENCV_HIGHGUI_REGISTRY_HPP
|
||||
@@ -0,0 +1,198 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
//
|
||||
// Not a standalone header, part of backend.cpp
|
||||
//
|
||||
|
||||
#include "opencv2/core/utils/filesystem.private.hpp" // OPENCV_HAVE_FILESYSTEM_SUPPORT
|
||||
|
||||
namespace cv { namespace highgui_backend {
|
||||
|
||||
#if OPENCV_HAVE_FILESYSTEM_SUPPORT && defined(ENABLE_PLUGINS)
|
||||
#define DECLARE_DYNAMIC_BACKEND(name) \
|
||||
BackendInfo { \
|
||||
1000, name, createPluginUIBackendFactory(name) \
|
||||
},
|
||||
#else
|
||||
#define DECLARE_DYNAMIC_BACKEND(name) /* nothing */
|
||||
#endif
|
||||
|
||||
#define DECLARE_STATIC_BACKEND(name, createBackendAPI) \
|
||||
BackendInfo { \
|
||||
1000, name, std::make_shared<cv::highgui_backend::StaticBackendFactory>([=] () -> std::shared_ptr<cv::highgui_backend::UIBackend> { return createBackendAPI(); }) \
|
||||
},
|
||||
|
||||
static
|
||||
std::vector<BackendInfo>& getBuiltinBackendsInfo()
|
||||
{
|
||||
static std::vector<BackendInfo> g_backends
|
||||
{
|
||||
#ifdef HAVE_GTK
|
||||
DECLARE_STATIC_BACKEND("GTK", createUIBackendGTK)
|
||||
#if defined(HAVE_GTK3)
|
||||
DECLARE_STATIC_BACKEND("GTK3", createUIBackendGTK)
|
||||
#elif defined(HAVE_GTK2)
|
||||
DECLARE_STATIC_BACKEND("GTK2", createUIBackendGTK)
|
||||
#else
|
||||
#warning "HAVE_GTK definition issue. Register new GTK backend"
|
||||
#endif
|
||||
#elif defined(ENABLE_PLUGINS)
|
||||
DECLARE_DYNAMIC_BACKEND("GTK")
|
||||
DECLARE_DYNAMIC_BACKEND("GTK3")
|
||||
DECLARE_DYNAMIC_BACKEND("GTK2")
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FRAMEBUFFER
|
||||
DECLARE_STATIC_BACKEND("FB", createUIBackendFramebuffer)
|
||||
#endif
|
||||
|
||||
#if 0 // TODO
|
||||
#ifdef HAVE_QT
|
||||
DECLARE_STATIC_BACKEND("QT", createUIBackendQT)
|
||||
#elif defined(ENABLE_PLUGINS)
|
||||
DECLARE_DYNAMIC_BACKEND("QT")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef HAVE_WIN32UI
|
||||
DECLARE_STATIC_BACKEND("WIN32", createUIBackendWin32UI)
|
||||
#elif defined(ENABLE_PLUGINS)
|
||||
DECLARE_DYNAMIC_BACKEND("WIN32")
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
return g_backends;
|
||||
}
|
||||
|
||||
static
|
||||
bool sortByPriority(const BackendInfo &lhs, const BackendInfo &rhs)
|
||||
{
|
||||
return lhs.priority > rhs.priority;
|
||||
}
|
||||
|
||||
/** @brief Manages list of enabled backends
|
||||
*/
|
||||
class UIBackendRegistry
|
||||
{
|
||||
protected:
|
||||
std::vector<BackendInfo> enabledBackends;
|
||||
UIBackendRegistry()
|
||||
{
|
||||
enabledBackends = getBuiltinBackendsInfo();
|
||||
int N = (int)enabledBackends.size();
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
BackendInfo& info = enabledBackends[i];
|
||||
info.priority = 1000 - i * 10;
|
||||
}
|
||||
CV_LOG_DEBUG(NULL, "UI: Builtin backends(" << N << "): " << dumpBackends());
|
||||
if (readPrioritySettings())
|
||||
{
|
||||
CV_LOG_INFO(NULL, "UI: Updated backends priorities: " << dumpBackends());
|
||||
N = (int)enabledBackends.size();
|
||||
}
|
||||
int enabled = 0;
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
BackendInfo& info = enabledBackends[enabled];
|
||||
if (enabled != i)
|
||||
info = enabledBackends[i];
|
||||
size_t param_priority = utils::getConfigurationParameterSizeT(cv::format("OPENCV_UI_PRIORITY_%s", info.name.c_str()).c_str(), (size_t)info.priority);
|
||||
CV_Assert(param_priority == (size_t)(int)param_priority); // overflow check
|
||||
if (param_priority > 0)
|
||||
{
|
||||
info.priority = (int)param_priority;
|
||||
enabled++;
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_LOG_INFO(NULL, "UI: Disable backend: " << info.name);
|
||||
}
|
||||
}
|
||||
enabledBackends.resize(enabled);
|
||||
CV_LOG_DEBUG(NULL, "UI: Available backends(" << enabled << "): " << dumpBackends());
|
||||
std::sort(enabledBackends.begin(), enabledBackends.end(), sortByPriority);
|
||||
CV_LOG_INFO(NULL, "UI: Enabled backends(" << enabled << ", sorted by priority): " << (enabledBackends.empty() ? std::string("N/A") : dumpBackends()));
|
||||
}
|
||||
|
||||
static std::vector<std::string> tokenize_string(const std::string& input, char token)
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
std::string::size_type prev_pos = 0, pos = 0;
|
||||
while((pos = input.find(token, pos)) != std::string::npos)
|
||||
{
|
||||
result.push_back(input.substr(prev_pos, pos-prev_pos));
|
||||
prev_pos = ++pos;
|
||||
}
|
||||
result.push_back(input.substr(prev_pos));
|
||||
return result;
|
||||
}
|
||||
bool readPrioritySettings()
|
||||
{
|
||||
bool hasChanges = false;
|
||||
cv::String prioritized_backends = utils::getConfigurationParameterString("OPENCV_UI_PRIORITY_LIST");
|
||||
if (prioritized_backends.empty())
|
||||
return hasChanges;
|
||||
CV_LOG_INFO(NULL, "UI: Configured priority list (OPENCV_UI_PRIORITY_LIST): " << prioritized_backends);
|
||||
const std::vector<std::string> names = tokenize_string(prioritized_backends, ',');
|
||||
for (size_t i = 0; i < names.size(); i++)
|
||||
{
|
||||
const std::string& name = names[i];
|
||||
int priority = (int)(100000 + (names.size() - i) * 1000);
|
||||
bool found = false;
|
||||
for (size_t k = 0; k < enabledBackends.size(); k++)
|
||||
{
|
||||
BackendInfo& info = enabledBackends[k];
|
||||
if (name == info.name)
|
||||
{
|
||||
info.priority = priority;
|
||||
CV_LOG_DEBUG(NULL, "UI: New backend priority: '" << name << "' => " << info.priority);
|
||||
found = true;
|
||||
hasChanges = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
CV_LOG_INFO(NULL, "UI: Adding backend (plugin): '" << name << "'");
|
||||
enabledBackends.push_back(BackendInfo{priority, name, createPluginUIBackendFactory(name)});
|
||||
hasChanges = true;
|
||||
}
|
||||
}
|
||||
return hasChanges;
|
||||
}
|
||||
public:
|
||||
std::string dumpBackends() const
|
||||
{
|
||||
std::ostringstream os;
|
||||
for (size_t i = 0; i < enabledBackends.size(); i++)
|
||||
{
|
||||
if (i > 0) os << "; ";
|
||||
const BackendInfo& info = enabledBackends[i];
|
||||
os << info.name << '(' << info.priority << ')';
|
||||
}
|
||||
#if !defined(OPENCV_HIGHGUI_WITHOUT_BUILTIN_BACKEND)
|
||||
os << " + BUILTIN(" OPENCV_HIGHGUI_BUILTIN_BACKEND_STR ")";
|
||||
#endif
|
||||
return os.str();
|
||||
}
|
||||
|
||||
static UIBackendRegistry& getInstance()
|
||||
{
|
||||
static UIBackendRegistry g_instance;
|
||||
return g_instance;
|
||||
}
|
||||
|
||||
inline const std::vector<BackendInfo>& getEnabledBackends() const { return enabledBackends; }
|
||||
};
|
||||
|
||||
|
||||
const std::vector<BackendInfo>& getBackendsInfo()
|
||||
{
|
||||
return cv::highgui_backend::UIBackendRegistry::getInstance().getEnabledBackends();
|
||||
}
|
||||
|
||||
}} // namespace
|
||||
@@ -0,0 +1,221 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#include "precomp.hpp"
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace cv;
|
||||
|
||||
namespace
|
||||
{
|
||||
class ROISelector
|
||||
{
|
||||
public:
|
||||
Rect select(const String &windowName, Mat img, bool showCrossair = true, bool fromCenter = true, bool printNotice = true)
|
||||
{
|
||||
if(printNotice)
|
||||
{
|
||||
// show notice to user
|
||||
printf("Select a ROI and then press SPACE or ENTER button!\n");
|
||||
printf("Cancel the selection process by pressing c button!\n");
|
||||
}
|
||||
|
||||
key = 0;
|
||||
imageSize = img.size();
|
||||
|
||||
// set the drawing mode
|
||||
selectorParams.drawFromCenter = fromCenter;
|
||||
|
||||
// show the image and give feedback to user
|
||||
imshow(windowName, img);
|
||||
|
||||
// copy the data, rectangle should be drawn in the fresh image
|
||||
selectorParams.image = img.clone();
|
||||
|
||||
// select the object
|
||||
setMouseCallback(windowName, mouseHandler, (void*)this);
|
||||
|
||||
// end selection process on SPACE (32) ESC (27) or ENTER (13)
|
||||
while (!(key == 32 || key == 27 || key == 13))
|
||||
{
|
||||
// draw the selected object
|
||||
rectangle(selectorParams.image, selectorParams.box, Scalar(255, 0, 0), 2, 1);
|
||||
|
||||
// draw cross air in the middle of bounding box
|
||||
if (showCrossair)
|
||||
{
|
||||
// horizontal line
|
||||
line(selectorParams.image,
|
||||
Point((int)selectorParams.box.x,
|
||||
(int)(selectorParams.box.y + selectorParams.box.height / 2)),
|
||||
Point((int)(selectorParams.box.x + selectorParams.box.width),
|
||||
(int)(selectorParams.box.y + selectorParams.box.height / 2)),
|
||||
Scalar(255, 0, 0), 2, 1);
|
||||
|
||||
// vertical line
|
||||
line(selectorParams.image,
|
||||
Point((int)(selectorParams.box.x + selectorParams.box.width / 2),
|
||||
(int)selectorParams.box.y),
|
||||
Point((int)(selectorParams.box.x + selectorParams.box.width / 2),
|
||||
(int)(selectorParams.box.y + selectorParams.box.height)),
|
||||
Scalar(255, 0, 0), 2, 1);
|
||||
}
|
||||
|
||||
// show the image bounding box
|
||||
imshow(windowName, selectorParams.image);
|
||||
|
||||
// reset the image
|
||||
selectorParams.image = img.clone();
|
||||
|
||||
// get keyboard event
|
||||
key = waitKey(30);
|
||||
|
||||
if (key == 'c' || key == 'C')//cancel selection
|
||||
{
|
||||
selectorParams.box = Rect();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//cleanup callback
|
||||
setMouseCallback(windowName, emptyMouseHandler, NULL);
|
||||
|
||||
return selectorParams.box;
|
||||
}
|
||||
|
||||
void select(const String &windowName, Mat img, std::vector<Rect> &boundingBoxes,
|
||||
bool showCrosshair = true, bool fromCenter = true, bool printNotice = true)
|
||||
{
|
||||
if(printNotice)
|
||||
{
|
||||
printf("Finish the selection process by pressing ESC button!\n");
|
||||
}
|
||||
boundingBoxes.clear();
|
||||
key = 0;
|
||||
|
||||
// while key is not ESC (27)
|
||||
for (;;)
|
||||
{
|
||||
Rect temp = select(windowName, img, showCrosshair, fromCenter, printNotice);
|
||||
if (key == 27)
|
||||
break;
|
||||
if (temp.width > 0 && temp.height > 0)
|
||||
boundingBoxes.push_back(temp);
|
||||
}
|
||||
}
|
||||
|
||||
struct handlerT
|
||||
{
|
||||
// basic parameters
|
||||
bool isDrawing;
|
||||
Rect2d box;
|
||||
Mat image;
|
||||
Point2f startPos;
|
||||
|
||||
// parameters for drawing from the center
|
||||
bool drawFromCenter;
|
||||
|
||||
// initializer list
|
||||
handlerT() : isDrawing(false), drawFromCenter(true){}
|
||||
} selectorParams;
|
||||
|
||||
private:
|
||||
static void emptyMouseHandler(int, int, int, int, void*)
|
||||
{
|
||||
}
|
||||
|
||||
static void mouseHandler(int event, int x, int y, int flags, void *param)
|
||||
{
|
||||
ROISelector *self = static_cast<ROISelector *>(param);
|
||||
self->opencv_mouse_callback(event, x, y, flags);
|
||||
}
|
||||
|
||||
void opencv_mouse_callback(int event, int x, int y, int)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
// update the selected bounding box
|
||||
case EVENT_MOUSEMOVE:
|
||||
if (selectorParams.isDrawing)
|
||||
{
|
||||
if (selectorParams.drawFromCenter)
|
||||
{
|
||||
// limit half extends to imageSize
|
||||
float halfWidth = std::min(std::min(
|
||||
std::abs(x - selectorParams.startPos.x),
|
||||
selectorParams.startPos.x),
|
||||
imageSize.width - selectorParams.startPos.x);
|
||||
float halfHeight = std::min(std::min(
|
||||
std::abs(y - selectorParams.startPos.y),
|
||||
selectorParams.startPos.y),
|
||||
imageSize.height - selectorParams.startPos.y);
|
||||
|
||||
selectorParams.box.width = halfWidth * 2;
|
||||
selectorParams.box.height = halfHeight * 2;
|
||||
selectorParams.box.x = selectorParams.startPos.x - halfWidth;
|
||||
selectorParams.box.y = selectorParams.startPos.y - halfHeight;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// limit x and y to imageSize
|
||||
int lx = std::min(std::max(x, 0), imageSize.width);
|
||||
int by = std::min(std::max(y, 0), imageSize.height);
|
||||
selectorParams.box.width = std::abs(lx - selectorParams.startPos.x);
|
||||
selectorParams.box.height = std::abs(by - selectorParams.startPos.y);
|
||||
selectorParams.box.x = std::min((float)lx, selectorParams.startPos.x);
|
||||
selectorParams.box.y = std::min((float)by, selectorParams.startPos.y);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// start to select the bounding box
|
||||
case EVENT_LBUTTONDOWN:
|
||||
selectorParams.isDrawing = true;
|
||||
selectorParams.box = Rect2d(x, y, 0, 0);
|
||||
selectorParams.startPos = Point2f((float)x, (float)y);
|
||||
break;
|
||||
|
||||
// cleaning up the selected bounding box
|
||||
case EVENT_LBUTTONUP:
|
||||
selectorParams.isDrawing = false;
|
||||
if (selectorParams.box.width < 0)
|
||||
{
|
||||
selectorParams.box.x += selectorParams.box.width;
|
||||
selectorParams.box.width *= -1;
|
||||
}
|
||||
if (selectorParams.box.height < 0)
|
||||
{
|
||||
selectorParams.box.y += selectorParams.box.height;
|
||||
selectorParams.box.height *= -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// save the keypressed character
|
||||
int key;
|
||||
Size imageSize;
|
||||
};
|
||||
}
|
||||
|
||||
Rect cv::selectROI(InputArray img, bool showCrosshair, bool fromCenter, bool printNotice)
|
||||
{
|
||||
ROISelector selector;
|
||||
return selector.select("ROI selector", img.getMat(), showCrosshair, fromCenter, printNotice);
|
||||
}
|
||||
|
||||
Rect cv::selectROI(const String& windowName, InputArray img, bool showCrosshair, bool fromCenter, bool printNotice)
|
||||
{
|
||||
ROISelector selector;
|
||||
return selector.select(windowName, img.getMat(), showCrosshair, fromCenter, printNotice);
|
||||
}
|
||||
|
||||
void cv::selectROIs(const String& windowName, InputArray img,
|
||||
std::vector<Rect>& boundingBox, bool showCrosshair, bool fromCenter, bool printNotice)
|
||||
{
|
||||
ROISelector selector;
|
||||
selector.select(windowName, img.getMat(), boundingBox, showCrosshair, fromCenter, printNotice);
|
||||
}
|
||||
@@ -0,0 +1,593 @@
|
||||
//IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
|
||||
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
|
||||
//Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
//Copyright (C) 2008-2010, Willow Garage Inc., all rights reserved.
|
||||
//Third party copyrights are property of their respective owners.
|
||||
|
||||
//Redistribution and use in source and binary forms, with or without modification,
|
||||
//are permitted provided that the following conditions are met:
|
||||
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
|
||||
//This software is provided by the copyright holders and contributors "as is" and
|
||||
//any express or implied warranties, including, but not limited to, the implied
|
||||
//warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
//In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
//indirect, incidental, special, exemplary, or consequential damages
|
||||
//(including, but not limited to, procurement of substitute goods or services;
|
||||
//loss of use, data, or profits; or business interruption) however caused
|
||||
//and on any theory of liability, whether in contract, strict liability,
|
||||
//or tort (including negligence or otherwise) arising in any way out of
|
||||
//the use of this software, even if advised of the possibility of such damage.
|
||||
|
||||
//--------------------Google Code 2010 -- Yannick Verdie--------------------//
|
||||
#ifndef __OPENCV_HIGHGUI_QT_H__
|
||||
#define __OPENCV_HIGHGUI_QT_H__
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
#ifndef _DEBUG
|
||||
#define QT_NO_DEBUG_OUTPUT
|
||||
#endif
|
||||
|
||||
#if defined( HAVE_QT_OPENGL )
|
||||
#include <QtOpenGL>
|
||||
|
||||
// QGLWidget deprecated and no longer functions with Qt6, use QOpenGLWidget instead
|
||||
#ifdef HAVE_QT6
|
||||
#include <QOpenGLWidget>
|
||||
#else
|
||||
#include <QGLWidget>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#include <QAbstractEventDispatcher>
|
||||
#include <QApplication>
|
||||
#include <QFile>
|
||||
#include <QPushButton>
|
||||
#include <QGraphicsView>
|
||||
#include <QSizePolicy>
|
||||
#include <QInputDialog>
|
||||
#include <QBoxLayout>
|
||||
#include <QSettings>
|
||||
#include <qtimer.h>
|
||||
#include <QtConcurrentRun>
|
||||
#include <QWaitCondition>
|
||||
#include <QKeyEvent>
|
||||
#include <QMetaObject>
|
||||
#include <QPointer>
|
||||
#include <QSlider>
|
||||
#include <QLabel>
|
||||
#include <QIODevice>
|
||||
#include <QShortcut>
|
||||
#include <QStatusBar>
|
||||
#include <QVarLengthArray>
|
||||
#include <QFileInfo>
|
||||
#include <QDate>
|
||||
#include <QFileDialog>
|
||||
#include <QToolBar>
|
||||
#include <QClipboard>
|
||||
|
||||
#include <QAction>
|
||||
#include <QCheckBox>
|
||||
#include <QRadioButton>
|
||||
#include <QButtonGroup>
|
||||
#include <QMenu>
|
||||
#include <QTest>
|
||||
|
||||
//start private enum
|
||||
enum { CV_MODE_NORMAL = 0, CV_MODE_OPENGL = 1 };
|
||||
|
||||
//we can change the keyboard shortcuts from here !
|
||||
enum { shortcut_zoom_normal = Qt::CTRL + Qt::Key_Z,
|
||||
shortcut_zoom_imgRegion = Qt::CTRL + Qt::Key_X,
|
||||
shortcut_save_img = Qt::CTRL + Qt::Key_S,
|
||||
shortcut_copy_clipbrd = Qt::CTRL + Qt::Key_C,
|
||||
shortcut_properties_win = Qt::CTRL + Qt::Key_P,
|
||||
shortcut_zoom_in = Qt::CTRL + Qt::Key_Plus,//QKeySequence(QKeySequence::ZoomIn),
|
||||
shortcut_zoom_out = Qt::CTRL + Qt::Key_Minus,//QKeySequence(QKeySequence::ZoomOut),
|
||||
shortcut_panning_left = Qt::CTRL + Qt::Key_Left,
|
||||
shortcut_panning_right = Qt::CTRL + Qt::Key_Right,
|
||||
shortcut_panning_up = Qt::CTRL + Qt::Key_Up,
|
||||
shortcut_panning_down = Qt::CTRL + Qt::Key_Down
|
||||
};
|
||||
//end enum
|
||||
|
||||
class CvWindow;
|
||||
class ViewPort;
|
||||
|
||||
|
||||
class GuiReceiver : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GuiReceiver();
|
||||
~GuiReceiver();
|
||||
|
||||
int start();
|
||||
void isLastWindow();
|
||||
|
||||
bool bTimeOut;
|
||||
QTimer* timer;
|
||||
|
||||
public slots:
|
||||
void createWindow( QString name, int flags = 0 );
|
||||
void destroyWindow(QString name);
|
||||
void destroyAllWindow();
|
||||
void addSlider(QString trackbar_name, QString window_name, void* value, int count, void* on_change);
|
||||
void addSlider2(QString trackbar_name, QString window_name, void* value, int count, void* on_change, void *userdata);
|
||||
void moveWindow(QString name, int x, int y);
|
||||
void resizeWindow(QString name, int width, int height);
|
||||
void showImage(QString name, void* arr);
|
||||
void displayInfo( QString name, QString text, int delayms );
|
||||
void displayStatusBar( QString name, QString text, int delayms );
|
||||
void timeOut();
|
||||
void toggleFullScreen(QString name, double flags );
|
||||
CvRect getWindowRect(QString name);
|
||||
double isFullScreen(QString name);
|
||||
double getPropWindow(QString name);
|
||||
void setPropWindow(QString name, double flags );
|
||||
void setWindowTitle(QString name, QString title);
|
||||
double getWindowVisible(QString name);
|
||||
double getRatioWindow(QString name);
|
||||
void setRatioWindow(QString name, double arg2 );
|
||||
void saveWindowParameters(QString name);
|
||||
void loadWindowParameters(QString name);
|
||||
void putText(void* arg1, QString text, QPoint org, void* font);
|
||||
void addButton(QString button_name, int button_type, int initial_button_state , void* on_change, void* userdata);
|
||||
void enablePropertiesButtonEachWindow();
|
||||
|
||||
void setOpenGlDrawCallback(QString name, void* callback, void* userdata);
|
||||
void setOpenGlContext(QString name);
|
||||
void updateWindow(QString name);
|
||||
double isOpenGl(QString name);
|
||||
|
||||
private:
|
||||
int nb_windows;
|
||||
bool doesExternalQAppExist;
|
||||
};
|
||||
|
||||
|
||||
enum typeBar { type_CvTrackbar = 0, type_CvButtonbar = 1 };
|
||||
class CvBar : public QHBoxLayout
|
||||
{
|
||||
public:
|
||||
typeBar type;
|
||||
QString name_bar;
|
||||
QPointer<QWidget> myparent;
|
||||
};
|
||||
|
||||
|
||||
class CvButtonbar : public CvBar
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CvButtonbar(QWidget* arg, QString bar_name);
|
||||
|
||||
void addButton(QString button_name, CvButtonCallback call, void* userdata, int button_type, int initial_button_state);
|
||||
|
||||
private:
|
||||
void setLabel();
|
||||
|
||||
QPointer<QLabel> label;
|
||||
QPointer<QButtonGroup> group_button;
|
||||
};
|
||||
|
||||
|
||||
class CvPushButton : public QPushButton
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CvPushButton(CvButtonbar* par, QString button_name, CvButtonCallback call, void* userdata);
|
||||
|
||||
private:
|
||||
CvButtonbar* myparent;
|
||||
QString button_name ;
|
||||
CvButtonCallback callback;
|
||||
void* userdata;
|
||||
|
||||
private slots:
|
||||
void callCallBack(bool);
|
||||
};
|
||||
|
||||
|
||||
class CvCheckBox : public QCheckBox
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CvCheckBox(CvButtonbar* par, QString button_name, CvButtonCallback call, void* userdata, int initial_button_state);
|
||||
|
||||
private:
|
||||
CvButtonbar* myparent;
|
||||
QString button_name ;
|
||||
CvButtonCallback callback;
|
||||
void* userdata;
|
||||
|
||||
private slots:
|
||||
void callCallBack(bool);
|
||||
};
|
||||
|
||||
|
||||
class CvRadioButton : public QRadioButton
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CvRadioButton(CvButtonbar* par, QString button_name, CvButtonCallback call, void* userdata, int initial_button_state);
|
||||
|
||||
private:
|
||||
CvButtonbar* myparent;
|
||||
QString button_name ;
|
||||
CvButtonCallback callback;
|
||||
void* userdata;
|
||||
|
||||
private slots:
|
||||
void callCallBack(bool);
|
||||
};
|
||||
|
||||
|
||||
class CvTrackbar : public CvBar
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CvTrackbar(CvWindow* parent, QString name, int* value, int count, CvTrackbarCallback on_change);
|
||||
CvTrackbar(CvWindow* parent, QString name, int* value, int count, CvTrackbarCallback2 on_change, void* data);
|
||||
|
||||
QPointer<QSlider> slider;
|
||||
|
||||
private slots:
|
||||
void createDialog();
|
||||
void update(int myvalue);
|
||||
|
||||
private:
|
||||
void setLabel(int myvalue);
|
||||
void create(CvWindow* arg, QString name, int* value, int count);
|
||||
QString createLabel();
|
||||
QPointer<QPushButton > label;
|
||||
CvTrackbarCallback callback;
|
||||
CvTrackbarCallback2 callback2;//look like it is use by python binding
|
||||
int* dataSlider; // deprecated
|
||||
void* userdata;
|
||||
};
|
||||
|
||||
//Both are top level window, so that a way to differentiate them.
|
||||
//if (obj->metaObject ()->className () == "CvWindow") does not give me robust result
|
||||
|
||||
enum typeWindow { type_CvWindow = 1, type_CvWinProperties = 2 };
|
||||
class CvWinModel : public QWidget
|
||||
{
|
||||
public:
|
||||
typeWindow type;
|
||||
};
|
||||
|
||||
|
||||
class CvWinProperties : public CvWinModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CvWinProperties(QString name, QObject* parent);
|
||||
~CvWinProperties();
|
||||
QPointer<QBoxLayout> myLayout;
|
||||
|
||||
private:
|
||||
void closeEvent ( QCloseEvent * e ) CV_OVERRIDE;
|
||||
void showEvent ( QShowEvent * event ) CV_OVERRIDE;
|
||||
void hideEvent ( QHideEvent * event ) CV_OVERRIDE;
|
||||
};
|
||||
|
||||
|
||||
class CvWindow : public CvWinModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CvWindow(QString arg2, int flag = CV_WINDOW_NORMAL);
|
||||
~CvWindow();
|
||||
|
||||
void setMouseCallBack(CvMouseCallback m, void* param);
|
||||
|
||||
void writeSettings();
|
||||
void readSettings();
|
||||
|
||||
double getRatio();
|
||||
void setRatio(int flags);
|
||||
|
||||
CvRect getWindowRect();
|
||||
int getPropWindow();
|
||||
void setPropWindow(int flags);
|
||||
|
||||
void toggleFullScreen(int flags);
|
||||
|
||||
void updateImage(void* arr);
|
||||
|
||||
void displayInfo(QString text, int delayms);
|
||||
void displayStatusBar(QString text, int delayms);
|
||||
|
||||
void enablePropertiesButton();
|
||||
|
||||
static CvButtonbar* createButtonBar(QString bar_name);
|
||||
|
||||
static void addSlider(CvWindow* w, QString name, int* value, int count, CvTrackbarCallback on_change CV_DEFAULT(NULL));
|
||||
static void addSlider2(CvWindow* w, QString name, int* value, int count, CvTrackbarCallback2 on_change CV_DEFAULT(NULL), void* userdata CV_DEFAULT(0));
|
||||
|
||||
void setOpenGlDrawCallback(CvOpenGlDrawCallback callback, void* userdata);
|
||||
void makeCurrentOpenGlContext();
|
||||
void updateGl();
|
||||
bool isOpenGl();
|
||||
|
||||
void setViewportSize(QSize size);
|
||||
|
||||
//parameters (will be save/load)
|
||||
int param_flags;
|
||||
int param_gui_mode;
|
||||
int param_ratio_mode;
|
||||
|
||||
QPointer<QBoxLayout> myGlobalLayout; //All the widget (toolbar, view, LayoutBar, ...) are attached to it
|
||||
QPointer<QBoxLayout> myBarLayout;
|
||||
|
||||
QVector<QAction*> vect_QActions;
|
||||
|
||||
QPointer<QStatusBar> myStatusBar;
|
||||
QPointer<QToolBar> myToolBar;
|
||||
QPointer<QLabel> myStatusBar_msg;
|
||||
|
||||
protected:
|
||||
virtual void keyPressEvent(QKeyEvent* event) CV_OVERRIDE;
|
||||
virtual void closeEvent(QCloseEvent* event) CV_OVERRIDE;
|
||||
|
||||
private:
|
||||
|
||||
int mode_display; //opengl or native
|
||||
ViewPort* myView;
|
||||
|
||||
QVector<QShortcut*> vect_QShortcuts;
|
||||
|
||||
void icvLoadTrackbars(QSettings *settings);
|
||||
void icvSaveTrackbars(QSettings *settings);
|
||||
void icvLoadControlPanel();
|
||||
void icvSaveControlPanel();
|
||||
void icvLoadButtonbar(CvButtonbar* t,QSettings *settings);
|
||||
void icvSaveButtonbar(CvButtonbar* t,QSettings *settings);
|
||||
|
||||
void createActions();
|
||||
void createShortcuts();
|
||||
void createToolBar();
|
||||
void createView();
|
||||
void createStatusBar();
|
||||
void createGlobalLayout();
|
||||
void createBarLayout();
|
||||
CvWinProperties* createParameterWindow();
|
||||
|
||||
void hideTools();
|
||||
void showTools();
|
||||
QSize getAvailableSize();
|
||||
|
||||
private slots:
|
||||
void displayPropertiesWin();
|
||||
};
|
||||
|
||||
|
||||
enum type_mouse_event { mouse_up = 0, mouse_down = 1, mouse_dbclick = 2, mouse_move = 3, mouse_wheel = 4 };
|
||||
static const int tableMouseButtons[][3]={
|
||||
{CV_EVENT_LBUTTONUP, CV_EVENT_RBUTTONUP, CV_EVENT_MBUTTONUP}, //mouse_up
|
||||
{CV_EVENT_LBUTTONDOWN, CV_EVENT_RBUTTONDOWN, CV_EVENT_MBUTTONDOWN}, //mouse_down
|
||||
{CV_EVENT_LBUTTONDBLCLK, CV_EVENT_RBUTTONDBLCLK, CV_EVENT_MBUTTONDBLCLK}, //mouse_dbclick
|
||||
{CV_EVENT_MOUSEMOVE, CV_EVENT_MOUSEMOVE, CV_EVENT_MOUSEMOVE}, //mouse_move
|
||||
{0, 0, 0} //mouse_wheel, to prevent exceptions in code
|
||||
};
|
||||
|
||||
|
||||
class ViewPort
|
||||
{
|
||||
public:
|
||||
virtual ~ViewPort() {}
|
||||
|
||||
virtual QWidget* getWidget() = 0;
|
||||
|
||||
virtual void setMouseCallBack(CvMouseCallback callback, void* param) = 0;
|
||||
|
||||
virtual void writeSettings(QSettings& settings) = 0;
|
||||
virtual void readSettings(QSettings& settings) = 0;
|
||||
|
||||
virtual double getRatio() = 0;
|
||||
virtual void setRatio(int flags) = 0;
|
||||
|
||||
virtual void updateImage(const CvArr* arr) = 0;
|
||||
|
||||
virtual void startDisplayInfo(QString text, int delayms) = 0;
|
||||
|
||||
virtual void setOpenGlDrawCallback(CvOpenGlDrawCallback callback, void* userdata) = 0;
|
||||
virtual void makeCurrentOpenGlContext() = 0;
|
||||
virtual void updateGl() = 0;
|
||||
|
||||
virtual void setSize(QSize size_) = 0;
|
||||
};
|
||||
|
||||
|
||||
class OCVViewPort : public ViewPort
|
||||
{
|
||||
public:
|
||||
explicit OCVViewPort();
|
||||
~OCVViewPort() CV_OVERRIDE {};
|
||||
void setMouseCallBack(CvMouseCallback callback, void* param) CV_OVERRIDE;
|
||||
|
||||
protected:
|
||||
void icvmouseEvent(QMouseEvent* event, type_mouse_event category);
|
||||
void icvmouseHandler(QMouseEvent* event, type_mouse_event category, int& cv_event, int& flags);
|
||||
virtual void icvmouseProcessing(QPointF pt, int cv_event, int flags);
|
||||
|
||||
CvMouseCallback mouseCallback;
|
||||
void* mouseData;
|
||||
};
|
||||
|
||||
|
||||
#ifdef HAVE_QT_OPENGL
|
||||
|
||||
// Use QOpenGLWidget for Qt6 (QGLWidget is deprecated)
|
||||
#ifdef HAVE_QT6
|
||||
typedef QOpenGLWidget OpenCVQtWidgetBase;
|
||||
#else
|
||||
typedef QGLWidget OpenCVQtWidgetBase;
|
||||
#endif
|
||||
|
||||
class OpenGlViewPort : public OpenCVQtWidgetBase, public OCVViewPort
|
||||
{
|
||||
public:
|
||||
explicit OpenGlViewPort(QWidget* parent);
|
||||
~OpenGlViewPort() CV_OVERRIDE;
|
||||
|
||||
QWidget* getWidget() CV_OVERRIDE;
|
||||
|
||||
void writeSettings(QSettings& settings) CV_OVERRIDE;
|
||||
void readSettings(QSettings& settings) CV_OVERRIDE;
|
||||
|
||||
double getRatio() CV_OVERRIDE;
|
||||
void setRatio(int flags) CV_OVERRIDE;
|
||||
|
||||
void updateImage(const CvArr* arr) CV_OVERRIDE;
|
||||
|
||||
void startDisplayInfo(QString text, int delayms) CV_OVERRIDE;
|
||||
|
||||
void setOpenGlDrawCallback(CvOpenGlDrawCallback callback, void* userdata) CV_OVERRIDE;
|
||||
void makeCurrentOpenGlContext() CV_OVERRIDE;
|
||||
void updateGl() CV_OVERRIDE;
|
||||
|
||||
void setSize(QSize size_) CV_OVERRIDE;
|
||||
|
||||
protected:
|
||||
void initializeGL() CV_OVERRIDE;
|
||||
void resizeGL(int w, int h) CV_OVERRIDE;
|
||||
void paintGL() CV_OVERRIDE;
|
||||
|
||||
void wheelEvent(QWheelEvent* event) CV_OVERRIDE;
|
||||
void mouseMoveEvent(QMouseEvent* event) CV_OVERRIDE;
|
||||
void mousePressEvent(QMouseEvent* event) CV_OVERRIDE;
|
||||
void mouseReleaseEvent(QMouseEvent* event) CV_OVERRIDE;
|
||||
void mouseDoubleClickEvent(QMouseEvent* event) CV_OVERRIDE;
|
||||
|
||||
QSize sizeHint() const CV_OVERRIDE;
|
||||
|
||||
private:
|
||||
QSize size;
|
||||
|
||||
CvOpenGlDrawCallback glDrawCallback;
|
||||
void* glDrawData;
|
||||
};
|
||||
|
||||
#endif // HAVE_QT_OPENGL
|
||||
|
||||
|
||||
class DefaultViewPort : public QGraphicsView, public OCVViewPort
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DefaultViewPort(CvWindow* centralWidget, int arg2);
|
||||
~DefaultViewPort() CV_OVERRIDE;
|
||||
|
||||
QWidget* getWidget() CV_OVERRIDE;
|
||||
|
||||
void writeSettings(QSettings& settings) CV_OVERRIDE;
|
||||
void readSettings(QSettings& settings) CV_OVERRIDE;
|
||||
|
||||
double getRatio() CV_OVERRIDE;
|
||||
void setRatio(int flags) CV_OVERRIDE;
|
||||
|
||||
void updateImage(const CvArr* arr) CV_OVERRIDE;
|
||||
|
||||
void startDisplayInfo(QString text, int delayms) CV_OVERRIDE;
|
||||
|
||||
void setOpenGlDrawCallback(CvOpenGlDrawCallback callback, void* userdata) CV_OVERRIDE;
|
||||
void makeCurrentOpenGlContext() CV_OVERRIDE;
|
||||
void updateGl() CV_OVERRIDE;
|
||||
|
||||
void setSize(QSize size_) CV_OVERRIDE;
|
||||
|
||||
public slots:
|
||||
//reference:
|
||||
//http://www.qtcentre.org/wiki/index.php?title=QGraphicsView:_Smooth_Panning_and_Zooming
|
||||
//http://doc.qt.nokia.com/4.6/gestures-imagegestures-imagewidget-cpp.html
|
||||
|
||||
void siftWindowOnLeft();
|
||||
void siftWindowOnRight();
|
||||
void siftWindowOnUp() ;
|
||||
void siftWindowOnDown();
|
||||
|
||||
void resetZoom();
|
||||
void imgRegion();
|
||||
void ZoomIn();
|
||||
void ZoomOut();
|
||||
|
||||
void saveView();
|
||||
void copy2Clipbrd();
|
||||
|
||||
protected:
|
||||
void contextMenuEvent(QContextMenuEvent* event) CV_OVERRIDE;
|
||||
void resizeEvent(QResizeEvent* event) CV_OVERRIDE;
|
||||
void paintEvent(QPaintEvent* paintEventInfo) CV_OVERRIDE;
|
||||
|
||||
void wheelEvent(QWheelEvent* event) CV_OVERRIDE;
|
||||
void mouseMoveEvent(QMouseEvent* event) CV_OVERRIDE;
|
||||
void mousePressEvent(QMouseEvent* event) CV_OVERRIDE;
|
||||
void mouseReleaseEvent(QMouseEvent* event) CV_OVERRIDE;
|
||||
void mouseDoubleClickEvent(QMouseEvent* event) CV_OVERRIDE;
|
||||
|
||||
private:
|
||||
int param_keepRatio;
|
||||
|
||||
//parameters (will be save/load)
|
||||
QTransform param_matrixWorld;
|
||||
|
||||
CvMat* image2Draw_mat;
|
||||
QImage image2Draw_qt;
|
||||
int nbChannelOriginImage;
|
||||
|
||||
|
||||
void scaleView(qreal scaleFactor, QPointF center);
|
||||
void moveView(QPointF delta);
|
||||
|
||||
QPoint mouseCoordinate;
|
||||
QPointF positionGrabbing;
|
||||
QRect positionCorners;
|
||||
QTransform matrixWorld_inv;
|
||||
float ratioX, ratioY;
|
||||
|
||||
bool isSameSize(IplImage* img1,IplImage* img2);
|
||||
|
||||
QSize sizeHint() const CV_OVERRIDE;
|
||||
QPointer<CvWindow> centralWidget;
|
||||
QPointer<QTimer> timerDisplay;
|
||||
bool drawInfo;
|
||||
QString infoText;
|
||||
QRectF target;
|
||||
|
||||
void drawInstructions(QPainter *painter);
|
||||
void drawViewOverview(QPainter *painter);
|
||||
void drawImgRegion(QPainter *painter);
|
||||
void draw2D(QPainter *painter);
|
||||
void drawStatusBar();
|
||||
void controlImagePosition();
|
||||
|
||||
void icvmouseProcessing(QPointF pt, int cv_event, int flags) CV_OVERRIDE;
|
||||
|
||||
private slots:
|
||||
void stopDisplayInfo();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,15 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file alias="left-icon">files_Qt/Material/28.png</file>
|
||||
<file alias="right-icon">files_Qt/Material/23.png</file>
|
||||
<file alias="up-icon">files_Qt/Material/19.png</file>
|
||||
<file alias="down-icon">files_Qt/Material/24.png</file>
|
||||
<file alias="zoom_x1-icon">files_Qt/Material/27.png</file>
|
||||
<file alias="imgRegion-icon">files_Qt/Material/61.png</file>
|
||||
<file alias="zoom_in-icon">files_Qt/Material/106.png</file>
|
||||
<file alias="zoom_out-icon">files_Qt/Material/107.png</file>
|
||||
<file alias="save-icon">files_Qt/Material/7.png</file>
|
||||
<file alias="copy_clipbrd-icon">files_Qt/Material/43.png</file>
|
||||
<file alias="properties-icon">files_Qt/Material/38.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -0,0 +1,798 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
#include "window_framebuffer.hpp"
|
||||
|
||||
#include <opencv2/core/utils/configuration.private.hpp>
|
||||
#include <opencv2/core/utils/logger.defines.hpp>
|
||||
#ifdef NDEBUG
|
||||
#define CV_LOG_STRIP_LEVEL CV_LOG_LEVEL_DEBUG + 1
|
||||
#else
|
||||
#define CV_LOG_STRIP_LEVEL CV_LOG_LEVEL_VERBOSE + 1
|
||||
#endif
|
||||
#include <opencv2/core/utils/logger.hpp>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <termios.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/input.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include "opencv2/imgproc.hpp"
|
||||
|
||||
#ifdef HAVE_FRAMEBUFFER_XVFB
|
||||
#include <X11/XWDFile.h>
|
||||
#include <X11/X.h>
|
||||
|
||||
#define C32INT(ptr) ((((unsigned char*)ptr)[0] << 24) | (((unsigned char*)ptr)[1] << 16) | \
|
||||
(((unsigned char*)ptr)[2] << 8) | (((unsigned char*)ptr)[3] << 0))
|
||||
#endif
|
||||
|
||||
|
||||
namespace cv {
|
||||
namespace highgui_backend {
|
||||
|
||||
std::shared_ptr<UIBackend> createUIBackendFramebuffer()
|
||||
{
|
||||
return std::make_shared<FramebufferBackend>();
|
||||
}
|
||||
|
||||
static std::string& getFBMode()
|
||||
{
|
||||
static std::string fbModeOpenCV =
|
||||
cv::utils::getConfigurationParameterString("OPENCV_HIGHGUI_FB_MODE", "FB");
|
||||
return fbModeOpenCV;
|
||||
}
|
||||
|
||||
static std::string& getFBFileName()
|
||||
{
|
||||
static std::string fbFileNameFB =
|
||||
cv::utils::getConfigurationParameterString("FRAMEBUFFER", "/dev/fb0");
|
||||
static std::string fbFileNameOpenCV =
|
||||
cv::utils::getConfigurationParameterString("OPENCV_HIGHGUI_FB_DEVICE", "");
|
||||
|
||||
if (!fbFileNameOpenCV.empty()) return fbFileNameOpenCV;
|
||||
return fbFileNameFB;
|
||||
}
|
||||
|
||||
FramebufferWindow::FramebufferWindow(FramebufferBackend &_backend, int _flags):
|
||||
backend(_backend), flags(_flags)
|
||||
{
|
||||
CV_LOG_DEBUG(NULL, "UI: FramebufferWindow::FramebufferWindow()");
|
||||
FB_ID = "FramebufferWindow";
|
||||
windowRect = Rect(0,0, backend.getFBWidth(), backend.getFBHeight());
|
||||
}
|
||||
|
||||
FramebufferWindow::~FramebufferWindow()
|
||||
{
|
||||
CV_LOG_DEBUG(NULL, "UI: FramebufferWindow::~FramebufferWindow()");
|
||||
}
|
||||
|
||||
void FramebufferWindow::imshow(InputArray image)
|
||||
{
|
||||
CV_LOG_DEBUG(NULL, "UI: FramebufferWindow::imshow(InputArray image)");
|
||||
currentImg = image.getMat().clone();
|
||||
|
||||
CV_LOG_INFO(NULL, "UI: InputArray image: "
|
||||
<< cv::typeToString(image.type()) << " size " << image.size());
|
||||
|
||||
if (currentImg.empty())
|
||||
{
|
||||
CV_LOG_WARNING(NULL, "UI: image is empty");
|
||||
return;
|
||||
}
|
||||
CV_CheckEQ(currentImg.dims, 2, "UI: dims != 2");
|
||||
|
||||
Mat img = image.getMat();
|
||||
switch (img.channels())
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
Mat tmp;
|
||||
switch(img.type())
|
||||
{
|
||||
case CV_8U:
|
||||
tmp = img;
|
||||
break;
|
||||
case CV_8S:
|
||||
cv::convertScaleAbs(img, tmp, 1, 127);
|
||||
break;
|
||||
case CV_16S:
|
||||
cv::convertScaleAbs(img, tmp, 1/255., 127);
|
||||
break;
|
||||
case CV_16U:
|
||||
cv::convertScaleAbs(img, tmp, 1/255.);
|
||||
break;
|
||||
case CV_32F:
|
||||
case CV_64F: // assuming image has values in range [0, 1)
|
||||
img.convertTo(tmp, CV_8U, 255., 0.);
|
||||
break;
|
||||
}
|
||||
Mat rgb(img.rows, img.cols, CV_8UC3);
|
||||
cvtColor(tmp, rgb, COLOR_GRAY2RGB);
|
||||
img = rgb;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
case 4:
|
||||
{
|
||||
Mat tmp(img.rows, img.cols, CV_8UC3);
|
||||
convertToShow(img, tmp, true);
|
||||
img = tmp;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
CV_Error(cv::Error::StsBadArg, "Bad image: wrong number of channels");
|
||||
}
|
||||
{
|
||||
Mat bgra(img.rows, img.cols, CV_8UC4);
|
||||
cvtColor(img, bgra, COLOR_RGB2BGRA, bgra.channels());
|
||||
img = bgra;
|
||||
}
|
||||
|
||||
int newWidth = windowRect.width;
|
||||
int newHeight = windowRect.height;
|
||||
int cntChannel = img.channels();
|
||||
cv::Size imgSize = currentImg.size();
|
||||
|
||||
if (flags & WINDOW_AUTOSIZE)
|
||||
{
|
||||
windowRect.width = imgSize.width;
|
||||
windowRect.height = imgSize.height;
|
||||
newWidth = windowRect.width;
|
||||
newHeight = windowRect.height;
|
||||
}
|
||||
|
||||
if (flags & WINDOW_FREERATIO)
|
||||
{
|
||||
newWidth = windowRect.width;
|
||||
newHeight = windowRect.height;
|
||||
}
|
||||
else //WINDOW_KEEPRATIO
|
||||
{
|
||||
double aspect_ratio = ((double)img.cols) / img.rows;
|
||||
newWidth = windowRect.width;
|
||||
newHeight = (int)(windowRect.width / aspect_ratio);
|
||||
|
||||
if (newHeight > windowRect.height)
|
||||
{
|
||||
newWidth = (int)(windowRect.height * aspect_ratio);
|
||||
newHeight = windowRect.height;
|
||||
}
|
||||
}
|
||||
|
||||
if ((newWidth != img.cols) && (newHeight != img.rows))
|
||||
{
|
||||
Mat imResize;
|
||||
cv::resize(img, imResize, cv::Size(newWidth, newHeight), INTER_LINEAR);
|
||||
img = imResize;
|
||||
}
|
||||
|
||||
CV_LOG_INFO(NULL, "UI: Formated image: "
|
||||
<< cv::typeToString(img.type()) << " size " << img.size());
|
||||
|
||||
if (backend.getMode() == FB_MODE_EMU)
|
||||
{
|
||||
CV_LOG_WARNING(NULL, "UI: FramebufferWindow::imshow is used in EMU mode");
|
||||
return;
|
||||
}
|
||||
|
||||
if (backend.getFBPointer() == MAP_FAILED)
|
||||
{
|
||||
CV_LOG_ERROR(NULL, "UI: Framebuffer is not mapped");
|
||||
return;
|
||||
}
|
||||
|
||||
int xOffset = backend.getFBXOffset();
|
||||
int yOffset = backend.getFBYOffset();
|
||||
int fbHeight = backend.getFBHeight();
|
||||
int fbWidth = backend.getFBWidth();
|
||||
int lineLength = backend.getFBLineLength();
|
||||
|
||||
int img_start_x;
|
||||
int img_start_y;
|
||||
int img_end_x;
|
||||
int img_end_y;
|
||||
int fb_start_x;
|
||||
int fb_start_y;
|
||||
|
||||
if (windowRect.y - yOffset < 0)
|
||||
{
|
||||
img_start_y = - (windowRect.y - yOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
img_start_y = 0;
|
||||
}
|
||||
if (windowRect.x - xOffset < 0)
|
||||
{
|
||||
img_start_x = - (windowRect.x - xOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
img_start_x = 0;
|
||||
}
|
||||
|
||||
if (windowRect.y + yOffset + img.rows > fbHeight)
|
||||
{
|
||||
img_end_y = fbHeight - windowRect.y - yOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
img_end_y = img.rows;
|
||||
}
|
||||
if (windowRect.x + xOffset + img.cols > fbWidth)
|
||||
{
|
||||
img_end_x = fbWidth - windowRect.x - xOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
img_end_x = img.cols;
|
||||
}
|
||||
|
||||
if (windowRect.y + yOffset >= 0)
|
||||
{
|
||||
fb_start_y = windowRect.y + yOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
fb_start_y = 0;
|
||||
}
|
||||
if (windowRect.x + xOffset >= 0)
|
||||
{
|
||||
fb_start_x = windowRect.x + xOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
fb_start_x = 0;
|
||||
}
|
||||
|
||||
for (int y = img_start_y; y < img_end_y; y++)
|
||||
{
|
||||
std::memcpy(backend.getFBPointer() +
|
||||
(fb_start_y + y - img_start_y) * lineLength + fb_start_x * cntChannel,
|
||||
img.ptr<unsigned char>(y) + img_start_x * cntChannel,
|
||||
(img_end_x - img_start_x) * cntChannel);
|
||||
}
|
||||
}
|
||||
|
||||
double FramebufferWindow::getProperty(int /*prop*/) const
|
||||
{
|
||||
CV_LOG_WARNING(NULL, "UI: getProperty (not supported)");
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
bool FramebufferWindow::setProperty(int /*prop*/, double /*value*/)
|
||||
{
|
||||
CV_LOG_WARNING(NULL, "UI: setProperty (not supported)");
|
||||
return false;
|
||||
}
|
||||
|
||||
void FramebufferWindow::resize(int width, int height)
|
||||
{
|
||||
CV_LOG_DEBUG(NULL, "UI: FramebufferWindow::resize(int width "
|
||||
<< width <<", height " << height << ")");
|
||||
|
||||
CV_Assert(width > 0);
|
||||
CV_Assert(height > 0);
|
||||
|
||||
if (!(flags & WINDOW_AUTOSIZE))
|
||||
{
|
||||
windowRect.width = width;
|
||||
windowRect.height = height;
|
||||
|
||||
if (!currentImg.empty())
|
||||
{
|
||||
imshow(currentImg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FramebufferWindow::move(int x, int y)
|
||||
{
|
||||
CV_LOG_DEBUG(NULL, "UI: FramebufferWindow::move(int x " << x << ", y " << y <<")");
|
||||
|
||||
windowRect.x = x;
|
||||
windowRect.y = y;
|
||||
|
||||
if (!currentImg.empty())
|
||||
{
|
||||
imshow(currentImg);
|
||||
}
|
||||
}
|
||||
|
||||
Rect FramebufferWindow::getImageRect() const
|
||||
{
|
||||
CV_LOG_DEBUG(NULL, "UI: FramebufferWindow::getImageRect()");
|
||||
return windowRect;
|
||||
}
|
||||
|
||||
void FramebufferWindow::setTitle(const std::string& /*title*/)
|
||||
{
|
||||
CV_LOG_WARNING(NULL, "UI: setTitle (not supported)");
|
||||
}
|
||||
|
||||
void FramebufferWindow::setMouseCallback(MouseCallback /*onMouse*/, void* /*userdata*/)
|
||||
{
|
||||
CV_LOG_WARNING(NULL, "UI: setMouseCallback (not supported)");
|
||||
}
|
||||
|
||||
std::shared_ptr<UITrackbar> FramebufferWindow::createTrackbar(
|
||||
const std::string& /*name*/,
|
||||
int /*count*/,
|
||||
TrackbarCallback /*onChange*/,
|
||||
void* /*userdata*/)
|
||||
{
|
||||
CV_LOG_WARNING(NULL, "UI: createTrackbar (not supported)");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<UITrackbar> FramebufferWindow::findTrackbar(const std::string& /*name*/)
|
||||
{
|
||||
CV_LOG_WARNING(NULL, "UI: findTrackbar (not supported)");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const std::string& FramebufferWindow::getID() const
|
||||
{
|
||||
CV_LOG_DEBUG(NULL, "UI: FramebufferWindow::getID()");
|
||||
return FB_ID;
|
||||
}
|
||||
|
||||
bool FramebufferWindow::isActive() const
|
||||
{
|
||||
CV_LOG_DEBUG(NULL, "UI: FramebufferWindow::isActive()");
|
||||
return true;
|
||||
}
|
||||
|
||||
void FramebufferWindow::destroy()
|
||||
{
|
||||
CV_LOG_DEBUG(NULL, "UI: FramebufferWindow::destroy()");
|
||||
}
|
||||
|
||||
int FramebufferBackend::fbOpenAndGetInfo()
|
||||
{
|
||||
std::string fbFileName = getFBFileName();
|
||||
CV_LOG_INFO(NULL, "UI: FramebufferWindow::The following is used as a framebuffer file: \n"
|
||||
<< fbFileName);
|
||||
|
||||
int fb_fd = open(fbFileName.c_str(), O_RDWR);
|
||||
if (fb_fd == -1)
|
||||
{
|
||||
CV_LOG_ERROR(NULL, "UI: can't open framebuffer");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &fixInfo))
|
||||
{
|
||||
CV_LOG_ERROR(NULL, "UI: can't read fix info for framebuffer");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &varInfo))
|
||||
{
|
||||
CV_LOG_ERROR(NULL, "UI: can't read var info for framebuffer");
|
||||
return -1;
|
||||
}
|
||||
|
||||
CV_LOG_INFO(NULL, "UI: framebuffer info: \n"
|
||||
<< " red offset " << varInfo.red.offset << " length " << varInfo.red.length << "\n"
|
||||
<< " green offset " << varInfo.green.offset << " length " << varInfo.green.length << "\n"
|
||||
<< " blue offset " << varInfo.blue.offset << " length " << varInfo.blue.length << "\n"
|
||||
<< "transp offset " << varInfo.transp.offset << " length " <<varInfo.transp.length << "\n"
|
||||
<< "bits_per_pixel " << varInfo.bits_per_pixel);
|
||||
|
||||
if ((varInfo.red.offset != 16) && (varInfo.red.length != 8) &&
|
||||
(varInfo.green.offset != 8) && (varInfo.green.length != 8) &&
|
||||
(varInfo.blue.offset != 0) && (varInfo.blue.length != 8) &&
|
||||
(varInfo.bits_per_pixel != 32) )
|
||||
{
|
||||
close(fb_fd);
|
||||
CV_LOG_ERROR(NULL, "UI: Framebuffer format is not supported "
|
||||
<< "(use BGRA format with bits_per_pixel = 32)");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fbWidth = varInfo.xres;
|
||||
fbHeight = varInfo.yres;
|
||||
fbXOffset = varInfo.xoffset;
|
||||
fbYOffset = varInfo.yoffset;
|
||||
fbBitsPerPixel = varInfo.bits_per_pixel;
|
||||
fbLineLength = fixInfo.line_length;
|
||||
|
||||
fbScreenSize = max(varInfo.xres, varInfo.xres_virtual) *
|
||||
max(varInfo.yres, varInfo.yres_virtual) *
|
||||
fbBitsPerPixel / 8;
|
||||
|
||||
fbPointer = (unsigned char*)
|
||||
mmap(0, fbScreenSize, PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, 0);
|
||||
|
||||
if (fbPointer == MAP_FAILED)
|
||||
{
|
||||
CV_LOG_ERROR(NULL, "UI: can't mmap framebuffer");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fb_fd;
|
||||
}
|
||||
|
||||
int FramebufferBackend::XvfbOpenAndGetInfo()
|
||||
{
|
||||
int fb_fd = -1;
|
||||
|
||||
#ifdef HAVE_FRAMEBUFFER_XVFB
|
||||
std::string fbFileName = getFBFileName();
|
||||
CV_LOG_INFO(NULL, "UI: FramebufferWindow::The following is used as a framebuffer file: \n"
|
||||
<< fbFileName);
|
||||
|
||||
fb_fd = open(fbFileName.c_str(), O_RDWR);
|
||||
if (fb_fd == -1)
|
||||
{
|
||||
CV_LOG_ERROR(NULL, "UI: can't open framebuffer");
|
||||
return -1;
|
||||
}
|
||||
|
||||
XWDFileHeader *xwd_header;
|
||||
|
||||
xwd_header = (XWDFileHeader*)
|
||||
mmap(NULL, sizeof(XWDFileHeader), PROT_READ, MAP_SHARED, fb_fd, 0);
|
||||
|
||||
if (xwd_header == MAP_FAILED)
|
||||
{
|
||||
CV_LOG_ERROR(NULL, "UI: can't mmap xwd header");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (C32INT(&(xwd_header->pixmap_format)) != ZPixmap)
|
||||
{
|
||||
CV_LOG_ERROR(NULL, "Unsupported pixmap format: " << xwd_header->pixmap_format);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (xwd_header->xoffset != 0)
|
||||
{
|
||||
CV_LOG_ERROR(NULL, "UI: Unsupported xoffset value: " << xwd_header->xoffset );
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsigned int r = C32INT(&(xwd_header->red_mask));
|
||||
unsigned int g = C32INT(&(xwd_header->green_mask));
|
||||
unsigned int b = C32INT(&(xwd_header->blue_mask));
|
||||
|
||||
fbWidth = C32INT(&(xwd_header->pixmap_width));
|
||||
fbHeight = C32INT(&(xwd_header->pixmap_height));
|
||||
fbXOffset = 0;
|
||||
fbYOffset = 0;
|
||||
fbLineLength = C32INT(&(xwd_header->bytes_per_line));
|
||||
fbBitsPerPixel = C32INT(&(xwd_header->bits_per_pixel));
|
||||
|
||||
CV_LOG_INFO(NULL, "UI: XVFB info: \n"
|
||||
<< " red_mask " << r << "\n"
|
||||
<< " green_mask " << g << "\n"
|
||||
<< " blue_mask " << b << "\n"
|
||||
<< "bits_per_pixel " << fbBitsPerPixel);
|
||||
|
||||
if ((r != 16711680 ) && (g != 65280 ) && (b != 255 ) &&
|
||||
(fbBitsPerPixel != 32))
|
||||
{
|
||||
CV_LOG_ERROR(NULL, "UI: Framebuffer format is not supported "
|
||||
<< "(use BGRA format with bits_per_pixel = 32)");
|
||||
return -1;
|
||||
}
|
||||
|
||||
xvfb_len_header = C32INT(&(xwd_header->header_size));
|
||||
xvfb_len_colors = sizeof(XWDColor) * C32INT(&(xwd_header->ncolors));
|
||||
xvfb_len_pixmap = C32INT(&(xwd_header->bytes_per_line)) *
|
||||
C32INT(&(xwd_header->pixmap_height));
|
||||
|
||||
munmap(xwd_header, sizeof(XWDFileHeader));
|
||||
|
||||
fbScreenSize = xvfb_len_header + xvfb_len_colors + xvfb_len_pixmap;
|
||||
xwd_header = (XWDFileHeader*)
|
||||
mmap(NULL, fbScreenSize, PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, 0);
|
||||
|
||||
fbPointer = (unsigned char*)xwd_header;
|
||||
fbPointer_dist = xvfb_len_header + xvfb_len_colors;
|
||||
|
||||
#else
|
||||
CV_LOG_WARNING(NULL, "UI: To use virtual framebuffer, "
|
||||
<< "compile OpenCV with the WITH_FRAMEBUFFER_XVFB=ON");
|
||||
#endif
|
||||
|
||||
return fb_fd;
|
||||
}
|
||||
|
||||
fb_var_screeninfo &FramebufferBackend::getVarInfo()
|
||||
{
|
||||
return varInfo;
|
||||
}
|
||||
|
||||
fb_fix_screeninfo &FramebufferBackend::getFixInfo()
|
||||
{
|
||||
return fixInfo;
|
||||
}
|
||||
|
||||
int FramebufferBackend::getFramebufferID()
|
||||
{
|
||||
return fbID;
|
||||
}
|
||||
|
||||
int FramebufferBackend::getFBWidth()
|
||||
{
|
||||
return fbWidth;
|
||||
}
|
||||
|
||||
int FramebufferBackend::getFBHeight()
|
||||
{
|
||||
return fbHeight;
|
||||
}
|
||||
|
||||
int FramebufferBackend::getFBXOffset()
|
||||
{
|
||||
return fbXOffset;
|
||||
}
|
||||
|
||||
int FramebufferBackend::getFBYOffset()
|
||||
{
|
||||
return fbYOffset;
|
||||
}
|
||||
|
||||
int FramebufferBackend::getFBBitsPerPixel()
|
||||
{
|
||||
return fbBitsPerPixel;
|
||||
}
|
||||
|
||||
int FramebufferBackend::getFBLineLength()
|
||||
{
|
||||
return fbLineLength;
|
||||
}
|
||||
|
||||
unsigned char* FramebufferBackend::getFBPointer()
|
||||
{
|
||||
return fbPointer + fbPointer_dist;
|
||||
}
|
||||
|
||||
Mat& FramebufferBackend::getBackgroundBuff()
|
||||
{
|
||||
return backgroundBuff;
|
||||
}
|
||||
|
||||
OpenCVFBMode FramebufferBackend::getMode()
|
||||
{
|
||||
return mode;
|
||||
}
|
||||
|
||||
FramebufferBackend::FramebufferBackend():mode(FB_MODE_FB), fbPointer_dist(0)
|
||||
{
|
||||
CV_LOG_DEBUG(NULL, "UI: FramebufferWindow::FramebufferBackend()");
|
||||
|
||||
std::string fbModeStr = getFBMode();
|
||||
|
||||
if (fbModeStr == "EMU")
|
||||
{
|
||||
mode = FB_MODE_EMU;
|
||||
CV_LOG_WARNING(NULL, "UI: FramebufferWindow is trying to use EMU mode");
|
||||
}
|
||||
if (fbModeStr == "FB")
|
||||
{
|
||||
mode = FB_MODE_FB;
|
||||
CV_LOG_WARNING(NULL, "UI: FramebufferWindow is trying to use FB mode");
|
||||
}
|
||||
if (fbModeStr == "XVFB")
|
||||
{
|
||||
mode = FB_MODE_XVFB;
|
||||
CV_LOG_WARNING(NULL, "UI: FramebufferWindow is trying to use XVFB mode");
|
||||
}
|
||||
|
||||
fbID = -1;
|
||||
if (mode == FB_MODE_FB)
|
||||
{
|
||||
fbID = fbOpenAndGetInfo();
|
||||
}
|
||||
if (mode == FB_MODE_XVFB)
|
||||
{
|
||||
fbID = XvfbOpenAndGetInfo();
|
||||
}
|
||||
|
||||
CV_LOG_INFO(NULL, "UI: FramebufferWindow::fbID " << fbID);
|
||||
|
||||
if (fbID == -1)
|
||||
{
|
||||
mode = FB_MODE_EMU;
|
||||
fbWidth = 640;
|
||||
fbHeight = 480;
|
||||
fbXOffset = 0;
|
||||
fbYOffset = 0;
|
||||
fbBitsPerPixel = 0;
|
||||
fbLineLength = 0;
|
||||
|
||||
CV_LOG_WARNING(NULL, "UI: FramebufferWindow is used in EMU mode");
|
||||
return;
|
||||
}
|
||||
|
||||
CV_LOG_INFO(NULL, "UI: Framebuffer's width, height, bits per pix: "
|
||||
<< fbWidth << " " << fbHeight << " " << fbBitsPerPixel);
|
||||
|
||||
CV_LOG_INFO(NULL, "UI: Framebuffer's offsets (x, y), line length: "
|
||||
<< fbXOffset << " " << fbYOffset << " " << fbLineLength);
|
||||
|
||||
backgroundBuff = Mat(fbHeight, fbWidth, CV_8UC4);
|
||||
int cntChannel = 4;
|
||||
for (int y = fbYOffset; y < backgroundBuff.rows + fbYOffset; y++)
|
||||
{
|
||||
std::memcpy(backgroundBuff.ptr<unsigned char>(y - fbYOffset),
|
||||
getFBPointer() + y * fbLineLength + fbXOffset * cntChannel,
|
||||
backgroundBuff.cols * cntChannel);
|
||||
}
|
||||
}
|
||||
|
||||
FramebufferBackend::~FramebufferBackend()
|
||||
{
|
||||
CV_LOG_DEBUG(NULL, "UI: FramebufferBackend::~FramebufferBackend()");
|
||||
if(fbID == -1) return;
|
||||
|
||||
if (fbPointer != MAP_FAILED)
|
||||
{
|
||||
int cntChannel = 4;
|
||||
for (int y = fbYOffset; y < backgroundBuff.rows + fbYOffset; y++)
|
||||
{
|
||||
std::memcpy(getFBPointer() + y * fbLineLength + fbXOffset * cntChannel,
|
||||
backgroundBuff.ptr<cv::Vec4b>(y - fbYOffset),
|
||||
backgroundBuff.cols * cntChannel);
|
||||
}
|
||||
|
||||
munmap(fbPointer, fbScreenSize);
|
||||
}
|
||||
close(fbID);
|
||||
}
|
||||
|
||||
void FramebufferBackend::destroyAllWindows() {
|
||||
CV_LOG_DEBUG(NULL, "UI: FramebufferBackend::destroyAllWindows()");
|
||||
}
|
||||
|
||||
// namedWindow
|
||||
std::shared_ptr<UIWindow> FramebufferBackend::createWindow(
|
||||
const std::string& winname,
|
||||
int flags)
|
||||
{
|
||||
CV_LOG_DEBUG(NULL, "UI: FramebufferBackend::createWindow("
|
||||
<< winname << ", " << flags << ")");
|
||||
return std::make_shared<FramebufferWindow>(*this, flags);
|
||||
}
|
||||
|
||||
void FramebufferBackend::initTermios(int echo, int wait)
|
||||
{
|
||||
tcgetattr(0, &old);
|
||||
current = old;
|
||||
current.c_lflag &= ~ICANON;
|
||||
current.c_lflag &= ~ISIG;
|
||||
current.c_cc[VMIN] = wait;
|
||||
if (echo)
|
||||
{
|
||||
current.c_lflag |= ECHO;
|
||||
}
|
||||
else
|
||||
{
|
||||
current.c_lflag &= ~ECHO;
|
||||
}
|
||||
tcsetattr(0, TCSANOW, ¤t);
|
||||
}
|
||||
|
||||
void FramebufferBackend::resetTermios(void)
|
||||
{
|
||||
tcsetattr(0, TCSANOW, &old);
|
||||
}
|
||||
|
||||
int FramebufferBackend::getch_(int echo, int wait)
|
||||
{
|
||||
int ch;
|
||||
initTermios(echo, wait);
|
||||
ch = getchar();
|
||||
if (ch < 0)
|
||||
{
|
||||
rewind(stdin);
|
||||
}
|
||||
resetTermios();
|
||||
return ch;
|
||||
}
|
||||
|
||||
bool FramebufferBackend::kbhit()
|
||||
{
|
||||
int byteswaiting = 0;
|
||||
initTermios(0, 1);
|
||||
if (ioctl(0, FIONREAD, &byteswaiting) < 0)
|
||||
{
|
||||
CV_LOG_ERROR(NULL, "UI: Framebuffer ERR byteswaiting" );
|
||||
}
|
||||
resetTermios();
|
||||
|
||||
return byteswaiting > 0;
|
||||
}
|
||||
|
||||
int FramebufferBackend::waitKeyEx(int delay)
|
||||
{
|
||||
CV_LOG_DEBUG(NULL, "UI: FramebufferBackend::waitKeyEx(int delay = " << delay << ")");
|
||||
|
||||
int code = -1;
|
||||
|
||||
if (delay <= 0)
|
||||
{
|
||||
int ch = getch_(0, 1);
|
||||
CV_LOG_INFO(NULL, "UI: FramebufferBackend::getch_() take value = " << (int)ch);
|
||||
code = ch;
|
||||
|
||||
while ((ch = getch_(0, 0)) >= 0)
|
||||
{
|
||||
CV_LOG_INFO(NULL, "UI: FramebufferBackend::getch_() take value = "
|
||||
<< (int)ch << " (additional code on <stdin>)");
|
||||
code = ch;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool f_kbhit = false;
|
||||
while (!(f_kbhit = kbhit()) && (delay > 0))
|
||||
{
|
||||
delay -= 1;
|
||||
usleep(1000);
|
||||
}
|
||||
if (f_kbhit)
|
||||
{
|
||||
CV_LOG_INFO(NULL, "UI: FramebufferBackend kbhit is True ");
|
||||
|
||||
int ch = getch_(0, 1);
|
||||
CV_LOG_INFO(NULL, "UI: FramebufferBackend::getch_() take value = " << (int)ch);
|
||||
code = ch;
|
||||
|
||||
while ((ch = getch_(0, 0)) >= 0)
|
||||
{
|
||||
CV_LOG_INFO(NULL, "UI: FramebufferBackend::getch_() take value = "
|
||||
<< (int)ch << " (additional code on <stdin>)");
|
||||
code = ch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CV_LOG_INFO(NULL, "UI: FramebufferBackend::waitKeyEx() result code = " << code);
|
||||
return code;
|
||||
}
|
||||
|
||||
int FramebufferBackend::pollKey()
|
||||
{
|
||||
CV_LOG_DEBUG(NULL, "UI: FramebufferBackend::pollKey()");
|
||||
int code = -1;
|
||||
bool f_kbhit = false;
|
||||
f_kbhit = kbhit();
|
||||
|
||||
if (f_kbhit)
|
||||
{
|
||||
CV_LOG_INFO(NULL, "UI: FramebufferBackend kbhit is True ");
|
||||
|
||||
int ch = getch_(0, 1);
|
||||
CV_LOG_INFO(NULL, "UI: FramebufferBackend::getch_() take value = " << (int)ch);
|
||||
code = ch;
|
||||
|
||||
while ((ch = getch_(0, 0)) >= 0)
|
||||
{
|
||||
CV_LOG_INFO(NULL, "UI: FramebufferBackend::getch_() take value = "
|
||||
<< (int)ch << " (additional code on <stdin>)");
|
||||
code = ch;
|
||||
}
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
const std::string FramebufferBackend::getName() const
|
||||
{
|
||||
return "FB";
|
||||
}
|
||||
|
||||
}} // cv::highgui_backend::
|
||||
@@ -0,0 +1,135 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#ifndef OPENCV_HIGHGUI_WINDOWS_FRAMEBUFFER_HPP
|
||||
#define OPENCV_HIGHGUI_WINDOWS_FRAMEBUFFER_HPP
|
||||
|
||||
#include "backend.hpp"
|
||||
|
||||
#include <linux/fb.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
#include <termios.h>
|
||||
|
||||
namespace cv {
|
||||
namespace highgui_backend {
|
||||
|
||||
enum OpenCVFBMode{
|
||||
FB_MODE_EMU,
|
||||
FB_MODE_FB,
|
||||
FB_MODE_XVFB
|
||||
};
|
||||
|
||||
class FramebufferBackend;
|
||||
class FramebufferWindow : public UIWindow
|
||||
{
|
||||
FramebufferBackend &backend;
|
||||
std::string FB_ID;
|
||||
Rect windowRect;
|
||||
|
||||
int flags;
|
||||
Mat currentImg;
|
||||
|
||||
public:
|
||||
FramebufferWindow(FramebufferBackend &backend, int flags);
|
||||
virtual ~FramebufferWindow();
|
||||
|
||||
virtual void imshow(InputArray image) override;
|
||||
|
||||
virtual double getProperty(int prop) const override;
|
||||
virtual bool setProperty(int prop, double value) override;
|
||||
|
||||
virtual void resize(int width, int height) override;
|
||||
virtual void move(int x, int y) override;
|
||||
|
||||
virtual Rect getImageRect() const override;
|
||||
|
||||
virtual void setTitle(const std::string& title) override;
|
||||
|
||||
virtual void setMouseCallback(MouseCallback onMouse, void* userdata /*= 0*/) override;
|
||||
|
||||
virtual std::shared_ptr<UITrackbar> createTrackbar(
|
||||
const std::string& name,
|
||||
int count,
|
||||
TrackbarCallback onChange /*= 0*/,
|
||||
void* userdata /*= 0*/
|
||||
) override;
|
||||
|
||||
virtual std::shared_ptr<UITrackbar> findTrackbar(const std::string& name) override;
|
||||
|
||||
virtual const std::string& getID() const override;
|
||||
|
||||
virtual bool isActive() const override;
|
||||
|
||||
virtual void destroy() override;
|
||||
}; // FramebufferWindow
|
||||
|
||||
class FramebufferBackend: public UIBackend
|
||||
{
|
||||
OpenCVFBMode mode;
|
||||
|
||||
struct termios old, current;
|
||||
|
||||
void initTermios(int echo, int wait);
|
||||
void resetTermios(void);
|
||||
int getch_(int echo, int wait);
|
||||
bool kbhit();
|
||||
|
||||
fb_var_screeninfo varInfo;
|
||||
fb_fix_screeninfo fixInfo;
|
||||
int fbWidth;
|
||||
int fbHeight;
|
||||
int fbXOffset;
|
||||
int fbYOffset;
|
||||
int fbBitsPerPixel;
|
||||
int fbLineLength;
|
||||
long int fbScreenSize;
|
||||
unsigned char* fbPointer;
|
||||
unsigned int fbPointer_dist;
|
||||
Mat backgroundBuff;
|
||||
|
||||
int fbOpenAndGetInfo();
|
||||
int fbID;
|
||||
|
||||
unsigned int xvfb_len_header;
|
||||
unsigned int xvfb_len_colors;
|
||||
unsigned int xvfb_len_pixmap;
|
||||
int XvfbOpenAndGetInfo();
|
||||
|
||||
public:
|
||||
|
||||
fb_var_screeninfo &getVarInfo();
|
||||
fb_fix_screeninfo &getFixInfo();
|
||||
int getFramebufferID();
|
||||
int getFBWidth();
|
||||
int getFBHeight();
|
||||
int getFBXOffset();
|
||||
int getFBYOffset();
|
||||
int getFBBitsPerPixel();
|
||||
int getFBLineLength();
|
||||
unsigned char* getFBPointer();
|
||||
Mat& getBackgroundBuff();
|
||||
OpenCVFBMode getMode();
|
||||
|
||||
FramebufferBackend();
|
||||
|
||||
virtual ~FramebufferBackend();
|
||||
|
||||
virtual void destroyAllWindows()override;
|
||||
|
||||
// namedWindow
|
||||
virtual std::shared_ptr<UIWindow> createWindow(
|
||||
const std::string& winname,
|
||||
int flags
|
||||
)override;
|
||||
|
||||
virtual int waitKeyEx(int delay /*= 0*/)override;
|
||||
virtual int pollKey() override;
|
||||
|
||||
virtual const std::string getName() const override;
|
||||
};
|
||||
|
||||
}} // cv::highgui_backend::
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,290 @@
|
||||
// highgui to XAML bridge for OpenCV
|
||||
|
||||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// (3 - clause BSD License)
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that
|
||||
// the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
|
||||
// following disclaimer.
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
|
||||
// following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or
|
||||
// promote products derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
// PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING
|
||||
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
#include <map>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <opencv2\highgui.hpp>
|
||||
#include <opencv2\highgui\highgui_winrt.hpp>
|
||||
#include "window_winrt_bridge.hpp"
|
||||
|
||||
#define CV_WINRT_NO_GUI_ERROR( funcname ) \
|
||||
{ \
|
||||
cvError( cv::Error::StsNotImplemented, funcname, \
|
||||
"The function is not implemented. ", \
|
||||
__FILE__, __LINE__ ); \
|
||||
}
|
||||
|
||||
#ifdef CV_ERROR
|
||||
#undef CV_ERROR
|
||||
#define CV_ERROR( Code, Msg ) \
|
||||
{ \
|
||||
cvError( (Code), cvFuncName, Msg, __FILE__, __LINE__ ); \
|
||||
};
|
||||
#endif
|
||||
|
||||
/********************************** WinRT Specific API Implementation ******************************************/
|
||||
|
||||
// Initializes or overrides container contents with default XAML markup structure
|
||||
void cv::winrt_initContainer(::Windows::UI::Xaml::Controls::Panel^ _container)
|
||||
{
|
||||
HighguiBridge::getInstance().setContainer(_container);
|
||||
}
|
||||
|
||||
/********************************** API Implementation *********************************************************/
|
||||
|
||||
CV_IMPL void cvShowImage(const char* name, const CvArr* arr)
|
||||
{
|
||||
CV_FUNCNAME("cvShowImage");
|
||||
|
||||
__BEGIN__;
|
||||
|
||||
CvMat stub, *image;
|
||||
|
||||
if (!name)
|
||||
CV_ERROR(cv::Error::StsNullPtr, "NULL name");
|
||||
|
||||
CvWindow* window = HighguiBridge::getInstance().namedWindow(name);
|
||||
|
||||
if (!window || !arr)
|
||||
return;
|
||||
|
||||
CV_CALL(image = cvGetMat(arr, &stub));
|
||||
|
||||
//TODO: use approach from window_w32.cpp or cv::Mat(.., .., CV_8UC4)
|
||||
// and cvtColor(.., .., CV_BGR2BGRA) to convert image here
|
||||
// than beforehand.
|
||||
|
||||
window->updateImage(image);
|
||||
HighguiBridge::getInstance().showWindow(window);
|
||||
|
||||
__END__;
|
||||
}
|
||||
|
||||
CV_IMPL int cvNamedWindow(const char* name, int flags)
|
||||
{
|
||||
CV_UNUSED(flags);
|
||||
CV_FUNCNAME("cvNamedWindow");
|
||||
|
||||
if (!name)
|
||||
CV_ERROR(cv::Error::StsNullPtr, "NULL name");
|
||||
|
||||
HighguiBridge::getInstance().namedWindow(name);
|
||||
|
||||
return CV_OK;
|
||||
}
|
||||
|
||||
CV_IMPL void cvDestroyWindow(const char* name)
|
||||
{
|
||||
CV_FUNCNAME("cvDestroyWindow");
|
||||
|
||||
if (!name)
|
||||
CV_ERROR(cv::Error::StsNullPtr, "NULL name string");
|
||||
|
||||
HighguiBridge::getInstance().destroyWindow(name);
|
||||
}
|
||||
|
||||
CV_IMPL void cvDestroyAllWindows()
|
||||
{
|
||||
HighguiBridge::getInstance().destroyAllWindows();
|
||||
}
|
||||
|
||||
CV_IMPL int cvCreateTrackbar2(const char* trackbar_name, const char* window_name,
|
||||
int* val, int count, CvTrackbarCallback2 on_notify, void* userdata)
|
||||
{
|
||||
CV_FUNCNAME("cvCreateTrackbar2");
|
||||
|
||||
if (!window_name || !trackbar_name)
|
||||
CV_ERROR(cv::Error::StsNullPtr, "NULL window or trackbar name");
|
||||
|
||||
if (count < 0)
|
||||
CV_ERROR(cv::Error::StsOutOfRange, "Bad trackbar max value");
|
||||
|
||||
CvWindow* window = HighguiBridge::getInstance().namedWindow(window_name);
|
||||
|
||||
if (!window)
|
||||
{
|
||||
CV_ERROR(cv::Error::StsNullPtr, "NULL window");
|
||||
}
|
||||
|
||||
window->createSlider(trackbar_name, val, count, on_notify, userdata);
|
||||
|
||||
return CV_OK;
|
||||
}
|
||||
|
||||
CV_IMPL void cvSetTrackbarPos(const char* trackbar_name, const char* window_name, int pos)
|
||||
{
|
||||
CV_FUNCNAME("cvSetTrackbarPos");
|
||||
|
||||
CvTrackbar* trackbar = 0;
|
||||
|
||||
if (trackbar_name == 0 || window_name == 0)
|
||||
CV_ERROR(cv::Error::StsNullPtr, "NULL trackbar or window name");
|
||||
|
||||
CvWindow* window = HighguiBridge::getInstance().findWindowByName(window_name);
|
||||
if (window)
|
||||
trackbar = window->findTrackbarByName(trackbar_name);
|
||||
|
||||
if (trackbar)
|
||||
trackbar->setPosition(pos);
|
||||
}
|
||||
|
||||
CV_IMPL void cvSetTrackbarMax(const char* trackbar_name, const char* window_name, int maxval)
|
||||
{
|
||||
CV_FUNCNAME("cvSetTrackbarMax");
|
||||
|
||||
if (maxval >= 0)
|
||||
{
|
||||
if (trackbar_name == 0 || window_name == 0)
|
||||
CV_ERROR(cv::Error::StsNullPtr, "NULL trackbar or window name");
|
||||
|
||||
CvTrackbar* trackbar = HighguiBridge::getInstance().findTrackbarByName(trackbar_name, window_name);
|
||||
|
||||
if (trackbar)
|
||||
trackbar->setMaxPosition(maxval);
|
||||
}
|
||||
}
|
||||
|
||||
CV_IMPL void cvSetTrackbarMin(const char* trackbar_name, const char* window_name, int minval)
|
||||
{
|
||||
CV_FUNCNAME("cvSetTrackbarMin");
|
||||
|
||||
if (minval >= 0)
|
||||
{
|
||||
if (trackbar_name == 0 || window_name == 0)
|
||||
CV_ERROR(cv::Error::StsNullPtr, "NULL trackbar or window name");
|
||||
|
||||
CvTrackbar* trackbar = HighguiBridge::getInstance().findTrackbarByName(trackbar_name, window_name);
|
||||
|
||||
if (trackbar)
|
||||
trackbar->setMinPosition(minval);
|
||||
}
|
||||
}
|
||||
|
||||
CV_IMPL int cvGetTrackbarPos(const char* trackbar_name, const char* window_name)
|
||||
{
|
||||
int pos = -1;
|
||||
|
||||
CV_FUNCNAME("cvGetTrackbarPos");
|
||||
|
||||
if (trackbar_name == 0 || window_name == 0)
|
||||
CV_ERROR(cv::Error::StsNullPtr, "NULL trackbar or window name");
|
||||
|
||||
CvTrackbar* trackbar = HighguiBridge::getInstance().findTrackbarByName(trackbar_name, window_name);
|
||||
|
||||
if (trackbar)
|
||||
pos = (int)trackbar->getPosition();
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
/********************************** Not YET implemented API ****************************************************/
|
||||
|
||||
CV_IMPL int cvWaitKey(int delay)
|
||||
{
|
||||
CV_WINRT_NO_GUI_ERROR("cvWaitKey");
|
||||
|
||||
// see https://msdn.microsoft.com/en-us/library/windows/desktop/ms724411(v=vs.85).aspx
|
||||
//int time0 = GetTickCount64();
|
||||
|
||||
for (;;)
|
||||
{
|
||||
// CvWindow* window;
|
||||
|
||||
if (delay <= 0)
|
||||
{
|
||||
// TODO: implement appropriate logic here
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CV_IMPL void cvSetMouseCallback(const char* window_name, CvMouseCallback on_mouse, void* param)
|
||||
{
|
||||
CV_UNUSED(on_mouse); CV_UNUSED(param);
|
||||
CV_WINRT_NO_GUI_ERROR("cvSetMouseCallback");
|
||||
|
||||
CV_FUNCNAME("cvSetMouseCallback");
|
||||
|
||||
if (!window_name)
|
||||
CV_ERROR(cv::Error::StsNullPtr, "NULL window name");
|
||||
|
||||
CvWindow* window = HighguiBridge::getInstance().findWindowByName(window_name);
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
// TODO: implement appropriate logic here
|
||||
}
|
||||
|
||||
/********************************** Disabled or not supported API **********************************************/
|
||||
|
||||
CV_IMPL void cvMoveWindow(const char* name, int x, int y)
|
||||
{
|
||||
CV_UNUSED(name); CV_UNUSED(x); CV_UNUSED(y);
|
||||
CV_WINRT_NO_GUI_ERROR("cvMoveWindow");
|
||||
}
|
||||
|
||||
CV_IMPL void cvResizeWindow(const char* name, int width, int height)
|
||||
{
|
||||
CV_UNUSED(name); CV_UNUSED(width); CV_UNUSED(height);
|
||||
CV_WINRT_NO_GUI_ERROR("cvResizeWindow");
|
||||
}
|
||||
|
||||
CV_IMPL int cvInitSystem(int, char**)
|
||||
{
|
||||
CV_WINRT_NO_GUI_ERROR("cvInitSystem");
|
||||
return cv::Error::StsNotImplemented;
|
||||
}
|
||||
|
||||
CV_IMPL void* cvGetWindowHandle(const char*)
|
||||
{
|
||||
CV_WINRT_NO_GUI_ERROR("cvGetWindowHandle");
|
||||
return (void*) cv::Error::StsNotImplemented;
|
||||
}
|
||||
|
||||
CV_IMPL const char* cvGetWindowName(void*)
|
||||
{
|
||||
CV_WINRT_NO_GUI_ERROR("cvGetWindowName");
|
||||
return (const char*) cv::Error::StsNotImplemented;
|
||||
}
|
||||
|
||||
void cvSetModeWindow_WinRT(const char* name, double prop_value) {
|
||||
CV_UNUSED(name); CV_UNUSED(prop_value);
|
||||
CV_WINRT_NO_GUI_ERROR("cvSetModeWindow");
|
||||
}
|
||||
|
||||
double cvGetModeWindow_WinRT(const char* name) {
|
||||
CV_UNUSED(name);
|
||||
CV_WINRT_NO_GUI_ERROR("cvGetModeWindow");
|
||||
return cv::Error::StsNotImplemented;
|
||||
}
|
||||
|
||||
CV_IMPL int cvStartWindowThread() {
|
||||
CV_WINRT_NO_GUI_ERROR("cvStartWindowThread");
|
||||
return cv::Error::StsNotImplemented;
|
||||
}
|
||||
@@ -0,0 +1,366 @@
|
||||
// highgui to XAML bridge for OpenCV
|
||||
|
||||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// (3 - clause BSD License)
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that
|
||||
// the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
|
||||
// following disclaimer.
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
|
||||
// following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or
|
||||
// promote products derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
// PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING
|
||||
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
#include "opencv2\highgui\highgui_winrt.hpp"
|
||||
#include "window_winrt_bridge.hpp"
|
||||
|
||||
#include <collection.h>
|
||||
#include <Robuffer.h> // Windows::Storage::Streams::IBufferByteAccess
|
||||
|
||||
using namespace Microsoft::WRL; // ComPtr
|
||||
using namespace Windows::Storage::Streams; // IBuffer
|
||||
using namespace Windows::UI::Xaml;
|
||||
using namespace Windows::UI::Xaml::Controls;
|
||||
using namespace Windows::UI::Xaml::Media::Imaging;
|
||||
|
||||
using namespace ::std;
|
||||
|
||||
/***************************** Constants ****************************************/
|
||||
|
||||
// Default markup for the container content allowing for proper components placement
|
||||
const Platform::String^ CvWindow::markupContent =
|
||||
"<Page \n" \
|
||||
" xmlns = \"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n" \
|
||||
" xmlns:x = \"http://schemas.microsoft.com/winfx/2006/xaml\" >\n" \
|
||||
" <StackPanel Name=\"Container\" Orientation=\"Vertical\" Width=\"Auto\" Height=\"Auto\" HorizontalAlignment=\"Left\" VerticalAlignment=\"Top\" Visibility=\"Visible\">\n" \
|
||||
" <Image Name=\"cvImage\" Width=\"Auto\" Height=\"Auto\" Margin=\"10\" HorizontalAlignment=\"Left\" VerticalAlignment=\"Top\" Visibility=\"Visible\"/>\n" \
|
||||
" <StackPanel Name=\"cvTrackbar\" Height=\"Auto\" Width=\"Auto\" Orientation=\"Vertical\" Visibility=\"Visible\"/>\n" \
|
||||
" <StackPanel Name=\"cvButton\" Height=\"Auto\" Width=\"Auto\" Orientation=\"Horizontal\" Visibility=\"Visible\"/>\n" \
|
||||
" </StackPanel>\n" \
|
||||
"</Page>";
|
||||
|
||||
const double CvWindow::sliderDefaultWidth = 100;
|
||||
|
||||
/***************************** HighguiBridge class ******************************/
|
||||
|
||||
HighguiBridge& HighguiBridge::getInstance()
|
||||
{
|
||||
static HighguiBridge instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
void HighguiBridge::setContainer(Windows::UI::Xaml::Controls::Panel^ container_)
|
||||
{
|
||||
this->container = container_;
|
||||
}
|
||||
|
||||
CvWindow* HighguiBridge::findWindowByName(cv::String name)
|
||||
{
|
||||
auto search = windowsMap->find(name);
|
||||
if (search != windowsMap->end()) {
|
||||
return search->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CvTrackbar* HighguiBridge::findTrackbarByName(cv::String trackbar_name, cv::String window_name)
|
||||
{
|
||||
CvWindow* window = findWindowByName(window_name);
|
||||
|
||||
if (window)
|
||||
return window->findTrackbarByName(trackbar_name);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Platform::String^ HighguiBridge::convertString(cv::String name)
|
||||
{
|
||||
auto data = name.c_str();
|
||||
int bufferSize = MultiByteToWideChar(CP_UTF8, 0, data, -1, nullptr, 0);
|
||||
auto wide = std::make_unique<wchar_t[]>(bufferSize);
|
||||
if (0 == MultiByteToWideChar(CP_UTF8, 0, data, -1, wide.get(), bufferSize))
|
||||
return nullptr;
|
||||
|
||||
std::wstring* stdStr = new std::wstring(wide.get());
|
||||
return ref new Platform::String(stdStr->c_str());
|
||||
}
|
||||
|
||||
void HighguiBridge::cleanContainer()
|
||||
{
|
||||
container->Children->Clear();
|
||||
}
|
||||
|
||||
void HighguiBridge::showWindow(CvWindow* window)
|
||||
{
|
||||
currentWindow = window;
|
||||
cleanContainer();
|
||||
HighguiBridge::getInstance().container->Children->Append(window->getPage());
|
||||
}
|
||||
|
||||
CvWindow* HighguiBridge::namedWindow(cv::String name) {
|
||||
|
||||
CvWindow* window = HighguiBridge::getInstance().findWindowByName(name.c_str());
|
||||
if (!window)
|
||||
{
|
||||
window = createWindow(name);
|
||||
}
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
void HighguiBridge::destroyWindow(cv::String name)
|
||||
{
|
||||
auto window = windowsMap->find(name);
|
||||
if (window != windowsMap->end())
|
||||
{
|
||||
// Check if deleted window is the one currently displayed
|
||||
// and clear container if this is the case
|
||||
if (window->second == currentWindow)
|
||||
{
|
||||
cleanContainer();
|
||||
}
|
||||
|
||||
windowsMap->erase(window);
|
||||
}
|
||||
}
|
||||
|
||||
void HighguiBridge::destroyAllWindows()
|
||||
{
|
||||
cleanContainer();
|
||||
windowsMap->clear();
|
||||
}
|
||||
|
||||
CvWindow* HighguiBridge::createWindow(cv::String name)
|
||||
{
|
||||
CvWindow* window = new CvWindow(name);
|
||||
windowsMap->insert(std::pair<cv::String, CvWindow*>(name, window));
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
/***************************** CvTrackbar class *********************************/
|
||||
|
||||
CvTrackbar::CvTrackbar(cv::String name, Slider^ slider, CvWindow* parent) : name(name), slider(slider), parent(parent) {}
|
||||
|
||||
CvTrackbar::~CvTrackbar() {}
|
||||
|
||||
void CvTrackbar::setPosition(double pos)
|
||||
{
|
||||
if (pos < 0)
|
||||
pos = 0;
|
||||
|
||||
if (pos > slider->Maximum)
|
||||
pos = slider->Maximum;
|
||||
|
||||
slider->Value = pos;
|
||||
}
|
||||
|
||||
void CvTrackbar::setMaxPosition(double pos)
|
||||
{
|
||||
//slider->Minimum is initialized with 0
|
||||
if (pos < slider->Minimum)
|
||||
pos = slider->Minimum;
|
||||
|
||||
slider->Maximum = pos;
|
||||
}
|
||||
|
||||
void CvTrackbar::setMinPosition(double pos)
|
||||
{
|
||||
if (pos < 0)
|
||||
pos = 0;
|
||||
//Min is always less than Max.
|
||||
if (pos > slider->Maximum)
|
||||
pos = slider->Maximum;
|
||||
slider->Minimum = pos;
|
||||
}
|
||||
|
||||
void CvTrackbar::setSlider(Slider^ slider_) {
|
||||
if (slider_)
|
||||
this->slider = slider_;
|
||||
}
|
||||
|
||||
double CvTrackbar::getPosition()
|
||||
{
|
||||
return slider->Value;
|
||||
}
|
||||
|
||||
double CvTrackbar::getMaxPosition()
|
||||
{
|
||||
return slider->Maximum;
|
||||
}
|
||||
|
||||
double CvTrackbar::getMinPosition()
|
||||
{
|
||||
return slider->Minimum;
|
||||
}
|
||||
|
||||
Slider^ CvTrackbar::getSlider()
|
||||
{
|
||||
return slider;
|
||||
}
|
||||
|
||||
/***************************** CvWindow class ***********************************/
|
||||
|
||||
CvWindow::CvWindow(cv::String name, int flags) : name(name)
|
||||
{
|
||||
CV_UNUSED(flags);
|
||||
this->page = (Page^)Windows::UI::Xaml::Markup::XamlReader::Load(const_cast<Platform::String^>(markupContent));
|
||||
this->sliderMap = new std::map<cv::String, CvTrackbar*>();
|
||||
|
||||
sliderPanel = (Panel^)page->FindName("cvTrackbar");
|
||||
imageControl = (Image^)page->FindName("cvImage");
|
||||
buttonPanel = (Panel^)page->FindName("cvButton");
|
||||
|
||||
// Required to adapt controls to the size of the image.
|
||||
// System calculates image control width first, after that we can
|
||||
// update other controls
|
||||
imageControl->Loaded += ref new Windows::UI::Xaml::RoutedEventHandler(
|
||||
[=](Platform::Object^ sender,
|
||||
Windows::UI::Xaml::RoutedEventArgs^ e)
|
||||
{
|
||||
// Need to update sliders with appropriate width
|
||||
for (auto iter = sliderMap->begin(); iter != sliderMap->end(); ++iter) {
|
||||
iter->second->getSlider()->Width = imageControl->ActualWidth;
|
||||
}
|
||||
|
||||
// Need to update buttons with appropriate width
|
||||
// TODO: implement when adding buttons
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
CvWindow::~CvWindow() {}
|
||||
|
||||
void CvWindow::createSlider(cv::String name_, int* val, int count, CvTrackbarCallback2 on_notify, void* userdata)
|
||||
{
|
||||
CV_UNUSED(userdata);
|
||||
CvTrackbar* trackbar = findTrackbarByName(name_);
|
||||
|
||||
// Creating slider if name is new or reusing the existing one
|
||||
Slider^ slider = !trackbar ? ref new Slider() : trackbar->getSlider();
|
||||
|
||||
slider->Header = HighguiBridge::getInstance().convertString(name_);
|
||||
|
||||
// Making slider the same size as the image control or setting minimal size.
|
||||
// This is added to cover potential edge cases because:
|
||||
// 1. Fist clause will not be true until the second call to any container-updating API
|
||||
// e.g. cv::createTrackbar, cv:imshow or cv::namedWindow
|
||||
// 2. Second clause will work but should be immediately overridden by Image->Loaded callback,
|
||||
// see CvWindow ctor.
|
||||
if (this->imageControl->ActualWidth > 0) {
|
||||
// One would use double.NaN for auto-stretching but there is no such constant in C++/CX
|
||||
// see https://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.frameworkelement.width
|
||||
slider->Width = this->imageControl->ActualWidth;
|
||||
} else {
|
||||
// This value would never be used/seen on the screen unless there is something wrong with the image.
|
||||
// Although this code actually gets called, slider width will be overridden in the callback after
|
||||
// Image control is loaded. See callback implementation in CvWindow ctor.
|
||||
slider->Width = sliderDefaultWidth;
|
||||
}
|
||||
slider->Value = val ? *val : 0;
|
||||
slider->Maximum = count;
|
||||
slider->Visibility = Windows::UI::Xaml::Visibility::Visible;
|
||||
slider->Margin = Windows::UI::Xaml::ThicknessHelper::FromLengths(10, 10, 10, 0);
|
||||
slider->HorizontalAlignment = Windows::UI::Xaml::HorizontalAlignment::Left;
|
||||
|
||||
if (!trackbar)
|
||||
{
|
||||
if (!sliderPanel) return;
|
||||
|
||||
// Adding slider to the list for current window
|
||||
CvTrackbar* trackbar_ = new CvTrackbar(name_, slider, this);
|
||||
trackbar_->callback = on_notify;
|
||||
slider->ValueChanged +=
|
||||
ref new Controls::Primitives::RangeBaseValueChangedEventHandler(
|
||||
[=](Platform::Object^ sender,
|
||||
Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventArgs^ e)
|
||||
{
|
||||
Slider^ slider = (Slider^)sender;
|
||||
trackbar_->callback((int)slider->Value, nullptr);
|
||||
});
|
||||
this->sliderMap->insert(std::pair<cv::String, CvTrackbar*>(name_, trackbar_));
|
||||
|
||||
// Adding slider to the window
|
||||
sliderPanel->Children->Append(slider);
|
||||
}
|
||||
}
|
||||
|
||||
CvTrackbar* CvWindow::findTrackbarByName(cv::String name_)
|
||||
{
|
||||
auto search = sliderMap->find(name_);
|
||||
if (search != sliderMap->end()) {
|
||||
return search->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CvWindow::updateImage(CvMat* src)
|
||||
{
|
||||
if (!imageControl) return;
|
||||
|
||||
this->imageData = src;
|
||||
this->imageWidth = src->width;
|
||||
|
||||
// Create the WriteableBitmap
|
||||
WriteableBitmap^ bitmap = ref new WriteableBitmap(src->cols, src->rows);
|
||||
|
||||
// Get access to the pixels
|
||||
IBuffer^ buffer = bitmap->PixelBuffer;
|
||||
unsigned char* dstPixels;
|
||||
|
||||
// Obtain IBufferByteAccess
|
||||
ComPtr<IBufferByteAccess> pBufferByteAccess;
|
||||
ComPtr<IInspectable> pBuffer((IInspectable*)buffer);
|
||||
pBuffer.As(&pBufferByteAccess);
|
||||
|
||||
// Get pointer to pixel bytes
|
||||
pBufferByteAccess->Buffer(&dstPixels);
|
||||
memcpy(dstPixels, src->data.ptr, CV_ELEM_SIZE(src->type) * src->cols*src->rows);
|
||||
|
||||
// Set the bitmap to the Image element
|
||||
imageControl->Source = bitmap;
|
||||
}
|
||||
|
||||
Page^ CvWindow::getPage()
|
||||
{
|
||||
return page;
|
||||
}
|
||||
|
||||
//TODO: prototype, not in use yet
|
||||
void CvWindow::createButton(cv::String name_)
|
||||
{
|
||||
if (!buttonPanel) return;
|
||||
|
||||
Button^ b = ref new Button();
|
||||
b->Content = HighguiBridge::getInstance().convertString(name_);
|
||||
b->Width = 260;
|
||||
b->Height = 80;
|
||||
b->Click += ref new Windows::UI::Xaml::RoutedEventHandler(
|
||||
[=](Platform::Object^ sender,
|
||||
Windows::UI::Xaml::RoutedEventArgs^ e)
|
||||
{
|
||||
Button^ button = (Button^)sender;
|
||||
// TODO: more logic here...
|
||||
});
|
||||
|
||||
buttonPanel->Children->Append(b);
|
||||
}
|
||||
|
||||
// end
|
||||
@@ -0,0 +1,234 @@
|
||||
// highgui to XAML bridge for OpenCV
|
||||
|
||||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// (3 - clause BSD License)
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that
|
||||
// the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
|
||||
// following disclaimer.
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
|
||||
// following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or
|
||||
// promote products derived from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
// PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING
|
||||
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <opencv2\core.hpp>
|
||||
|
||||
using namespace Windows::UI::Xaml::Controls;
|
||||
|
||||
class CvWindow;
|
||||
class CvTrackbar;
|
||||
|
||||
class HighguiBridge
|
||||
{
|
||||
public:
|
||||
|
||||
/** @brief Instantiates a Highgui singleton (Meyers type).
|
||||
|
||||
The function Instantiates a Highgui singleton (Meyers type) and returns reference to that instance.
|
||||
*/
|
||||
static HighguiBridge& getInstance();
|
||||
|
||||
/** @brief Finds window by name and returns the reference to it.
|
||||
|
||||
@param name Name of the window.
|
||||
|
||||
The function finds window by name and returns the reference to it. Returns nullptr
|
||||
if window with specified name is not found or name argument is null.
|
||||
*/
|
||||
CvWindow* findWindowByName(cv::String name);
|
||||
|
||||
/** @brief Returns reference to the trackbar(slider) registered within window with a provided name.
|
||||
|
||||
@param name Name of the window.
|
||||
|
||||
The function returns reference to the trackbar(slider) registered within window with a provided name.
|
||||
Returns nullptr if trackbar with specified name is not found or window reference is nullptr.
|
||||
*/
|
||||
CvTrackbar* findTrackbarByName(cv::String trackbarName, cv::String windowName);
|
||||
|
||||
/** @brief Converts cv::String to Platform::String.
|
||||
|
||||
@param name String to convert.
|
||||
|
||||
The function converts cv::String to Platform::String.
|
||||
Returns nullptr if conversion fails.
|
||||
*/
|
||||
Platform::String^ convertString(cv::String name);
|
||||
|
||||
/** @brief Creates window if there is no window with this name, otherwise returns existing window.
|
||||
|
||||
@param name Window name.
|
||||
|
||||
The function creates window if there is no window with this name, otherwise returns existing window.
|
||||
*/
|
||||
CvWindow* namedWindow(cv::String name);
|
||||
|
||||
/** @brief Shows provided window.
|
||||
|
||||
The function shows provided window: makes provided window current, removes current container
|
||||
contents and shows current window by putting it as a container content.
|
||||
*/
|
||||
void showWindow(CvWindow* window);
|
||||
|
||||
/** @brief Destroys window if there exists window with this name, otherwise does nothing.
|
||||
|
||||
@param name Window name.
|
||||
|
||||
The function destroys window if there exists window with this name, otherwise does nothing.
|
||||
If window being destroyed is the current one, it will be hidden by clearing the window container.
|
||||
*/
|
||||
void destroyWindow(cv::String name);
|
||||
|
||||
/** @brief Destroys all windows.
|
||||
|
||||
The function destroys all windows.
|
||||
*/
|
||||
void destroyAllWindows();
|
||||
|
||||
/** @brief Assigns container used to display windows.
|
||||
|
||||
@param _container Container reference.
|
||||
|
||||
The function assigns container used to display windows.
|
||||
*/
|
||||
void setContainer(Windows::UI::Xaml::Controls::Panel^ _container);
|
||||
|
||||
private:
|
||||
|
||||
// Meyers singleton
|
||||
HighguiBridge(const HighguiBridge &);
|
||||
HighguiBridge() {
|
||||
windowsMap = new std::map<cv::String, CvWindow*>();
|
||||
};
|
||||
|
||||
/** @brief Creates window if there is no window with this name.
|
||||
|
||||
@param name Window name.
|
||||
|
||||
The function creates window if there is no window with this name.
|
||||
*/
|
||||
CvWindow* createWindow(cv::String name);
|
||||
|
||||
/** @brief Cleans current container contents.
|
||||
|
||||
The function cleans current container contents.
|
||||
*/
|
||||
void cleanContainer();
|
||||
|
||||
// see https://msdn.microsoft.com/en-US/library/windows/apps/xaml/hh700103.aspx
|
||||
// see https://msdn.microsoft.com/ru-ru/library/windows.foundation.collections.aspx
|
||||
std::map<cv::String, CvWindow*>* windowsMap;
|
||||
CvWindow* currentWindow;
|
||||
|
||||
// Holds current container/content to manipulate with
|
||||
Windows::UI::Xaml::Controls::Panel^ container;
|
||||
};
|
||||
|
||||
class CvTrackbar
|
||||
{
|
||||
public:
|
||||
CvTrackbar(cv::String name, Slider^ slider, CvWindow* parent);
|
||||
~CvTrackbar();
|
||||
|
||||
double getPosition();
|
||||
void setPosition(double pos);
|
||||
double getMaxPosition();
|
||||
void setMaxPosition(double pos);
|
||||
double getMinPosition();
|
||||
void setMinPosition(double pos);
|
||||
Slider^ getSlider();
|
||||
void setSlider(Slider^ pos);
|
||||
|
||||
CvTrackbarCallback2 callback;
|
||||
|
||||
private:
|
||||
cv::String name;
|
||||
Slider^ slider;
|
||||
CvWindow* parent;
|
||||
};
|
||||
|
||||
class CvWindow
|
||||
{
|
||||
public:
|
||||
CvWindow(cv::String name, int flag = CV_WINDOW_NORMAL);
|
||||
~CvWindow();
|
||||
|
||||
/** @brief NOTE: prototype.
|
||||
|
||||
Should create button if there is no button with this name already.
|
||||
*/
|
||||
void createButton(cv::String name);
|
||||
|
||||
/** @brief Creates slider if there is no slider with this name already.
|
||||
|
||||
The function creates slider if there is no slider with this name already OR resets
|
||||
provided values for the existing one.
|
||||
*/
|
||||
void createSlider(cv::String name, int* val, int count, CvTrackbarCallback2 on_notify, void* userdata);
|
||||
|
||||
/** @brief Updates window image.
|
||||
|
||||
@param src Image data object reference.
|
||||
|
||||
The function updates window image. If argument is null or image control is not found - does nothing.
|
||||
*/
|
||||
void updateImage(CvMat* arr);
|
||||
|
||||
/** @brief Returns reference to the trackbar(slider) registered within provided window.
|
||||
|
||||
@param name Name of the window.
|
||||
|
||||
The function returns reference to the trackbar(slider) registered within provided window.
|
||||
Returns nullptr if trackbar with specified name is not found or window reference is nullptr.
|
||||
*/
|
||||
CvTrackbar* findTrackbarByName(cv::String name);
|
||||
Page^ getPage();
|
||||
|
||||
private:
|
||||
cv::String name;
|
||||
|
||||
// Holds image data in CV format
|
||||
CvMat* imageData;
|
||||
|
||||
// Map of all sliders assigned to this window
|
||||
std::map<cv::String, CvTrackbar*>* sliderMap;
|
||||
|
||||
// Window contents holder
|
||||
Page^ page;
|
||||
|
||||
// Image control displayed by this window
|
||||
Image^ imageControl;
|
||||
|
||||
// Container for sliders
|
||||
Panel^ sliderPanel;
|
||||
|
||||
// Container for buttons
|
||||
// TODO: prototype, not available via API
|
||||
Panel^ buttonPanel;
|
||||
|
||||
// Holds image width to arrange other UI elements.
|
||||
// Required since imageData->width value gets recalculated when processing
|
||||
int imageWidth;
|
||||
|
||||
// Default markup for the container content allowing for proper components placement
|
||||
static const Platform::String^ markupContent;
|
||||
|
||||
// Default Slider size, fallback solution for unexpected edge cases
|
||||
static const double sliderDefaultWidth;
|
||||
};
|
||||
@@ -0,0 +1,258 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
namespace opencv_test { namespace {
|
||||
|
||||
inline void verify_size(const std::string &nm, const cv::Mat &img)
|
||||
{
|
||||
EXPECT_NO_THROW(imshow(nm, img));
|
||||
EXPECT_EQ(-1, waitKey(200));
|
||||
|
||||
// see https://github.com/opencv/opencv/issues/25550
|
||||
// Wayland backend is not supported getWindowImageRect().
|
||||
string framework;
|
||||
EXPECT_NO_THROW(framework = currentUIFramework());
|
||||
if(framework == "WAYLAND")
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Rect rc;
|
||||
EXPECT_NO_THROW(rc = getWindowImageRect(nm));
|
||||
EXPECT_EQ(rc.size(), img.size());
|
||||
}
|
||||
|
||||
#if (!defined(ENABLE_PLUGINS) \
|
||||
&& !defined HAVE_GTK \
|
||||
&& !defined HAVE_QT \
|
||||
&& !defined HAVE_WIN32UI \
|
||||
&& !defined HAVE_COCOA \
|
||||
&& !defined HAVE_WAYLAND \
|
||||
)
|
||||
TEST(Highgui_GUI, DISABLED_regression)
|
||||
#else
|
||||
TEST(Highgui_GUI, regression)
|
||||
#endif
|
||||
{
|
||||
const std::string window_name("opencv_highgui_test_window");
|
||||
const cv::Size image_size(800, 600);
|
||||
|
||||
EXPECT_NO_THROW(destroyAllWindows());
|
||||
ASSERT_NO_THROW(namedWindow(window_name));
|
||||
const vector<int> channels = {1, 3, 4};
|
||||
const vector<int> depths = {CV_8U, CV_8S, CV_16U, CV_16S, CV_32F, CV_64F};
|
||||
for(int cn : channels)
|
||||
{
|
||||
SCOPED_TRACE(cn);
|
||||
for(int depth : depths)
|
||||
{
|
||||
SCOPED_TRACE(depth);
|
||||
double min_val = 0.;
|
||||
double max_val = 256.;
|
||||
switch(depth)
|
||||
{
|
||||
case CV_8S:
|
||||
min_val = static_cast<double>(-0x7F);
|
||||
max_val = static_cast<double>(0x7F + 1);
|
||||
break;
|
||||
case CV_16S:
|
||||
min_val = static_cast<double>(-0x7FFF);
|
||||
max_val = static_cast<double>(0x7FFF + 1);
|
||||
break;
|
||||
case CV_16U:
|
||||
max_val = static_cast<double>(0xFFFF + 1);
|
||||
break;
|
||||
case CV_32F:
|
||||
case CV_64F:
|
||||
max_val = 1.0;
|
||||
break;
|
||||
}
|
||||
Mat m = cvtest::randomMat(TS::ptr()->get_rng(), image_size, CV_MAKE_TYPE(depth, cn), min_val, max_val, false);
|
||||
verify_size(window_name, m);
|
||||
|
||||
Mat bgr(image_size, CV_MAKE_TYPE(depth, cn));
|
||||
int b_g = image_size.width / 3, g_r = b_g * 2;
|
||||
if (cn > 1)
|
||||
{
|
||||
bgr.colRange(0, b_g).setTo(cv::Scalar(max_val, min_val, min_val));
|
||||
bgr.colRange(b_g, g_r).setTo(cv::Scalar(min_val, max_val, min_val));
|
||||
bgr.colRange(g_r, image_size.width).setTo(cv::Scalar(min_val, min_val, max_val));
|
||||
}
|
||||
else
|
||||
{
|
||||
bgr.colRange(0, b_g).setTo(cv::Scalar::all(min_val));
|
||||
bgr.colRange(b_g, g_r).setTo(cv::Scalar::all((min_val + max_val) / 2));
|
||||
bgr.colRange(g_r, image_size.width).setTo(cv::Scalar::all(max_val));
|
||||
}
|
||||
verify_size(window_name, bgr);
|
||||
}
|
||||
}
|
||||
EXPECT_NO_THROW(destroyAllWindows());
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
static void Foo(int, void* counter)
|
||||
{
|
||||
if (counter)
|
||||
{
|
||||
int *counter_int = static_cast<int*>(counter);
|
||||
(*counter_int)++;
|
||||
}
|
||||
}
|
||||
|
||||
#if (!defined(ENABLE_PLUGINS) \
|
||||
&& !defined HAVE_GTK \
|
||||
&& !defined HAVE_QT \
|
||||
&& !defined HAVE_WIN32UI \
|
||||
&& !defined HAVE_WAYLAND \
|
||||
) \
|
||||
|| defined(__APPLE__) /* test fails on Mac (cocoa) */ \
|
||||
|| defined HAVE_FRAMEBUFFER /* trackbar is not supported */
|
||||
TEST(Highgui_GUI, DISABLED_trackbar_unsafe)
|
||||
#else
|
||||
TEST(Highgui_GUI, trackbar_unsafe)
|
||||
#endif
|
||||
{
|
||||
int value = 50;
|
||||
int callback_count = 0;
|
||||
const std::string window_name("trackbar_test_window");
|
||||
const std::string trackbar_name("trackbar");
|
||||
|
||||
EXPECT_NO_THROW(destroyAllWindows());
|
||||
ASSERT_NO_THROW(namedWindow(window_name));
|
||||
EXPECT_EQ((int)1, createTrackbar(trackbar_name, window_name, &value, 100, Foo, &callback_count));
|
||||
EXPECT_EQ(value, getTrackbarPos(trackbar_name, window_name));
|
||||
EXPECT_GE(callback_count, 0);
|
||||
EXPECT_LE(callback_count, 1);
|
||||
int callback_count_base = callback_count;
|
||||
EXPECT_NO_THROW(setTrackbarPos(trackbar_name, window_name, 90));
|
||||
EXPECT_EQ(callback_count_base + 1, callback_count);
|
||||
EXPECT_EQ(90, value);
|
||||
EXPECT_EQ(90, getTrackbarPos(trackbar_name, window_name));
|
||||
EXPECT_NO_THROW(destroyAllWindows());
|
||||
}
|
||||
|
||||
static
|
||||
void testTrackbarCallback(int pos, void* param)
|
||||
{
|
||||
CV_Assert(param);
|
||||
int* status = (int*)param;
|
||||
status[0] = pos;
|
||||
status[1]++;
|
||||
}
|
||||
|
||||
#if (!defined(ENABLE_PLUGINS) \
|
||||
&& !defined HAVE_GTK \
|
||||
&& !defined HAVE_QT \
|
||||
&& !defined HAVE_WIN32UI \
|
||||
&& !defined HAVE_WAYLAND \
|
||||
) \
|
||||
|| defined(__APPLE__) /* test fails on Mac (cocoa) */ \
|
||||
|| defined HAVE_FRAMEBUFFER /* trackbar is not supported */
|
||||
TEST(Highgui_GUI, DISABLED_trackbar)
|
||||
#else
|
||||
TEST(Highgui_GUI, trackbar)
|
||||
#endif
|
||||
{
|
||||
int status[2] = {-1, 0}; // pos, counter
|
||||
const std::string window_name("trackbar_test_window");
|
||||
const std::string trackbar_name("trackbar");
|
||||
|
||||
EXPECT_NO_THROW(destroyAllWindows());
|
||||
ASSERT_NO_THROW(namedWindow(window_name));
|
||||
EXPECT_EQ((int)1, createTrackbar(trackbar_name, window_name, NULL, 100, testTrackbarCallback, status));
|
||||
EXPECT_EQ(0, getTrackbarPos(trackbar_name, window_name));
|
||||
int callback_count = status[1];
|
||||
EXPECT_GE(callback_count, 0);
|
||||
EXPECT_LE(callback_count, 1);
|
||||
int callback_count_base = callback_count;
|
||||
EXPECT_NO_THROW(setTrackbarPos(trackbar_name, window_name, 90));
|
||||
callback_count = status[1];
|
||||
EXPECT_EQ(callback_count_base + 1, callback_count);
|
||||
int value = status[0];
|
||||
EXPECT_EQ(90, value);
|
||||
EXPECT_EQ(90, getTrackbarPos(trackbar_name, window_name));
|
||||
EXPECT_NO_THROW(destroyAllWindows());
|
||||
}
|
||||
|
||||
// See https://github.com/opencv/opencv/issues/25560
|
||||
#if (!defined(ENABLE_PLUGINS) \
|
||||
&& !defined HAVE_GTK \
|
||||
&& !defined HAVE_QT \
|
||||
&& !defined HAVE_WIN32UI \
|
||||
&& !defined HAVE_WAYLAND)
|
||||
TEST(Highgui_GUI, DISABLED_small_width_image)
|
||||
#else
|
||||
TEST(Highgui_GUI, small_width_image)
|
||||
#endif
|
||||
{
|
||||
const std::string window_name("trackbar_test_window");
|
||||
cv::Mat src(1,1,CV_8UC3,cv::Scalar(0));
|
||||
EXPECT_NO_THROW(destroyAllWindows());
|
||||
ASSERT_NO_THROW(namedWindow(window_name));
|
||||
ASSERT_NO_THROW(imshow(window_name, src));
|
||||
EXPECT_NO_THROW(waitKey(10));
|
||||
EXPECT_NO_THROW(destroyAllWindows());
|
||||
}
|
||||
|
||||
TEST(Highgui_GUI, currentUIFramework)
|
||||
{
|
||||
auto framework = currentUIFramework();
|
||||
std::cout << "UI framework: \"" << framework << "\"" << std::endl;
|
||||
#if (!defined(ENABLE_PLUGINS) \
|
||||
&& !defined HAVE_GTK \
|
||||
&& !defined HAVE_QT \
|
||||
&& !defined HAVE_WIN32UI \
|
||||
&& !defined HAVE_COCOA \
|
||||
&& !defined HAVE_WAYLAND \
|
||||
)
|
||||
EXPECT_TRUE(framework.empty());
|
||||
#elif !defined(ENABLE_PLUGINS)
|
||||
EXPECT_GT(framework.size(), 0); // builtin backends
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
}} // namespace
|
||||
@@ -0,0 +1,10 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
#if defined(HAVE_HPX)
|
||||
#include <hpx/hpx_main.hpp>
|
||||
#endif
|
||||
|
||||
CV_TEST_MAIN("highgui")
|
||||
@@ -0,0 +1,5 @@
|
||||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
#include "opencv2/ts.hpp"
|
||||
#include "opencv2/highgui.hpp"
|
||||