chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:06:04 +08:00
commit 86c9b1c39f
7743 changed files with 3316339 additions and 0 deletions
+333
View File
@@ -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()
+49
View File
@@ -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()
+48
View File
@@ -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)
+61
View File
@@ -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()
+39
View File
@@ -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;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 371 KiB

+830
View File
@@ -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
![image](pics/qtgui.png)
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
View File
@@ -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);
}
}
}
+72
View File
@@ -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
+21
View File
@@ -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
+181
View File
@@ -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
+140
View File
@@ -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
+48
View File
@@ -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
Binary file not shown.

After

Width:  |  Height:  |  Size: 832 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 799 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 522 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 531 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 561 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 761 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 536 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 688 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 579 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 914 B

Binary file not shown.

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/
+72
View File
@@ -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
+294
View File
@@ -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
+196
View File
@@ -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_ */
+25
View File
@@ -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
+198
View File
@@ -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
+221
View File
@@ -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);
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+593
View File
@@ -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
+15
View File
@@ -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>
File diff suppressed because it is too large Load Diff
+798
View File
@@ -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, &current);
}
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::
+135
View File
@@ -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
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+290
View File
@@ -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;
}
+366
View File
@@ -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
+234
View File
@@ -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;
};
+258
View File
@@ -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
+10
View File
@@ -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")
+5
View File
@@ -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"