Merge pull request #4155 from MSOpenTech:highgui_contrib
This commit is contained in:
commit
d0c43f16e0
@ -29,6 +29,9 @@ file(GLOB highgui_ext_hdrs
|
|||||||
"${CMAKE_CURRENT_LIST_DIR}/include/opencv2/${name}/*.hpp"
|
"${CMAKE_CURRENT_LIST_DIR}/include/opencv2/${name}/*.hpp"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/include/opencv2/${name}/*.h")
|
"${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")
|
||||||
|
|
||||||
if(HAVE_QT5)
|
if(HAVE_QT5)
|
||||||
set(CMAKE_AUTOMOC ON)
|
set(CMAKE_AUTOMOC ON)
|
||||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
@ -66,12 +69,23 @@ elseif(HAVE_QT)
|
|||||||
if(${_have_flag})
|
if(${_have_flag})
|
||||||
set_source_files_properties(${_RCC_OUTFILES} PROPERTIES COMPILE_FLAGS -Wno-missing-declarations)
|
set_source_files_properties(${_RCC_OUTFILES} PROPERTIES COMPILE_FLAGS -Wno-missing-declarations)
|
||||||
endif()
|
endif()
|
||||||
elseif(WINRT AND NOT WINRT_8_0)
|
elseif(WINRT)
|
||||||
|
if(NOT WINRT_8_0)
|
||||||
# Dependencies used by the implementation referenced
|
# Dependencies used by the implementation referenced
|
||||||
# below are not available on WinRT 8.0.
|
# below are not available on WinRT 8.0.
|
||||||
# Enabling it for WiRT 8.1+ only.
|
# Enabling it for WiRT 8.1+ only.
|
||||||
status(" ${name}: WinRT detected")
|
|
||||||
list(APPEND highgui_srcs ${CMAKE_CURRENT_LIST_DIR}/src/window_winrt.cpp)
|
# WinRT 8.1+ detected. Adding WinRT API header.
|
||||||
|
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
|
# libraries below are neither available nor required
|
||||||
# on ARM devices and/or Windows Phone
|
# on ARM devices and/or Windows Phone
|
||||||
@ -81,6 +95,10 @@ elseif(WINRT AND NOT WINRT_8_0)
|
|||||||
status(" ${name}: Windows Phone detected")
|
status(" ${name}: Windows Phone detected")
|
||||||
elseif(OpenCV_ARCH STREQUAL "ARM")
|
elseif(OpenCV_ARCH STREQUAL "ARM")
|
||||||
status(" ${name}: ARM detected")
|
status(" ${name}: ARM detected")
|
||||||
|
if(WINRT_STORE)
|
||||||
|
list(REMOVE_ITEM HIGHGUI_LIBRARIES "ws2_32")
|
||||||
|
status(" ${name}: Removing 'ws2_32.lib'")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
status(" ${name}: Removing 'comctl32.lib, gdi32.lib, ole32.lib, setupapi.lib'")
|
status(" ${name}: Removing 'comctl32.lib, gdi32.lib, ole32.lib, setupapi.lib'")
|
||||||
status(" ${name}: Leaving '${HIGHGUI_LIBRARIES}'")
|
status(" ${name}: Leaving '${HIGHGUI_LIBRARIES}'")
|
||||||
|
@ -79,7 +79,7 @@ It provides easy interface to:
|
|||||||
attached to the control panel is a trackbar, or the control panel is empty, a new buttonbar is
|
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.
|
created. Then, a new button is attached to it.
|
||||||
|
|
||||||
See below the example used to generate the figure: :
|
See below the example used to generate the figure:
|
||||||
@code
|
@code
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
int value = 50;
|
int value = 50;
|
||||||
@ -122,6 +122,45 @@ It provides easy interface to:
|
|||||||
}
|
}
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
|
|
||||||
|
@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);
|
||||||
|
cvtColor(image, converted, CV_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
|
||||||
|
|
||||||
@defgroup highgui_c C API
|
@defgroup highgui_c C API
|
||||||
@}
|
@}
|
||||||
*/
|
*/
|
||||||
|
48
modules/highgui/include/opencv2/highgui/highgui_winrt.hpp
Normal file
48
modules/highgui/include/opencv2/highgui/highgui_winrt.hpp
Normal file
@ -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
|
@ -95,16 +95,18 @@
|
|||||||
#define CV_WINDOW_MAGIC_VAL 0x00420042
|
#define CV_WINDOW_MAGIC_VAL 0x00420042
|
||||||
#define CV_TRACKBAR_MAGIC_VAL 0x00420043
|
#define CV_TRACKBAR_MAGIC_VAL 0x00420043
|
||||||
|
|
||||||
//Yannick Verdie 2010
|
//Yannick Verdie 2010, Max Kostin 2015
|
||||||
void cvSetModeWindow_W32(const char* name, double prop_value);
|
void cvSetModeWindow_W32(const char* name, double prop_value);
|
||||||
void cvSetModeWindow_GTK(const char* name, double prop_value);
|
void cvSetModeWindow_GTK(const char* name, double prop_value);
|
||||||
void cvSetModeWindow_CARBON(const char* name, double prop_value);
|
void cvSetModeWindow_CARBON(const char* name, double prop_value);
|
||||||
void cvSetModeWindow_COCOA(const char* name, double prop_value);
|
void cvSetModeWindow_COCOA(const char* name, double prop_value);
|
||||||
|
void cvSetModeWindow_WinRT(const char* name, double prop_value);
|
||||||
|
|
||||||
double cvGetModeWindow_W32(const char* name);
|
double cvGetModeWindow_W32(const char* name);
|
||||||
double cvGetModeWindow_GTK(const char* name);
|
double cvGetModeWindow_GTK(const char* name);
|
||||||
double cvGetModeWindow_CARBON(const char* name);
|
double cvGetModeWindow_CARBON(const char* name);
|
||||||
double cvGetModeWindow_COCOA(const char* name);
|
double cvGetModeWindow_COCOA(const char* name);
|
||||||
|
double cvGetModeWindow_WinRT(const char* name);
|
||||||
|
|
||||||
double cvGetPropWindowAutoSize_W32(const char* name);
|
double cvGetPropWindowAutoSize_W32(const char* name);
|
||||||
double cvGetPropWindowAutoSize_GTK(const char* name);
|
double cvGetPropWindowAutoSize_GTK(const char* name);
|
||||||
|
@ -65,7 +65,10 @@ CV_IMPL void cvSetWindowProperty(const char* name, int prop_id, double prop_valu
|
|||||||
cvSetModeWindow_CARBON(name,prop_value);
|
cvSetModeWindow_CARBON(name,prop_value);
|
||||||
#elif defined (HAVE_COCOA)
|
#elif defined (HAVE_COCOA)
|
||||||
cvSetModeWindow_COCOA(name,prop_value);
|
cvSetModeWindow_COCOA(name,prop_value);
|
||||||
|
#elif defined (WINRT)
|
||||||
|
cvSetModeWindow_WinRT(name, prop_value);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CV_WND_PROP_AUTOSIZE:
|
case CV_WND_PROP_AUTOSIZE:
|
||||||
@ -104,6 +107,8 @@ CV_IMPL double cvGetWindowProperty(const char* name, int prop_id)
|
|||||||
return cvGetModeWindow_CARBON(name);
|
return cvGetModeWindow_CARBON(name);
|
||||||
#elif defined (HAVE_COCOA)
|
#elif defined (HAVE_COCOA)
|
||||||
return cvGetModeWindow_COCOA(name);
|
return cvGetModeWindow_COCOA(name);
|
||||||
|
#elif defined (WINRT)
|
||||||
|
return cvGetModeWindow_WinRT(name);
|
||||||
#else
|
#else
|
||||||
return -1;
|
return -1;
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,438 +1,268 @@
|
|||||||
|
// 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 "precomp.hpp"
|
||||||
|
|
||||||
#if defined WINRT && !defined WINRT_8_0
|
#include <map>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <opencv2\highgui.hpp>
|
||||||
|
#include <opencv2\highgui\highgui_winrt.hpp>
|
||||||
|
#include <window_winrt_bridge.hpp>
|
||||||
|
|
||||||
struct CvWindow;
|
#define CV_WINRT_NO_GUI_ERROR( funcname ) \
|
||||||
|
{ \
|
||||||
|
cvError( CV_StsNotImplemented, funcname, \
|
||||||
|
"The function is not implemented. ", \
|
||||||
|
__FILE__, __LINE__ ); \
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct CvTrackbar
|
#define CV_ERROR( Code, Msg ) \
|
||||||
|
{ \
|
||||||
|
cvError( (Code), cvFuncName, Msg, __FILE__, __LINE__ ); \
|
||||||
|
};
|
||||||
|
|
||||||
|
/********************************** WinRT Specific API Implementation ******************************************/
|
||||||
|
|
||||||
|
// Initializes or overrides container contents with default XAML markup structure
|
||||||
|
void cv::winrt_initContainer(::Windows::UI::Xaml::Controls::Panel^ _container)
|
||||||
{
|
{
|
||||||
int signature;
|
HighguiBridge::getInstance().setContainer(_container);
|
||||||
void* hwnd; // TODO: use proper handle type
|
|
||||||
char* name;
|
|
||||||
CvTrackbar* next;
|
|
||||||
CvWindow* parent;
|
|
||||||
int* data;
|
|
||||||
int pos;
|
|
||||||
int maxval;
|
|
||||||
void (*notify)(int);
|
|
||||||
void (*notify2)(int, void*);
|
|
||||||
void* userdata;
|
|
||||||
int id;
|
|
||||||
}
|
}
|
||||||
CvTrackbar;
|
|
||||||
|
|
||||||
|
/********************************** API Implementation *********************************************************/
|
||||||
|
|
||||||
typedef struct CvWindow
|
CV_IMPL void cvShowImage(const char* name, const CvArr* arr)
|
||||||
{
|
{
|
||||||
int signature;
|
CV_FUNCNAME("cvShowImage");
|
||||||
void* hwnd; // TODO: use proper handle type
|
|
||||||
char* name;
|
|
||||||
CvWindow* prev;
|
|
||||||
CvWindow* next;
|
|
||||||
|
|
||||||
HGDIOBJ image;
|
|
||||||
int flags;
|
|
||||||
|
|
||||||
CvMouseCallback on_mouse;
|
|
||||||
void* on_mouse_param;
|
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
void* toolbar; // TODO: use proper handle type
|
|
||||||
int pos;
|
|
||||||
int rows;
|
|
||||||
CvTrackbar* first;
|
|
||||||
}
|
|
||||||
toolbar;
|
|
||||||
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
}
|
|
||||||
CvWindow;
|
|
||||||
|
|
||||||
static CvWindow* hg_windows = 0;
|
|
||||||
|
|
||||||
// typedef int (CV_CDECL * CvWin32WindowCallback)(HWND, UINT, WPARAM, LPARAM, int*);
|
|
||||||
|
|
||||||
static CvWindow* icvFindWindowByName(const char* name) {
|
|
||||||
CvWindow* window = hg_windows;
|
|
||||||
|
|
||||||
for (; window != 0 && strcmp(name, window->name) != 0; window = window->next)
|
|
||||||
;
|
|
||||||
|
|
||||||
return window;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CvTrackbar*
|
|
||||||
icvFindTrackbarByName(const CvWindow* window, const char* name) {
|
|
||||||
CvTrackbar* trackbar = window->toolbar.first;
|
|
||||||
|
|
||||||
for (; trackbar != 0 && strcmp(trackbar->name, name) != 0; trackbar = trackbar->next)
|
|
||||||
;
|
|
||||||
|
|
||||||
return trackbar;
|
|
||||||
}
|
|
||||||
|
|
||||||
CV_IMPL int cvInitSystem( int, char** )
|
|
||||||
{
|
|
||||||
static int wasInitialized = 0;
|
|
||||||
|
|
||||||
if (!wasInitialized)
|
|
||||||
{
|
|
||||||
hg_windows = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
CV_IMPL int cvStartWindowThread(){
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
CV_IMPL int cvNamedWindow( const char* name, int flags )
|
|
||||||
{
|
|
||||||
int result = 0;
|
|
||||||
CV_FUNCNAME( "cvNamedWindow" );
|
|
||||||
|
|
||||||
__BEGIN__;
|
|
||||||
__END__;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
CV_IMPL void cvDestroyWindow( const char* name )
|
|
||||||
{
|
|
||||||
CV_FUNCNAME( "cvDestroyWindow" );
|
|
||||||
|
|
||||||
__BEGIN__;
|
__BEGIN__;
|
||||||
|
|
||||||
CvWindow* window;
|
CvMat stub, *image;
|
||||||
|
|
||||||
if(!name)
|
if (!name)
|
||||||
CV_ERROR( CV_StsNullPtr, "NULL name string" );
|
CV_ERROR(CV_StsNullPtr, "NULL name");
|
||||||
|
|
||||||
window = icvFindWindowByName(name);
|
CvWindow* window = HighguiBridge::getInstance().namedWindow(name);
|
||||||
if( !window )
|
|
||||||
EXIT;
|
|
||||||
|
|
||||||
__END__;
|
if (!window || !arr)
|
||||||
}
|
|
||||||
|
|
||||||
CV_IMPL void cvShowImage( const char* name, const CvArr* arr )
|
|
||||||
{
|
|
||||||
CV_FUNCNAME( "cvShowImage" );
|
|
||||||
|
|
||||||
__BEGIN__;
|
|
||||||
|
|
||||||
CvWindow* window;
|
|
||||||
SIZE size = { 0, 0 };
|
|
||||||
int channels = 0;
|
|
||||||
void* dst_ptr = 0;
|
|
||||||
const int channels_def = 3;
|
|
||||||
int origin = 0;
|
|
||||||
CvMat stub, dst, *image;
|
|
||||||
bool changed_size = false;
|
|
||||||
|
|
||||||
if( !name )
|
|
||||||
CV_ERROR( CV_StsNullPtr, "NULL name" );
|
|
||||||
|
|
||||||
window = icvFindWindowByName(name);
|
|
||||||
if(!window)
|
|
||||||
{
|
|
||||||
cvNamedWindow(name, CV_WINDOW_AUTOSIZE);
|
|
||||||
window = icvFindWindowByName(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !window || !arr )
|
|
||||||
EXIT;
|
|
||||||
|
|
||||||
if( CV_IS_IMAGE_HDR( arr ))
|
|
||||||
origin = ((IplImage*)arr)->origin;
|
|
||||||
|
|
||||||
CV_CALL( image = cvGetMat( arr, &stub ));
|
|
||||||
|
|
||||||
#ifdef HAVE_OPENGL
|
|
||||||
if (window->useGl)
|
|
||||||
{
|
|
||||||
cv::imshow(name, cv::cvarrToMat(image));
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (window->image)
|
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_FUNCNAME("cvNamedWindow");
|
||||||
|
|
||||||
|
if (!name)
|
||||||
|
CV_ERROR(CV_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_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");
|
||||||
|
|
||||||
|
int pos = 0;
|
||||||
|
|
||||||
|
if (!window_name || !trackbar_name)
|
||||||
|
CV_ERROR(CV_StsNullPtr, "NULL window or trackbar name");
|
||||||
|
|
||||||
|
if (count < 0)
|
||||||
|
CV_ERROR(CV_StsOutOfRange, "Bad trackbar max value");
|
||||||
|
|
||||||
|
CvWindow* window = HighguiBridge::getInstance().namedWindow(window_name);
|
||||||
|
|
||||||
|
if (!window)
|
||||||
{
|
{
|
||||||
//TODO: validate image
|
CV_ERROR(CV_StsNullPtr, "NULL window");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size.cx != image->width || size.cy != image->height || channels != channels_def)
|
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_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)
|
||||||
{
|
{
|
||||||
changed_size = true;
|
if (trackbar_name == 0 || window_name == 0)
|
||||||
|
CV_ERROR(CV_StsNullPtr, "NULL trackbar or window name");
|
||||||
|
|
||||||
//TODO: handle image resize
|
CvTrackbar* trackbar = HighguiBridge::getInstance().findTrackbarByName(trackbar_name, window_name);
|
||||||
|
|
||||||
|
if (trackbar)
|
||||||
|
trackbar->setMaxPosition(maxval);
|
||||||
}
|
}
|
||||||
|
|
||||||
cvInitMatHeader( &dst, size.cy, size.cx, CV_8UC3,
|
|
||||||
dst_ptr, (size.cx * channels + 3) & -4 );
|
|
||||||
cvConvertImage( image, &dst, origin == 0 ? CV_CVTIMG_FLIP : 0 );
|
|
||||||
|
|
||||||
if (changed_size)
|
|
||||||
//TODO: handle consequent image resize
|
|
||||||
|
|
||||||
__END__;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CV_IMPL void cvResizeWindow(const char* name, int width, int height )
|
CV_IMPL int cvGetTrackbarPos(const char* trackbar_name, const char* window_name)
|
||||||
{
|
{
|
||||||
CV_FUNCNAME( "cvResizeWindow" );
|
int pos = -1;
|
||||||
|
|
||||||
__BEGIN__;
|
CV_FUNCNAME("cvGetTrackbarPos");
|
||||||
|
|
||||||
CvWindow* window;
|
if (trackbar_name == 0 || window_name == 0)
|
||||||
|
CV_ERROR(CV_StsNullPtr, "NULL trackbar or window name");
|
||||||
|
|
||||||
if( !name )
|
CvTrackbar* trackbar = HighguiBridge::getInstance().findTrackbarByName(trackbar_name, window_name);
|
||||||
CV_ERROR( CV_StsNullPtr, "NULL name" );
|
|
||||||
|
|
||||||
window = icvFindWindowByName(name);
|
if (trackbar)
|
||||||
if(!window)
|
pos = trackbar->getPosition();
|
||||||
EXIT;
|
|
||||||
|
|
||||||
// TODO: implement appropriate logic here
|
return pos;
|
||||||
|
|
||||||
__END__;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************************** Not YET implemented API ****************************************************/
|
||||||
|
|
||||||
CV_IMPL void cvMoveWindow( const char* name, int x, int y )
|
CV_IMPL int cvWaitKey(int delay)
|
||||||
{
|
{
|
||||||
CV_FUNCNAME( "cvMoveWindow" );
|
CV_WINRT_NO_GUI_ERROR("cvWaitKey");
|
||||||
|
|
||||||
__BEGIN__;
|
|
||||||
|
|
||||||
CvWindow* window;
|
|
||||||
RECT rect;
|
|
||||||
|
|
||||||
if( !name )
|
|
||||||
CV_ERROR( CV_StsNullPtr, "NULL name" );
|
|
||||||
|
|
||||||
window = icvFindWindowByName(name);
|
|
||||||
if(!window)
|
|
||||||
EXIT;
|
|
||||||
|
|
||||||
// TODO: implement appropriate logic here
|
|
||||||
|
|
||||||
__END__;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
CV_IMPL void cvDestroyAllWindows(void)
|
|
||||||
{
|
|
||||||
// TODO: implement appropriate logic here
|
|
||||||
}
|
|
||||||
|
|
||||||
CV_IMPL int cvWaitKey( int delay )
|
|
||||||
{
|
|
||||||
// see https://msdn.microsoft.com/en-us/library/windows/desktop/ms724411(v=vs.85).aspx
|
// see https://msdn.microsoft.com/en-us/library/windows/desktop/ms724411(v=vs.85).aspx
|
||||||
int time0 = GetTickCount64();
|
int time0 = GetTickCount64();
|
||||||
|
|
||||||
for(;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
CvWindow* window;
|
CvWindow* window;
|
||||||
|
|
||||||
if ((delay > 0 && abs((int)(GetTickCount64() - time0)) >= delay) || hg_windows == 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (delay <= 0)
|
if (delay <= 0)
|
||||||
{
|
{
|
||||||
// TODO: implement appropriate logic here
|
// TODO: implement appropriate logic here
|
||||||
}
|
}
|
||||||
|
|
||||||
for( window = hg_windows; window != 0; window = window->next )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CV_IMPL void cvSetMouseCallback(const char* window_name, CvMouseCallback on_mouse, void* param)
|
||||||
|
|
||||||
CV_IMPL int
|
|
||||||
cvCreateTrackbar( const char* trackbar_name, const char* window_name,
|
|
||||||
int* val, int count, CvTrackbarCallback on_notify )
|
|
||||||
{
|
{
|
||||||
// TODO: implement appropriate logic here
|
CV_WINRT_NO_GUI_ERROR("cvSetMouseCallback");
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
CV_IMPL int
|
CV_FUNCNAME("cvSetMouseCallback");
|
||||||
cvCreateTrackbar2( const char* trackbar_name, const char* window_name,
|
|
||||||
int* val, int count, CvTrackbarCallback2 on_notify2,
|
|
||||||
void* userdata )
|
|
||||||
{
|
|
||||||
// TODO: implement appropriate logic here
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
CV_IMPL void
|
if (!window_name)
|
||||||
cvSetMouseCallback( const char* window_name, CvMouseCallback on_mouse, void* param )
|
CV_ERROR(CV_StsNullPtr, "NULL window name");
|
||||||
{
|
|
||||||
CV_FUNCNAME( "cvSetMouseCallback" );
|
|
||||||
|
|
||||||
__BEGIN__;
|
CvWindow* window = HighguiBridge::getInstance().findWindowByName(window_name);
|
||||||
|
if (!window)
|
||||||
CvWindow* window = 0;
|
return;
|
||||||
|
|
||||||
if( !window_name )
|
|
||||||
CV_ERROR( CV_StsNullPtr, "NULL window name" );
|
|
||||||
|
|
||||||
window = icvFindWindowByName(window_name);
|
|
||||||
if( !window )
|
|
||||||
EXIT;
|
|
||||||
|
|
||||||
// TODO: implement appropriate logic here
|
// TODO: implement appropriate logic here
|
||||||
|
|
||||||
__END__;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************************** Disabled or not supported API **********************************************/
|
||||||
|
|
||||||
CV_IMPL int cvGetTrackbarPos( const char* trackbar_name, const char* window_name )
|
CV_IMPL void cvMoveWindow(const char* name, int x, int y)
|
||||||
{
|
{
|
||||||
int pos = -1;
|
CV_WINRT_NO_GUI_ERROR("cvMoveWindow");
|
||||||
|
|
||||||
CV_FUNCNAME( "cvGetTrackbarPos" );
|
|
||||||
|
|
||||||
__BEGIN__;
|
|
||||||
|
|
||||||
CvWindow* window;
|
|
||||||
CvTrackbar* trackbar = 0;
|
|
||||||
|
|
||||||
if( trackbar_name == 0 || window_name == 0 )
|
|
||||||
CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name" );
|
|
||||||
|
|
||||||
window = icvFindWindowByName( window_name );
|
|
||||||
if( window )
|
|
||||||
trackbar = icvFindTrackbarByName( window, trackbar_name );
|
|
||||||
|
|
||||||
if( trackbar )
|
|
||||||
pos = trackbar->pos;
|
|
||||||
|
|
||||||
__END__;
|
|
||||||
|
|
||||||
return pos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CV_IMPL void cvResizeWindow(const char* name, int width, int height)
|
||||||
CV_IMPL void cvSetTrackbarPos( const char* trackbar_name, const char* window_name, int pos )
|
|
||||||
{
|
{
|
||||||
CV_FUNCNAME( "cvSetTrackbarPos" );
|
CV_WINRT_NO_GUI_ERROR("cvResizeWindow");
|
||||||
|
|
||||||
__BEGIN__;
|
|
||||||
|
|
||||||
CvWindow* window;
|
|
||||||
CvTrackbar* trackbar = 0;
|
|
||||||
|
|
||||||
if( trackbar_name == 0 || window_name == 0 )
|
|
||||||
CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name" );
|
|
||||||
|
|
||||||
window = icvFindWindowByName( window_name );
|
|
||||||
if( window )
|
|
||||||
trackbar = icvFindTrackbarByName( window, trackbar_name );
|
|
||||||
|
|
||||||
if( trackbar )
|
|
||||||
{
|
|
||||||
if( pos < 0 )
|
|
||||||
pos = 0;
|
|
||||||
|
|
||||||
if( pos > trackbar->maxval )
|
|
||||||
pos = trackbar->maxval;
|
|
||||||
|
|
||||||
//TODO: update trackbar
|
|
||||||
}
|
|
||||||
|
|
||||||
__END__;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CV_IMPL int cvInitSystem(int, char**)
|
||||||
CV_IMPL void cvSetTrackbarMax(const char* trackbar_name, const char* window_name, int maxval)
|
|
||||||
{
|
{
|
||||||
CV_FUNCNAME( "cvSetTrackbarMax" );
|
CV_WINRT_NO_GUI_ERROR("cvInitSystem");
|
||||||
|
return CV_StsNotImplemented;
|
||||||
__BEGIN__;
|
|
||||||
|
|
||||||
if (maxval >= 0)
|
|
||||||
{
|
|
||||||
CvWindow* window = 0;
|
|
||||||
CvTrackbar* trackbar = 0;
|
|
||||||
if (trackbar_name == 0 || window_name == 0)
|
|
||||||
{
|
|
||||||
CV_ERROR(CV_StsNullPtr, "NULL trackbar or window name");
|
|
||||||
}
|
|
||||||
|
|
||||||
window = icvFindWindowByName(window_name);
|
|
||||||
if (window)
|
|
||||||
{
|
|
||||||
trackbar = icvFindTrackbarByName(window, trackbar_name);
|
|
||||||
if (trackbar)
|
|
||||||
{
|
|
||||||
// The position will be min(pos, maxval).
|
|
||||||
trackbar->maxval = maxval;
|
|
||||||
|
|
||||||
//TODO: update trackbar
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
__END__;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CV_IMPL void* cvGetWindowHandle(const char*)
|
||||||
CV_IMPL void* cvGetWindowHandle( const char* window_name )
|
|
||||||
{
|
{
|
||||||
void* hwnd = 0;
|
CV_WINRT_NO_GUI_ERROR("cvGetWindowHandle");
|
||||||
|
return (void*) CV_StsNotImplemented;
|
||||||
CV_FUNCNAME( "cvGetWindowHandle" );
|
|
||||||
|
|
||||||
__BEGIN__;
|
|
||||||
|
|
||||||
CvWindow* window;
|
|
||||||
|
|
||||||
if( window_name == 0 )
|
|
||||||
CV_ERROR( CV_StsNullPtr, "NULL window name" );
|
|
||||||
|
|
||||||
window = icvFindWindowByName( window_name );
|
|
||||||
if( window )
|
|
||||||
hwnd = (void*)window->hwnd;
|
|
||||||
|
|
||||||
__END__;
|
|
||||||
|
|
||||||
return hwnd;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CV_IMPL const char* cvGetWindowName(void*)
|
||||||
CV_IMPL const char* cvGetWindowName( void* window_handle )
|
|
||||||
{
|
{
|
||||||
const char* window_name = "";
|
CV_WINRT_NO_GUI_ERROR("cvGetWindowName");
|
||||||
|
return (const char*) CV_StsNotImplemented;
|
||||||
CV_FUNCNAME( "cvGetWindowName" );
|
|
||||||
|
|
||||||
__BEGIN__;
|
|
||||||
|
|
||||||
CvWindow* window = 0;
|
|
||||||
|
|
||||||
if( window_handle == 0 )
|
|
||||||
CV_ERROR( CV_StsNullPtr, "NULL window" );
|
|
||||||
|
|
||||||
// window = TODO: find window by handle
|
|
||||||
if( window )
|
|
||||||
window_name = window->name;
|
|
||||||
|
|
||||||
__END__;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //defined WINRT && !defined WINRT_8_0
|
void cvSetModeWindow_WinRT(const char* name, double prop_value) {
|
||||||
|
CV_WINRT_NO_GUI_ERROR("cvSetModeWindow");
|
||||||
|
}
|
||||||
|
|
||||||
|
double cvGetModeWindow_WinRT(const char* name) {
|
||||||
|
CV_WINRT_NO_GUI_ERROR("cvGetModeWindow");
|
||||||
|
return CV_StsNotImplemented;
|
||||||
|
}
|
||||||
|
|
||||||
|
CV_IMPL int cvStartWindowThread() {
|
||||||
|
CV_WINRT_NO_GUI_ERROR("cvStartWindowThread");
|
||||||
|
return CV_StsNotImplemented;
|
||||||
|
}
|
346
modules/highgui/src/window_winrt_bridge.cpp
Normal file
346
modules/highgui/src/window_winrt_bridge.cpp
Normal file
@ -0,0 +1,346 @@
|
|||||||
|
// 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 "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)
|
||||||
|
{
|
||||||
|
if (pos < 0)
|
||||||
|
pos = 0;
|
||||||
|
|
||||||
|
slider->Maximum = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CvTrackbar::setSlider(Slider^ slider) {
|
||||||
|
if (slider)
|
||||||
|
this->slider = slider;
|
||||||
|
}
|
||||||
|
|
||||||
|
double CvTrackbar::getPosition()
|
||||||
|
{
|
||||||
|
return slider->Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
double CvTrackbar::getMaxPosition()
|
||||||
|
{
|
||||||
|
return slider->Maximum;
|
||||||
|
}
|
||||||
|
|
||||||
|
Slider^ CvTrackbar::getSlider()
|
||||||
|
{
|
||||||
|
return slider;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************** CvWindow class ***********************************/
|
||||||
|
|
||||||
|
CvWindow::CvWindow(cv::String name, int flags) : name(name)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
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(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
|
233
modules/highgui/src/window_winrt_bridge.hpp
Normal file
233
modules/highgui/src/window_winrt_bridge.hpp
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
// 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 &);
|
||||||
|
void operator=(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);
|
||||||
|
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;
|
||||||
|
};
|
@ -1,16 +1,34 @@
|
|||||||
<Page
|
<Page x:Class="FaceDetection.MainPage"
|
||||||
x:Class="FaceDetection.MainPage"
|
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:local="using:FaceDetection"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:local="using:FaceDetection"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
|
|
||||||
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||||
<Button x:Name="InitBtn" Content="Initialize" HorizontalAlignment="Left" Height="67" Margin="69,81,0,0" VerticalAlignment="Top" Width="218" Click="InitBtn_Click"/>
|
<Button x:Name="InitBtn"
|
||||||
<Button x:Name="detectBtn" Content="Detect Faces" HorizontalAlignment="Left" Height="67" Margin="69,168,0,0" VerticalAlignment="Top" Width="218" Click="detectBtn_Click"/>
|
Width="218"
|
||||||
<Image x:Name="img1" HorizontalAlignment="Left" Height="446" Margin="354,84,0,0" VerticalAlignment="Top" Width="883"/>
|
Height="67"
|
||||||
|
Margin="69,81,0,0"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Click="InitBtn_Click"
|
||||||
|
Content="Initialize" />
|
||||||
|
<Button x:Name="detectBtn"
|
||||||
|
Width="218"
|
||||||
|
Height="67"
|
||||||
|
Margin="69,168,0,0"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Click="detectBtn_Click"
|
||||||
|
Content="Detect Faces" />
|
||||||
|
<StackPanel x:Name="cvContainer"
|
||||||
|
Width="883"
|
||||||
|
Height="446"
|
||||||
|
Margin="354,84,0,0"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
VerticalAlignment="Top" />
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Page>
|
</Page>
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
#include <opencv2\imgcodecs\imgcodecs.hpp>
|
#include <opencv2\imgcodecs\imgcodecs.hpp>
|
||||||
#include <opencv2\core\core.hpp>
|
#include <opencv2\core\core.hpp>
|
||||||
#include <opencv2\imgproc\imgproc.hpp>
|
#include <opencv2\imgproc\imgproc.hpp>
|
||||||
|
#include <opencv2\highgui.hpp>
|
||||||
|
#include <opencv2\highgui\highgui_winrt.hpp>
|
||||||
|
|
||||||
#include <Robuffer.h>
|
#include <Robuffer.h>
|
||||||
|
|
||||||
@ -33,6 +35,7 @@ using namespace Microsoft::WRL;
|
|||||||
|
|
||||||
// Name of the resource classifier used to detect human faces (frontal)
|
// Name of the resource classifier used to detect human faces (frontal)
|
||||||
cv::String face_cascade_name = "Assets/haarcascade_frontalface_alt.xml";
|
cv::String face_cascade_name = "Assets/haarcascade_frontalface_alt.xml";
|
||||||
|
cv::String window_name = "Faces";
|
||||||
|
|
||||||
MainPage::MainPage()
|
MainPage::MainPage()
|
||||||
{
|
{
|
||||||
@ -45,7 +48,8 @@ void FaceDetection::MainPage::InitBtn_Click(Platform::Object^ sender, Windows::U
|
|||||||
cv::Mat image = cv::imread("Assets/group1.jpg");
|
cv::Mat image = cv::imread("Assets/group1.jpg");
|
||||||
groupFaces = cv::Mat(image.rows, image.cols, CV_8UC4);
|
groupFaces = cv::Mat(image.rows, image.cols, CV_8UC4);
|
||||||
cv::cvtColor(image, groupFaces, CV_BGR2BGRA);
|
cv::cvtColor(image, groupFaces, CV_BGR2BGRA);
|
||||||
UpdateImage(groupFaces);
|
cv::winrt_initContainer(cvContainer);
|
||||||
|
cv::imshow(window_name, groupFaces);
|
||||||
|
|
||||||
if (!face_cascade.load(face_cascade_name)) {
|
if (!face_cascade.load(face_cascade_name)) {
|
||||||
Windows::UI::Popups::MessageDialog("Couldn't load face detector \n").ShowAsync();
|
Windows::UI::Popups::MessageDialog("Couldn't load face detector \n").ShowAsync();
|
||||||
@ -70,29 +74,8 @@ void FaceDetection::MainPage::detectBtn_Click(Platform::Object^ sender, Windows:
|
|||||||
cv::rectangle(groupFaces, face, cv::Scalar(0, 255, 255), 5);
|
cv::rectangle(groupFaces, face, cv::Scalar(0, 255, 255), 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateImage(groupFaces);
|
cv::imshow(window_name, groupFaces);
|
||||||
} else {
|
} else {
|
||||||
Windows::UI::Popups::MessageDialog("Initialize image before processing \n").ShowAsync();
|
Windows::UI::Popups::MessageDialog("Initialize image before processing \n").ShowAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FaceDetection::MainPage::UpdateImage(const cv::Mat& image) {
|
|
||||||
// Create the WriteableBitmap
|
|
||||||
WriteableBitmap^ bitmap = ref new WriteableBitmap(image.cols, image.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, image.data, image.step.buf[1] * image.cols*image.rows);
|
|
||||||
|
|
||||||
// Set the bitmap to the Image element
|
|
||||||
img1->Source = bitmap;
|
|
||||||
}
|
|
@ -2,13 +2,14 @@
|
|||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ImportGroup Label="PropertySheets" />
|
<ImportGroup Label="PropertySheets" />
|
||||||
<PropertyGroup Label="UserMacros">
|
<PropertyGroup Label="UserMacros">
|
||||||
<OpenCV_Bin>$(OPENCV_WINRT_INSTALL_DIR)\WS\8.1\$(PlatformTarget)\$(PlatformTarget)\vc12\bin\</OpenCV_Bin>
|
<Runtime Condition="'$(ApplicationType)'=='Windows Phone'">WP</Runtime>
|
||||||
<OpenCV_Lib>$(OPENCV_WINRT_INSTALL_DIR)\WS\8.1\$(PlatformTarget)\$(PlatformTarget)\vc12\lib\</OpenCV_Lib>
|
<Runtime Condition="'$(ApplicationType)'=='Windows Store'">WS</Runtime>
|
||||||
<OpenCV_Include>$(OPENCV_WINRT_INSTALL_DIR)\WS\8.1\$(PlatformTarget)\include\</OpenCV_Include>
|
<OpenCV_Bin>$(OPENCV_WINRT_INSTALL_DIR)\$(Runtime)\8.1\$(PlatformTarget)\$(PlatformTarget)\vc12\bin\</OpenCV_Bin>
|
||||||
|
<OpenCV_Lib>$(OPENCV_WINRT_INSTALL_DIR)\$(Runtime)\8.1\$(PlatformTarget)\$(PlatformTarget)\vc12\lib\</OpenCV_Lib>
|
||||||
|
<OpenCV_Include>$(OPENCV_WINRT_INSTALL_DIR)\$(Runtime)\8.1\$(PlatformTarget)\include\</OpenCV_Include>
|
||||||
<!--debug suffix for OpenCV dlls and libs -->
|
<!--debug suffix for OpenCV dlls and libs -->
|
||||||
<DebugSuffix Condition="'$(Configuration)'=='Debug'">d</DebugSuffix>
|
<DebugSuffix Condition="'$(Configuration)'=='Debug'">d</DebugSuffix>
|
||||||
<DebugSuffix Condition="'$(Configuration)'!='Debug'">
|
<DebugSuffix Condition="'$(Configuration)'!='Debug'"></DebugSuffix>
|
||||||
</DebugSuffix>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<!--Add required OpenCV dlls here-->
|
<!--Add required OpenCV dlls here-->
|
||||||
@ -33,14 +34,20 @@
|
|||||||
<None Include="$(OpenCV_Bin)opencv_objdetect300$(DebugSuffix).dll">
|
<None Include="$(OpenCV_Bin)opencv_objdetect300$(DebugSuffix).dll">
|
||||||
<DeploymentContent>true</DeploymentContent>
|
<DeploymentContent>true</DeploymentContent>
|
||||||
</None>
|
</None>
|
||||||
|
<None Include="$(OpenCV_Bin)opencv_videoio300$(DebugSuffix).dll">
|
||||||
|
<DeploymentContent>true</DeploymentContent>
|
||||||
|
</None>
|
||||||
|
<None Include="$(OpenCV_Bin)opencv_highgui300$(DebugSuffix).dll">
|
||||||
|
<DeploymentContent>true</DeploymentContent>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemDefinitionGroup>
|
<ItemDefinitionGroup>
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<AdditionalIncludeDirectories>$(OpenCV_Include);$(ProjectDir);$(GeneratedFilesDir);$(IntDir);%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>$(OpenCV_Include);%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<!--Add required OpenCV libs here-->
|
<!--Add required OpenCV libs here-->
|
||||||
<AdditionalDependencies>opencv_core300$(DebugSuffix).lib;opencv_imgcodecs300$(DebugSuffix).lib;opencv_imgproc300$(DebugSuffix).lib;opencv_features2d300$(DebugSuffix).lib;opencv_flann300$(DebugSuffix).lib;opencv_ml300$(DebugSuffix).lib;opencv_imgcodecs300$(DebugSuffix).lib;opencv_objdetect300$(DebugSuffix).lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>opencv_core300$(DebugSuffix).lib;opencv_imgproc300$(DebugSuffix).lib;opencv_imgcodecs300$(DebugSuffix).lib;opencv_flann300$(DebugSuffix).lib;opencv_videoio300$(DebugSuffix).lib;opencv_features2d300$(DebugSuffix).lib;opencv_objdetect300$(DebugSuffix).lib;opencv_ml300$(DebugSuffix).lib;opencv_highgui300$(DebugSuffix).lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
<AdditionalLibraryDirectories>$(OpenCV_Lib);%(AdditionalLibraryDirectories);</AdditionalLibraryDirectories>
|
<AdditionalLibraryDirectories>$(OpenCV_Lib);%(AdditionalLibraryDirectories);</AdditionalLibraryDirectories>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user