mirror of
https://github.com/opencv/opencv.git
synced 2026-07-22 20:03:03 +04:00
Compare commits
125 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 05b9c991dd | |||
| 46be47cb4b | |||
| 4eb9b9d6cf | |||
| 53494ba397 | |||
| 15678efe84 | |||
| 8399568edf | |||
| 0566ab4d3d | |||
| df63060e4d | |||
| 4175916b2a | |||
| d649f47eeb | |||
| d014cb8fb4 | |||
| c45492371a | |||
| 719149877e | |||
| ee36717db4 | |||
| c48777a1c3 | |||
| 0ccc903647 | |||
| 41fd711ab0 | |||
| 4b885e2067 | |||
| 4f6f6e8cac | |||
| 6ef0253fb7 | |||
| f7b5e6544f | |||
| 648facccd6 | |||
| 709e8e8e07 | |||
| 734bf8babd | |||
| 4880858119 | |||
| cea9a97434 | |||
| b3eee49451 | |||
| 60906d9175 | |||
| d6a88397b4 | |||
| 8fe79738ce | |||
| 86aabf704f | |||
| f9aa148ba9 | |||
| 358e59e91b | |||
| b94963d381 | |||
| e79c875fe2 | |||
| 24be7b26cd | |||
| 0206f419c1 | |||
| 1e038e2837 | |||
| 4aa9f83100 | |||
| 1acc1085d2 | |||
| 83fe2f3b16 | |||
| 1e27b07e29 | |||
| 4293a54447 | |||
| edce617a58 | |||
| 51d3138dff | |||
| 83cdd43a4c | |||
| 58e7d9f32f | |||
| f22d9a232d | |||
| 4ec1930949 | |||
| bc72f4d2a2 | |||
| 08d8faf9da | |||
| f9268d34dc | |||
| 6e22be4100 | |||
| ce07840e9f | |||
| 6b7d890f34 | |||
| 9941c6710d | |||
| e8dd31aacd | |||
| d6a7e8f84f | |||
| b633c73c46 | |||
| 529bd41751 | |||
| 27c1bd2762 | |||
| 069f3d8d9a | |||
| 2509fa8080 | |||
| 5a5c82bb1d | |||
| 26f5d2d639 | |||
| b674cd8571 | |||
| 8c91a1af71 | |||
| 037ffcdf99 | |||
| 22a3cf0fba | |||
| 0cea828a10 | |||
| bc741ab25f | |||
| 64c94cb22c | |||
| d449ba104a | |||
| 6da7c50fb5 | |||
| 442082eb0f | |||
| 92fc763925 | |||
| 459e7d4a80 | |||
| 400fea8626 | |||
| a9687a341e | |||
| ae9d24d433 | |||
| 8c60498673 | |||
| 1ae71fe205 | |||
| be530bd085 | |||
| 80d0593dbd | |||
| 66145ea06c | |||
| dd71bef6f5 | |||
| e719bee2b8 | |||
| 63ae0eeba5 | |||
| 34c630faf4 | |||
| 3a6d248bee | |||
| ea0c9b7f5c | |||
| cc08e00876 | |||
| fffac2f085 | |||
| dfe7c98090 | |||
| f3ee1c3d2f | |||
| 917b883cf0 | |||
| a63576e76d | |||
| de431609db | |||
| 5d5527d03e | |||
| 4088013251 | |||
| 88a883e68e | |||
| 8660e048bc | |||
| d4087f19a2 | |||
| 12c25b9310 | |||
| e88253ccad | |||
| f44de302a0 | |||
| b7c97f6e30 | |||
| e8d2a9752b | |||
| 10849d1c7a | |||
| 17ca7f9545 | |||
| 658282fcbe | |||
| ee270d1a18 | |||
| 740b1f235e | |||
| a118577a57 | |||
| ce503c64bf | |||
| 00a180185e | |||
| 1c639befe6 | |||
| b1899e5489 | |||
| 6f292d8036 | |||
| f07e9e7c5f | |||
| 2784fd7b27 | |||
| c289c8a700 | |||
| 13c058ecf8 | |||
| df0c43321d | |||
| eb7ff99f80 |
Vendored
-502
@@ -1,502 +0,0 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// multimon.h -- Stub module that fakes multiple monitor apis on Win32 OSes
|
||||
// without them.
|
||||
//
|
||||
// By using this header your code will get back default values from
|
||||
// GetSystemMetrics() for new metrics, and the new multimonitor APIs
|
||||
// will act like only one display is present on a Win32 OS without
|
||||
// multimonitor APIs.
|
||||
//
|
||||
// Exactly one source must include this with COMPILE_MULTIMON_STUBS defined.
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { // Assume C declarations for C++
|
||||
#endif // __cplusplus
|
||||
|
||||
//
|
||||
// If we are building with Win95/NT4 headers, we need to declare
|
||||
// the multimonitor-related metrics and APIs ourselves.
|
||||
//
|
||||
#ifndef SM_CMONITORS
|
||||
|
||||
#define SM_XVIRTUALSCREEN 76
|
||||
#define SM_YVIRTUALSCREEN 77
|
||||
#define SM_CXVIRTUALSCREEN 78
|
||||
#define SM_CYVIRTUALSCREEN 79
|
||||
#define SM_CMONITORS 80
|
||||
#define SM_SAMEDISPLAYFORMAT 81
|
||||
|
||||
// HMONITOR is already declared if WINVER >= 0x0500 in windef.h
|
||||
// This is for components built with an older version number.
|
||||
//
|
||||
#if !defined(HMONITOR_DECLARED) && (WINVER < 0x0500)
|
||||
DECLARE_HANDLE(HMONITOR);
|
||||
#define HMONITOR_DECLARED
|
||||
#endif
|
||||
|
||||
#define MONITOR_DEFAULTTONULL 0x00000000
|
||||
#define MONITOR_DEFAULTTOPRIMARY 0x00000001
|
||||
#define MONITOR_DEFAULTTONEAREST 0x00000002
|
||||
|
||||
#define MONITORINFOF_PRIMARY 0x00000001
|
||||
|
||||
typedef struct tagMONITORINFO
|
||||
{
|
||||
DWORD cbSize;
|
||||
RECT rcMonitor;
|
||||
RECT rcWork;
|
||||
DWORD dwFlags;
|
||||
} MONITORINFO, *LPMONITORINFO;
|
||||
|
||||
#ifndef CCHDEVICENAME
|
||||
#define CCHDEVICENAME 32
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
typedef struct tagMONITORINFOEXA : public tagMONITORINFO
|
||||
{
|
||||
CHAR szDevice[CCHDEVICENAME];
|
||||
} MONITORINFOEXA, *LPMONITORINFOEXA;
|
||||
typedef struct tagMONITORINFOEXW : public tagMONITORINFO
|
||||
{
|
||||
WCHAR szDevice[CCHDEVICENAME];
|
||||
} MONITORINFOEXW, *LPMONITORINFOEXW;
|
||||
#ifdef UNICODE
|
||||
typedef MONITORINFOEXW MONITORINFOEX;
|
||||
typedef LPMONITORINFOEXW LPMONITORINFOEX;
|
||||
#else
|
||||
typedef MONITORINFOEXA MONITORINFOEX;
|
||||
typedef LPMONITORINFOEXA LPMONITORINFOEX;
|
||||
#endif // UNICODE
|
||||
#else // ndef __cplusplus
|
||||
typedef struct tagMONITORINFOEXA
|
||||
{
|
||||
MONITORINFO;
|
||||
CHAR szDevice[CCHDEVICENAME];
|
||||
} MONITORINFOEXA, *LPMONITORINFOEXA;
|
||||
typedef struct tagMONITORINFOEXW
|
||||
{
|
||||
MONITORINFO;
|
||||
WCHAR szDevice[CCHDEVICENAME];
|
||||
} MONITORINFOEXW, *LPMONITORINFOEXW;
|
||||
#ifdef UNICODE
|
||||
typedef MONITORINFOEXW MONITORINFOEX;
|
||||
typedef LPMONITORINFOEXW LPMONITORINFOEX;
|
||||
#else
|
||||
typedef MONITORINFOEXA MONITORINFOEX;
|
||||
typedef LPMONITORINFOEXA LPMONITORINFOEX;
|
||||
#endif // UNICODE
|
||||
#endif
|
||||
|
||||
typedef BOOL (CALLBACK* MONITORENUMPROC)(HMONITOR, HDC, LPRECT, LPARAM);
|
||||
|
||||
#ifndef DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
|
||||
typedef struct _DISPLAY_DEVICEA {
|
||||
DWORD cb;
|
||||
CHAR DeviceName[32];
|
||||
CHAR DeviceString[128];
|
||||
DWORD StateFlags;
|
||||
CHAR DeviceID[128];
|
||||
CHAR DeviceKey[128];
|
||||
} DISPLAY_DEVICEA, *PDISPLAY_DEVICEA, *LPDISPLAY_DEVICEA;
|
||||
typedef struct _DISPLAY_DEVICEW {
|
||||
DWORD cb;
|
||||
WCHAR DeviceName[32];
|
||||
WCHAR DeviceString[128];
|
||||
DWORD StateFlags;
|
||||
WCHAR DeviceID[128];
|
||||
WCHAR DeviceKey[128];
|
||||
} DISPLAY_DEVICEW, *PDISPLAY_DEVICEW, *LPDISPLAY_DEVICEW;
|
||||
#ifdef UNICODE
|
||||
typedef DISPLAY_DEVICEW DISPLAY_DEVICE;
|
||||
typedef PDISPLAY_DEVICEW PDISPLAY_DEVICE;
|
||||
typedef LPDISPLAY_DEVICEW LPDISPLAY_DEVICE;
|
||||
#else
|
||||
typedef DISPLAY_DEVICEA DISPLAY_DEVICE;
|
||||
typedef PDISPLAY_DEVICEA PDISPLAY_DEVICE;
|
||||
typedef LPDISPLAY_DEVICEA LPDISPLAY_DEVICE;
|
||||
#endif // UNICODE
|
||||
|
||||
#define DISPLAY_DEVICE_ATTACHED_TO_DESKTOP 0x00000001
|
||||
#define DISPLAY_DEVICE_MULTI_DRIVER 0x00000002
|
||||
#define DISPLAY_DEVICE_PRIMARY_DEVICE 0x00000004
|
||||
#define DISPLAY_DEVICE_MIRRORING_DRIVER 0x00000008
|
||||
#define DISPLAY_DEVICE_VGA_COMPATIBLE 0x00000010
|
||||
#endif
|
||||
|
||||
#endif // SM_CMONITORS
|
||||
|
||||
#undef GetMonitorInfo
|
||||
#undef GetSystemMetrics
|
||||
#undef MonitorFromWindow
|
||||
#undef MonitorFromRect
|
||||
#undef MonitorFromPoint
|
||||
#undef EnumDisplayMonitors
|
||||
#undef EnumDisplayDevices
|
||||
|
||||
//
|
||||
// Define COMPILE_MULTIMON_STUBS to compile the stubs;
|
||||
// otherwise, you get the declarations.
|
||||
//
|
||||
#ifdef COMPILE_MULTIMON_STUBS
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Implement the API stubs.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _MULTIMON_USE_SECURE_CRT
|
||||
#if defined(__GOT_SECURE_LIB__) && __GOT_SECURE_LIB__ >= 200402L
|
||||
#define _MULTIMON_USE_SECURE_CRT 1
|
||||
#else
|
||||
#define _MULTIMON_USE_SECURE_CRT 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef MULTIMON_FNS_DEFINED
|
||||
|
||||
int (WINAPI* g_pfnGetSystemMetrics)(int) = NULL;
|
||||
HMONITOR (WINAPI* g_pfnMonitorFromWindow)(HWND, DWORD) = NULL;
|
||||
HMONITOR (WINAPI* g_pfnMonitorFromRect)(LPCRECT, DWORD) = NULL;
|
||||
HMONITOR (WINAPI* g_pfnMonitorFromPoint)(POINT, DWORD) = NULL;
|
||||
BOOL (WINAPI* g_pfnGetMonitorInfo)(HMONITOR, LPMONITORINFO) = NULL;
|
||||
BOOL (WINAPI* g_pfnEnumDisplayMonitors)(HDC, LPCRECT, MONITORENUMPROC, LPARAM) = NULL;
|
||||
BOOL (WINAPI* g_pfnEnumDisplayDevices)(PVOID, DWORD, PDISPLAY_DEVICE,DWORD) = NULL;
|
||||
BOOL g_fMultiMonInitDone = FALSE;
|
||||
BOOL g_fMultimonPlatformNT = FALSE;
|
||||
|
||||
#endif
|
||||
|
||||
BOOL IsPlatformNT()
|
||||
{
|
||||
OSVERSIONINFOA osvi = {0};
|
||||
osvi.dwOSVersionInfoSize = sizeof(osvi);
|
||||
GetVersionExA((OSVERSIONINFOA*)&osvi);
|
||||
return (VER_PLATFORM_WIN32_NT == osvi.dwPlatformId);
|
||||
}
|
||||
|
||||
BOOL InitMultipleMonitorStubs(void)
|
||||
{
|
||||
HMODULE hUser32;
|
||||
if (g_fMultiMonInitDone)
|
||||
{
|
||||
return g_pfnGetMonitorInfo != NULL;
|
||||
}
|
||||
|
||||
g_fMultimonPlatformNT = IsPlatformNT();
|
||||
hUser32 = GetModuleHandle(TEXT("USER32"));
|
||||
if (hUser32 &&
|
||||
(*(FARPROC*)&g_pfnGetSystemMetrics = GetProcAddress(hUser32,"GetSystemMetrics")) != NULL &&
|
||||
(*(FARPROC*)&g_pfnMonitorFromWindow = GetProcAddress(hUser32,"MonitorFromWindow")) != NULL &&
|
||||
(*(FARPROC*)&g_pfnMonitorFromRect = GetProcAddress(hUser32,"MonitorFromRect")) != NULL &&
|
||||
(*(FARPROC*)&g_pfnMonitorFromPoint = GetProcAddress(hUser32,"MonitorFromPoint")) != NULL &&
|
||||
(*(FARPROC*)&g_pfnEnumDisplayMonitors = GetProcAddress(hUser32,"EnumDisplayMonitors")) != NULL &&
|
||||
#ifdef UNICODE
|
||||
(*(FARPROC*)&g_pfnEnumDisplayDevices = GetProcAddress(hUser32,"EnumDisplayDevicesW")) != NULL &&
|
||||
(*(FARPROC*)&g_pfnGetMonitorInfo = g_fMultimonPlatformNT ? GetProcAddress(hUser32,"GetMonitorInfoW") :
|
||||
GetProcAddress(hUser32,"GetMonitorInfoA")) != NULL
|
||||
#else
|
||||
(*(FARPROC*)&g_pfnGetMonitorInfo = GetProcAddress(hUser32,"GetMonitorInfoA")) != NULL &&
|
||||
(*(FARPROC*)&g_pfnEnumDisplayDevices = GetProcAddress(hUser32,"EnumDisplayDevicesA")) != NULL
|
||||
#endif
|
||||
) {
|
||||
g_fMultiMonInitDone = TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pfnGetSystemMetrics = NULL;
|
||||
g_pfnMonitorFromWindow = NULL;
|
||||
g_pfnMonitorFromRect = NULL;
|
||||
g_pfnMonitorFromPoint = NULL;
|
||||
g_pfnGetMonitorInfo = NULL;
|
||||
g_pfnEnumDisplayMonitors = NULL;
|
||||
g_pfnEnumDisplayDevices = NULL;
|
||||
|
||||
g_fMultiMonInitDone = TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// fake implementations of Monitor APIs that work with the primary display
|
||||
// no special parameter validation is made since these run in client code
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int WINAPI
|
||||
xGetSystemMetrics(int nIndex)
|
||||
{
|
||||
if (InitMultipleMonitorStubs())
|
||||
return g_pfnGetSystemMetrics(nIndex);
|
||||
|
||||
switch (nIndex)
|
||||
{
|
||||
case SM_CMONITORS:
|
||||
case SM_SAMEDISPLAYFORMAT:
|
||||
return 1;
|
||||
|
||||
case SM_XVIRTUALSCREEN:
|
||||
case SM_YVIRTUALSCREEN:
|
||||
return 0;
|
||||
|
||||
case SM_CXVIRTUALSCREEN:
|
||||
nIndex = SM_CXSCREEN;
|
||||
break;
|
||||
|
||||
case SM_CYVIRTUALSCREEN:
|
||||
nIndex = SM_CYSCREEN;
|
||||
break;
|
||||
}
|
||||
|
||||
return GetSystemMetrics(nIndex);
|
||||
}
|
||||
|
||||
#define xPRIMARY_MONITOR ((HMONITOR)0x12340042)
|
||||
|
||||
HMONITOR WINAPI
|
||||
xMonitorFromPoint(POINT ptScreenCoords, DWORD dwFlags)
|
||||
{
|
||||
if (InitMultipleMonitorStubs())
|
||||
return g_pfnMonitorFromPoint(ptScreenCoords, dwFlags);
|
||||
|
||||
if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
|
||||
((ptScreenCoords.x >= 0) &&
|
||||
(ptScreenCoords.x < GetSystemMetrics(SM_CXSCREEN)) &&
|
||||
(ptScreenCoords.y >= 0) &&
|
||||
(ptScreenCoords.y < GetSystemMetrics(SM_CYSCREEN))))
|
||||
{
|
||||
return xPRIMARY_MONITOR;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HMONITOR WINAPI
|
||||
xMonitorFromRect(LPCRECT lprcScreenCoords, DWORD dwFlags)
|
||||
{
|
||||
if (InitMultipleMonitorStubs())
|
||||
return g_pfnMonitorFromRect(lprcScreenCoords, dwFlags);
|
||||
|
||||
if ((dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST)) ||
|
||||
((lprcScreenCoords->right > 0) &&
|
||||
(lprcScreenCoords->bottom > 0) &&
|
||||
(lprcScreenCoords->left < GetSystemMetrics(SM_CXSCREEN)) &&
|
||||
(lprcScreenCoords->top < GetSystemMetrics(SM_CYSCREEN))))
|
||||
{
|
||||
return xPRIMARY_MONITOR;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HMONITOR WINAPI
|
||||
xMonitorFromWindow(HWND hWnd, DWORD dwFlags)
|
||||
{
|
||||
WINDOWPLACEMENT wp;
|
||||
|
||||
if (InitMultipleMonitorStubs())
|
||||
return g_pfnMonitorFromWindow(hWnd, dwFlags);
|
||||
|
||||
if (dwFlags & (MONITOR_DEFAULTTOPRIMARY | MONITOR_DEFAULTTONEAREST))
|
||||
return xPRIMARY_MONITOR;
|
||||
|
||||
if (IsIconic(hWnd) ?
|
||||
GetWindowPlacement(hWnd, &wp) :
|
||||
GetWindowRect(hWnd, &wp.rcNormalPosition)) {
|
||||
|
||||
return xMonitorFromRect(&wp.rcNormalPosition, dwFlags);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL WINAPI
|
||||
xGetMonitorInfo(HMONITOR hMonitor, __inout LPMONITORINFO lpMonitorInfo)
|
||||
{
|
||||
RECT rcWork;
|
||||
|
||||
if (InitMultipleMonitorStubs())
|
||||
{
|
||||
BOOL f = g_pfnGetMonitorInfo(hMonitor, lpMonitorInfo);
|
||||
#ifdef UNICODE
|
||||
if (f && !g_fMultimonPlatformNT && (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEX)))
|
||||
{
|
||||
MultiByteToWideChar(CP_ACP, 0,
|
||||
(LPSTR)((MONITORINFOEX*)lpMonitorInfo)->szDevice, -1,
|
||||
((MONITORINFOEX*)lpMonitorInfo)->szDevice, (sizeof(((MONITORINFOEX*)lpMonitorInfo)->szDevice)/sizeof(TCHAR)));
|
||||
}
|
||||
#endif
|
||||
return f;
|
||||
}
|
||||
|
||||
if ((hMonitor == xPRIMARY_MONITOR) &&
|
||||
lpMonitorInfo &&
|
||||
(lpMonitorInfo->cbSize >= sizeof(MONITORINFO)) &&
|
||||
SystemParametersInfoA(SPI_GETWORKAREA, 0, &rcWork, 0))
|
||||
{
|
||||
lpMonitorInfo->rcMonitor.left = 0;
|
||||
lpMonitorInfo->rcMonitor.top = 0;
|
||||
lpMonitorInfo->rcMonitor.right = GetSystemMetrics(SM_CXSCREEN);
|
||||
lpMonitorInfo->rcMonitor.bottom = GetSystemMetrics(SM_CYSCREEN);
|
||||
lpMonitorInfo->rcWork = rcWork;
|
||||
lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;
|
||||
|
||||
if (lpMonitorInfo->cbSize >= sizeof(MONITORINFOEX))
|
||||
{
|
||||
#ifdef UNICODE
|
||||
MultiByteToWideChar(CP_ACP, 0, "DISPLAY", -1, ((MONITORINFOEX*)lpMonitorInfo)->szDevice, (sizeof(((MONITORINFOEX*)lpMonitorInfo)->szDevice)/sizeof(TCHAR)));
|
||||
#else // UNICODE
|
||||
#if _MULTIMON_USE_SECURE_CRT
|
||||
strncpy_s(((MONITORINFOEX*)lpMonitorInfo)->szDevice, (sizeof(((MONITORINFOEX*)lpMonitorInfo)->szDevice)/sizeof(TCHAR)), TEXT("DISPLAY"), (sizeof(((MONITORINFOEX*)lpMonitorInfo)->szDevice)/sizeof(TCHAR)) - 1);
|
||||
#else
|
||||
lstrcpyn(((MONITORINFOEX*)lpMonitorInfo)->szDevice, TEXT("DISPLAY"), (sizeof(((MONITORINFOEX*)lpMonitorInfo)->szDevice)/sizeof(TCHAR)));
|
||||
#endif // _MULTIMON_USE_SECURE_CRT
|
||||
#endif // UNICODE
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL WINAPI
|
||||
xEnumDisplayMonitors(
|
||||
HDC hdcOptionalForPainting,
|
||||
LPCRECT lprcEnumMonitorsThatIntersect,
|
||||
MONITORENUMPROC lpfnEnumProc,
|
||||
LPARAM dwData)
|
||||
{
|
||||
RECT rcLimit;
|
||||
|
||||
if (InitMultipleMonitorStubs()) {
|
||||
return g_pfnEnumDisplayMonitors(
|
||||
hdcOptionalForPainting,
|
||||
lprcEnumMonitorsThatIntersect,
|
||||
lpfnEnumProc,
|
||||
dwData);
|
||||
}
|
||||
|
||||
if (!lpfnEnumProc)
|
||||
return FALSE;
|
||||
|
||||
rcLimit.left = 0;
|
||||
rcLimit.top = 0;
|
||||
rcLimit.right = GetSystemMetrics(SM_CXSCREEN);
|
||||
rcLimit.bottom = GetSystemMetrics(SM_CYSCREEN);
|
||||
|
||||
if (hdcOptionalForPainting)
|
||||
{
|
||||
RECT rcClip;
|
||||
POINT ptOrg;
|
||||
|
||||
switch (GetClipBox(hdcOptionalForPainting, &rcClip))
|
||||
{
|
||||
default:
|
||||
if (!GetDCOrgEx(hdcOptionalForPainting, &ptOrg))
|
||||
return FALSE;
|
||||
|
||||
OffsetRect(&rcLimit, -ptOrg.x, -ptOrg.y);
|
||||
if (IntersectRect(&rcLimit, &rcLimit, &rcClip) &&
|
||||
(!lprcEnumMonitorsThatIntersect ||
|
||||
IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect))) {
|
||||
|
||||
break;
|
||||
}
|
||||
//fall thru
|
||||
case NULLREGION:
|
||||
return TRUE;
|
||||
case ERROR:
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
if ( lprcEnumMonitorsThatIntersect &&
|
||||
!IntersectRect(&rcLimit, &rcLimit, lprcEnumMonitorsThatIntersect)) {
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return lpfnEnumProc(
|
||||
xPRIMARY_MONITOR,
|
||||
hdcOptionalForPainting,
|
||||
&rcLimit,
|
||||
dwData);
|
||||
}
|
||||
|
||||
BOOL WINAPI
|
||||
xEnumDisplayDevices(
|
||||
PVOID Unused,
|
||||
DWORD iDevNum,
|
||||
__inout PDISPLAY_DEVICE lpDisplayDevice,
|
||||
DWORD dwFlags)
|
||||
{
|
||||
if (InitMultipleMonitorStubs())
|
||||
return g_pfnEnumDisplayDevices(Unused, iDevNum, lpDisplayDevice, dwFlags);
|
||||
|
||||
if (Unused != NULL)
|
||||
return FALSE;
|
||||
|
||||
if (iDevNum != 0)
|
||||
return FALSE;
|
||||
|
||||
if (lpDisplayDevice == NULL || lpDisplayDevice->cb < sizeof(DISPLAY_DEVICE))
|
||||
return FALSE;
|
||||
|
||||
#ifdef UNICODE
|
||||
MultiByteToWideChar(CP_ACP, 0, "DISPLAY", -1, lpDisplayDevice->DeviceName, (sizeof(lpDisplayDevice->DeviceName)/sizeof(TCHAR)));
|
||||
MultiByteToWideChar(CP_ACP, 0, "DISPLAY", -1, lpDisplayDevice->DeviceString, (sizeof(lpDisplayDevice->DeviceString)/sizeof(TCHAR)));
|
||||
#else // UNICODE
|
||||
#if _MULTIMON_USE_SECURE_CRT
|
||||
strncpy_s((LPTSTR)lpDisplayDevice->DeviceName, (sizeof(lpDisplayDevice->DeviceName)/sizeof(TCHAR)), TEXT("DISPLAY"), (sizeof(lpDisplayDevice->DeviceName)/sizeof(TCHAR)) - 1);
|
||||
strncpy_s((LPTSTR)lpDisplayDevice->DeviceString, (sizeof(lpDisplayDevice->DeviceString)/sizeof(TCHAR)), TEXT("DISPLAY"), (sizeof(lpDisplayDevice->DeviceName)/sizeof(TCHAR)) - 1);
|
||||
#else
|
||||
lstrcpyn((LPTSTR)lpDisplayDevice->DeviceName, TEXT("DISPLAY"), (sizeof(lpDisplayDevice->DeviceName)/sizeof(TCHAR)));
|
||||
lstrcpyn((LPTSTR)lpDisplayDevice->DeviceString, TEXT("DISPLAY"), (sizeof(lpDisplayDevice->DeviceString)/sizeof(TCHAR)));
|
||||
#endif // _MULTIMON_USE_SECURE_CRT
|
||||
#endif // UNICODE
|
||||
|
||||
lpDisplayDevice->StateFlags = DISPLAY_DEVICE_ATTACHED_TO_DESKTOP | DISPLAY_DEVICE_PRIMARY_DEVICE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#undef xPRIMARY_MONITOR
|
||||
#undef COMPILE_MULTIMON_STUBS
|
||||
|
||||
#else // COMPILE_MULTIMON_STUBS
|
||||
|
||||
extern int WINAPI xGetSystemMetrics(int);
|
||||
extern HMONITOR WINAPI xMonitorFromWindow(HWND, DWORD);
|
||||
extern HMONITOR WINAPI xMonitorFromRect(LPCRECT, DWORD);
|
||||
extern HMONITOR WINAPI xMonitorFromPoint(POINT, DWORD);
|
||||
extern BOOL WINAPI xGetMonitorInfo(HMONITOR, LPMONITORINFO);
|
||||
extern BOOL WINAPI xEnumDisplayMonitors(HDC, LPCRECT, MONITORENUMPROC, LPARAM);
|
||||
extern BOOL WINAPI xEnumDisplayDevices(PVOID, DWORD, PDISPLAY_DEVICE, DWORD);
|
||||
|
||||
#endif // COMPILE_MULTIMON_STUBS
|
||||
|
||||
//
|
||||
// build defines that replace the regular APIs with our versions
|
||||
//
|
||||
#define GetSystemMetrics xGetSystemMetrics
|
||||
#define MonitorFromWindow xMonitorFromWindow
|
||||
#define MonitorFromRect xMonitorFromRect
|
||||
#define MonitorFromPoint xMonitorFromPoint
|
||||
#define GetMonitorInfo xGetMonitorInfo
|
||||
#define EnumDisplayMonitors xEnumDisplayMonitors
|
||||
#define EnumDisplayDevices xEnumDisplayDevices
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
|
||||
+26
-3
@@ -163,7 +163,7 @@ OCV_OPTION(WITH_XINE "Include Xine support (GPL)" OFF
|
||||
OCV_OPTION(WITH_OPENCL "Include OpenCL Runtime support" ON IF (NOT IOS) )
|
||||
OCV_OPTION(WITH_OPENCLAMDFFT "Include AMD OpenCL FFT library support" ON IF (NOT ANDROID AND NOT IOS) )
|
||||
OCV_OPTION(WITH_OPENCLAMDBLAS "Include AMD OpenCL BLAS library support" ON IF (NOT ANDROID AND NOT IOS) )
|
||||
|
||||
OCV_OPTION(WITH_INTELPERC "Include Intel Perceptual Computing support" OFF IF WIN32 )
|
||||
|
||||
# OpenCV build components
|
||||
# ===================================================
|
||||
@@ -201,6 +201,7 @@ OCV_OPTION(INSTALL_TO_MANGLED_PATHS "Enables mangled install paths, that help wi
|
||||
|
||||
# OpenCV build options
|
||||
# ===================================================
|
||||
OCV_OPTION(ENABLE_DYNAMIC_CUDA "Enabled dynamic CUDA linkage" ON IF ANDROID )
|
||||
OCV_OPTION(ENABLE_PRECOMPILED_HEADERS "Use precompiled headers" ON IF (NOT IOS) )
|
||||
OCV_OPTION(ENABLE_SOLUTION_FOLDERS "Solution folder in Visual Studio or in other IDEs" (MSVC_IDE OR CMAKE_GENERATOR MATCHES Xcode) IF (CMAKE_VERSION VERSION_GREATER "2.8.0") )
|
||||
OCV_OPTION(ENABLE_PROFILING "Enable profiling in the GCC compiler (Add flags: -g -pg)" OFF IF CMAKE_COMPILER_IS_GNUCXX )
|
||||
@@ -214,9 +215,12 @@ OCV_OPTION(ENABLE_SSSE3 "Enable SSSE3 instructions"
|
||||
OCV_OPTION(ENABLE_SSE41 "Enable SSE4.1 instructions" OFF IF ((CV_ICC OR CMAKE_COMPILER_IS_GNUCXX) AND (X86 OR X86_64)) )
|
||||
OCV_OPTION(ENABLE_SSE42 "Enable SSE4.2 instructions" OFF IF (CMAKE_COMPILER_IS_GNUCXX AND (X86 OR X86_64)) )
|
||||
OCV_OPTION(ENABLE_AVX "Enable AVX instructions" OFF IF ((MSVC OR CMAKE_COMPILER_IS_GNUCXX) AND (X86 OR X86_64)) )
|
||||
OCV_OPTION(ENABLE_NEON "Enable NEON instructions" OFF IF CMAKE_COMPILER_IS_GNUCXX AND ARM )
|
||||
OCV_OPTION(ENABLE_VFPV3 "Enable VFPv3-D32 instructions" OFF IF CMAKE_COMPILER_IS_GNUCXX AND ARM )
|
||||
OCV_OPTION(ENABLE_NOISY_WARNINGS "Show all warnings even if they are too noisy" OFF )
|
||||
OCV_OPTION(OPENCV_WARNINGS_ARE_ERRORS "Treat warnings as errors" OFF )
|
||||
OCV_OPTION(ENABLE_WINRT_MODE "Build with Windows Runtime support" OFF IF WIN32 )
|
||||
OCV_OPTION(ENABLE_WINRT_MODE_NATIVE "Build with Windows Runtime native C++ support" OFF IF WIN32 )
|
||||
|
||||
# uncategorized options
|
||||
# ===================================================
|
||||
@@ -240,6 +244,15 @@ include(cmake/OpenCVVersion.cmake)
|
||||
# Save libs and executables in the same place
|
||||
set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}/bin" CACHE PATH "Output directory for applications" )
|
||||
|
||||
if (ANDROID)
|
||||
if (ANDROID_ABI MATCHES "NEON")
|
||||
set(ENABLE_NEON ON)
|
||||
endif()
|
||||
if (ANDROID_ABI MATCHES "VFPV3")
|
||||
set(ENABLE_VFPV3 ON)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ANDROID OR WIN32)
|
||||
set(OPENCV_DOC_INSTALL_PATH doc)
|
||||
elseif(INSTALL_TO_MANGLED_PATHS)
|
||||
@@ -461,7 +474,11 @@ endif()
|
||||
# ----------------------------------------------------------------------------
|
||||
# Add CUDA libraries (needed for apps/tools, samples)
|
||||
# ----------------------------------------------------------------------------
|
||||
if(HAVE_CUDA)
|
||||
if(NOT HAVE_CUDA)
|
||||
set(ENABLE_DYNAMIC_CUDA OFF)
|
||||
endif()
|
||||
|
||||
if(HAVE_CUDA AND NOT ENABLE_DYNAMIC_CUDA)
|
||||
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY})
|
||||
if(HAVE_CUBLAS)
|
||||
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDA_cublas_LIBRARY})
|
||||
@@ -470,6 +487,7 @@ if(HAVE_CUDA)
|
||||
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDA_cufft_LIBRARY})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Solution folders:
|
||||
# ----------------------------------------------------------------------------
|
||||
@@ -649,7 +667,7 @@ endif()
|
||||
if(WIN32)
|
||||
status("")
|
||||
status(" Windows RT support:" HAVE_WINRT THEN YES ELSE NO)
|
||||
if (ENABLE_WINRT_MODE)
|
||||
if (ENABLE_WINRT_MODE OR ENABLE_WINRT_MODE_NATIVE)
|
||||
status(" Windows SDK v8.0:" ${WINDOWS_SDK_PATH})
|
||||
status(" Visual Studio 2012:" ${VISUAL_STUDIO_PATH})
|
||||
endif()
|
||||
@@ -829,6 +847,11 @@ if(DEFINED WITH_XINE)
|
||||
status(" Xine:" HAVE_XINE THEN "YES (ver ${ALIASOF_libxine_VERSION})" ELSE NO)
|
||||
endif(DEFINED WITH_XINE)
|
||||
|
||||
if(DEFINED WITH_INTELPERC)
|
||||
status(" Intel PerC:" HAVE_INTELPERC THEN "YES" ELSE NO)
|
||||
endif(DEFINED WITH_INTELPERC)
|
||||
|
||||
|
||||
# ========================== Other third-party libraries ==========================
|
||||
status("")
|
||||
status(" Other third-party libraries:")
|
||||
|
||||
@@ -9,7 +9,7 @@ set(HAVE_WINRT FALSE)
|
||||
# search Windows Platform SDK
|
||||
message(STATUS "Checking for Windows Platform SDK")
|
||||
GET_FILENAME_COMPONENT(WINDOWS_SDK_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v8.0;InstallationFolder]" ABSOLUTE CACHE)
|
||||
if (WINDOWS_SDK_PATH STREQUAL "")
|
||||
if(WINDOWS_SDK_PATH STREQUAL "")
|
||||
set(HAVE_MSPDK FALSE)
|
||||
message(STATUS "Windows Platform SDK 8.0 was not found")
|
||||
else()
|
||||
@@ -19,7 +19,7 @@ endif()
|
||||
#search for Visual Studio 11.0 install directory
|
||||
message(STATUS "Checking for Visual Studio 2012")
|
||||
GET_FILENAME_COMPONENT(VISUAL_STUDIO_PATH [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\11.0\\Setup\\VS;ProductDir] REALPATH CACHE)
|
||||
if (VISUAL_STUDIO_PATH STREQUAL "")
|
||||
if(VISUAL_STUDIO_PATH STREQUAL "")
|
||||
set(HAVE_MSVC2012 FALSE)
|
||||
message(STATUS "Visual Studio 2012 was not found")
|
||||
else()
|
||||
@@ -30,11 +30,15 @@ try_compile(HAVE_WINRT_SDK
|
||||
"${OpenCV_BINARY_DIR}"
|
||||
"${OpenCV_SOURCE_DIR}/cmake/checks/winrttest.cpp")
|
||||
|
||||
if (ENABLE_WINRT_MODE AND HAVE_WINRT_SDK AND HAVE_MSVC2012 AND HAVE_MSPDK)
|
||||
if(ENABLE_WINRT_MODE AND HAVE_WINRT_SDK AND HAVE_MSVC2012 AND HAVE_MSPDK)
|
||||
set(HAVE_WINRT TRUE)
|
||||
set(HAVE_WINRT_CX TRUE)
|
||||
elseif(ENABLE_WINRT_MODE_NATIVE AND HAVE_WINRT_SDK AND HAVE_MSVC2012 AND HAVE_MSPDK)
|
||||
set(HAVE_WINRT TRUE)
|
||||
set(HAVE_WINRT_CX FALSE)
|
||||
endif()
|
||||
|
||||
if (HAVE_WINRT)
|
||||
if(HAVE_WINRT)
|
||||
add_definitions(/DWINVER=0x0602 /DNTDDI_VERSION=NTDDI_WIN8 /D_WIN32_WINNT=0x0602)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /appcontainer")
|
||||
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /appcontainer")
|
||||
|
||||
@@ -130,6 +130,12 @@ if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
if(ENABLE_SSE2)
|
||||
add_extra_compiler_option(-msse2)
|
||||
endif()
|
||||
if (ENABLE_NEON)
|
||||
add_extra_compiler_option("-mfpu=neon")
|
||||
endif()
|
||||
if (ENABLE_VFPV3 AND NOT ENABLE_NEON)
|
||||
add_extra_compiler_option("-mfpu=vfpv3")
|
||||
endif()
|
||||
|
||||
# SSE3 and further should be disabled under MingW because it generates compiler errors
|
||||
if(NOT MINGW)
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
# Main variables:
|
||||
# INTELPERC_LIBRARIES and INTELPERC_INCLUDE to link Intel Perceptial Computing SDK modules
|
||||
# HAVE_INTELPERC for conditional compilation OpenCV with/without Intel Perceptial Computing SDK
|
||||
|
||||
if(X86_64)
|
||||
find_path(INTELPERC_INCLUDE_DIR "pxcsession.h" PATHS "$ENV{PCSDK_DIR}include" DOC "Path to Intel Perceptual Computing SDK interface headers")
|
||||
find_file(INTELPERC_LIBRARIES "libpxc.lib" PATHS "$ENV{PCSDK_DIR}lib/x64" DOC "Path to Intel Perceptual Computing SDK interface libraries")
|
||||
else()
|
||||
find_path(INTELPERC_INCLUDE_DIR "pxcsession.h" PATHS "$ENV{PCSDK_DIR}include" DOC "Path to Intel Perceptual Computing SDK interface headers")
|
||||
find_file(INTELPERC_LIBRARIES "libpxc.lib" PATHS "$ENV{PCSDK_DIR}lib/Win32" DOC "Path to Intel Perceptual Computing SDK interface libraries")
|
||||
endif()
|
||||
|
||||
if(INTELPERC_INCLUDE_DIR AND INTELPERC_LIBRARIES)
|
||||
set(HAVE_INTELPERC TRUE)
|
||||
else()
|
||||
set(HAVE_INTELPERC FALSE)
|
||||
message(WARNING "Intel Perceptual Computing SDK library directory (set by INTELPERC_LIB_DIR variable) is not found or does not have Intel Perceptual Computing SDK libraries.")
|
||||
endif() #if(INTELPERC_INCLUDE_DIR AND INTELPERC_LIBRARIES)
|
||||
|
||||
mark_as_advanced(FORCE INTELPERC_LIBRARIES INTELPERC_INCLUDE_DIR)
|
||||
@@ -250,3 +250,8 @@ if (NOT IOS)
|
||||
set(HAVE_QTKIT YES)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# --- Intel Perceptual Computing SDK ---
|
||||
if(WITH_INTELPERC)
|
||||
include("${OpenCV_SOURCE_DIR}/cmake/OpenCVFindIntelPerCSDK.cmake")
|
||||
endif(WITH_INTELPERC)
|
||||
|
||||
@@ -44,6 +44,7 @@ if(ANDROID)
|
||||
|
||||
# build the list of opencv libs and dependencies for all modules
|
||||
set(OPENCV_MODULES_CONFIGMAKE "")
|
||||
set(OPENCV_HAVE_GPU_MODULE_CONFIGMAKE "off")
|
||||
set(OPENCV_EXTRA_COMPONENTS_CONFIGMAKE "")
|
||||
set(OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE "")
|
||||
foreach(m ${OPENCV_MODULES_PUBLIC})
|
||||
@@ -53,6 +54,11 @@ if(ANDROID)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# remove CUDA runtime and NPP from regular deps
|
||||
# it can be added separately if needed.
|
||||
ocv_list_filterout(OPENCV_EXTRA_COMPONENTS_CONFIGMAKE "libcu")
|
||||
ocv_list_filterout(OPENCV_EXTRA_COMPONENTS_CONFIGMAKE "libnpp")
|
||||
|
||||
# split 3rdparty libs and modules
|
||||
foreach(mod ${OPENCV_MODULES_CONFIGMAKE})
|
||||
if(NOT mod MATCHES "^opencv_.+$")
|
||||
@@ -63,6 +69,14 @@ if(ANDROID)
|
||||
list(REMOVE_ITEM OPENCV_MODULES_CONFIGMAKE ${OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE})
|
||||
endif()
|
||||
|
||||
# GPU module enabled separately
|
||||
list(REMOVE_ITEM OPENCV_MODULES_CONFIGMAKE "opencv_gpu")
|
||||
list(REMOVE_ITEM OPENCV_MODULES_CONFIGMAKE "opencv_dynamicuda")
|
||||
|
||||
if(HAVE_opencv_gpu)
|
||||
set(OPENCV_HAVE_GPU_MODULE_CONFIGMAKE "on")
|
||||
endif()
|
||||
|
||||
# convert CMake lists to makefile literals
|
||||
foreach(lst OPENCV_MODULES_CONFIGMAKE OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE OPENCV_EXTRA_COMPONENTS_CONFIGMAKE)
|
||||
ocv_list_unique(${lst})
|
||||
|
||||
@@ -488,7 +488,7 @@ macro(ocv_glob_module_sources)
|
||||
file(GLOB lib_cuda_srcs "src/cuda/*.cu")
|
||||
set(cuda_objs "")
|
||||
set(lib_cuda_hdrs "")
|
||||
if(HAVE_CUDA AND lib_cuda_srcs)
|
||||
if(HAVE_CUDA)
|
||||
ocv_include_directories(${CUDA_INCLUDE_DIRS})
|
||||
file(GLOB lib_cuda_hdrs "src/cuda/*.hpp")
|
||||
|
||||
@@ -537,9 +537,6 @@ macro(ocv_create_module)
|
||||
target_link_libraries(${the_module} ${OPENCV_MODULE_${the_module}_DEPS})
|
||||
target_link_libraries(${the_module} LINK_INTERFACE_LIBRARIES ${OPENCV_MODULE_${the_module}_DEPS})
|
||||
target_link_libraries(${the_module} ${OPENCV_MODULE_${the_module}_DEPS_EXT} ${OPENCV_LINKER_LIBS} ${IPP_LIBS} ${ARGN})
|
||||
if (HAVE_CUDA)
|
||||
target_link_libraries(${the_module} ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_dependencies(opencv_modules ${the_module})
|
||||
|
||||
@@ -13,6 +13,19 @@ OPENCV_BASEDIR:=@OPENCV_BASE_INCLUDE_DIR_CONFIGCMAKE@
|
||||
OPENCV_LOCAL_C_INCLUDES:=@OPENCV_INCLUDE_DIRS_CONFIGCMAKE@
|
||||
OPENCV_MODULES:=@OPENCV_MODULES_CONFIGMAKE@
|
||||
|
||||
OPENCV_HAVE_GPU_MODULE=@OPENCV_HAVE_GPU_MODULE_CONFIGMAKE@
|
||||
OPENCV_USE_GPU_MODULE:=
|
||||
|
||||
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
|
||||
ifeq ($(OPENCV_HAVE_GPU_MODULE),on)
|
||||
ifneq ($(CUDA_TOOLKIT_DIR),)
|
||||
OPENCV_USE_GPU_MODULE:=on
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
CUDA_RUNTIME_LIBS:=cufft npps nppi nppc cudart
|
||||
|
||||
ifeq ($(OPENCV_LIB_TYPE),)
|
||||
OPENCV_LIB_TYPE:=@OPENCV_LIBTYPE_CONFIGMAKE@
|
||||
endif
|
||||
@@ -102,12 +115,22 @@ ifeq ($(OPENCV_MK_$(OPENCV_TARGET_ARCH_ABI)_ALREADY_INCLUDED),)
|
||||
|
||||
ifneq ($(OPENCV_BASEDIR),)
|
||||
OPENCV_LOCAL_C_INCLUDES += $(foreach mod, $(OPENCV_MODULES), $(OPENCV_BASEDIR)/modules/$(mod)/include)
|
||||
ifeq ($(OPENCV_USE_GPU_MODULE),on)
|
||||
OPENCV_LOCAL_C_INCLUDES += $(OPENCV_BASEDIR)/modules/gpu/include
|
||||
endif
|
||||
endif
|
||||
|
||||
#turn off module installation to prevent their redefinition
|
||||
OPENCV_MK_$(OPENCV_TARGET_ARCH_ABI)_ALREADY_INCLUDED:=on
|
||||
endif
|
||||
|
||||
ifeq ($(OPENCV_USE_GPU_MODULE),on)
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE:=opencv_gpu
|
||||
LOCAL_SRC_FILES:=$(OPENCV_LIBS_DIR)/libopencv_gpu.a
|
||||
include $(PREBUILT_STATIC_LIBRARY)
|
||||
endif
|
||||
|
||||
ifeq ($(OPENCV_LOCAL_CFLAGS),)
|
||||
OPENCV_LOCAL_CFLAGS := -fPIC -DANDROID -fsigned-char
|
||||
endif
|
||||
@@ -116,6 +139,10 @@ include $(CLEAR_VARS)
|
||||
LOCAL_C_INCLUDES += $(OPENCV_LOCAL_C_INCLUDES)
|
||||
LOCAL_CFLAGS += $(OPENCV_LOCAL_CFLAGS)
|
||||
|
||||
ifeq ($(OPENCV_USE_GPU_MODULE),on)
|
||||
LOCAL_C_INCLUDES += $(CUDA_TOOLKIT_DIR)/include
|
||||
endif
|
||||
|
||||
ifeq ($(OPENCV_INSTALL_MODULES),on)
|
||||
LOCAL_$(OPENCV_LIB_TYPE)_LIBRARIES += $(foreach mod, $(OPENCV_LIBS), opencv_$(mod))
|
||||
else
|
||||
@@ -128,5 +155,10 @@ endif
|
||||
|
||||
LOCAL_LDLIBS += $(foreach lib,$(OPENCV_EXTRA_COMPONENTS), -l$(lib))
|
||||
|
||||
ifeq ($(OPENCV_USE_GPU_MODULE),on)
|
||||
LOCAL_STATIC_LIBRARIES+=libopencv_gpu
|
||||
LOCAL_LDLIBS += -L$(CUDA_TOOLKIT_DIR)/lib $(foreach lib, $(CUDA_RUNTIME_LIBS), -l$(lib))
|
||||
endif
|
||||
|
||||
#restore the LOCAL_PATH
|
||||
LOCAL_PATH:=$(USER_LOCAL_PATH)
|
||||
|
||||
@@ -85,6 +85,9 @@
|
||||
/* Apple ImageIO Framework */
|
||||
#cmakedefine HAVE_IMAGEIO
|
||||
|
||||
/* Intel Perceptual Computing SDK library */
|
||||
#cmakedefine HAVE_INTELPERC
|
||||
|
||||
/* Intel Integrated Performance Primitives */
|
||||
#cmakedefine HAVE_IPP
|
||||
|
||||
|
||||
@@ -11,4 +11,5 @@
|
||||
.. |Author_EricCh| unicode:: Eric U+0020 Christiansen
|
||||
.. |Author_AndreyP| unicode:: Andrey U+0020 Pavlenko
|
||||
.. |Author_AlexS| unicode:: Alexander U+0020 Smorkalov
|
||||
.. |Author_BarisD| unicode:: Bar U+0131 U+015F U+0020 Evrim U+0020 Demir U+00F6 z
|
||||
.. |Author_MimmoC| unicode:: Mimmo U+0020 Cosenza
|
||||
.. |Author_BarisD| unicode:: Bar U+0131 U+015F U+0020 Evrim U+0020 Demir U+00F6 z
|
||||
|
||||
@@ -48,10 +48,10 @@ The structure of package contents looks as follows:
|
||||
|
||||
::
|
||||
|
||||
OpenCV-2.4.7-android-sdk
|
||||
OpenCV-2.4.8-android-sdk
|
||||
|_ apk
|
||||
| |_ OpenCV_2.4.7_binary_pack_armv7a.apk
|
||||
| |_ OpenCV_2.4.7_Manager_2.14_XXX.apk
|
||||
| |_ OpenCV_2.4.8_binary_pack_armv7a.apk
|
||||
| |_ OpenCV_2.4.8_Manager_2.16_XXX.apk
|
||||
|
|
||||
|_ doc
|
||||
|_ samples
|
||||
@@ -157,10 +157,10 @@ Get the OpenCV4Android SDK
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
unzip ~/Downloads/OpenCV-2.4.7-android-sdk.zip
|
||||
unzip ~/Downloads/OpenCV-2.4.8-android-sdk.zip
|
||||
|
||||
.. |opencv_android_bin_pack| replace:: :file:`OpenCV-2.4.7-android-sdk.zip`
|
||||
.. _opencv_android_bin_pack_url: http://sourceforge.net/projects/opencvlibrary/files/opencv-android/2.4.7/OpenCV-2.4.7-android-sdk.zip/download
|
||||
.. |opencv_android_bin_pack| replace:: :file:`OpenCV-2.4.8-android-sdk.zip`
|
||||
.. _opencv_android_bin_pack_url: http://sourceforge.net/projects/opencvlibrary/files/opencv-android/2.4.8/OpenCV-2.4.8-android-sdk.zip/download
|
||||
.. |opencv_android_bin_pack_url| replace:: |opencv_android_bin_pack|
|
||||
.. |seven_zip| replace:: 7-Zip
|
||||
.. _seven_zip: http://www.7-zip.org/
|
||||
@@ -295,7 +295,7 @@ Well, running samples from Eclipse is very simple:
|
||||
.. code-block:: sh
|
||||
:linenos:
|
||||
|
||||
<Android SDK path>/platform-tools/adb install <OpenCV4Android SDK path>/apk/OpenCV_2.4.7_Manager_2.14_armv7a-neon.apk
|
||||
<Android SDK path>/platform-tools/adb install <OpenCV4Android SDK path>/apk/OpenCV_2.4.8_Manager_2.16_armv7a-neon.apk
|
||||
|
||||
.. note:: ``armeabi``, ``armv7a-neon``, ``arm7a-neon-android8``, ``mips`` and ``x86`` stand for
|
||||
platform targets:
|
||||
|
||||
@@ -55,14 +55,14 @@ Manager to access OpenCV libraries externally installed in the target system.
|
||||
:guilabel:`File -> Import -> Existing project in your workspace`.
|
||||
|
||||
Press :guilabel:`Browse` button and locate OpenCV4Android SDK
|
||||
(:file:`OpenCV-2.4.7-android-sdk/sdk`).
|
||||
(:file:`OpenCV-2.4.8-android-sdk/sdk`).
|
||||
|
||||
.. image:: images/eclipse_opencv_dependency0.png
|
||||
:alt: Add dependency from OpenCV library
|
||||
:align: center
|
||||
|
||||
#. In application project add a reference to the OpenCV Java SDK in
|
||||
:guilabel:`Project -> Properties -> Android -> Library -> Add` select ``OpenCV Library - 2.4.7``.
|
||||
:guilabel:`Project -> Properties -> Android -> Library -> Add` select ``OpenCV Library - 2.4.8``.
|
||||
|
||||
.. image:: images/eclipse_opencv_dependency1.png
|
||||
:alt: Add dependency from OpenCV library
|
||||
@@ -128,27 +128,27 @@ described above.
|
||||
#. Add the OpenCV library project to your workspace the same way as for the async initialization
|
||||
above. Use menu :guilabel:`File -> Import -> Existing project in your workspace`,
|
||||
press :guilabel:`Browse` button and select OpenCV SDK path
|
||||
(:file:`OpenCV-2.4.7-android-sdk/sdk`).
|
||||
(:file:`OpenCV-2.4.8-android-sdk/sdk`).
|
||||
|
||||
.. image:: images/eclipse_opencv_dependency0.png
|
||||
:alt: Add dependency from OpenCV library
|
||||
:align: center
|
||||
|
||||
#. In the application project add a reference to the OpenCV4Android SDK in
|
||||
:guilabel:`Project -> Properties -> Android -> Library -> Add` select ``OpenCV Library - 2.4.7``;
|
||||
:guilabel:`Project -> Properties -> Android -> Library -> Add` select ``OpenCV Library - 2.4.8``;
|
||||
|
||||
.. image:: images/eclipse_opencv_dependency1.png
|
||||
:alt: Add dependency from OpenCV library
|
||||
:align: center
|
||||
|
||||
#. If your application project **doesn't have a JNI part**, just copy the corresponding OpenCV
|
||||
native libs from :file:`<OpenCV-2.4.7-android-sdk>/sdk/native/libs/<target_arch>` to your
|
||||
native libs from :file:`<OpenCV-2.4.8-android-sdk>/sdk/native/libs/<target_arch>` to your
|
||||
project directory to folder :file:`libs/<target_arch>`.
|
||||
|
||||
In case of the application project **with a JNI part**, instead of manual libraries copying you
|
||||
need to modify your ``Android.mk`` file:
|
||||
add the following two code lines after the ``"include $(CLEAR_VARS)"`` and before
|
||||
``"include path_to_OpenCV-2.4.7-android-sdk/sdk/native/jni/OpenCV.mk"``
|
||||
``"include path_to_OpenCV-2.4.8-android-sdk/sdk/native/jni/OpenCV.mk"``
|
||||
|
||||
.. code-block:: make
|
||||
:linenos:
|
||||
@@ -221,7 +221,7 @@ taken:
|
||||
|
||||
.. code-block:: make
|
||||
|
||||
include C:\Work\OpenCV4Android\OpenCV-2.4.7-android-sdk\sdk\native\jni\OpenCV.mk
|
||||
include C:\Work\OpenCV4Android\OpenCV-2.4.8-android-sdk\sdk\native\jni\OpenCV.mk
|
||||
|
||||
Should be inserted into the :file:`jni/Android.mk` file **after** this line:
|
||||
|
||||
|
||||
@@ -0,0 +1,728 @@
|
||||
.. _clojure_dev_intro:
|
||||
|
||||
Introduction to OpenCV Development with Clojure
|
||||
***********************************************
|
||||
|
||||
As of OpenCV 2.4.4, OpenCV supports desktop Java development using
|
||||
nearly the same interface as for Android development.
|
||||
|
||||
`Clojure <http://clojure.org/>`_ is a contemporary LISP dialect hosted
|
||||
by the Java Virtual Machine and it offers a complete interoperability
|
||||
with the underlying JVM. This means that we should even be able to use
|
||||
the Clojure REPL (Read Eval Print Loop) as and interactive programmable
|
||||
interface to the underlying OpenCV engine.
|
||||
|
||||
What we'll do in this tutorial
|
||||
==============================
|
||||
|
||||
This tutorial will help you in setting up a basic Clojure environment
|
||||
for interactively learning OpenCV within the fully programmable
|
||||
CLojure REPL.
|
||||
|
||||
Tutorial source code
|
||||
--------------------
|
||||
|
||||
You can find a runnable source code of the sample in the
|
||||
:file:`samples/java/clojure/simple-sample` folder of the OpenCV
|
||||
repository. After having installed OpenCV and Clojure as explained in
|
||||
the tutorial, issue the following command to run the sample from the
|
||||
command line.
|
||||
|
||||
.. code:: bash
|
||||
|
||||
cd path/to/samples/java/clojure/simple-sample
|
||||
lein run
|
||||
|
||||
Preamble
|
||||
========
|
||||
|
||||
For detailed instruction on installing OpenCV with desktop Java support
|
||||
refer to the `corresponding tutorial <http://docs.opencv.org/2.4.4-beta/doc/tutorials/introduction/desktop_java/java_dev_intro.html>`_.
|
||||
|
||||
If you are in hurry, here is a minimum quick start guide to install
|
||||
OpenCV on Mac OS X:
|
||||
|
||||
NOTE 1: I'm assuming you already installed
|
||||
`xcode <https://developer.apple.com/xcode/>`_,
|
||||
`jdk <http://www.oracle.com/technetwork/java/javase/downloads/index.html>`_
|
||||
and `Cmake <http://www.cmake.org/cmake/resources/software.html>`_.
|
||||
|
||||
.. code:: bash
|
||||
|
||||
cd ~/
|
||||
mkdir opt
|
||||
git clone https://github.com/Itseez/opencv.git
|
||||
cd opencv
|
||||
git checkout 2.4
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DBUILD_SHARED_LIBS=OFF ..
|
||||
...
|
||||
...
|
||||
make -j8
|
||||
# optional
|
||||
# make install
|
||||
|
||||
Install Leiningen
|
||||
=================
|
||||
|
||||
Once you installed OpenCV with desktop java support the only other
|
||||
requirement is to install
|
||||
`Leiningeng <https://github.com/technomancy/leiningen>`_ which allows
|
||||
you to manage the entire life cycle of your CLJ projects.
|
||||
|
||||
The available `installation guide <https://github.com/technomancy/leiningen#installation>`_ is very easy to be followed:
|
||||
|
||||
1. `Download the script <https://raw.github.com/technomancy/leiningen/stable/bin/lein>`_
|
||||
2. Place it on your ``$PATH`` (cf. ``~/bin`` is a good choice if it is
|
||||
on your ``path``.)
|
||||
3. Set the script to be executable. (i.e. ``chmod 755 ~/bin/lein``).
|
||||
|
||||
If you work on Windows, follow `this instruction <https://github.com/technomancy/leiningen#windows>`_
|
||||
|
||||
You now have both the OpenCV library and a fully installed basic Clojure
|
||||
environment. What is now needed is to configure the Clojure environment
|
||||
to interact with the OpenCV library.
|
||||
|
||||
Install the localrepo Leiningen plugin
|
||||
=======================================
|
||||
|
||||
The set of commands (tasks in Leiningen parlance) natively supported by
|
||||
Leiningen can be very easily extended by various plugins. One of them is
|
||||
the `lein-localrepo <https://github.com/kumarshantanu/lein-localrepo>`_
|
||||
plugin which allows to install any jar lib as an artifact in the local
|
||||
maven repository of your machine (typically in the ``~/.m2/repository``
|
||||
directory of your username).
|
||||
|
||||
We're going to use this ``lein`` plugin to add to the local maven
|
||||
repository the opencv components needed by Java and Clojure to use the
|
||||
opencv lib.
|
||||
|
||||
Generally speaking, if you want to use a plugin on project base only, it
|
||||
can be added directly to a CLJ project created by ``lein``.
|
||||
|
||||
Instead, when you want a plugin to be available to any CLJ project in
|
||||
your username space, you can add it to the ``profiles.clj`` in the
|
||||
``~/.lein/`` directory.
|
||||
|
||||
The ``lein-localrepo`` plugin will be useful to me in other CLJ
|
||||
projects where I need to call native libs wrapped by a Java interface.
|
||||
So I decide to make it available to any CLJ project:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
mkdir ~/.lein
|
||||
|
||||
Create a file named ``profiles.clj`` in the ``~/.lein`` directory and
|
||||
copy into it the following content:
|
||||
|
||||
.. code:: clojure
|
||||
|
||||
{:user {:plugins [[lein-localrepo "0.5.2"]]}}
|
||||
|
||||
Here we're saying that the version release ``"0.5.2"`` of the
|
||||
``lein-localrepo`` plugin will be available to the ``:user`` profile for
|
||||
any CLJ project created by ``lein``.
|
||||
|
||||
You do not need to do anything else to install the plugin because it
|
||||
will be automatically downloaded from a remote repository the very first
|
||||
time you issue any ``lein`` task.
|
||||
|
||||
Install the java specific libs as local repository
|
||||
==================================================
|
||||
|
||||
If you followed the standard documentation for installing OpenCV on your
|
||||
computer, you should find the following two libs under the directory
|
||||
where you built OpenCV:
|
||||
|
||||
- the ``build/bin/opencv-247.jar`` java lib
|
||||
- the ``build/lib/libopencv_java247.dylib`` native lib (or ``.so`` in
|
||||
you built OpenCV a GNU/Linux OS)
|
||||
|
||||
They are the only opencv libs needed by the JVM to interact with OpenCV.
|
||||
|
||||
Take apart the needed opencv libs
|
||||
---------------------------------
|
||||
|
||||
Create a new directory to store in the above two libs. Start by copying
|
||||
into it the ``opencv-247.jar`` lib.
|
||||
|
||||
.. code:: bash
|
||||
|
||||
cd ~/opt
|
||||
mkdir clj-opencv
|
||||
cd clj-opencv
|
||||
cp ~/opt/opencv/build/bin/opencv-247.jar .
|
||||
|
||||
First lib done.
|
||||
|
||||
Now, to be able to add the ``libopencv_java247.dylib`` shared native lib
|
||||
to the local maven repository, we first need to package it as a jar
|
||||
file.
|
||||
|
||||
The native lib has to be copied into a directories layout which mimics
|
||||
the names of your operating system and architecture. I'm using a Mac OS
|
||||
X with a X86 64 bit architecture. So my layout will be the following:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
mkdir -p native/macosx/x86_64
|
||||
|
||||
Copy into the ``x86_64`` directory the ``libopencv_java247.dylib`` lib.
|
||||
|
||||
.. code:: bash
|
||||
|
||||
cp ~/opt/opencv/build/lib/libopencv_java247.dylib native/macosx/x86_64/
|
||||
|
||||
If you're running OpenCV from a different OS/Architecture pair, here
|
||||
is a summary of the mapping you can choose from.
|
||||
|
||||
.. code:: bash
|
||||
|
||||
OS
|
||||
|
||||
Mac OS X -> macosx
|
||||
Windows -> windows
|
||||
Linux -> linux
|
||||
SunOS -> solaris
|
||||
|
||||
Architectures
|
||||
|
||||
amd64 -> x86_64
|
||||
x86_64 -> x86_64
|
||||
x86 -> x86
|
||||
i386 -> x86
|
||||
arm -> arm
|
||||
sparc -> sparc
|
||||
|
||||
Package the native lib as a jar
|
||||
-------------------------------
|
||||
|
||||
Next you need to package the native lib in a jar file by using the
|
||||
``jar`` command to create a new jar file from a directory.
|
||||
|
||||
.. code:: bash
|
||||
|
||||
jar -cMf opencv-native-247.jar native
|
||||
|
||||
Note that ehe ``M`` option instructs the ``jar`` command to not create
|
||||
a MANIFEST file for the artifact.
|
||||
|
||||
Your directories layout should look like the following:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
tree
|
||||
.
|
||||
|__ native
|
||||
| |__ macosx
|
||||
| |__ x86_64
|
||||
| |__ libopencv_java247.dylib
|
||||
|
|
||||
|__ opencv-247.jar
|
||||
|__ opencv-native-247.jar
|
||||
|
||||
3 directories, 3 files
|
||||
|
||||
Locally install the jars
|
||||
------------------------
|
||||
|
||||
We are now ready to add the two jars as artifacts to the local maven
|
||||
repository with the help of the ``lein-localrepo`` plugin.
|
||||
|
||||
.. code:: bash
|
||||
|
||||
lein localrepo install opencv-247.jar opencv/opencv 2.4.7
|
||||
|
||||
Here the ``localrepo install`` task creates the ``2.4.7.`` release of
|
||||
the ``opencv/opencv`` maven artifact from the ``opencv-247.jar`` lib and
|
||||
then installs it into the local maven repository. The ``opencv/opencv``
|
||||
artifact will then be available to any maven compliant project
|
||||
(Leiningen is internally based on maven).
|
||||
|
||||
Do the same thing with the native lib previously wrapped in a new jar
|
||||
file.
|
||||
|
||||
.. code:: bash
|
||||
|
||||
lein localrepo install opencv-native-247.jar opencv/opencv-native 2.4.7
|
||||
|
||||
Note that the groupId, ``opencv``, of the two artifacts is the same. We
|
||||
are now ready to create a new CLJ project to start interacting with
|
||||
OpenCV.
|
||||
|
||||
Create a project
|
||||
----------------
|
||||
|
||||
Create a new CLJ project by using the ``lein new`` task from the
|
||||
terminal.
|
||||
|
||||
.. code:: bash
|
||||
|
||||
# cd in the directory where you work with your development projects (e.g. ~/devel)
|
||||
lein new simple-sample
|
||||
Generating a project called simple-sample based on the 'default' template.
|
||||
To see other templates (app, lein plugin, etc), try `lein help new`.
|
||||
|
||||
The above task creates the following ``simple-sample`` directories
|
||||
layout:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
tree simple-sample/
|
||||
simple-sample/
|
||||
|__ LICENSE
|
||||
|__ README.md
|
||||
|__ doc
|
||||
| |__ intro.md
|
||||
|
|
||||
|__ project.clj
|
||||
|__ resources
|
||||
|__ src
|
||||
| |__ simple_sample
|
||||
| |__ core.clj
|
||||
|__ test
|
||||
|__ simple_sample
|
||||
|__ core_test.clj
|
||||
|
||||
6 directories, 6 files
|
||||
|
||||
We need to add the two ``opencv`` artifacts as dependencies of the newly
|
||||
created project. Open the ``project.clj`` and modify its dependencies
|
||||
section as follows:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
(defproject simple-sample "0.1.0-SNAPSHOT"
|
||||
:description "FIXME: write description"
|
||||
:url "http://example.com/FIXME"
|
||||
:license {:name "Eclipse Public License"
|
||||
:url "http://www.eclipse.org/legal/epl-v10.html"}
|
||||
:dependencies [[org.clojure/clojure "1.5.1"]
|
||||
[opencv/opencv "2.4.7"] ; added line
|
||||
[opencv/opencv-native "2.4.7"]]) ;added line
|
||||
|
||||
|
||||
Note that The Clojure Programming Language is a jar artifact too. This
|
||||
is why Clojure is called an hosted language.
|
||||
|
||||
To verify that everything went right issue the ``lein deps`` task. The
|
||||
very first time you run a ``lein`` task it will take sometime to
|
||||
download all the required dependencies before executing the task
|
||||
itself.
|
||||
|
||||
.. code:: bash
|
||||
|
||||
cd simple-sample
|
||||
lein deps
|
||||
...
|
||||
|
||||
The ``deps`` task reads and merges from the ``project.clj`` and the
|
||||
``~/.lein/profiles.clj`` files all the dependencies of the
|
||||
``simple-sample`` project and verifies if they have already been
|
||||
cached in the local maven repository. If the task returns without
|
||||
messages about not being able to retrieve the two new artifacts your
|
||||
installation is correct, otherwise go back and double check that you
|
||||
did everything right.
|
||||
|
||||
REPLing with OpenCV
|
||||
-------------------
|
||||
|
||||
Now ``cd`` in the ``simple-sample`` directory and issue the following
|
||||
``lein`` task:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
cd simple-sample
|
||||
lein repl
|
||||
...
|
||||
...
|
||||
nREPL server started on port 50907 on host 127.0.0.1
|
||||
REPL-y 0.3.0
|
||||
Clojure 1.5.1
|
||||
Docs: (doc function-name-here)
|
||||
(find-doc "part-of-name-here")
|
||||
Source: (source function-name-here)
|
||||
Javadoc: (javadoc java-object-or-class-here)
|
||||
Exit: Control+D or (exit) or (quit)
|
||||
Results: Stored in vars *1, *2, *3, an exception in *e
|
||||
|
||||
user=>
|
||||
|
||||
You can immediately interact with the REPL by issuing any CLJ expression
|
||||
to be evaluated.
|
||||
|
||||
.. code:: clojure
|
||||
|
||||
user=> (+ 41 1)
|
||||
42
|
||||
user=> (println "Hello, OpenCV!")
|
||||
Hello, OpenCV!
|
||||
nil
|
||||
user=> (defn foo [] (str "bar"))
|
||||
#'user/foo
|
||||
user=> (foo)
|
||||
"bar"
|
||||
|
||||
When ran from the home directory of a lein based project, even if the
|
||||
``lein repl`` task automatically loads all the project dependencies, you
|
||||
still need to load the opencv native library to be able to interact with
|
||||
the OpenCV.
|
||||
|
||||
.. code:: clojure
|
||||
|
||||
user=> (clojure.lang.RT/loadLibrary org.opencv.core.Core/NATIVE_LIBRARY_NAME)
|
||||
nil
|
||||
|
||||
Then you can start interacting with OpenCV by just referencing the fully
|
||||
qualified names of its classes.
|
||||
|
||||
NOTE 2: `Here <http://docs.opencv.org/java/>`_ you can find the
|
||||
full OpenCV Java API.
|
||||
|
||||
.. code:: clojure
|
||||
|
||||
user=> (org.opencv.core.Point. 0 0)
|
||||
#<Point {0.0, 0.0}>
|
||||
|
||||
Here we created a two dimensions opencv ``Point`` instance. Even if all
|
||||
the java packages included within the java interface to OpenCV are
|
||||
immediately available from the CLJ REPL, it's very annoying to prefix
|
||||
the ``Point.`` instance constructors with the fully qualified package
|
||||
name.
|
||||
|
||||
Fortunately CLJ offer a very easy way to overcome this annoyance by
|
||||
directly importing the ``Point`` class.
|
||||
|
||||
.. code:: clojure
|
||||
|
||||
user=> (import 'org.opencv.core.Point)
|
||||
org.opencv.core.Point
|
||||
user=> (def p1 (Point. 0 0))
|
||||
#'user/p1
|
||||
user=> p1
|
||||
#<Point {0.0, 0.0}>
|
||||
user=> (def p2 (Point. 100 100))
|
||||
#'user/p2
|
||||
|
||||
We can even inspect the class of an instance and verify if the value of
|
||||
a symbol is an instance of a ``Point`` java class.
|
||||
|
||||
.. code:: clojure
|
||||
|
||||
user=> (class p1)
|
||||
org.opencv.core.Point
|
||||
user=> (instance? org.opencv.core.Point p1)
|
||||
true
|
||||
|
||||
If we now want to use the opencv ``Rect`` class to create a rectangle,
|
||||
we again have to fully qualify its constructor even if it leaves in
|
||||
the same ``org.opencv.core`` package of the ``Point`` class.
|
||||
|
||||
.. code:: clojure
|
||||
|
||||
user=> (org.opencv.core.Rect. p1 p2)
|
||||
#<Rect {0, 0, 100x100}>
|
||||
|
||||
Again, the CLJ importing facilities is very handy and let you to map
|
||||
more symbols in one shot.
|
||||
|
||||
.. code:: clojure
|
||||
|
||||
user=> (import '[org.opencv.core Point Rect Size])
|
||||
org.opencv.core.Size
|
||||
user=> (def r1 (Rect. p1 p2))
|
||||
#'user/r1
|
||||
user=> r1
|
||||
#<Rect {0, 0, 100x100}>
|
||||
user=> (class r1)
|
||||
org.opencv.core.Rect
|
||||
user=> (instance? org.opencv.core.Rect r1)
|
||||
true
|
||||
user=> (Size. 100 100)
|
||||
#<Size 100x100>
|
||||
user=> (def sq-100 (Size. 100 100))
|
||||
#'user/sq-100
|
||||
user=> (class sq-100)
|
||||
org.opencv.core.Size
|
||||
user=> (instance? org.opencv.core.Size sq-100)
|
||||
true
|
||||
|
||||
Obviously you can call methods on instances as well.
|
||||
|
||||
.. code:: clojure
|
||||
|
||||
user=> (.area r1)
|
||||
10000.0
|
||||
user=> (.area sq-100)
|
||||
10000.0
|
||||
|
||||
Or modify the value of a member field.
|
||||
|
||||
.. code:: clojure
|
||||
|
||||
user=> (set! (.x p1) 10)
|
||||
10
|
||||
user=> p1
|
||||
#<Point {10.0, 0.0}>
|
||||
user=> (set! (.width sq-100) 10)
|
||||
10
|
||||
user=> (set! (.height sq-100) 10)
|
||||
10
|
||||
user=> (.area sq-100)
|
||||
100.0
|
||||
|
||||
If you find yourself not remembering a OpenCV class behavior, the
|
||||
REPL gives you the opportunity to easily search the corresponding
|
||||
javadoc documention:
|
||||
|
||||
.. code:: clojure
|
||||
|
||||
user=> (javadoc Rect)
|
||||
"http://www.google.com/search?btnI=I%27m%20Feeling%20Lucky&q=allinurl:org/opencv/core/Rect.html"
|
||||
|
||||
Mimic the OpenCV Java Tutorial Sample in the REPL
|
||||
-------------------------------------------------
|
||||
|
||||
Let's now try to port to Clojure the `opencv java tutorial sample <http://docs.opencv.org/2.4.4-beta/doc/tutorials/introduction/desktop_java/java_dev_intro.html>`_.
|
||||
Instead of writing it in a source file we're going to evaluate it at the
|
||||
REPL.
|
||||
|
||||
Following is the original Java source code of the cited sample.
|
||||
|
||||
.. code:: java
|
||||
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.CvType;
|
||||
import org.opencv.core.Scalar;
|
||||
|
||||
class SimpleSample {
|
||||
|
||||
static{ System.loadLibrary("opencv_java244"); }
|
||||
|
||||
public static void main(String[] args) {
|
||||
Mat m = new Mat(5, 10, CvType.CV_8UC1, new Scalar(0));
|
||||
System.out.println("OpenCV Mat: " + m);
|
||||
Mat mr1 = m.row(1);
|
||||
mr1.setTo(new Scalar(1));
|
||||
Mat mc5 = m.col(5);
|
||||
mc5.setTo(new Scalar(5));
|
||||
System.out.println("OpenCV Mat data:\n" + m.dump());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Add injections to the project
|
||||
-----------------------------
|
||||
|
||||
Before start coding, we'd like to eliminate the boring need of
|
||||
interactively loading the native opencv lib any time we start a new REPL
|
||||
to interact with it.
|
||||
|
||||
First, stop the REPL by evaluating the ``(exit)`` expression at the REPL
|
||||
prompt.
|
||||
|
||||
.. code:: clojure
|
||||
|
||||
user=> (exit)
|
||||
Bye for now!
|
||||
|
||||
Then open your ``project.clj`` file and edit it as follows:
|
||||
|
||||
.. code:: clojure
|
||||
|
||||
(defproject simple-sample "0.1.0-SNAPSHOT"
|
||||
...
|
||||
:injections [(clojure.lang.RT/loadLibrary org.opencv.core.Core/NATIVE_LIBRARY_NAME)])
|
||||
|
||||
Here we're saying to load the opencv native lib anytime we run the REPL
|
||||
in such a way that we have not anymore to remember to manually do it.
|
||||
|
||||
Rerun the ``lein repl`` task
|
||||
|
||||
.. code:: bash
|
||||
|
||||
lein repl
|
||||
nREPL server started on port 51645 on host 127.0.0.1
|
||||
REPL-y 0.3.0
|
||||
Clojure 1.5.1
|
||||
Docs: (doc function-name-here)
|
||||
(find-doc "part-of-name-here")
|
||||
Source: (source function-name-here)
|
||||
Javadoc: (javadoc java-object-or-class-here)
|
||||
Exit: Control+D or (exit) or (quit)
|
||||
Results: Stored in vars *1, *2, *3, an exception in *e
|
||||
|
||||
user=>
|
||||
|
||||
Import the interested OpenCV java interfaces.
|
||||
|
||||
.. code:: clojure
|
||||
|
||||
user=> (import '[org.opencv.core Mat CvType Scalar])
|
||||
org.opencv.core.Scalar
|
||||
|
||||
We're going to mimic almost verbatim the original OpenCV java tutorial
|
||||
to:
|
||||
|
||||
- create a 5x10 matrix with all its elements intialized to 0
|
||||
- change the value of every element of the second row to 1
|
||||
- change the value of every element of the 6th column to 5
|
||||
- print the content of the obtained matrix
|
||||
|
||||
.. code:: clojure
|
||||
|
||||
user=> (def m (Mat. 5 10 CvType/CV_8UC1 (Scalar. 0 0)))
|
||||
#'user/m
|
||||
user=> (def mr1 (.row m 1))
|
||||
#'user/mr1
|
||||
user=> (.setTo mr1 (Scalar. 1 0))
|
||||
#<Mat Mat [ 1*10*CV_8UC1, isCont=true, isSubmat=true, nativeObj=0x7fc9dac49880, dataAddr=0x7fc9d9c98d5a ]>
|
||||
user=> (def mc5 (.col m 5))
|
||||
#'user/mc5
|
||||
user=> (.setTo mc5 (Scalar. 5 0))
|
||||
#<Mat Mat [ 5*1*CV_8UC1, isCont=false, isSubmat=true, nativeObj=0x7fc9d9c995a0, dataAddr=0x7fc9d9c98d55 ]>
|
||||
user=> (println (.dump m))
|
||||
[0, 0, 0, 0, 0, 5, 0, 0, 0, 0;
|
||||
1, 1, 1, 1, 1, 5, 1, 1, 1, 1;
|
||||
0, 0, 0, 0, 0, 5, 0, 0, 0, 0;
|
||||
0, 0, 0, 0, 0, 5, 0, 0, 0, 0;
|
||||
0, 0, 0, 0, 0, 5, 0, 0, 0, 0]
|
||||
nil
|
||||
|
||||
If you are accustomed to a functional language all those abused and
|
||||
mutating nouns are going to irritate your preference for verbs. Even
|
||||
if the CLJ interop syntax is very handy and complete, there is still
|
||||
an impedance mismatch between any OOP language and any FP language
|
||||
(bein Scala a mixed paradigms programming language).
|
||||
|
||||
To exit the REPL type ``(exit)``, ``ctr-D`` or ``(quit)`` at the REPL
|
||||
prompt.
|
||||
|
||||
.. code:: clojure
|
||||
|
||||
user=> (exit)
|
||||
Bye for now!
|
||||
|
||||
Interactively load and blur an image
|
||||
------------------------------------
|
||||
|
||||
In the next sample you will learn how to interactively load and blur and
|
||||
image from the REPL by using the following OpenCV methods:
|
||||
|
||||
- the ``imread`` static method from the ``Highgui`` class to read an
|
||||
image from a file
|
||||
- the ``imwrite`` static method from the ``Highgui`` class to write an
|
||||
image to a file
|
||||
- the ``GaussianBlur`` static method from the ``Imgproc`` class to
|
||||
apply to blur the original image
|
||||
|
||||
We're also going to use the ``Mat`` class which is returned from the
|
||||
``imread`` method and accpeted as the main argument to both the
|
||||
``GaussianBlur`` and the ``imwrite`` methods.
|
||||
|
||||
Add an image to the project
|
||||
---------------------------
|
||||
|
||||
First we want to add an image file to a newly create directory for
|
||||
storing static resources of the project.
|
||||
|
||||
.. image:: images/lena.png
|
||||
:alt: Original Image
|
||||
:align: center
|
||||
|
||||
.. code:: bash
|
||||
|
||||
mkdir -p resources/images
|
||||
cp ~/opt/opencv/doc/tutorials/introduction/desktop_java/images/lena.png resource/images/
|
||||
|
||||
Read the image
|
||||
--------------
|
||||
|
||||
Now launch the REPL as usual and start by importing all the OpenCV
|
||||
classes we're going to use:
|
||||
|
||||
.. code:: clojure
|
||||
|
||||
lein repl
|
||||
nREPL server started on port 50624 on host 127.0.0.1
|
||||
REPL-y 0.3.0
|
||||
Clojure 1.5.1
|
||||
Docs: (doc function-name-here)
|
||||
(find-doc "part-of-name-here")
|
||||
Source: (source function-name-here)
|
||||
Javadoc: (javadoc java-object-or-class-here)
|
||||
Exit: Control+D or (exit) or (quit)
|
||||
Results: Stored in vars *1, *2, *3, an exception in *e
|
||||
|
||||
user=> (import '[org.opencv.core Mat Size CvType]
|
||||
'[org.opencv.highgui Highgui]
|
||||
'[org.opencv.imgproc Imgproc])
|
||||
org.opencv.imgproc.Imgproc
|
||||
|
||||
Now read the image from the ``resources/images/lena.png`` file.
|
||||
|
||||
.. code:: clojure
|
||||
|
||||
user=> (def lena (Highgui/imread "resources/images/lena.png"))
|
||||
#'user/lena
|
||||
user=> lena
|
||||
#<Mat Mat [ 512*512*CV_8UC3, isCont=true, isSubmat=false, nativeObj=0x7f9ab3054c40, dataAddr=0x19fea9010 ]>
|
||||
|
||||
As you see, by simply evaluating the ``lena`` symbol we know that
|
||||
``lena.png`` is a ``512x512`` matrix of ``CV_8UC3`` elements type. Let's
|
||||
create a new ``Mat`` instance of the same dimensions and elements type.
|
||||
|
||||
.. code:: clojure
|
||||
|
||||
user=> (def blurred (Mat. 512 512 CvType/CV_8UC3))
|
||||
#'user/blurred
|
||||
user=>
|
||||
|
||||
Now apply a ``GaussianBlur`` filter using ``lena`` as the source matrix
|
||||
and ``blurred`` as the destination matrix.
|
||||
|
||||
.. code:: clojure
|
||||
|
||||
user=> (Imgproc/GaussianBlur lena blurred (Size. 5 5) 3 3)
|
||||
nil
|
||||
|
||||
As a last step just save the ``blurred`` matrix in a new image file.
|
||||
|
||||
.. code:: clojure
|
||||
|
||||
user=> (Highgui/imwrite "resources/images/blurred.png" blurred)
|
||||
true
|
||||
user=> (exit)
|
||||
Bye for now!
|
||||
|
||||
Following is the new blurred image of Lena.
|
||||
|
||||
.. image:: images/blurred.png
|
||||
:alt: Blurred Image
|
||||
:align: center
|
||||
|
||||
Next Steps
|
||||
==========
|
||||
|
||||
This tutorial only introduces the very basic environment set up to be
|
||||
able to interact with OpenCV in a CLJ REPL.
|
||||
|
||||
I recommend any Clojure newbie to read the `Clojure Java Interop chapter <http://clojure.org/java_interop>`_ to get all you need to know
|
||||
to interoperate with any plain java lib that has not been wrapped in
|
||||
Clojure to make it usable in a more idiomatic and functional way within
|
||||
Clojure.
|
||||
|
||||
The OpenCV Java API does not wrap the ``highgui`` module
|
||||
functionalities depending on ``Qt`` (e.g. ``namedWindow`` and
|
||||
``imshow``. If you want to create windows and show images into them
|
||||
while interacting with OpenCV from the REPL, at the moment you're left
|
||||
at your own. You could use Java Swing to fill the gap.
|
||||
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
Copyright © 2013 Giacomo (Mimmo) Cosenza aka Magomimmo
|
||||
|
||||
Distributed under the BSD 3-clause License, the same of OpenCV.
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 351 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 606 KiB |
@@ -106,8 +106,8 @@ Enable hardware optimizations
|
||||
-----------------------------
|
||||
|
||||
Depending on target platform architecture different instruction sets can be used. By default
|
||||
compiler generates code for armv5l without VFPv3 and NEON extensions. Add ``-DUSE_VFPV3=ON``
|
||||
to cmake command line to enable code generation for VFPv3 and ``-DUSE_NEON=ON`` for using
|
||||
compiler generates code for armv5l without VFPv3 and NEON extensions. Add ``-DENABLE_VFPV3=ON``
|
||||
to cmake command line to enable code generation for VFPv3 and ``-DENABLE_NEON=ON`` for using
|
||||
NEON SIMD extensions.
|
||||
|
||||
TBB is supported on multi core ARM SoCs also.
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 7.7 KiB |
+16
@@ -156,6 +156,21 @@ world of the OpenCV.
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
================ =================================================
|
||||
|ClojureLogo| **Title:** :ref:`clojure_dev_intro`
|
||||
|
||||
*Compatibility:* > OpenCV 2.4.4
|
||||
|
||||
*Author:* |Author_MimmoC|
|
||||
|
||||
A tutorial on how to interactively use OpenCV from the Clojure REPL.
|
||||
|
||||
================ =================================================
|
||||
|
||||
.. |ClojureLogo| image:: images/clojure-logo.png
|
||||
:height: 90pt
|
||||
:width: 90pt
|
||||
|
||||
* **Android**
|
||||
|
||||
.. tabularcolumns:: m{100pt} m{300pt}
|
||||
@@ -314,6 +329,7 @@ world of the OpenCV.
|
||||
../windows_visual_studio_image_watch/windows_visual_studio_image_watch
|
||||
../desktop_java/java_dev_intro
|
||||
../java_eclipse/java_eclipse
|
||||
../clojure_dev_intro/clojure_dev_intro
|
||||
../android_binary_package/android_dev_intro
|
||||
../android_binary_package/O4A_SDK
|
||||
../android_binary_package/dev_with_OCV_on_Android
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
*******
|
||||
HighGUI
|
||||
*******
|
||||
|
||||
.. highlight:: cpp
|
||||
|
||||
Using Creative Senz3D and other Intel Perceptual Computing SDK compatible depth sensors
|
||||
=======================================================================================
|
||||
|
||||
Depth sensors compatible with Intel Perceptual Computing SDK are supported through ``VideoCapture`` class. Depth map, RGB image and some other formats of output can be retrieved by using familiar interface of ``VideoCapture``.
|
||||
|
||||
In order to use depth sensor with OpenCV you should do the following preliminary steps:
|
||||
|
||||
#.
|
||||
Install Intel Perceptual Computing SDK (from here http://www.intel.com/software/perceptual).
|
||||
|
||||
#.
|
||||
Configure OpenCV with Intel Perceptual Computing SDK support by setting ``WITH_INTELPERC`` flag in CMake. If Intel Perceptual Computing SDK is found in install folders OpenCV will be built with Intel Perceptual Computing SDK library (see a status ``INTELPERC`` in CMake log). If CMake process doesn't find Intel Perceptual Computing SDK installation folder automatically, the user should change corresponding CMake variables ``INTELPERC_LIB_DIR`` and ``INTELPERC_INCLUDE_DIR`` to the proper value.
|
||||
|
||||
#.
|
||||
Build OpenCV.
|
||||
|
||||
VideoCapture can retrieve the following data:
|
||||
|
||||
#.
|
||||
data given from depth generator:
|
||||
* ``CV_CAP_INTELPERC_DEPTH_MAP`` - each pixel is a 16-bit integer. The value indicates the distance from an object to the camera's XY plane or the Cartesian depth. (CV_16UC1)
|
||||
* ``CV_CAP_INTELPERC_UVDEPTH_MAP`` - each pixel contains two 32-bit floating point values in the range of 0-1, representing the mapping of depth coordinates to the color coordinates. (CV_32FC2)
|
||||
* ``CV_CAP_INTELPERC_IR_MAP`` - each pixel is a 16-bit integer. The value indicates the intensity of the reflected laser beam. (CV_16UC1)
|
||||
#.
|
||||
data given from RGB image generator:
|
||||
* ``CV_CAP_INTELPERC_IMAGE`` - color image. (CV_8UC3)
|
||||
|
||||
In order to get depth map from depth sensor use ``VideoCapture::operator >>``, e. g. ::
|
||||
|
||||
VideoCapture capture( CV_CAP_INTELPERC );
|
||||
for(;;)
|
||||
{
|
||||
Mat depthMap;
|
||||
capture >> depthMap;
|
||||
|
||||
if( waitKey( 30 ) >= 0 )
|
||||
break;
|
||||
}
|
||||
|
||||
For getting several data maps use ``VideoCapture::grab`` and ``VideoCapture::retrieve``, e.g. ::
|
||||
|
||||
VideoCapture capture(CV_CAP_INTELPERC);
|
||||
for(;;)
|
||||
{
|
||||
Mat depthMap;
|
||||
Mat image;
|
||||
Mat irImage;
|
||||
|
||||
capture.grab();
|
||||
|
||||
capture.retrieve( depthMap, CV_CAP_INTELPERC_DEPTH_MAP );
|
||||
capture.retrieve( image, CV_CAP_INTELPERC_IMAGE );
|
||||
capture.retrieve( irImage, CV_CAP_INTELPERC_IR_MAP);
|
||||
|
||||
if( waitKey( 30 ) >= 0 )
|
||||
break;
|
||||
}
|
||||
|
||||
For setting and getting some property of sensor` data generators use ``VideoCapture::set`` and ``VideoCapture::get`` methods respectively, e.g. ::
|
||||
|
||||
VideoCapture capture( CV_CAP_INTELPERC );
|
||||
capture.set( CV_CAP_INTELPERC_DEPTH_GENERATOR | CV_CAP_PROP_INTELPERC_PROFILE_IDX, 0 );
|
||||
cout << "FPS " << capture.get( CV_CAP_INTELPERC_DEPTH_GENERATOR+CV_CAP_PROP_FPS ) << endl;
|
||||
|
||||
Since two types of sensor's data generators are supported (image generator and depth generator), there are two flags that should be used to set/get property of the needed generator:
|
||||
|
||||
* CV_CAP_INTELPERC_IMAGE_GENERATOR -- a flag for access to the image generator properties.
|
||||
|
||||
* CV_CAP_INTELPERC_DEPTH_GENERATOR -- a flag for access to the depth generator properties. This flag value is assumed by default if neither of the two possible values of the property is set.
|
||||
|
||||
For more information please refer to the example of usage intelperc_capture.cpp_ in ``opencv/samples/cpp`` folder.
|
||||
|
||||
.. _intelperc_capture.cpp: https://github.com/Itseez/opencv/tree/master/samples/cpp/intelperc_capture.cpp
|
||||
@@ -9,3 +9,4 @@ OpenCV User Guide
|
||||
ug_features2d.rst
|
||||
ug_highgui.rst
|
||||
ug_traincascade.rst
|
||||
ug_intelperc.rst
|
||||
|
||||
@@ -1,9 +1,26 @@
|
||||
set(the_description "The Core Functionality")
|
||||
ocv_add_module(core PRIVATE_REQUIRED ${ZLIB_LIBRARIES})
|
||||
ocv_module_include_directories(${ZLIB_INCLUDE_DIR})
|
||||
|
||||
if (NOT HAVE_CUDA OR ENABLE_DYNAMIC_CUDA)
|
||||
ocv_add_module(core PRIVATE_REQUIRED ${ZLIB_LIBRARIES})
|
||||
else()
|
||||
ocv_add_module(core PRIVATE_REQUIRED ${ZLIB_LIBRARIES} ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY})
|
||||
endif()
|
||||
|
||||
ocv_module_include_directories("${OpenCV_SOURCE_DIR}/modules/dynamicuda/include/" ${ZLIB_INCLUDE_DIR})
|
||||
|
||||
if(HAVE_WINRT_CX)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /ZW")
|
||||
endif()
|
||||
if(HAVE_WINRT)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /ZW /GS /Gm- /AI\"${WINDOWS_SDK_PATH}/References/CommonConfiguration/Neutral\" /AI\"${VISUAL_STUDIO_PATH}/vcpackages\"")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GS /Gm- /AI\"${WINDOWS_SDK_PATH}/References/CommonConfiguration/Neutral\" /AI\"${VISUAL_STUDIO_PATH}/vcpackages\"")
|
||||
endif()
|
||||
|
||||
if(ENABLE_DYNAMIC_CUDA)
|
||||
add_definitions(-DDYNAMIC_CUDA_SUPPORT)
|
||||
else()
|
||||
if (HAVE_CUDA)
|
||||
add_definitions(-DUSE_CUDA)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(HAVE_CUDA)
|
||||
@@ -14,11 +31,26 @@ endif()
|
||||
file(GLOB lib_cuda_hdrs "include/opencv2/${name}/cuda/*.hpp" "include/opencv2/${name}/cuda/*.h")
|
||||
file(GLOB lib_cuda_hdrs_detail "include/opencv2/${name}/cuda/detail/*.hpp" "include/opencv2/${name}/cuda/detail/*.h")
|
||||
|
||||
if(HAVE_CUDA AND NOT ENABLE_DYNAMIC_CUDA)
|
||||
file(GLOB lib_cuda "../dynamicuda/src/cuda/*.cu*")
|
||||
ocv_include_directories(${CUDA_INCLUDE_DIRS})
|
||||
ocv_cuda_compile(cuda_objs ${lib_cuda})
|
||||
endif()
|
||||
|
||||
source_group("Cuda Headers" FILES ${lib_cuda_hdrs})
|
||||
source_group("Cuda Headers\\Detail" FILES ${lib_cuda_hdrs_detail})
|
||||
|
||||
ocv_glob_module_sources(SOURCES "${opencv_core_BINARY_DIR}/version_string.inc"
|
||||
HEADERS ${lib_cuda_hdrs} ${lib_cuda_hdrs_detail})
|
||||
if (HAVE_CUDA AND NOT ENABLE_DYNAMIC_CUDA)
|
||||
source_group("Src\\Cuda" FILES ${lib_cuda} ${lib_cuda_hdrs})
|
||||
endif()
|
||||
|
||||
if (NOT HAVE_CUDA OR ENABLE_DYNAMIC_CUDA)
|
||||
ocv_glob_module_sources(SOURCES "${opencv_core_BINARY_DIR}/version_string.inc"
|
||||
HEADERS ${lib_cuda_hdrs} ${lib_cuda_hdrs_detail})
|
||||
else()
|
||||
ocv_glob_module_sources(SOURCES "${opencv_core_BINARY_DIR}/version_string.inc" ${lib_cuda} ${cuda_objs}
|
||||
HEADERS ${lib_cuda_hdrs} ${lib_cuda_hdrs_detail})
|
||||
endif()
|
||||
|
||||
ocv_create_module()
|
||||
ocv_add_precompiled_headers(${the_module})
|
||||
|
||||
@@ -929,7 +929,7 @@ So, the function chooses an operation mode depending on the flags and size of th
|
||||
|
||||
* When ``DFT_COMPLEX_OUTPUT`` is set, the output is a complex matrix of the same size as input.
|
||||
|
||||
* When ``DFT_COMPLEX_OUTPUT`` is not set, the output is a real matrix of the same size as input. In case of 2D transform, it uses the packed format as shown above. In case of a single 1D transform, it looks like the first row of the matrix above. In case of multiple 1D transforms (when using the ``DCT_ROWS`` flag), each row of the output matrix looks like the first row of the matrix above.
|
||||
* When ``DFT_COMPLEX_OUTPUT`` is not set, the output is a real matrix of the same size as input. In case of 2D transform, it uses the packed format as shown above. In case of a single 1D transform, it looks like the first row of the matrix above. In case of multiple 1D transforms (when using the ``DFT_ROWS`` flag), each row of the output matrix looks like the first row of the matrix above.
|
||||
|
||||
* If the input array is complex and either ``DFT_INVERSE`` or ``DFT_REAL_OUTPUT`` are not set, the output is a complex array of the same size as input. The function performs a forward or inverse 1D or 2D transform of the whole input array or each row of the input array independently, depending on the flags ``DFT_INVERSE`` and ``DFT_ROWS``.
|
||||
|
||||
|
||||
@@ -4821,6 +4821,32 @@ private:
|
||||
AutoLock& operator = (const AutoLock&);
|
||||
};
|
||||
|
||||
class TLSDataContainer
|
||||
{
|
||||
private:
|
||||
int key_;
|
||||
protected:
|
||||
CV_EXPORTS TLSDataContainer();
|
||||
CV_EXPORTS ~TLSDataContainer(); // virtual is not required
|
||||
public:
|
||||
virtual void* createDataInstance() const = 0;
|
||||
virtual void deleteDataInstance(void* data) const = 0;
|
||||
|
||||
CV_EXPORTS void* getData() const;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class TLSData : protected TLSDataContainer
|
||||
{
|
||||
public:
|
||||
inline TLSData() {}
|
||||
inline ~TLSData() {}
|
||||
inline T* get() const { return (T*)getData(); }
|
||||
private:
|
||||
virtual void* createDataInstance() const { return new T; }
|
||||
virtual void deleteDataInstance(void* data) const { delete (T*)data; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
@@ -49,8 +49,8 @@
|
||||
|
||||
#define CV_VERSION_EPOCH 2
|
||||
#define CV_VERSION_MAJOR 4
|
||||
#define CV_VERSION_MINOR 7
|
||||
#define CV_VERSION_REVISION 2
|
||||
#define CV_VERSION_MINOR 8
|
||||
#define CV_VERSION_REVISION 0
|
||||
|
||||
#define CVAUX_STR_EXP(__A) #__A
|
||||
#define CVAUX_STR(__A) CVAUX_STR_EXP(__A)
|
||||
|
||||
@@ -2284,7 +2284,7 @@ void cv::dct( InputArray _src0, OutputArray _dst, int flags )
|
||||
|
||||
DCTFunc dct_func = dct_tbl[(int)inv + (depth == CV_64F)*2];
|
||||
|
||||
if( (flags & DFT_ROWS) || src.rows == 1 ||
|
||||
if( (flags & DCT_ROWS) || src.rows == 1 ||
|
||||
(src.cols == 1 && (src.isContinuous() && dst.isContinuous())))
|
||||
{
|
||||
stage = end_stage = 0;
|
||||
@@ -2304,7 +2304,7 @@ void cv::dct( InputArray _src0, OutputArray _dst, int flags )
|
||||
{
|
||||
len = src.cols;
|
||||
count = src.rows;
|
||||
if( len == 1 && !(flags & DFT_ROWS) )
|
||||
if( len == 1 && !(flags & DCT_ROWS) )
|
||||
{
|
||||
len = src.rows;
|
||||
count = 1;
|
||||
|
||||
+265
-1067
File diff suppressed because it is too large
Load Diff
+11
-26
@@ -2032,39 +2032,24 @@ void cv::transpose( InputArray _src, OutputArray _dst )
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////// completeSymm /////////////////////////////////////////
|
||||
|
||||
void cv::completeSymm( InputOutputArray _m, bool LtoR )
|
||||
{
|
||||
Mat m = _m.getMat();
|
||||
CV_Assert( m.dims <= 2 );
|
||||
size_t step = m.step, esz = m.elemSize();
|
||||
CV_Assert( m.dims <= 2 && m.rows == m.cols );
|
||||
|
||||
int i, j, nrows = m.rows, type = m.type();
|
||||
int j0 = 0, j1 = nrows;
|
||||
CV_Assert( m.rows == m.cols );
|
||||
int rows = m.rows;
|
||||
int j0 = 0, j1 = rows;
|
||||
|
||||
if( type == CV_32FC1 || type == CV_32SC1 )
|
||||
uchar* data = m.data;
|
||||
for( int i = 0; i < rows; i++ )
|
||||
{
|
||||
int* data = (int*)m.data;
|
||||
size_t step = m.step/sizeof(data[0]);
|
||||
for( i = 0; i < nrows; i++ )
|
||||
{
|
||||
if( !LtoR ) j1 = i; else j0 = i+1;
|
||||
for( j = j0; j < j1; j++ )
|
||||
data[i*step + j] = data[j*step + i];
|
||||
}
|
||||
if( !LtoR ) j1 = i; else j0 = i+1;
|
||||
for( int j = j0; j < j1; j++ )
|
||||
memcpy(data + (i*step + j*esz), data + (j*step + i*esz), esz);
|
||||
}
|
||||
else if( type == CV_64FC1 )
|
||||
{
|
||||
double* data = (double*)m.data;
|
||||
size_t step = m.step/sizeof(data[0]);
|
||||
for( i = 0; i < nrows; i++ )
|
||||
{
|
||||
if( !LtoR ) j1 = i; else j0 = i+1;
|
||||
for( j = j0; j < j1; j++ )
|
||||
data[i*step + j] = data[j*step + i];
|
||||
}
|
||||
}
|
||||
else
|
||||
CV_Error( CV_StsUnsupportedFormat, "" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
+248
-18
@@ -87,10 +87,41 @@
|
||||
|
||||
#ifdef HAVE_WINRT
|
||||
#include <wrl/client.h>
|
||||
#ifndef __cplusplus_winrt
|
||||
#include <windows.storage.h>
|
||||
#pragma comment(lib, "runtimeobject.lib")
|
||||
#endif
|
||||
|
||||
std::wstring GetTempPathWinRT()
|
||||
{
|
||||
#ifdef __cplusplus_winrt
|
||||
return std::wstring(Windows::Storage::ApplicationData::Current->TemporaryFolder->Path->Data());
|
||||
#else
|
||||
Microsoft::WRL::ComPtr<ABI::Windows::Storage::IApplicationDataStatics> appdataFactory;
|
||||
Microsoft::WRL::ComPtr<ABI::Windows::Storage::IApplicationData> appdataRef;
|
||||
Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageFolder> storagefolderRef;
|
||||
Microsoft::WRL::ComPtr<ABI::Windows::Storage::IStorageItem> storageitemRef;
|
||||
HSTRING str;
|
||||
HSTRING_HEADER hstrHead;
|
||||
std::wstring wstr;
|
||||
if (FAILED(WindowsCreateStringReference(RuntimeClass_Windows_Storage_ApplicationData,
|
||||
(UINT32)wcslen(RuntimeClass_Windows_Storage_ApplicationData), &hstrHead, &str)))
|
||||
return wstr;
|
||||
if (FAILED(RoGetActivationFactory(str, IID_PPV_ARGS(appdataFactory.ReleaseAndGetAddressOf()))))
|
||||
return wstr;
|
||||
if (FAILED(appdataFactory->get_Current(appdataRef.ReleaseAndGetAddressOf())))
|
||||
return wstr;
|
||||
if (FAILED(appdataRef->get_TemporaryFolder(storagefolderRef.ReleaseAndGetAddressOf())))
|
||||
return wstr;
|
||||
if (FAILED(storagefolderRef.As(&storageitemRef)))
|
||||
return wstr;
|
||||
str = NULL;
|
||||
if (FAILED(storageitemRef->get_Path(&str)))
|
||||
return wstr;
|
||||
wstr = WindowsGetStringRawBuffer(str, NULL);
|
||||
WindowsDeleteString(str);
|
||||
return wstr;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::wstring GetTempFileNameWinRT(std::wstring prefix)
|
||||
@@ -806,24 +837,6 @@ cvGetModuleInfo( const char* name, const char **version, const char **plugin_lis
|
||||
*plugin_list = plugin_list_buf;
|
||||
}
|
||||
|
||||
#if defined CVAPI_EXPORTS && defined WIN32 && !defined WINCE
|
||||
#ifdef HAVE_WINRT
|
||||
#pragma warning(disable:4447) // Disable warning 'main' signature found without threading model
|
||||
#endif
|
||||
|
||||
BOOL WINAPI DllMain( HINSTANCE, DWORD fdwReason, LPVOID );
|
||||
|
||||
BOOL WINAPI DllMain( HINSTANCE, DWORD fdwReason, LPVOID )
|
||||
{
|
||||
if( fdwReason == DLL_THREAD_DETACH || fdwReason == DLL_PROCESS_DETACH )
|
||||
{
|
||||
cv::deleteThreadAllocData();
|
||||
cv::deleteThreadRNGData();
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
@@ -941,6 +954,223 @@ void Mutex::lock() { impl->lock(); }
|
||||
void Mutex::unlock() { impl->unlock(); }
|
||||
bool Mutex::trylock() { return impl->trylock(); }
|
||||
|
||||
|
||||
//////////////////////////////// thread-local storage ////////////////////////////////
|
||||
|
||||
class TLSStorage
|
||||
{
|
||||
std::vector<void*> tlsData_;
|
||||
public:
|
||||
TLSStorage() { tlsData_.reserve(16); }
|
||||
~TLSStorage();
|
||||
inline void* getData(int key) const
|
||||
{
|
||||
CV_DbgAssert(key >= 0);
|
||||
return (key < (int)tlsData_.size()) ? tlsData_[key] : NULL;
|
||||
}
|
||||
inline void setData(int key, void* data)
|
||||
{
|
||||
CV_DbgAssert(key >= 0);
|
||||
if (key >= (int)tlsData_.size())
|
||||
{
|
||||
tlsData_.resize(key + 1, NULL);
|
||||
}
|
||||
tlsData_[key] = data;
|
||||
}
|
||||
|
||||
inline static TLSStorage* get();
|
||||
};
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma warning(disable:4505) // unreferenced local function has been removed
|
||||
|
||||
#ifdef HAVE_WINRT
|
||||
// using C++11 thread attribute for local thread data
|
||||
static __declspec( thread ) TLSStorage* g_tlsdata = NULL;
|
||||
|
||||
static void deleteThreadData()
|
||||
{
|
||||
if (g_tlsdata)
|
||||
{
|
||||
delete g_tlsdata;
|
||||
g_tlsdata = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
inline TLSStorage* TLSStorage::get()
|
||||
{
|
||||
if (!g_tlsdata)
|
||||
{
|
||||
g_tlsdata = new TLSStorage;
|
||||
}
|
||||
return g_tlsdata;
|
||||
}
|
||||
#else
|
||||
#ifdef WINCE
|
||||
# define TLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF)
|
||||
#endif
|
||||
static DWORD tlsKey = TLS_OUT_OF_INDEXES;
|
||||
|
||||
static void deleteThreadData()
|
||||
{
|
||||
if(tlsKey != TLS_OUT_OF_INDEXES)
|
||||
{
|
||||
delete (TLSStorage*)TlsGetValue(tlsKey);
|
||||
TlsSetValue(tlsKey, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
inline TLSStorage* TLSStorage::get()
|
||||
{
|
||||
if (tlsKey == TLS_OUT_OF_INDEXES)
|
||||
{
|
||||
tlsKey = TlsAlloc();
|
||||
CV_Assert(tlsKey != TLS_OUT_OF_INDEXES);
|
||||
}
|
||||
TLSStorage* d = (TLSStorage*)TlsGetValue(tlsKey);
|
||||
if (!d)
|
||||
{
|
||||
d = new TLSStorage;
|
||||
TlsSetValue(tlsKey, d);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
#endif //HAVE_WINRT
|
||||
|
||||
#if defined CVAPI_EXPORTS && defined WIN32 && !defined WINCE
|
||||
#ifdef HAVE_WINRT
|
||||
#pragma warning(disable:4447) // Disable warning 'main' signature found without threading model
|
||||
#endif
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE, DWORD fdwReason, LPVOID);
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE, DWORD fdwReason, LPVOID)
|
||||
{
|
||||
if (fdwReason == DLL_THREAD_DETACH || fdwReason == DLL_PROCESS_DETACH)
|
||||
{
|
||||
cv::deleteThreadAllocData();
|
||||
cv::deleteThreadRNGData();
|
||||
cv::deleteThreadData();
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
static pthread_key_t tlsKey = 0;
|
||||
static pthread_once_t tlsKeyOnce = PTHREAD_ONCE_INIT;
|
||||
|
||||
static void deleteTLSStorage(void* data)
|
||||
{
|
||||
delete (TLSStorage*)data;
|
||||
}
|
||||
|
||||
static void makeKey()
|
||||
{
|
||||
int errcode = pthread_key_create(&tlsKey, deleteTLSStorage);
|
||||
CV_Assert(errcode == 0);
|
||||
}
|
||||
|
||||
inline TLSStorage* TLSStorage::get()
|
||||
{
|
||||
pthread_once(&tlsKeyOnce, makeKey);
|
||||
TLSStorage* d = (TLSStorage*)pthread_getspecific(tlsKey);
|
||||
if( !d )
|
||||
{
|
||||
d = new TLSStorage;
|
||||
pthread_setspecific(tlsKey, d);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
#endif
|
||||
|
||||
class TLSContainerStorage
|
||||
{
|
||||
cv::Mutex mutex_;
|
||||
std::vector<TLSDataContainer*> tlsContainers_;
|
||||
public:
|
||||
TLSContainerStorage() { }
|
||||
~TLSContainerStorage()
|
||||
{
|
||||
for (size_t i = 0; i < tlsContainers_.size(); i++)
|
||||
{
|
||||
CV_DbgAssert(tlsContainers_[i] == NULL); // not all keys released
|
||||
tlsContainers_[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int allocateKey(TLSDataContainer* pContainer)
|
||||
{
|
||||
cv::AutoLock lock(mutex_);
|
||||
tlsContainers_.push_back(pContainer);
|
||||
return (int)tlsContainers_.size() - 1;
|
||||
}
|
||||
void releaseKey(int id, TLSDataContainer* pContainer)
|
||||
{
|
||||
cv::AutoLock lock(mutex_);
|
||||
CV_Assert(tlsContainers_[id] == pContainer);
|
||||
tlsContainers_[id] = NULL;
|
||||
// currently, we don't go into thread's TLSData and release data for this key
|
||||
}
|
||||
|
||||
void destroyData(int key, void* data)
|
||||
{
|
||||
cv::AutoLock lock(mutex_);
|
||||
TLSDataContainer* k = tlsContainers_[key];
|
||||
if (!k)
|
||||
return;
|
||||
try
|
||||
{
|
||||
k->deleteDataInstance(data);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
CV_DbgAssert(k == NULL); // Debug this!
|
||||
}
|
||||
}
|
||||
};
|
||||
static TLSContainerStorage tlsContainerStorage;
|
||||
|
||||
TLSDataContainer::TLSDataContainer()
|
||||
: key_(-1)
|
||||
{
|
||||
key_ = tlsContainerStorage.allocateKey(this);
|
||||
}
|
||||
|
||||
TLSDataContainer::~TLSDataContainer()
|
||||
{
|
||||
tlsContainerStorage.releaseKey(key_, this);
|
||||
key_ = -1;
|
||||
}
|
||||
|
||||
void* TLSDataContainer::getData() const
|
||||
{
|
||||
CV_Assert(key_ >= 0);
|
||||
TLSStorage* tlsData = TLSStorage::get();
|
||||
void* data = tlsData->getData(key_);
|
||||
if (!data)
|
||||
{
|
||||
data = this->createDataInstance();
|
||||
CV_DbgAssert(data != NULL);
|
||||
tlsData->setData(key_, data);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
TLSStorage::~TLSStorage()
|
||||
{
|
||||
for (int i = 0; i < (int)tlsData_.size(); i++)
|
||||
{
|
||||
void*& data = tlsData_[i];
|
||||
if (data)
|
||||
{
|
||||
tlsContainerStorage.destroyData(i, data);
|
||||
data = NULL;
|
||||
}
|
||||
}
|
||||
tlsData_.clear();
|
||||
}
|
||||
|
||||
} // namespace cv
|
||||
|
||||
/* End of file. */
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
if(NOT ENABLE_DYNAMIC_CUDA)
|
||||
ocv_module_disable(dynamicuda)
|
||||
endif()
|
||||
|
||||
set(the_description "Dynamic CUDA linkage")
|
||||
|
||||
add_definitions(-DUSE_CUDA)
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef -Wshadow)
|
||||
ocv_module_include_directories("${OpenCV_SOURCE_DIR}/modules/gpu/include")
|
||||
set(OPENCV_MODULE_TYPE SHARED)
|
||||
if (BUILD_FAT_JAVA_LIB)
|
||||
ocv_define_module(dynamicuda INTERNAL opencv_java PRIVATE_REQUIRED ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY})
|
||||
else()
|
||||
ocv_define_module(dynamicuda INTERNAL opencv_core PRIVATE_REQUIRED ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY})
|
||||
endif()
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,55 @@
|
||||
#include "cvconfig.h"
|
||||
#include "opencv2/core/core.hpp"
|
||||
#include "opencv2/core/gpumat.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
|
||||
#ifdef HAVE_CUDA
|
||||
# include <cuda_runtime.h>
|
||||
# include <npp.h>
|
||||
|
||||
# define CUDART_MINIMUM_REQUIRED_VERSION 4020
|
||||
# define NPP_MINIMUM_REQUIRED_VERSION 4200
|
||||
|
||||
# if (CUDART_VERSION < CUDART_MINIMUM_REQUIRED_VERSION)
|
||||
# error "Insufficient Cuda Runtime library version, please update it."
|
||||
# endif
|
||||
|
||||
# if (NPP_VERSION_MAJOR * 1000 + NPP_VERSION_MINOR * 100 + NPP_VERSION_BUILD < NPP_MINIMUM_REQUIRED_VERSION)
|
||||
# error "Insufficient NPP version, please update it."
|
||||
# endif
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
using namespace cv::gpu;
|
||||
|
||||
#define throw_nogpu CV_Error(CV_GpuNotSupported, "The library is compiled without CUDA support")
|
||||
|
||||
#include "opencv2/dynamicuda/dynamicuda.hpp"
|
||||
|
||||
#ifdef HAVE_CUDA
|
||||
static CudaDeviceInfoFuncTable deviceInfoTable;
|
||||
static CudaFuncTable gpuTable;
|
||||
#else
|
||||
static EmptyDeviceInfoFuncTable deviceInfoTable;
|
||||
static EmptyFuncTable gpuTable;
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
|
||||
DeviceInfoFuncTable* deviceInfoFactory();
|
||||
GpuFuncTable* gpuFactory();
|
||||
|
||||
DeviceInfoFuncTable* deviceInfoFactory()
|
||||
{
|
||||
return (DeviceInfoFuncTable*)&deviceInfoTable;
|
||||
}
|
||||
|
||||
GpuFuncTable* gpuFactory()
|
||||
{
|
||||
return (GpuFuncTable*)&gpuTable;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -54,8 +54,9 @@ static const int FREAK_NB_SCALES = FREAK::NB_SCALES;
|
||||
static const int FREAK_NB_PAIRS = FREAK::NB_PAIRS;
|
||||
static const int FREAK_NB_ORIENPAIRS = FREAK::NB_ORIENPAIRS;
|
||||
|
||||
// default pairs
|
||||
static const int FREAK_DEF_PAIRS[FREAK::NB_PAIRS] =
|
||||
{ // default pairs
|
||||
{
|
||||
404,431,818,511,181,52,311,874,774,543,719,230,417,205,11,
|
||||
560,149,265,39,306,165,857,250,8,61,15,55,717,44,412,
|
||||
592,134,761,695,660,782,625,487,549,516,271,665,762,392,178,
|
||||
@@ -92,15 +93,17 @@ static const int FREAK_DEF_PAIRS[FREAK::NB_PAIRS] =
|
||||
670,249,36,581,389,605,331,518,442,822
|
||||
};
|
||||
|
||||
// used to sort pairs during pairs selection
|
||||
struct PairStat
|
||||
{ // used to sort pairs during pairs selection
|
||||
{
|
||||
double mean;
|
||||
int idx;
|
||||
};
|
||||
|
||||
struct sortMean
|
||||
{
|
||||
bool operator()( const PairStat& a, const PairStat& b ) const {
|
||||
bool operator()( const PairStat& a, const PairStat& b ) const
|
||||
{
|
||||
return a.mean < b.mean;
|
||||
}
|
||||
};
|
||||
@@ -130,17 +133,21 @@ void FREAK::buildPattern()
|
||||
radius[6]/2.0, radius[6]/2.0
|
||||
};
|
||||
// fill the lookup table
|
||||
for( int scaleIdx=0; scaleIdx < FREAK_NB_SCALES; ++scaleIdx ) {
|
||||
for( int scaleIdx=0; scaleIdx < FREAK_NB_SCALES; ++scaleIdx )
|
||||
{
|
||||
patternSizes[scaleIdx] = 0; // proper initialization
|
||||
scalingFactor = pow(scaleStep,scaleIdx); //scale of the pattern, scaleStep ^ scaleIdx
|
||||
|
||||
for( int orientationIdx = 0; orientationIdx < FREAK_NB_ORIENTATION; ++orientationIdx ) {
|
||||
for( int orientationIdx = 0; orientationIdx < FREAK_NB_ORIENTATION; ++orientationIdx )
|
||||
{
|
||||
theta = double(orientationIdx)* 2*CV_PI/double(FREAK_NB_ORIENTATION); // orientation of the pattern
|
||||
int pointIdx = 0;
|
||||
|
||||
PatternPoint* patternLookupPtr = &patternLookup[0];
|
||||
for( size_t i = 0; i < 8; ++i ) {
|
||||
for( int k = 0 ; k < n[i]; ++k ) {
|
||||
for( size_t i = 0; i < 8; ++i )
|
||||
{
|
||||
for( int k = 0 ; k < n[i]; ++k )
|
||||
{
|
||||
beta = CV_PI/n[i] * (i%2); // orientation offset so that groups of points on each circles are staggered
|
||||
alpha = double(k)* 2*CV_PI/double(n[i])+beta+theta;
|
||||
|
||||
@@ -182,7 +189,8 @@ void FREAK::buildPattern()
|
||||
orientationPairs[39].i=30; orientationPairs[39].j=33; orientationPairs[40].i=31; orientationPairs[40].j=34; orientationPairs[41].i=32; orientationPairs[41].j=35;
|
||||
orientationPairs[42].i=36; orientationPairs[42].j=39; orientationPairs[43].i=37; orientationPairs[43].j=40; orientationPairs[44].i=38; orientationPairs[44].j=41;
|
||||
|
||||
for( unsigned m = FREAK_NB_ORIENPAIRS; m--; ) {
|
||||
for( unsigned m = FREAK_NB_ORIENPAIRS; m--; )
|
||||
{
|
||||
const float dx = patternLookup[orientationPairs[m].i].x-patternLookup[orientationPairs[m].j].x;
|
||||
const float dy = patternLookup[orientationPairs[m].i].y-patternLookup[orientationPairs[m].j].y;
|
||||
const float norm_sq = (dx*dx+dy*dy);
|
||||
@@ -192,30 +200,37 @@ void FREAK::buildPattern()
|
||||
|
||||
// build the list of description pairs
|
||||
std::vector<DescriptionPair> allPairs;
|
||||
for( unsigned int i = 1; i < (unsigned int)FREAK_NB_POINTS; ++i ) {
|
||||
for( unsigned int i = 1; i < (unsigned int)FREAK_NB_POINTS; ++i )
|
||||
{
|
||||
// (generate all the pairs)
|
||||
for( unsigned int j = 0; (unsigned int)j < i; ++j ) {
|
||||
for( unsigned int j = 0; (unsigned int)j < i; ++j )
|
||||
{
|
||||
DescriptionPair pair = {(uchar)i,(uchar)j};
|
||||
allPairs.push_back(pair);
|
||||
}
|
||||
}
|
||||
// Input vector provided
|
||||
if( !selectedPairs0.empty() ) {
|
||||
if( (int)selectedPairs0.size() == FREAK_NB_PAIRS ) {
|
||||
if( !selectedPairs0.empty() )
|
||||
{
|
||||
if( (int)selectedPairs0.size() == FREAK_NB_PAIRS )
|
||||
{
|
||||
for( int i = 0; i < FREAK_NB_PAIRS; ++i )
|
||||
descriptionPairs[i] = allPairs[selectedPairs0.at(i)];
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
CV_Error(CV_StsVecLengthErr, "Input vector does not match the required size");
|
||||
}
|
||||
}
|
||||
else { // default selected pairs
|
||||
else // default selected pairs
|
||||
{
|
||||
for( int i = 0; i < FREAK_NB_PAIRS; ++i )
|
||||
descriptionPairs[i] = allPairs[FREAK_DEF_PAIRS[i]];
|
||||
}
|
||||
}
|
||||
|
||||
void FREAK::computeImpl( const Mat& image, std::vector<KeyPoint>& keypoints, Mat& descriptors ) const {
|
||||
void FREAK::computeImpl( const Mat& image, std::vector<KeyPoint>& keypoints, Mat& descriptors ) const
|
||||
{
|
||||
|
||||
if( image.empty() )
|
||||
return;
|
||||
@@ -236,8 +251,10 @@ void FREAK::computeImpl( const Mat& image, std::vector<KeyPoint>& keypoints, Mat
|
||||
int direction1;
|
||||
|
||||
// compute the scale index corresponding to the keypoint size and remove keypoints close to the border
|
||||
if( scaleNormalized ) {
|
||||
for( size_t k = keypoints.size(); k--; ) {
|
||||
if( scaleNormalized )
|
||||
{
|
||||
for( size_t k = keypoints.size(); k--; )
|
||||
{
|
||||
//Is k non-zero? If so, decrement it and continue"
|
||||
kpScaleIdx[k] = max( (int)(log(keypoints[k].size/FREAK_SMALLEST_KP_SIZE)*sizeCst+0.5) ,0);
|
||||
if( kpScaleIdx[k] >= FREAK_NB_SCALES )
|
||||
@@ -247,24 +264,29 @@ void FREAK::computeImpl( const Mat& image, std::vector<KeyPoint>& keypoints, Mat
|
||||
keypoints[k].pt.y <= patternSizes[kpScaleIdx[k]] ||
|
||||
keypoints[k].pt.x >= image.cols-patternSizes[kpScaleIdx[k]] ||
|
||||
keypoints[k].pt.y >= image.rows-patternSizes[kpScaleIdx[k]]
|
||||
) {
|
||||
)
|
||||
{
|
||||
keypoints.erase(kpBegin+k);
|
||||
kpScaleIdx.erase(ScaleIdxBegin+k);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
const int scIdx = max( (int)(1.0986122886681*sizeCst+0.5) ,0);
|
||||
for( size_t k = keypoints.size(); k--; ) {
|
||||
for( size_t k = keypoints.size(); k--; )
|
||||
{
|
||||
kpScaleIdx[k] = scIdx; // equivalent to the formule when the scale is normalized with a constant size of keypoints[k].size=3*SMALLEST_KP_SIZE
|
||||
if( kpScaleIdx[k] >= FREAK_NB_SCALES ) {
|
||||
if( kpScaleIdx[k] >= FREAK_NB_SCALES )
|
||||
{
|
||||
kpScaleIdx[k] = FREAK_NB_SCALES-1;
|
||||
}
|
||||
if( keypoints[k].pt.x <= patternSizes[kpScaleIdx[k]] ||
|
||||
keypoints[k].pt.y <= patternSizes[kpScaleIdx[k]] ||
|
||||
keypoints[k].pt.x >= image.cols-patternSizes[kpScaleIdx[k]] ||
|
||||
keypoints[k].pt.y >= image.rows-patternSizes[kpScaleIdx[k]]
|
||||
) {
|
||||
)
|
||||
{
|
||||
keypoints.erase(kpBegin+k);
|
||||
kpScaleIdx.erase(ScaleIdxBegin+k);
|
||||
}
|
||||
@@ -272,7 +294,8 @@ void FREAK::computeImpl( const Mat& image, std::vector<KeyPoint>& keypoints, Mat
|
||||
}
|
||||
|
||||
// allocate descriptor memory, estimate orientations, extract descriptors
|
||||
if( !extAll ) {
|
||||
if( !extAll )
|
||||
{
|
||||
// extract the best comparisons only
|
||||
descriptors = cv::Mat::zeros((int)keypoints.size(), FREAK_NB_PAIRS/8, CV_8U);
|
||||
#if CV_SSE2
|
||||
@@ -280,20 +303,25 @@ void FREAK::computeImpl( const Mat& image, std::vector<KeyPoint>& keypoints, Mat
|
||||
#else
|
||||
std::bitset<FREAK_NB_PAIRS>* ptr = (std::bitset<FREAK_NB_PAIRS>*) (descriptors.data+(keypoints.size()-1)*descriptors.step[0]);
|
||||
#endif
|
||||
for( size_t k = keypoints.size(); k--; ) {
|
||||
for( size_t k = keypoints.size(); k--; )
|
||||
{
|
||||
// estimate orientation (gradient)
|
||||
if( !orientationNormalized ) {
|
||||
if( !orientationNormalized )
|
||||
{
|
||||
thetaIdx = 0; // assign 0° to all keypoints
|
||||
keypoints[k].angle = 0.0;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
// get the points intensity value in the un-rotated pattern
|
||||
for( int i = FREAK_NB_POINTS; i--; ) {
|
||||
for( int i = FREAK_NB_POINTS; i--; )
|
||||
{
|
||||
pointsValue[i] = meanIntensity(image, imgIntegral, keypoints[k].pt.x,keypoints[k].pt.y, kpScaleIdx[k], 0, i);
|
||||
}
|
||||
direction0 = 0;
|
||||
direction1 = 0;
|
||||
for( int m = 45; m--; ) {
|
||||
for( int m = 45; m--; )
|
||||
{
|
||||
//iterate through the orientation pairs
|
||||
const int delta = (pointsValue[ orientationPairs[m].i ]-pointsValue[ orientationPairs[m].j ]);
|
||||
direction0 += delta*(orientationPairs[m].weight_dx)/2048;
|
||||
@@ -309,7 +337,8 @@ void FREAK::computeImpl( const Mat& image, std::vector<KeyPoint>& keypoints, Mat
|
||||
thetaIdx -= FREAK_NB_ORIENTATION;
|
||||
}
|
||||
// extract descriptor at the computed orientation
|
||||
for( int i = FREAK_NB_POINTS; i--; ) {
|
||||
for( int i = FREAK_NB_POINTS; i--; )
|
||||
{
|
||||
pointsValue[i] = meanIntensity(image, imgIntegral, keypoints[k].pt.x,keypoints[k].pt.y, kpScaleIdx[k], thetaIdx, i);
|
||||
}
|
||||
#if CV_SSE2
|
||||
@@ -384,24 +413,29 @@ void FREAK::computeImpl( const Mat& image, std::vector<KeyPoint>& keypoints, Mat
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else { // extract all possible comparisons for selection
|
||||
else // extract all possible comparisons for selection
|
||||
{
|
||||
descriptors = cv::Mat::zeros((int)keypoints.size(), 128, CV_8U);
|
||||
std::bitset<1024>* ptr = (std::bitset<1024>*) (descriptors.data+(keypoints.size()-1)*descriptors.step[0]);
|
||||
|
||||
for( size_t k = keypoints.size(); k--; ) {
|
||||
for( size_t k = keypoints.size(); k--; )
|
||||
{
|
||||
//estimate orientation (gradient)
|
||||
if( !orientationNormalized ) {
|
||||
if( !orientationNormalized )
|
||||
{
|
||||
thetaIdx = 0;//assign 0° to all keypoints
|
||||
keypoints[k].angle = 0.0;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
//get the points intensity value in the un-rotated pattern
|
||||
for( int i = FREAK_NB_POINTS;i--; )
|
||||
pointsValue[i] = meanIntensity(image, imgIntegral, keypoints[k].pt.x,keypoints[k].pt.y, kpScaleIdx[k], 0, i);
|
||||
|
||||
direction0 = 0;
|
||||
direction1 = 0;
|
||||
for( int m = 45; m--; ) {
|
||||
for( int m = 45; m--; )
|
||||
{
|
||||
//iterate through the orientation pairs
|
||||
const int delta = (pointsValue[ orientationPairs[m].i ]-pointsValue[ orientationPairs[m].j ]);
|
||||
direction0 += delta*(orientationPairs[m].weight_dx)/2048;
|
||||
@@ -418,15 +452,18 @@ void FREAK::computeImpl( const Mat& image, std::vector<KeyPoint>& keypoints, Mat
|
||||
thetaIdx -= FREAK_NB_ORIENTATION;
|
||||
}
|
||||
// get the points intensity value in the rotated pattern
|
||||
for( int i = FREAK_NB_POINTS; i--; ) {
|
||||
for( int i = FREAK_NB_POINTS; i--; )
|
||||
{
|
||||
pointsValue[i] = meanIntensity(image, imgIntegral, keypoints[k].pt.x,
|
||||
keypoints[k].pt.y, kpScaleIdx[k], thetaIdx, i);
|
||||
}
|
||||
|
||||
int cnt(0);
|
||||
for( int i = 1; i < FREAK_NB_POINTS; ++i ) {
|
||||
for( int i = 1; i < FREAK_NB_POINTS; ++i )
|
||||
{
|
||||
//(generate all the pairs)
|
||||
for( int j = 0; j < i; ++j ) {
|
||||
for( int j = 0; j < i; ++j )
|
||||
{
|
||||
ptr->set(cnt, pointsValue[i] >= pointsValue[j] );
|
||||
++cnt;
|
||||
}
|
||||
@@ -442,7 +479,8 @@ uchar FREAK::meanIntensity( const cv::Mat& image, const cv::Mat& integral,
|
||||
const float kp_y,
|
||||
const unsigned int scale,
|
||||
const unsigned int rot,
|
||||
const unsigned int point) const {
|
||||
const unsigned int point) const
|
||||
{
|
||||
// get point position in image
|
||||
const PatternPoint& FreakPoint = patternLookup[scale*FREAK_NB_ORIENTATION*FREAK_NB_POINTS + rot*FREAK_NB_POINTS + point];
|
||||
const float xf = FreakPoint.x+kp_x;
|
||||
@@ -455,7 +493,8 @@ uchar FREAK::meanIntensity( const cv::Mat& image, const cv::Mat& integral,
|
||||
const float radius = FreakPoint.sigma;
|
||||
|
||||
// calculate output:
|
||||
if( radius < 0.5 ) {
|
||||
if( radius < 0.5 )
|
||||
{
|
||||
// interpolation multipliers:
|
||||
const int r_x = static_cast<int>((xf-x)*1024);
|
||||
const int r_y = static_cast<int>((yf-y)*1024);
|
||||
@@ -507,7 +546,8 @@ vector<int> FREAK::selectPairs(const std::vector<Mat>& images
|
||||
if( verbose )
|
||||
std::cout << "Number of images: " << images.size() << std::endl;
|
||||
|
||||
for( size_t i = 0;i < images.size(); ++i ) {
|
||||
for( size_t i = 0;i < images.size(); ++i )
|
||||
{
|
||||
Mat descriptorsTmp;
|
||||
computeImpl(images[i],keypoints[i],descriptorsTmp);
|
||||
descriptors.push_back(descriptorsTmp);
|
||||
@@ -520,8 +560,10 @@ vector<int> FREAK::selectPairs(const std::vector<Mat>& images
|
||||
Mat descriptorsFloat = Mat::zeros(descriptors.rows, 903, CV_32F);
|
||||
|
||||
std::bitset<1024>* ptr = (std::bitset<1024>*) (descriptors.data+(descriptors.rows-1)*descriptors.step[0]);
|
||||
for( int m = descriptors.rows; m--; ) {
|
||||
for( int n = 903; n--; ) {
|
||||
for( int m = descriptors.rows; m--; )
|
||||
{
|
||||
for( int n = 903; n--; )
|
||||
{
|
||||
if( ptr->test(n) == true )
|
||||
descriptorsFloat.at<float>(m,n)=1.0f;
|
||||
}
|
||||
@@ -529,7 +571,8 @@ vector<int> FREAK::selectPairs(const std::vector<Mat>& images
|
||||
}
|
||||
|
||||
std::vector<PairStat> pairStat;
|
||||
for( int n = 903; n--; ) {
|
||||
for( int n = 903; n--; )
|
||||
{
|
||||
// the higher the variance, the better --> mean = 0.5
|
||||
PairStat tmp = { fabs( mean(descriptorsFloat.col(n))[0]-0.5 ) ,n};
|
||||
pairStat.push_back(tmp);
|
||||
@@ -538,19 +581,22 @@ vector<int> FREAK::selectPairs(const std::vector<Mat>& images
|
||||
std::sort( pairStat.begin(),pairStat.end(), sortMean() );
|
||||
|
||||
std::vector<PairStat> bestPairs;
|
||||
for( int m = 0; m < 903; ++m ) {
|
||||
for( int m = 0; m < 903; ++m )
|
||||
{
|
||||
if( verbose )
|
||||
std::cout << m << ":" << bestPairs.size() << " " << std::flush;
|
||||
double corrMax(0);
|
||||
|
||||
for( size_t n = 0; n < bestPairs.size(); ++n ) {
|
||||
for( size_t n = 0; n < bestPairs.size(); ++n )
|
||||
{
|
||||
int idxA = bestPairs[n].idx;
|
||||
int idxB = pairStat[m].idx;
|
||||
double corr(0);
|
||||
// compute correlation between 2 pairs
|
||||
corr = fabs(compareHist(descriptorsFloat.col(idxA), descriptorsFloat.col(idxB), CV_COMP_CORREL));
|
||||
|
||||
if( corr > corrMax ) {
|
||||
if( corr > corrMax )
|
||||
{
|
||||
corrMax = corr;
|
||||
if( corrMax >= corrTresh )
|
||||
break;
|
||||
@@ -560,7 +606,8 @@ vector<int> FREAK::selectPairs(const std::vector<Mat>& images
|
||||
if( corrMax < corrTresh/*0.7*/ )
|
||||
bestPairs.push_back(pairStat[m]);
|
||||
|
||||
if( bestPairs.size() >= 512 ) {
|
||||
if( bestPairs.size() >= 512 )
|
||||
{
|
||||
if( verbose )
|
||||
std::cout << m << std::endl;
|
||||
break;
|
||||
@@ -568,11 +615,13 @@ vector<int> FREAK::selectPairs(const std::vector<Mat>& images
|
||||
}
|
||||
|
||||
std::vector<int> idxBestPairs;
|
||||
if( (int)bestPairs.size() >= FREAK_NB_PAIRS ) {
|
||||
if( (int)bestPairs.size() >= FREAK_NB_PAIRS )
|
||||
{
|
||||
for( int i = 0; i < FREAK_NB_PAIRS; ++i )
|
||||
idxBestPairs.push_back(bestPairs[i].idx);
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
if( verbose )
|
||||
std::cout << "correlation threshold too small (restrictive)" << std::endl;
|
||||
CV_Error(CV_StsError, "correlation threshold too small (restrictive)");
|
||||
@@ -583,11 +632,13 @@ vector<int> FREAK::selectPairs(const std::vector<Mat>& images
|
||||
|
||||
|
||||
/*
|
||||
// create an image showing the brisk pattern
|
||||
void FREAKImpl::drawPattern()
|
||||
{ // create an image showing the brisk pattern
|
||||
{
|
||||
Mat pattern = Mat::zeros(1000, 1000, CV_8UC3) + Scalar(255,255,255);
|
||||
int sFac = 500 / patternScale;
|
||||
for( int n = 0; n < kNB_POINTS; ++n ) {
|
||||
for( int n = 0; n < kNB_POINTS; ++n )
|
||||
{
|
||||
PatternPoint& pt = patternLookup[n];
|
||||
circle(pattern, Point( pt.x*sFac,pt.y*sFac)+Point(500,500), pt.sigma*sFac, Scalar(0,0,255),2);
|
||||
// rectangle(pattern, Point( (pt.x-pt.sigma)*sFac,(pt.y-pt.sigma)*sFac)+Point(500,500), Point( (pt.x+pt.sigma)*sFac,(pt.y+pt.sigma)*sFac)+Point(500,500), Scalar(0,0,255),2);
|
||||
@@ -615,11 +666,13 @@ FREAK::~FREAK()
|
||||
{
|
||||
}
|
||||
|
||||
int FREAK::descriptorSize() const {
|
||||
int FREAK::descriptorSize() const
|
||||
{
|
||||
return FREAK_NB_PAIRS / 8; // descriptor length in bytes
|
||||
}
|
||||
|
||||
int FREAK::descriptorType() const {
|
||||
int FREAK::descriptorType() const
|
||||
{
|
||||
return CV_8U;
|
||||
}
|
||||
|
||||
|
||||
@@ -298,6 +298,11 @@ public:
|
||||
trees_ = get_param(params,"trees",4);
|
||||
root = new NodePtr[trees_];
|
||||
indices = new int*[trees_];
|
||||
|
||||
for (int i=0; i<trees_; ++i) {
|
||||
root[i] = NULL;
|
||||
indices[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
HierarchicalClusteringIndex(const HierarchicalClusteringIndex&);
|
||||
@@ -310,11 +315,34 @@ public:
|
||||
*/
|
||||
virtual ~HierarchicalClusteringIndex()
|
||||
{
|
||||
free_elements();
|
||||
|
||||
if (root!=NULL) {
|
||||
delete[] root;
|
||||
}
|
||||
|
||||
if (indices!=NULL) {
|
||||
delete[] indices;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Release the inner elements of indices[]
|
||||
*/
|
||||
void free_elements()
|
||||
{
|
||||
if (indices!=NULL) {
|
||||
for(int i=0; i<trees_; ++i) {
|
||||
if (indices[i]!=NULL) {
|
||||
delete[] indices[i];
|
||||
indices[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns size of index.
|
||||
*/
|
||||
@@ -349,6 +377,9 @@ public:
|
||||
if (branching_<2) {
|
||||
throw FLANNException("Branching factor must be at least 2");
|
||||
}
|
||||
|
||||
free_elements();
|
||||
|
||||
for (int i=0; i<trees_; ++i) {
|
||||
indices[i] = new int[size_];
|
||||
for (size_t j=0; j<size_; ++j) {
|
||||
@@ -388,6 +419,17 @@ public:
|
||||
load_value(stream, centers_init_);
|
||||
load_value(stream, leaf_size_);
|
||||
load_value(stream, memoryCounter);
|
||||
|
||||
free_elements();
|
||||
|
||||
if (root!=NULL) {
|
||||
delete[] root;
|
||||
}
|
||||
|
||||
if (indices!=NULL) {
|
||||
delete[] indices;
|
||||
}
|
||||
|
||||
indices = new int*[trees_];
|
||||
root = new NodePtr[trees_];
|
||||
for (int i=0; i<trees_; ++i) {
|
||||
|
||||
@@ -3,7 +3,8 @@ if(IOS)
|
||||
endif()
|
||||
|
||||
set(the_description "GPU-accelerated Computer Vision")
|
||||
ocv_add_module(gpu opencv_imgproc opencv_calib3d opencv_objdetect opencv_video opencv_photo opencv_legacy)
|
||||
ocv_add_module(gpu opencv_imgproc opencv_calib3d opencv_objdetect opencv_video opencv_photo opencv_legacy
|
||||
OPTIONAL ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY} ${CUDA_cublas_LIBRARY} ${CUDA_cufft_LIBRARY})
|
||||
|
||||
ocv_module_include_directories("${CMAKE_CURRENT_SOURCE_DIR}/src/cuda")
|
||||
|
||||
|
||||
@@ -1303,6 +1303,8 @@ PERF_TEST_P(Sz_3Depth, Core_AddWeighted,
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// GEMM
|
||||
|
||||
#ifdef HAVE_CUBLAS
|
||||
|
||||
CV_FLAGS(GemmFlags, 0, GEMM_1_T, GEMM_2_T, GEMM_3_T)
|
||||
#define ALL_GEMM_FLAGS Values(0, CV_GEMM_A_T, CV_GEMM_B_T, CV_GEMM_C_T, CV_GEMM_A_T | CV_GEMM_B_T, CV_GEMM_A_T | CV_GEMM_C_T, CV_GEMM_A_T | CV_GEMM_B_T | CV_GEMM_C_T)
|
||||
|
||||
@@ -1351,6 +1353,8 @@ PERF_TEST_P(Sz_Type_Flags, Core_GEMM,
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Transpose
|
||||
|
||||
|
||||
@@ -500,7 +500,7 @@ PERF_TEST_P(ImagePair, Video_OpticalFlowBM,
|
||||
}
|
||||
}
|
||||
|
||||
PERF_TEST_P(ImagePair, Video_FastOpticalFlowBM,
|
||||
PERF_TEST_P(ImagePair, DISABLED_Video_FastOpticalFlowBM,
|
||||
Values<pair_string>(make_pair("gpu/opticalflow/frame0.png", "gpu/opticalflow/frame1.png")))
|
||||
{
|
||||
declare.time(400);
|
||||
|
||||
@@ -2,26 +2,28 @@ set(PERF4AU_REQUIRED_DEPS opencv_core opencv_imgproc opencv_highgui opencv_video
|
||||
|
||||
ocv_check_dependencies(${PERF4AU_REQUIRED_DEPS})
|
||||
|
||||
set(the_target gpu_perf4au)
|
||||
project(${the_target})
|
||||
if (OCV_DEPENDENCIES_FOUND)
|
||||
set(the_target gpu_perf4au)
|
||||
project(${the_target})
|
||||
|
||||
ocv_include_modules(${PERF4AU_REQUIRED_DEPS})
|
||||
ocv_include_modules(${PERF4AU_REQUIRED_DEPS})
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX AND NOT ENABLE_NOISY_WARNINGS)
|
||||
if(CMAKE_COMPILER_IS_GNUCXX AND NOT ENABLE_NOISY_WARNINGS)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
file(GLOB srcs RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp *.h *.hpp)
|
||||
add_executable(${the_target} ${srcs})
|
||||
file(GLOB srcs RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp *.h *.hpp)
|
||||
add_executable(${the_target} ${srcs})
|
||||
|
||||
target_link_libraries(${the_target} ${OPENCV_LINKER_LIBS} ${PERF4AU_REQUIRED_DEPS})
|
||||
target_link_libraries(${the_target} ${OPENCV_LINKER_LIBS} ${PERF4AU_REQUIRED_DEPS})
|
||||
|
||||
if(ENABLE_SOLUTION_FOLDERS)
|
||||
set_target_properties(${the_target} PROPERTIES FOLDER "tests performance")
|
||||
endif()
|
||||
if(ENABLE_SOLUTION_FOLDERS)
|
||||
set_target_properties(${the_target} PROPERTIES FOLDER "tests performance")
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
if(WIN32)
|
||||
if(MSVC AND NOT BUILD_SHARED_LIBS)
|
||||
set_target_properties(${the_target} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:atlthunk.lib /NODEFAULTLIB:atlsd.lib /DEBUG")
|
||||
set_target_properties(${the_target} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:atlthunk.lib /NODEFAULTLIB:atlsd.lib /DEBUG")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
@@ -715,7 +715,7 @@ GPU_TEST_P(CvtColor, BGR2YCrCb)
|
||||
cv::Mat dst_gold;
|
||||
cv::cvtColor(src, dst_gold, cv::COLOR_BGR2YCrCb);
|
||||
|
||||
EXPECT_MAT_NEAR(dst_gold, dst, 1e-5);
|
||||
EXPECT_MAT_NEAR(dst_gold, dst, 1.0);
|
||||
}
|
||||
|
||||
GPU_TEST_P(CvtColor, RGB2YCrCb)
|
||||
@@ -728,7 +728,7 @@ GPU_TEST_P(CvtColor, RGB2YCrCb)
|
||||
cv::Mat dst_gold;
|
||||
cv::cvtColor(src, dst_gold, cv::COLOR_RGB2YCrCb);
|
||||
|
||||
EXPECT_MAT_NEAR(dst_gold, dst, 1e-5);
|
||||
EXPECT_MAT_NEAR(dst_gold, dst, 1.0);
|
||||
}
|
||||
|
||||
GPU_TEST_P(CvtColor, BGR2YCrCb4)
|
||||
@@ -749,7 +749,7 @@ GPU_TEST_P(CvtColor, BGR2YCrCb4)
|
||||
cv::split(h_dst, channels);
|
||||
cv::merge(channels, 3, h_dst);
|
||||
|
||||
EXPECT_MAT_NEAR(dst_gold, h_dst, 1e-5);
|
||||
EXPECT_MAT_NEAR(dst_gold, h_dst, 1.0);
|
||||
}
|
||||
|
||||
GPU_TEST_P(CvtColor, RGBA2YCrCb4)
|
||||
@@ -771,7 +771,7 @@ GPU_TEST_P(CvtColor, RGBA2YCrCb4)
|
||||
cv::split(h_dst, channels);
|
||||
cv::merge(channels, 3, h_dst);
|
||||
|
||||
EXPECT_MAT_NEAR(dst_gold, h_dst, 1e-5);
|
||||
EXPECT_MAT_NEAR(dst_gold, h_dst, 1.0);
|
||||
}
|
||||
|
||||
GPU_TEST_P(CvtColor, YCrCb2BGR)
|
||||
|
||||
@@ -2353,7 +2353,7 @@ GPU_TEST_P(AddWeighted, Accuracy)
|
||||
cv::Mat dst_gold;
|
||||
cv::addWeighted(src1, alpha, src2, beta, gamma, dst_gold, dst_depth);
|
||||
|
||||
EXPECT_MAT_NEAR(dst_gold, dst, dst_depth < CV_32F ? 1.0 : 1e-3);
|
||||
EXPECT_MAT_NEAR(dst_gold, dst, dst_depth < CV_32F ? 2.0 : 1e-3);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3582,7 +3582,7 @@ GPU_TEST_P(Normalize, WithOutMask)
|
||||
cv::Mat dst_gold;
|
||||
cv::normalize(src, dst_gold, alpha, beta, norm_type, type);
|
||||
|
||||
EXPECT_MAT_NEAR(dst_gold, dst, 1e-6);
|
||||
EXPECT_MAT_NEAR(dst_gold, dst, 1.0);
|
||||
}
|
||||
|
||||
GPU_TEST_P(Normalize, WithMask)
|
||||
@@ -3598,7 +3598,7 @@ GPU_TEST_P(Normalize, WithMask)
|
||||
dst_gold.setTo(cv::Scalar::all(0));
|
||||
cv::normalize(src, dst_gold, alpha, beta, norm_type, type, mask);
|
||||
|
||||
EXPECT_MAT_NEAR(dst_gold, dst, 1e-6);
|
||||
EXPECT_MAT_NEAR(dst_gold, dst, 1.0);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(GPU_Core, Normalize, testing::Combine(
|
||||
|
||||
@@ -281,7 +281,7 @@ GPU_TEST_P(ConvertTo, WithOutScaling)
|
||||
cv::Mat dst_gold;
|
||||
src.convertTo(dst_gold, depth2);
|
||||
|
||||
EXPECT_MAT_NEAR(dst_gold, dst, 0.0);
|
||||
EXPECT_MAT_NEAR(dst_gold, dst, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -177,7 +177,7 @@ struct HOG : testing::TestWithParam<cv::gpu::DeviceInfo>, cv::gpu::HOGDescriptor
|
||||
};
|
||||
|
||||
// desabled while resize does not fixed
|
||||
GPU_TEST_P(HOG, Detect)
|
||||
GPU_TEST_P(HOG, DISABLED_Detect)
|
||||
{
|
||||
cv::Mat img_rgb = readImage("hog/road.png");
|
||||
ASSERT_FALSE(img_rgb.empty());
|
||||
|
||||
@@ -218,6 +218,12 @@ elseif(HAVE_QTKIT)
|
||||
list(APPEND HIGHGUI_LIBRARIES "-framework QTKit" "-framework QuartzCore" "-framework AppKit")
|
||||
endif()
|
||||
|
||||
if(HAVE_INTELPERC)
|
||||
list(APPEND highgui_srcs src/cap_intelperc.cpp)
|
||||
ocv_include_directories(${INTELPERC_INCLUDE_DIR})
|
||||
list(APPEND HIGHGUI_LIBRARIES ${INTELPERC_LIBRARIES})
|
||||
endif(HAVE_INTELPERC)
|
||||
|
||||
if(IOS)
|
||||
add_definitions(-DHAVE_IOS=1)
|
||||
list(APPEND highgui_srcs src/ios_conversions.mm src/cap_ios_abstract_camera.mm src/cap_ios_photo_camera.mm src/cap_ios_video_camera.mm)
|
||||
|
||||
@@ -312,7 +312,9 @@ enum
|
||||
|
||||
CV_CAP_AVFOUNDATION = 1200, // AVFoundation framework for iOS (OS X Lion will have the same API)
|
||||
|
||||
CV_CAP_GIGANETIX = 1300 // Smartek Giganetix GigEVisionSDK
|
||||
CV_CAP_GIGANETIX = 1300, // Smartek Giganetix GigEVisionSDK
|
||||
|
||||
CV_CAP_INTELPERC = 1500 // Intel Perceptual Computing SDK
|
||||
};
|
||||
|
||||
/* start capturing frames from camera: index = camera_index + domain_offset (CV_CAP_*) */
|
||||
@@ -458,16 +460,29 @@ enum
|
||||
CV_CAP_PROP_IOS_DEVICE_EXPOSURE = 9002,
|
||||
CV_CAP_PROP_IOS_DEVICE_FLASH = 9003,
|
||||
CV_CAP_PROP_IOS_DEVICE_WHITEBALANCE = 9004,
|
||||
CV_CAP_PROP_IOS_DEVICE_TORCH = 9005
|
||||
CV_CAP_PROP_IOS_DEVICE_TORCH = 9005,
|
||||
|
||||
// Properties of cameras available through Smartek Giganetix Ethernet Vision interface
|
||||
/* --- Vladimir Litvinenko (litvinenko.vladimir@gmail.com) --- */
|
||||
,CV_CAP_PROP_GIGA_FRAME_OFFSET_X = 10001,
|
||||
CV_CAP_PROP_GIGA_FRAME_OFFSET_X = 10001,
|
||||
CV_CAP_PROP_GIGA_FRAME_OFFSET_Y = 10002,
|
||||
CV_CAP_PROP_GIGA_FRAME_WIDTH_MAX = 10003,
|
||||
CV_CAP_PROP_GIGA_FRAME_HEIGH_MAX = 10004,
|
||||
CV_CAP_PROP_GIGA_FRAME_SENS_WIDTH = 10005,
|
||||
CV_CAP_PROP_GIGA_FRAME_SENS_HEIGH = 10006
|
||||
CV_CAP_PROP_GIGA_FRAME_SENS_HEIGH = 10006,
|
||||
|
||||
CV_CAP_PROP_INTELPERC_PROFILE_COUNT = 11001,
|
||||
CV_CAP_PROP_INTELPERC_PROFILE_IDX = 11002,
|
||||
CV_CAP_PROP_INTELPERC_DEPTH_LOW_CONFIDENCE_VALUE = 11003,
|
||||
CV_CAP_PROP_INTELPERC_DEPTH_SATURATION_VALUE = 11004,
|
||||
CV_CAP_PROP_INTELPERC_DEPTH_CONFIDENCE_THRESHOLD = 11005,
|
||||
CV_CAP_PROP_INTELPERC_DEPTH_FOCAL_LENGTH_HORZ = 11006,
|
||||
CV_CAP_PROP_INTELPERC_DEPTH_FOCAL_LENGTH_VERT = 11007,
|
||||
|
||||
// Intel PerC streams
|
||||
CV_CAP_INTELPERC_DEPTH_GENERATOR = 1 << 29,
|
||||
CV_CAP_INTELPERC_IMAGE_GENERATOR = 1 << 28,
|
||||
CV_CAP_INTELPERC_GENERATORS_MASK = CV_CAP_INTELPERC_DEPTH_GENERATOR + CV_CAP_INTELPERC_IMAGE_GENERATOR
|
||||
};
|
||||
|
||||
enum
|
||||
@@ -548,6 +563,14 @@ enum
|
||||
CV_CAP_ANDROID_ANTIBANDING_OFF
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CV_CAP_INTELPERC_DEPTH_MAP = 0, // Each pixel is a 16-bit integer. The value indicates the distance from an object to the camera's XY plane or the Cartesian depth.
|
||||
CV_CAP_INTELPERC_UVDEPTH_MAP = 1, // Each pixel contains two 32-bit floating point values in the range of 0-1, representing the mapping of depth coordinates to the color coordinates.
|
||||
CV_CAP_INTELPERC_IR_MAP = 2, // Each pixel is a 16-bit integer. The value indicates the intensity of the reflected laser beam.
|
||||
CV_CAP_INTELPERC_IMAGE = 3
|
||||
};
|
||||
|
||||
/* retrieve or set capture properties */
|
||||
CVAPI(double) cvGetCaptureProperty( CvCapture* capture, int property_id );
|
||||
CVAPI(int) cvSetCaptureProperty( CvCapture* capture, int property_id, double value );
|
||||
|
||||
@@ -155,6 +155,9 @@ CV_IMPL CvCapture * cvCreateCameraCapture (int index)
|
||||
#endif
|
||||
#ifdef HAVE_GIGE_API
|
||||
CV_CAP_GIGANETIX,
|
||||
#endif
|
||||
#ifdef HAVE_INTELPERC
|
||||
CV_CAP_INTELPERC,
|
||||
#endif
|
||||
-1
|
||||
};
|
||||
@@ -193,6 +196,7 @@ CV_IMPL CvCapture * cvCreateCameraCapture (int index)
|
||||
defined(HAVE_AVFOUNDATION) || \
|
||||
defined(HAVE_ANDROID_NATIVE_CAMERA) || \
|
||||
defined(HAVE_GIGE_API) || \
|
||||
defined(HAVE_INTELPERC) || \
|
||||
(0)
|
||||
// local variable to memorize the captured device
|
||||
CvCapture *capture;
|
||||
@@ -341,6 +345,14 @@ CV_IMPL CvCapture * cvCreateCameraCapture (int index)
|
||||
return capture;
|
||||
break; // CV_CAP_GIGANETIX
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_INTELPERC
|
||||
case CV_CAP_INTELPERC:
|
||||
capture = cvCreateCameraCapture_IntelPerC(index);
|
||||
if (capture)
|
||||
return capture;
|
||||
break; // CV_CAP_INTEL_PERC
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,714 @@
|
||||
#include "precomp.hpp"
|
||||
|
||||
#ifdef HAVE_INTELPERC
|
||||
|
||||
#include "pxcsession.h"
|
||||
#include "pxcsmartptr.h"
|
||||
#include "pxccapture.h"
|
||||
|
||||
class CvIntelPerCStreamBase
|
||||
{
|
||||
protected:
|
||||
struct FrameInternal
|
||||
{
|
||||
IplImage* retrieveFrame()
|
||||
{
|
||||
if (m_mat.empty())
|
||||
return NULL;
|
||||
m_iplHeader = IplImage(m_mat);
|
||||
return &m_iplHeader;
|
||||
}
|
||||
cv::Mat m_mat;
|
||||
private:
|
||||
IplImage m_iplHeader;
|
||||
};
|
||||
public:
|
||||
CvIntelPerCStreamBase()
|
||||
: m_profileIdx(-1)
|
||||
, m_frameIdx(0)
|
||||
, m_timeStampStartNS(0)
|
||||
{
|
||||
}
|
||||
virtual ~CvIntelPerCStreamBase()
|
||||
{
|
||||
}
|
||||
|
||||
bool isValid()
|
||||
{
|
||||
return (m_device.IsValid() && m_stream.IsValid());
|
||||
}
|
||||
bool grabFrame()
|
||||
{
|
||||
if (!m_stream.IsValid())
|
||||
return false;
|
||||
if (-1 == m_profileIdx)
|
||||
{
|
||||
if (!setProperty(CV_CAP_PROP_INTELPERC_PROFILE_IDX, 0))
|
||||
return false;
|
||||
}
|
||||
PXCSmartPtr<PXCImage> pxcImage; PXCSmartSP sp;
|
||||
if (PXC_STATUS_NO_ERROR > m_stream->ReadStreamAsync(&pxcImage, &sp))
|
||||
return false;
|
||||
if (PXC_STATUS_NO_ERROR > sp->Synchronize())
|
||||
return false;
|
||||
if (0 == m_timeStampStartNS)
|
||||
m_timeStampStartNS = pxcImage->QueryTimeStamp();
|
||||
m_timeStamp = (double)((pxcImage->QueryTimeStamp() - m_timeStampStartNS) / 10000);
|
||||
m_frameIdx++;
|
||||
return prepareIplImage(pxcImage);
|
||||
}
|
||||
int getProfileIDX() const
|
||||
{
|
||||
return m_profileIdx;
|
||||
}
|
||||
public:
|
||||
virtual bool initStream(PXCSession *session) = 0;
|
||||
virtual double getProperty(int propIdx)
|
||||
{
|
||||
double ret = 0.0;
|
||||
switch (propIdx)
|
||||
{
|
||||
case CV_CAP_PROP_INTELPERC_PROFILE_COUNT:
|
||||
ret = (double)m_profiles.size();
|
||||
break;
|
||||
case CV_CAP_PROP_FRAME_WIDTH :
|
||||
if ((0 <= m_profileIdx) && (m_profileIdx < m_profiles.size()))
|
||||
ret = (double)m_profiles[m_profileIdx].imageInfo.width;
|
||||
break;
|
||||
case CV_CAP_PROP_FRAME_HEIGHT :
|
||||
if ((0 <= m_profileIdx) && (m_profileIdx < m_profiles.size()))
|
||||
ret = (double)m_profiles[m_profileIdx].imageInfo.height;
|
||||
break;
|
||||
case CV_CAP_PROP_FPS :
|
||||
if ((0 <= m_profileIdx) && (m_profileIdx < m_profiles.size()))
|
||||
{
|
||||
ret = ((double)m_profiles[m_profileIdx].frameRateMin.numerator / (double)m_profiles[m_profileIdx].frameRateMin.denominator
|
||||
+ (double)m_profiles[m_profileIdx].frameRateMax.numerator / (double)m_profiles[m_profileIdx].frameRateMax.denominator) / 2.0;
|
||||
}
|
||||
break;
|
||||
case CV_CAP_PROP_POS_FRAMES:
|
||||
ret = (double)m_frameIdx;
|
||||
break;
|
||||
case CV_CAP_PROP_POS_MSEC:
|
||||
ret = m_timeStamp;
|
||||
break;
|
||||
};
|
||||
return ret;
|
||||
}
|
||||
virtual bool setProperty(int propIdx, double propVal)
|
||||
{
|
||||
bool isSet = false;
|
||||
switch (propIdx)
|
||||
{
|
||||
case CV_CAP_PROP_INTELPERC_PROFILE_IDX:
|
||||
{
|
||||
int propValInt = (int)propVal;
|
||||
if ((0 <= propValInt) && (propValInt < m_profiles.size()))
|
||||
{
|
||||
if (m_profileIdx != propValInt)
|
||||
{
|
||||
m_profileIdx = propValInt;
|
||||
if (m_stream.IsValid())
|
||||
m_stream->SetProfile(&m_profiles[m_profileIdx]);
|
||||
m_frameIdx = 0;
|
||||
m_timeStampStartNS = 0;
|
||||
}
|
||||
isSet = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
};
|
||||
return isSet;
|
||||
}
|
||||
protected:
|
||||
PXCSmartPtr<PXCCapture::Device> m_device;
|
||||
bool initDevice(PXCSession *session)
|
||||
{
|
||||
if (NULL == session)
|
||||
return false;
|
||||
|
||||
pxcStatus sts = PXC_STATUS_NO_ERROR;
|
||||
PXCSession::ImplDesc templat;
|
||||
memset(&templat,0,sizeof(templat));
|
||||
templat.group = PXCSession::IMPL_GROUP_SENSOR;
|
||||
templat.subgroup= PXCSession::IMPL_SUBGROUP_VIDEO_CAPTURE;
|
||||
|
||||
for (int modidx = 0; PXC_STATUS_NO_ERROR <= sts; modidx++)
|
||||
{
|
||||
PXCSession::ImplDesc desc;
|
||||
sts = session->QueryImpl(&templat, modidx, &desc);
|
||||
if (PXC_STATUS_NO_ERROR > sts)
|
||||
break;
|
||||
|
||||
PXCSmartPtr<PXCCapture> capture;
|
||||
sts = session->CreateImpl<PXCCapture>(&desc, &capture);
|
||||
if (!capture.IsValid())
|
||||
continue;
|
||||
|
||||
/* enumerate devices */
|
||||
for (int devidx = 0; PXC_STATUS_NO_ERROR <= sts; devidx++)
|
||||
{
|
||||
PXCSmartPtr<PXCCapture::Device> device;
|
||||
sts = capture->CreateDevice(devidx, &device);
|
||||
if (PXC_STATUS_NO_ERROR <= sts)
|
||||
{
|
||||
m_device = device.ReleasePtr();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
PXCSmartPtr<PXCCapture::VideoStream> m_stream;
|
||||
void initStreamImpl(PXCImage::ImageType type)
|
||||
{
|
||||
if (!m_device.IsValid())
|
||||
return;
|
||||
|
||||
pxcStatus sts = PXC_STATUS_NO_ERROR;
|
||||
/* enumerate streams */
|
||||
for (int streamidx = 0; PXC_STATUS_NO_ERROR <= sts; streamidx++)
|
||||
{
|
||||
PXCCapture::Device::StreamInfo sinfo;
|
||||
sts = m_device->QueryStream(streamidx, &sinfo);
|
||||
if (PXC_STATUS_NO_ERROR > sts)
|
||||
break;
|
||||
if (PXCCapture::VideoStream::CUID != sinfo.cuid)
|
||||
continue;
|
||||
if (type != sinfo.imageType)
|
||||
continue;
|
||||
|
||||
sts = m_device->CreateStream<PXCCapture::VideoStream>(streamidx, &m_stream);
|
||||
if (PXC_STATUS_NO_ERROR == sts)
|
||||
break;
|
||||
m_stream.ReleaseRef();
|
||||
}
|
||||
}
|
||||
protected:
|
||||
std::vector<PXCCapture::VideoStream::ProfileInfo> m_profiles;
|
||||
int m_profileIdx;
|
||||
int m_frameIdx;
|
||||
pxcU64 m_timeStampStartNS;
|
||||
double m_timeStamp;
|
||||
|
||||
virtual bool validProfile(const PXCCapture::VideoStream::ProfileInfo& /*pinfo*/)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
void enumProfiles()
|
||||
{
|
||||
m_profiles.clear();
|
||||
if (!m_stream.IsValid())
|
||||
return;
|
||||
pxcStatus sts = PXC_STATUS_NO_ERROR;
|
||||
for (int profidx = 0; PXC_STATUS_NO_ERROR <= sts; profidx++)
|
||||
{
|
||||
PXCCapture::VideoStream::ProfileInfo pinfo;
|
||||
sts = m_stream->QueryProfile(profidx, &pinfo);
|
||||
if (PXC_STATUS_NO_ERROR > sts)
|
||||
break;
|
||||
if (validProfile(pinfo))
|
||||
m_profiles.push_back(pinfo);
|
||||
}
|
||||
}
|
||||
virtual bool prepareIplImage(PXCImage *pxcImage) = 0;
|
||||
};
|
||||
|
||||
class CvIntelPerCStreamImage
|
||||
: public CvIntelPerCStreamBase
|
||||
{
|
||||
public:
|
||||
CvIntelPerCStreamImage()
|
||||
{
|
||||
}
|
||||
virtual ~CvIntelPerCStreamImage()
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool initStream(PXCSession *session)
|
||||
{
|
||||
if (!initDevice(session))
|
||||
return false;
|
||||
initStreamImpl(PXCImage::IMAGE_TYPE_COLOR);
|
||||
if (!m_stream.IsValid())
|
||||
return false;
|
||||
enumProfiles();
|
||||
return true;
|
||||
}
|
||||
virtual double getProperty(int propIdx)
|
||||
{
|
||||
switch (propIdx)
|
||||
{
|
||||
case CV_CAP_PROP_BRIGHTNESS:
|
||||
{
|
||||
if (!m_device.IsValid())
|
||||
return 0.0;
|
||||
float fret = 0.0f;
|
||||
if (PXC_STATUS_NO_ERROR == m_device->QueryProperty(PXCCapture::Device::PROPERTY_COLOR_BRIGHTNESS, &fret))
|
||||
return (double)fret;
|
||||
return 0.0;
|
||||
}
|
||||
break;
|
||||
case CV_CAP_PROP_CONTRAST:
|
||||
{
|
||||
if (!m_device.IsValid())
|
||||
return 0.0;
|
||||
float fret = 0.0f;
|
||||
if (PXC_STATUS_NO_ERROR == m_device->QueryProperty(PXCCapture::Device::PROPERTY_COLOR_CONTRAST, &fret))
|
||||
return (double)fret;
|
||||
return 0.0;
|
||||
}
|
||||
break;
|
||||
case CV_CAP_PROP_SATURATION:
|
||||
{
|
||||
if (!m_device.IsValid())
|
||||
return 0.0;
|
||||
float fret = 0.0f;
|
||||
if (PXC_STATUS_NO_ERROR == m_device->QueryProperty(PXCCapture::Device::PROPERTY_COLOR_SATURATION, &fret))
|
||||
return (double)fret;
|
||||
return 0.0;
|
||||
}
|
||||
break;
|
||||
case CV_CAP_PROP_HUE:
|
||||
{
|
||||
if (!m_device.IsValid())
|
||||
return 0.0;
|
||||
float fret = 0.0f;
|
||||
if (PXC_STATUS_NO_ERROR == m_device->QueryProperty(PXCCapture::Device::PROPERTY_COLOR_HUE, &fret))
|
||||
return (double)fret;
|
||||
return 0.0;
|
||||
}
|
||||
break;
|
||||
case CV_CAP_PROP_GAMMA:
|
||||
{
|
||||
if (!m_device.IsValid())
|
||||
return 0.0;
|
||||
float fret = 0.0f;
|
||||
if (PXC_STATUS_NO_ERROR == m_device->QueryProperty(PXCCapture::Device::PROPERTY_COLOR_GAMMA, &fret))
|
||||
return (double)fret;
|
||||
return 0.0;
|
||||
}
|
||||
break;
|
||||
case CV_CAP_PROP_SHARPNESS:
|
||||
{
|
||||
if (!m_device.IsValid())
|
||||
return 0.0;
|
||||
float fret = 0.0f;
|
||||
if (PXC_STATUS_NO_ERROR == m_device->QueryProperty(PXCCapture::Device::PROPERTY_COLOR_SHARPNESS, &fret))
|
||||
return (double)fret;
|
||||
return 0.0;
|
||||
}
|
||||
break;
|
||||
case CV_CAP_PROP_GAIN:
|
||||
{
|
||||
if (!m_device.IsValid())
|
||||
return 0.0;
|
||||
float fret = 0.0f;
|
||||
if (PXC_STATUS_NO_ERROR == m_device->QueryProperty(PXCCapture::Device::PROPERTY_COLOR_GAIN, &fret))
|
||||
return (double)fret;
|
||||
return 0.0;
|
||||
}
|
||||
break;
|
||||
case CV_CAP_PROP_BACKLIGHT:
|
||||
{
|
||||
if (!m_device.IsValid())
|
||||
return 0.0;
|
||||
float fret = 0.0f;
|
||||
if (PXC_STATUS_NO_ERROR == m_device->QueryProperty(PXCCapture::Device::PROPERTY_COLOR_BACK_LIGHT_COMPENSATION, &fret))
|
||||
return (double)fret;
|
||||
return 0.0;
|
||||
}
|
||||
break;
|
||||
case CV_CAP_PROP_EXPOSURE:
|
||||
{
|
||||
if (!m_device.IsValid())
|
||||
return 0.0;
|
||||
float fret = 0.0f;
|
||||
if (PXC_STATUS_NO_ERROR == m_device->QueryProperty(PXCCapture::Device::PROPERTY_COLOR_EXPOSURE, &fret))
|
||||
return (double)fret;
|
||||
return 0.0;
|
||||
}
|
||||
break;
|
||||
//Add image stream specific properties
|
||||
}
|
||||
return CvIntelPerCStreamBase::getProperty(propIdx);
|
||||
}
|
||||
virtual bool setProperty(int propIdx, double propVal)
|
||||
{
|
||||
switch (propIdx)
|
||||
{
|
||||
case CV_CAP_PROP_BRIGHTNESS:
|
||||
{
|
||||
if (!m_device.IsValid())
|
||||
return false;
|
||||
return (PXC_STATUS_NO_ERROR == m_device->SetProperty(PXCCapture::Device::PROPERTY_COLOR_BRIGHTNESS, (float)propVal));
|
||||
}
|
||||
break;
|
||||
case CV_CAP_PROP_CONTRAST:
|
||||
{
|
||||
if (!m_device.IsValid())
|
||||
return false;
|
||||
return (PXC_STATUS_NO_ERROR == m_device->SetProperty(PXCCapture::Device::PROPERTY_COLOR_CONTRAST, (float)propVal));
|
||||
}
|
||||
break;
|
||||
case CV_CAP_PROP_SATURATION:
|
||||
{
|
||||
if (!m_device.IsValid())
|
||||
return false;
|
||||
return (PXC_STATUS_NO_ERROR == m_device->SetProperty(PXCCapture::Device::PROPERTY_COLOR_SATURATION, (float)propVal));
|
||||
}
|
||||
break;
|
||||
case CV_CAP_PROP_HUE:
|
||||
{
|
||||
if (!m_device.IsValid())
|
||||
return false;
|
||||
return (PXC_STATUS_NO_ERROR == m_device->SetProperty(PXCCapture::Device::PROPERTY_COLOR_HUE, (float)propVal));
|
||||
}
|
||||
break;
|
||||
case CV_CAP_PROP_GAMMA:
|
||||
{
|
||||
if (!m_device.IsValid())
|
||||
return false;
|
||||
return (PXC_STATUS_NO_ERROR == m_device->SetProperty(PXCCapture::Device::PROPERTY_COLOR_GAMMA, (float)propVal));
|
||||
}
|
||||
break;
|
||||
case CV_CAP_PROP_SHARPNESS:
|
||||
{
|
||||
if (!m_device.IsValid())
|
||||
return false;
|
||||
return (PXC_STATUS_NO_ERROR == m_device->SetProperty(PXCCapture::Device::PROPERTY_COLOR_SHARPNESS, (float)propVal));
|
||||
}
|
||||
break;
|
||||
case CV_CAP_PROP_GAIN:
|
||||
{
|
||||
if (!m_device.IsValid())
|
||||
return false;
|
||||
return (PXC_STATUS_NO_ERROR == m_device->SetProperty(PXCCapture::Device::PROPERTY_COLOR_GAIN, (float)propVal));
|
||||
}
|
||||
break;
|
||||
case CV_CAP_PROP_BACKLIGHT:
|
||||
{
|
||||
if (!m_device.IsValid())
|
||||
return false;
|
||||
return (PXC_STATUS_NO_ERROR == m_device->SetProperty(PXCCapture::Device::PROPERTY_COLOR_BACK_LIGHT_COMPENSATION, (float)propVal));
|
||||
}
|
||||
break;
|
||||
case CV_CAP_PROP_EXPOSURE:
|
||||
{
|
||||
if (!m_device.IsValid())
|
||||
return false;
|
||||
return (PXC_STATUS_NO_ERROR == m_device->SetProperty(PXCCapture::Device::PROPERTY_COLOR_EXPOSURE, (float)propVal));
|
||||
}
|
||||
break;
|
||||
//Add image stream specific properties
|
||||
}
|
||||
return CvIntelPerCStreamBase::setProperty(propIdx, propVal);
|
||||
}
|
||||
public:
|
||||
IplImage* retrieveFrame()
|
||||
{
|
||||
return m_frame.retrieveFrame();
|
||||
}
|
||||
protected:
|
||||
FrameInternal m_frame;
|
||||
bool prepareIplImage(PXCImage *pxcImage)
|
||||
{
|
||||
if (NULL == pxcImage)
|
||||
return false;
|
||||
PXCImage::ImageInfo info;
|
||||
pxcImage->QueryInfo(&info);
|
||||
|
||||
PXCImage::ImageData data;
|
||||
pxcImage->AcquireAccess(PXCImage::ACCESS_READ, PXCImage::COLOR_FORMAT_RGB24, &data);
|
||||
|
||||
if (PXCImage::SURFACE_TYPE_SYSTEM_MEMORY != data.type)
|
||||
return false;
|
||||
|
||||
cv::Mat temp(info.height, info.width, CV_8UC3, data.planes[0], data.pitches[0]);
|
||||
temp.copyTo(m_frame.m_mat);
|
||||
|
||||
pxcImage->ReleaseAccess(&data);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class CvIntelPerCStreamDepth
|
||||
: public CvIntelPerCStreamBase
|
||||
{
|
||||
public:
|
||||
CvIntelPerCStreamDepth()
|
||||
{
|
||||
}
|
||||
virtual ~CvIntelPerCStreamDepth()
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool initStream(PXCSession *session)
|
||||
{
|
||||
if (!initDevice(session))
|
||||
return false;
|
||||
initStreamImpl(PXCImage::IMAGE_TYPE_DEPTH);
|
||||
if (!m_stream.IsValid())
|
||||
return false;
|
||||
enumProfiles();
|
||||
return true;
|
||||
}
|
||||
virtual double getProperty(int propIdx)
|
||||
{
|
||||
switch (propIdx)
|
||||
{
|
||||
case CV_CAP_PROP_INTELPERC_DEPTH_LOW_CONFIDENCE_VALUE:
|
||||
{
|
||||
if (!m_device.IsValid())
|
||||
return 0.0;
|
||||
float fret = 0.0f;
|
||||
if (PXC_STATUS_NO_ERROR == m_device->QueryProperty(PXCCapture::Device::PROPERTY_DEPTH_LOW_CONFIDENCE_VALUE, &fret))
|
||||
return (double)fret;
|
||||
return 0.0;
|
||||
}
|
||||
break;
|
||||
case CV_CAP_PROP_INTELPERC_DEPTH_SATURATION_VALUE:
|
||||
{
|
||||
if (!m_device.IsValid())
|
||||
return 0.0;
|
||||
float fret = 0.0f;
|
||||
if (PXC_STATUS_NO_ERROR == m_device->QueryProperty(PXCCapture::Device::PROPERTY_DEPTH_SATURATION_VALUE, &fret))
|
||||
return (double)fret;
|
||||
return 0.0;
|
||||
}
|
||||
break;
|
||||
case CV_CAP_PROP_INTELPERC_DEPTH_CONFIDENCE_THRESHOLD:
|
||||
{
|
||||
if (!m_device.IsValid())
|
||||
return 0.0;
|
||||
float fret = 0.0f;
|
||||
if (PXC_STATUS_NO_ERROR == m_device->QueryProperty(PXCCapture::Device::PROPERTY_DEPTH_CONFIDENCE_THRESHOLD, &fret))
|
||||
return (double)fret;
|
||||
return 0.0;
|
||||
}
|
||||
break;
|
||||
case CV_CAP_PROP_INTELPERC_DEPTH_FOCAL_LENGTH_HORZ:
|
||||
{
|
||||
if (!m_device.IsValid())
|
||||
return 0.0f;
|
||||
PXCPointF32 ptf;
|
||||
if (PXC_STATUS_NO_ERROR == m_device->QueryPropertyAsPoint(PXCCapture::Device::PROPERTY_DEPTH_FOCAL_LENGTH, &ptf))
|
||||
return (double)ptf.x;
|
||||
return 0.0;
|
||||
}
|
||||
break;
|
||||
case CV_CAP_PROP_INTELPERC_DEPTH_FOCAL_LENGTH_VERT:
|
||||
{
|
||||
if (!m_device.IsValid())
|
||||
return 0.0f;
|
||||
PXCPointF32 ptf;
|
||||
if (PXC_STATUS_NO_ERROR == m_device->QueryPropertyAsPoint(PXCCapture::Device::PROPERTY_DEPTH_FOCAL_LENGTH, &ptf))
|
||||
return (double)ptf.y;
|
||||
return 0.0;
|
||||
}
|
||||
break;
|
||||
//Add depth stream sepcific properties
|
||||
}
|
||||
return CvIntelPerCStreamBase::getProperty(propIdx);
|
||||
}
|
||||
virtual bool setProperty(int propIdx, double propVal)
|
||||
{
|
||||
switch (propIdx)
|
||||
{
|
||||
case CV_CAP_PROP_INTELPERC_DEPTH_LOW_CONFIDENCE_VALUE:
|
||||
{
|
||||
if (!m_device.IsValid())
|
||||
return false;
|
||||
return (PXC_STATUS_NO_ERROR == m_device->SetProperty(PXCCapture::Device::PROPERTY_DEPTH_LOW_CONFIDENCE_VALUE, (float)propVal));
|
||||
}
|
||||
break;
|
||||
case CV_CAP_PROP_INTELPERC_DEPTH_SATURATION_VALUE:
|
||||
{
|
||||
if (!m_device.IsValid())
|
||||
return false;
|
||||
return (PXC_STATUS_NO_ERROR == m_device->SetProperty(PXCCapture::Device::PROPERTY_DEPTH_SATURATION_VALUE, (float)propVal));
|
||||
}
|
||||
break;
|
||||
case CV_CAP_PROP_INTELPERC_DEPTH_CONFIDENCE_THRESHOLD:
|
||||
{
|
||||
if (!m_device.IsValid())
|
||||
return false;
|
||||
return (PXC_STATUS_NO_ERROR == m_device->SetProperty(PXCCapture::Device::PROPERTY_DEPTH_CONFIDENCE_THRESHOLD, (float)propVal));
|
||||
}
|
||||
break;
|
||||
//Add depth stream sepcific properties
|
||||
}
|
||||
return CvIntelPerCStreamBase::setProperty(propIdx, propVal);
|
||||
}
|
||||
public:
|
||||
IplImage* retrieveDepthFrame()
|
||||
{
|
||||
return m_frameDepth.retrieveFrame();
|
||||
}
|
||||
IplImage* retrieveIRFrame()
|
||||
{
|
||||
return m_frameIR.retrieveFrame();
|
||||
}
|
||||
IplImage* retrieveUVFrame()
|
||||
{
|
||||
return m_frameUV.retrieveFrame();
|
||||
}
|
||||
protected:
|
||||
virtual bool validProfile(const PXCCapture::VideoStream::ProfileInfo& pinfo)
|
||||
{
|
||||
return (PXCImage::COLOR_FORMAT_DEPTH == pinfo.imageInfo.format);
|
||||
}
|
||||
protected:
|
||||
FrameInternal m_frameDepth;
|
||||
FrameInternal m_frameIR;
|
||||
FrameInternal m_frameUV;
|
||||
|
||||
bool prepareIplImage(PXCImage *pxcImage)
|
||||
{
|
||||
if (NULL == pxcImage)
|
||||
return false;
|
||||
PXCImage::ImageInfo info;
|
||||
pxcImage->QueryInfo(&info);
|
||||
|
||||
PXCImage::ImageData data;
|
||||
pxcImage->AcquireAccess(PXCImage::ACCESS_READ, &data);
|
||||
|
||||
if (PXCImage::SURFACE_TYPE_SYSTEM_MEMORY != data.type)
|
||||
return false;
|
||||
|
||||
if (PXCImage::COLOR_FORMAT_DEPTH != data.format)
|
||||
return false;
|
||||
|
||||
{
|
||||
cv::Mat temp(info.height, info.width, CV_16SC1, data.planes[0], data.pitches[0]);
|
||||
temp.copyTo(m_frameDepth.m_mat);
|
||||
}
|
||||
{
|
||||
cv::Mat temp(info.height, info.width, CV_16SC1, data.planes[1], data.pitches[1]);
|
||||
temp.copyTo(m_frameIR.m_mat);
|
||||
}
|
||||
{
|
||||
cv::Mat temp(info.height, info.width, CV_32FC2, data.planes[2], data.pitches[2]);
|
||||
temp.copyTo(m_frameUV.m_mat);
|
||||
}
|
||||
|
||||
pxcImage->ReleaseAccess(&data);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
class CvCapture_IntelPerC : public CvCapture
|
||||
{
|
||||
public:
|
||||
CvCapture_IntelPerC(int /*index*/)
|
||||
: m_contextOpened(false)
|
||||
{
|
||||
pxcStatus sts = PXCSession_Create(&m_session);
|
||||
if (PXC_STATUS_NO_ERROR > sts)
|
||||
return;
|
||||
m_contextOpened = m_imageStream.initStream(m_session);
|
||||
m_contextOpened &= m_depthStream.initStream(m_session);
|
||||
}
|
||||
virtual ~CvCapture_IntelPerC(){}
|
||||
|
||||
virtual double getProperty(int propIdx)
|
||||
{
|
||||
double propValue = 0;
|
||||
int purePropIdx = propIdx & ~CV_CAP_INTELPERC_GENERATORS_MASK;
|
||||
if (CV_CAP_INTELPERC_IMAGE_GENERATOR == (propIdx & CV_CAP_INTELPERC_GENERATORS_MASK))
|
||||
{
|
||||
propValue = m_imageStream.getProperty(purePropIdx);
|
||||
}
|
||||
else if (CV_CAP_INTELPERC_DEPTH_GENERATOR == (propIdx & CV_CAP_INTELPERC_GENERATORS_MASK))
|
||||
{
|
||||
propValue = m_depthStream.getProperty(purePropIdx);
|
||||
}
|
||||
else
|
||||
{
|
||||
propValue = m_depthStream.getProperty(purePropIdx);
|
||||
}
|
||||
return propValue;
|
||||
}
|
||||
virtual bool setProperty(int propIdx, double propVal)
|
||||
{
|
||||
bool isSet = false;
|
||||
int purePropIdx = propIdx & ~CV_CAP_INTELPERC_GENERATORS_MASK;
|
||||
if (CV_CAP_INTELPERC_IMAGE_GENERATOR == (propIdx & CV_CAP_INTELPERC_GENERATORS_MASK))
|
||||
{
|
||||
isSet = m_imageStream.setProperty(purePropIdx, propVal);
|
||||
}
|
||||
else if (CV_CAP_INTELPERC_DEPTH_GENERATOR == (propIdx & CV_CAP_INTELPERC_GENERATORS_MASK))
|
||||
{
|
||||
isSet = m_depthStream.setProperty(purePropIdx, propVal);
|
||||
}
|
||||
else
|
||||
{
|
||||
isSet = m_depthStream.setProperty(purePropIdx, propVal);
|
||||
}
|
||||
return isSet;
|
||||
}
|
||||
|
||||
bool grabFrame()
|
||||
{
|
||||
if (!isOpened())
|
||||
return false;
|
||||
|
||||
bool isGrabbed = false;
|
||||
if (m_depthStream.isValid())
|
||||
isGrabbed = m_depthStream.grabFrame();
|
||||
if ((m_imageStream.isValid()) && (-1 != m_imageStream.getProfileIDX()))
|
||||
isGrabbed &= m_imageStream.grabFrame();
|
||||
|
||||
return isGrabbed;
|
||||
}
|
||||
|
||||
virtual IplImage* retrieveFrame(int outputType)
|
||||
{
|
||||
IplImage* image = 0;
|
||||
switch (outputType)
|
||||
{
|
||||
case CV_CAP_INTELPERC_DEPTH_MAP:
|
||||
image = m_depthStream.retrieveDepthFrame();
|
||||
break;
|
||||
case CV_CAP_INTELPERC_UVDEPTH_MAP:
|
||||
image = m_depthStream.retrieveUVFrame();
|
||||
break;
|
||||
case CV_CAP_INTELPERC_IR_MAP:
|
||||
image = m_depthStream.retrieveIRFrame();
|
||||
break;
|
||||
case CV_CAP_INTELPERC_IMAGE:
|
||||
image = m_imageStream.retrieveFrame();
|
||||
break;
|
||||
}
|
||||
CV_Assert(NULL != image);
|
||||
return image;
|
||||
}
|
||||
|
||||
bool isOpened() const
|
||||
{
|
||||
return m_contextOpened;
|
||||
}
|
||||
protected:
|
||||
bool m_contextOpened;
|
||||
|
||||
PXCSmartPtr<PXCSession> m_session;
|
||||
CvIntelPerCStreamImage m_imageStream;
|
||||
CvIntelPerCStreamDepth m_depthStream;
|
||||
};
|
||||
|
||||
|
||||
CvCapture* cvCreateCameraCapture_IntelPerC(int index)
|
||||
{
|
||||
CvCapture_IntelPerC* capture = new CvCapture_IntelPerC(index);
|
||||
|
||||
if( capture->isOpened() )
|
||||
return capture;
|
||||
|
||||
delete capture;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif //HAVE_INTELPERC
|
||||
@@ -127,6 +127,7 @@ CvCapture* cvCreateFileCapture_OpenNI( const char* filename );
|
||||
CvCapture* cvCreateCameraCapture_Android( int index );
|
||||
CvCapture* cvCreateCameraCapture_XIMEA( int index );
|
||||
CvCapture* cvCreateCameraCapture_AVFoundation(int index);
|
||||
CvCapture* cvCreateCameraCapture_IntelPerC(int index);
|
||||
|
||||
|
||||
CVAPI(int) cvHaveImageReader(const char* filename);
|
||||
|
||||
@@ -61,7 +61,6 @@
|
||||
#ifdef __GNUC__
|
||||
# pragma GCC diagnostic ignored "-Wmissing-declarations"
|
||||
#endif
|
||||
#include <MultiMon.h>
|
||||
|
||||
#include <commctrl.h>
|
||||
#include <winuser.h>
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
defined(HAVE_XIMEA) || \
|
||||
defined(HAVE_AVFOUNDATION) || \
|
||||
defined(HAVE_GIGE_API) || \
|
||||
defined(HAVE_INTELPERC) || \
|
||||
(0)
|
||||
//defined(HAVE_ANDROID_NATIVE_CAMERA) || - enable after #1193
|
||||
# define BUILD_WITH_CAMERA_SUPPORT 1
|
||||
|
||||
@@ -36,7 +36,7 @@ http://en.wikipedia.org/wiki/Canny_edge_detector
|
||||
|
||||
* An example on using the canny edge detector can be found at opencv_source_code/samples/cpp/edge.cpp
|
||||
|
||||
* (Python) An example on using the canny edge detector can be found at opencv_source_code/samples/cpp/edge.py
|
||||
* (Python) An example on using the canny edge detector can be found at opencv_source_code/samples/python/edge.py
|
||||
|
||||
cornerEigenValsAndVecs
|
||||
----------------------
|
||||
|
||||
@@ -365,7 +365,7 @@ CV_INLINE double cvContourPerimeter( const void* contour )
|
||||
}
|
||||
|
||||
|
||||
/* Calculates contour boundning rectangle (update=1) or
|
||||
/* Calculates contour bounding rectangle (update=1) or
|
||||
just retrieves pre-calculated rectangle (update=0) */
|
||||
CVAPI(CvRect) cvBoundingRect( CvArr* points, int update CV_DEFAULT(0) );
|
||||
|
||||
|
||||
@@ -41,12 +41,13 @@
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
/*
|
||||
#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
|
||||
#define USE_IPP_CANNY 1
|
||||
#else
|
||||
#undef USE_IPP_CANNY
|
||||
#endif
|
||||
|
||||
*/
|
||||
#ifdef USE_IPP_CANNY
|
||||
namespace cv
|
||||
{
|
||||
|
||||
@@ -3737,7 +3737,7 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn )
|
||||
CV_Assert( scn == 3 || scn == 4 );
|
||||
_dst.create(sz, CV_MAKETYPE(depth, 1));
|
||||
dst = _dst.getMat();
|
||||
|
||||
/*
|
||||
#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
|
||||
if( code == CV_BGR2GRAY )
|
||||
{
|
||||
@@ -3760,7 +3760,7 @@ void cv::cvtColor( InputArray _src, OutputArray _dst, int code, int dcn )
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
*/
|
||||
bidx = code == CV_BGR2GRAY || code == CV_BGRA2GRAY ? 0 : 2;
|
||||
|
||||
if( depth == CV_8U )
|
||||
|
||||
@@ -1846,7 +1846,7 @@ void cv::resize( InputArray _src, OutputArray _dst, Size dsize,
|
||||
int depth = src.depth(), cn = src.channels();
|
||||
double scale_x = 1./inv_scale_x, scale_y = 1./inv_scale_y;
|
||||
int k, sx, sy, dx, dy;
|
||||
|
||||
/*
|
||||
#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
|
||||
int mode = interpolation == INTER_LINEAR ? IPPI_INTER_LINEAR : 0;
|
||||
int type = src.type();
|
||||
@@ -1874,7 +1874,7 @@ void cv::resize( InputArray _src, OutputArray _dst, Size dsize,
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
*/
|
||||
if( interpolation == INTER_NEAREST )
|
||||
{
|
||||
resizeNN( src, dst, inv_scale_x, inv_scale_y );
|
||||
@@ -2935,7 +2935,10 @@ public:
|
||||
if( m1->type() == CV_16SC2 && (m2->type() == CV_16UC1 || m2->type() == CV_16SC1) )
|
||||
{
|
||||
bufxy = (*m1)(Rect(x, y, bcols, brows));
|
||||
bufa = (*m2)(Rect(x, y, bcols, brows));
|
||||
|
||||
const ushort* sA = (const ushort*)(m2->data + m2->step*(y+y1)) + x;
|
||||
for( x1 = 0; x1 < bcols; x1++ )
|
||||
A[x1] = (ushort)(sA[x1] & (INTER_TAB_SIZE2-1));
|
||||
}
|
||||
else if( planar_input )
|
||||
{
|
||||
@@ -3242,7 +3245,7 @@ void cv::convertMaps( InputArray _map1, InputArray _map2,
|
||||
{
|
||||
for( x = 0; x < size.width; x++ )
|
||||
{
|
||||
int fxy = src2 ? src2[x] : 0;
|
||||
int fxy = src2 ? src2[x] & (INTER_TAB_SIZE2-1) : 0;
|
||||
dst1f[x] = src1[x*2] + (fxy & (INTER_TAB_SIZE-1))*scale;
|
||||
dst2f[x] = src1[x*2+1] + (fxy >> INTER_BITS)*scale;
|
||||
}
|
||||
@@ -3251,7 +3254,7 @@ void cv::convertMaps( InputArray _map1, InputArray _map2,
|
||||
{
|
||||
for( x = 0; x < size.width; x++ )
|
||||
{
|
||||
int fxy = src2 ? src2[x] : 0;
|
||||
int fxy = src2 ? src2[x] & (INTER_TAB_SIZE2-1): 0;
|
||||
dst1f[x*2] = src1[x*2] + (fxy & (INTER_TAB_SIZE-1))*scale;
|
||||
dst1f[x*2+1] = src1[x*2+1] + (fxy >> INTER_BITS)*scale;
|
||||
}
|
||||
@@ -3474,7 +3477,7 @@ void cv::warpAffine( InputArray _src, OutputArray _dst,
|
||||
int* adelta = &_abdelta[0], *bdelta = adelta + dst.cols;
|
||||
const int AB_BITS = MAX(10, (int)INTER_BITS);
|
||||
const int AB_SCALE = 1 << AB_BITS;
|
||||
|
||||
/*
|
||||
#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
|
||||
int depth = src.depth();
|
||||
int channels = src.channels();
|
||||
@@ -3518,7 +3521,7 @@ void cv::warpAffine( InputArray _src, OutputArray _dst,
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
*/
|
||||
for( x = 0; x < dst.cols; x++ )
|
||||
{
|
||||
adelta[x] = saturate_cast<int>(M[0]*x*AB_SCALE);
|
||||
@@ -3699,7 +3702,7 @@ void cv::warpPerspective( InputArray _src, OutputArray _dst, InputArray _M0,
|
||||
|
||||
if( !(flags & WARP_INVERSE_MAP) )
|
||||
invert(matM, matM);
|
||||
|
||||
/*
|
||||
#if defined (HAVE_IPP) && (IPP_VERSION_MAJOR >= 7)
|
||||
int depth = src.depth();
|
||||
int channels = src.channels();
|
||||
@@ -3743,7 +3746,7 @@ void cv::warpPerspective( InputArray _src, OutputArray _dst, InputArray _M0,
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
*/
|
||||
Range range(0, dst.rows);
|
||||
warpPerspectiveInvoker invoker(src, dst, M, interpolation, borderType, borderValue);
|
||||
parallel_for_(range, invoker, dst.total()/(double)(1<<16));
|
||||
|
||||
@@ -297,6 +297,12 @@ if(BUILD_FAT_JAVA_LIB)
|
||||
list(REMOVE_ITEM __deps ${m})
|
||||
endif()
|
||||
endforeach()
|
||||
if (ENABLE_DYNAMIC_CUDA)
|
||||
list(REMOVE_ITEM __deps "opencv_dynamicuda")
|
||||
endif()
|
||||
if (ANDROID AND HAVE_opencv_gpu)
|
||||
list(REMOVE_ITEM __deps "opencv_gpu")
|
||||
endif()
|
||||
ocv_list_unique(__deps)
|
||||
set(__extradeps ${__deps})
|
||||
ocv_list_filterout(__extradeps "^opencv_")
|
||||
|
||||
@@ -18,6 +18,8 @@ class_ignore_list = (
|
||||
const_ignore_list = (
|
||||
"CV_CAP_OPENNI",
|
||||
"CV_CAP_PROP_OPENNI_",
|
||||
"CV_CAP_INTELPERC",
|
||||
"CV_CAP_PROP_INTELPERC_"
|
||||
"WINDOW_AUTOSIZE",
|
||||
"CV_WND_PROP_",
|
||||
"CV_WINDOW_",
|
||||
|
||||
@@ -0,0 +1,770 @@
|
||||
#define LOG_TAG "org.opencv.gpu"
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "opencv2/opencv_modules.hpp"
|
||||
#include "opencv2/core/gpumat.hpp"
|
||||
|
||||
using namespace cv;
|
||||
using namespace cv::gpu;
|
||||
|
||||
/// throw java exception
|
||||
static void throwJavaException(JNIEnv *env, const std::exception *e, const char *method) {
|
||||
std::string what = "unknown exception";
|
||||
jclass je = 0;
|
||||
|
||||
if(e) {
|
||||
std::string exception_type = "std::exception";
|
||||
|
||||
if(dynamic_cast<const cv::Exception*>(e)) {
|
||||
exception_type = "cv::Exception";
|
||||
je = env->FindClass("org/opencv/core/CvException");
|
||||
}
|
||||
|
||||
what = exception_type + ": " + e->what();
|
||||
}
|
||||
|
||||
if(!je) je = env->FindClass("java/lang/Exception");
|
||||
env->ThrowNew(je, what.c_str());
|
||||
|
||||
LOGE("%s caught %s", method, what.c_str());
|
||||
(void)method; // avoid "unused" warning
|
||||
}
|
||||
|
||||
|
||||
extern "C" {
|
||||
|
||||
|
||||
//
|
||||
// bool deviceSupports(cv::gpu::FeatureSet feature_set)
|
||||
//
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_opencv_gpu_Gpu_deviceSupports_10 (JNIEnv*, jclass, jint);
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_opencv_gpu_Gpu_deviceSupports_10
|
||||
(JNIEnv* env, jclass , jint feature_set)
|
||||
{
|
||||
static const char method_name[] = "gpu::deviceSupports_10()";
|
||||
try {
|
||||
LOGD("%s", method_name);
|
||||
|
||||
bool _retval_ = deviceSupports( (cv::gpu::FeatureSet)feature_set );
|
||||
return _retval_;
|
||||
} catch(const std::exception &e) {
|
||||
throwJavaException(env, &e, method_name);
|
||||
} catch (...) {
|
||||
throwJavaException(env, 0, method_name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// int getCudaEnabledDeviceCount()
|
||||
//
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_opencv_gpu_Gpu_getCudaEnabledDeviceCount_10 (JNIEnv*, jclass);
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_opencv_gpu_Gpu_getCudaEnabledDeviceCount_10
|
||||
(JNIEnv* env, jclass )
|
||||
{
|
||||
static const char method_name[] = "gpu::getCudaEnabledDeviceCount_10()";
|
||||
try {
|
||||
LOGD("%s", method_name);
|
||||
|
||||
int _retval_ = getCudaEnabledDeviceCount( );
|
||||
return _retval_;
|
||||
} catch(const std::exception &e) {
|
||||
throwJavaException(env, &e, method_name);
|
||||
} catch (...) {
|
||||
throwJavaException(env, 0, method_name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// int getDevice()
|
||||
//
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_opencv_gpu_Gpu_getDevice_10 (JNIEnv*, jclass);
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_opencv_gpu_Gpu_getDevice_10
|
||||
(JNIEnv* env, jclass )
|
||||
{
|
||||
static const char method_name[] = "gpu::getDevice_10()";
|
||||
try {
|
||||
LOGD("%s", method_name);
|
||||
|
||||
int _retval_ = getDevice( );
|
||||
return _retval_;
|
||||
} catch(const std::exception &e) {
|
||||
throwJavaException(env, &e, method_name);
|
||||
} catch (...) {
|
||||
throwJavaException(env, 0, method_name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// void printCudaDeviceInfo(int device)
|
||||
//
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_opencv_gpu_Gpu_printCudaDeviceInfo_10 (JNIEnv*, jclass, jint);
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_opencv_gpu_Gpu_printCudaDeviceInfo_10
|
||||
(JNIEnv* env, jclass , jint device)
|
||||
{
|
||||
static const char method_name[] = "gpu::printCudaDeviceInfo_10()";
|
||||
try {
|
||||
LOGD("%s", method_name);
|
||||
|
||||
printCudaDeviceInfo( (int)device );
|
||||
return;
|
||||
} catch(const std::exception &e) {
|
||||
throwJavaException(env, &e, method_name);
|
||||
} catch (...) {
|
||||
throwJavaException(env, 0, method_name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// void printShortCudaDeviceInfo(int device)
|
||||
//
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_opencv_gpu_Gpu_printShortCudaDeviceInfo_10 (JNIEnv*, jclass, jint);
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_opencv_gpu_Gpu_printShortCudaDeviceInfo_10
|
||||
(JNIEnv* env, jclass , jint device)
|
||||
{
|
||||
static const char method_name[] = "gpu::printShortCudaDeviceInfo_10()";
|
||||
try {
|
||||
LOGD("%s", method_name);
|
||||
|
||||
printShortCudaDeviceInfo( (int)device );
|
||||
return;
|
||||
} catch(const std::exception &e) {
|
||||
throwJavaException(env, &e, method_name);
|
||||
} catch (...) {
|
||||
throwJavaException(env, 0, method_name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// void resetDevice()
|
||||
//
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_opencv_gpu_Gpu_resetDevice_10 (JNIEnv*, jclass);
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_opencv_gpu_Gpu_resetDevice_10
|
||||
(JNIEnv* env, jclass )
|
||||
{
|
||||
static const char method_name[] = "gpu::resetDevice_10()";
|
||||
try {
|
||||
LOGD("%s", method_name);
|
||||
|
||||
resetDevice();
|
||||
return;
|
||||
} catch(const std::exception &e) {
|
||||
throwJavaException(env, &e, method_name);
|
||||
} catch (...) {
|
||||
throwJavaException(env, 0, method_name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// void setDevice(int device)
|
||||
//
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_opencv_gpu_Gpu_setDevice_10 (JNIEnv*, jclass, jint);
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_opencv_gpu_Gpu_setDevice_10
|
||||
(JNIEnv* env, jclass , jint device)
|
||||
{
|
||||
static const char method_name[] = "gpu::setDevice_10()";
|
||||
try {
|
||||
LOGD("%s", method_name);
|
||||
|
||||
setDevice( (int)device );
|
||||
return;
|
||||
} catch(const std::exception &e) {
|
||||
throwJavaException(env, &e, method_name);
|
||||
} catch (...) {
|
||||
throwJavaException(env, 0, method_name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// DeviceInfo::DeviceInfo()
|
||||
//
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_org_opencv_gpu_DeviceInfo_DeviceInfo_10 (JNIEnv*, jclass);
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_org_opencv_gpu_DeviceInfo_DeviceInfo_10
|
||||
(JNIEnv* env, jclass )
|
||||
{
|
||||
static const char method_name[] = "gpu::DeviceInfo_10()";
|
||||
try {
|
||||
LOGD("%s", method_name);
|
||||
|
||||
DeviceInfo* _retval_ = new DeviceInfo( );
|
||||
return (jlong) _retval_;
|
||||
} catch(const std::exception &e) {
|
||||
throwJavaException(env, &e, method_name);
|
||||
} catch (...) {
|
||||
throwJavaException(env, 0, method_name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// DeviceInfo::DeviceInfo(int device_id)
|
||||
//
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_org_opencv_gpu_DeviceInfo_DeviceInfo_11 (JNIEnv*, jclass, jint);
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_org_opencv_gpu_DeviceInfo_DeviceInfo_11
|
||||
(JNIEnv* env, jclass , jint device_id)
|
||||
{
|
||||
static const char method_name[] = "gpu::DeviceInfo_11()";
|
||||
try {
|
||||
LOGD("%s", method_name);
|
||||
|
||||
DeviceInfo* _retval_ = new DeviceInfo( (int)device_id );
|
||||
return (jlong) _retval_;
|
||||
} catch(const std::exception &e) {
|
||||
throwJavaException(env, &e, method_name);
|
||||
} catch (...) {
|
||||
throwJavaException(env, 0, method_name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// int DeviceInfo::deviceID()
|
||||
//
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_opencv_gpu_DeviceInfo_deviceID_10 (JNIEnv*, jclass, jlong);
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_opencv_gpu_DeviceInfo_deviceID_10
|
||||
(JNIEnv* env, jclass , jlong self)
|
||||
{
|
||||
static const char method_name[] = "gpu::deviceID_10()";
|
||||
try {
|
||||
LOGD("%s", method_name);
|
||||
DeviceInfo* me = (DeviceInfo*) self; //TODO: check for NULL
|
||||
int _retval_ = me->deviceID( );
|
||||
return _retval_;
|
||||
} catch(const std::exception &e) {
|
||||
throwJavaException(env, &e, method_name);
|
||||
} catch (...) {
|
||||
throwJavaException(env, 0, method_name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// size_t DeviceInfo::freeMemory()
|
||||
//
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_org_opencv_gpu_DeviceInfo_freeMemory_10 (JNIEnv*, jclass, jlong);
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_org_opencv_gpu_DeviceInfo_freeMemory_10
|
||||
(JNIEnv* env, jclass , jlong self)
|
||||
{
|
||||
static const char method_name[] = "gpu::freeMemory_10()";
|
||||
try {
|
||||
LOGD("%s", method_name);
|
||||
DeviceInfo* me = (DeviceInfo*) self; //TODO: check for NULL
|
||||
size_t _retval_ = me->freeMemory( );
|
||||
return _retval_;
|
||||
} catch(const std::exception &e) {
|
||||
throwJavaException(env, &e, method_name);
|
||||
} catch (...) {
|
||||
throwJavaException(env, 0, method_name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// bool DeviceInfo::isCompatible()
|
||||
//
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_opencv_gpu_DeviceInfo_isCompatible_10 (JNIEnv*, jclass, jlong);
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_opencv_gpu_DeviceInfo_isCompatible_10
|
||||
(JNIEnv* env, jclass , jlong self)
|
||||
{
|
||||
static const char method_name[] = "gpu::isCompatible_10()";
|
||||
try {
|
||||
LOGD("%s", method_name);
|
||||
DeviceInfo* me = (DeviceInfo*) self; //TODO: check for NULL
|
||||
bool _retval_ = me->isCompatible( );
|
||||
return _retval_;
|
||||
} catch(const std::exception &e) {
|
||||
throwJavaException(env, &e, method_name);
|
||||
} catch (...) {
|
||||
throwJavaException(env, 0, method_name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// int DeviceInfo::majorVersion()
|
||||
//
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_opencv_gpu_DeviceInfo_majorVersion_10 (JNIEnv*, jclass, jlong);
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_opencv_gpu_DeviceInfo_majorVersion_10
|
||||
(JNIEnv* env, jclass , jlong self)
|
||||
{
|
||||
static const char method_name[] = "gpu::majorVersion_10()";
|
||||
try {
|
||||
LOGD("%s", method_name);
|
||||
DeviceInfo* me = (DeviceInfo*) self; //TODO: check for NULL
|
||||
int _retval_ = me->majorVersion( );
|
||||
return _retval_;
|
||||
} catch(const std::exception &e) {
|
||||
throwJavaException(env, &e, method_name);
|
||||
} catch (...) {
|
||||
throwJavaException(env, 0, method_name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// int DeviceInfo::minorVersion()
|
||||
//
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_opencv_gpu_DeviceInfo_minorVersion_10 (JNIEnv*, jclass, jlong);
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_opencv_gpu_DeviceInfo_minorVersion_10
|
||||
(JNIEnv* env, jclass , jlong self)
|
||||
{
|
||||
static const char method_name[] = "gpu::minorVersion_10()";
|
||||
try {
|
||||
LOGD("%s", method_name);
|
||||
DeviceInfo* me = (DeviceInfo*) self; //TODO: check for NULL
|
||||
int _retval_ = me->minorVersion( );
|
||||
return _retval_;
|
||||
} catch(const std::exception &e) {
|
||||
throwJavaException(env, &e, method_name);
|
||||
} catch (...) {
|
||||
throwJavaException(env, 0, method_name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// int DeviceInfo::multiProcessorCount()
|
||||
//
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_opencv_gpu_DeviceInfo_multiProcessorCount_10 (JNIEnv*, jclass, jlong);
|
||||
|
||||
JNIEXPORT jint JNICALL Java_org_opencv_gpu_DeviceInfo_multiProcessorCount_10
|
||||
(JNIEnv* env, jclass , jlong self)
|
||||
{
|
||||
static const char method_name[] = "gpu::multiProcessorCount_10()";
|
||||
try {
|
||||
LOGD("%s", method_name);
|
||||
DeviceInfo* me = (DeviceInfo*) self; //TODO: check for NULL
|
||||
int _retval_ = me->multiProcessorCount( );
|
||||
return _retval_;
|
||||
} catch(const std::exception &e) {
|
||||
throwJavaException(env, &e, method_name);
|
||||
} catch (...) {
|
||||
throwJavaException(env, 0, method_name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// string DeviceInfo::name()
|
||||
//
|
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_opencv_gpu_DeviceInfo_name_10 (JNIEnv*, jclass, jlong);
|
||||
|
||||
JNIEXPORT jstring JNICALL Java_org_opencv_gpu_DeviceInfo_name_10
|
||||
(JNIEnv* env, jclass , jlong self)
|
||||
{
|
||||
static const char method_name[] = "gpu::name_10()";
|
||||
try {
|
||||
LOGD("%s", method_name);
|
||||
DeviceInfo* me = (DeviceInfo*) self; //TODO: check for NULL
|
||||
string _retval_ = me->name( );
|
||||
return env->NewStringUTF(_retval_.c_str());
|
||||
} catch(const std::exception &e) {
|
||||
throwJavaException(env, &e, method_name);
|
||||
} catch (...) {
|
||||
throwJavaException(env, 0, method_name);
|
||||
}
|
||||
return env->NewStringUTF("");
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// void DeviceInfo::queryMemory(size_t& totalMemory, size_t& freeMemory)
|
||||
//
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_opencv_gpu_DeviceInfo_queryMemory_10 (JNIEnv*, jclass, jlong, jdoubleArray, jdoubleArray);
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_opencv_gpu_DeviceInfo_queryMemory_10
|
||||
(JNIEnv* env, jclass , jlong self, jdoubleArray totalMemory_out, jdoubleArray freeMemory_out)
|
||||
{
|
||||
static const char method_name[] = "gpu::queryMemory_10()";
|
||||
try {
|
||||
LOGD("%s", method_name);
|
||||
DeviceInfo* me = (DeviceInfo*) self; //TODO: check for NULL
|
||||
size_t totalMemory;
|
||||
size_t freeMemory;
|
||||
me->queryMemory( totalMemory, freeMemory );
|
||||
jdouble tmp_totalMemory[1] = {totalMemory};
|
||||
env->SetDoubleArrayRegion(totalMemory_out, 0, 1, tmp_totalMemory);
|
||||
jdouble tmp_freeMemory[1] = {freeMemory};
|
||||
env->SetDoubleArrayRegion(freeMemory_out, 0, 1, tmp_freeMemory);
|
||||
return;
|
||||
} catch(const std::exception &e) {
|
||||
throwJavaException(env, &e, method_name);
|
||||
} catch (...) {
|
||||
throwJavaException(env, 0, method_name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// size_t DeviceInfo::sharedMemPerBlock()
|
||||
//
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_org_opencv_gpu_DeviceInfo_sharedMemPerBlock_10 (JNIEnv*, jclass, jlong);
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_org_opencv_gpu_DeviceInfo_sharedMemPerBlock_10
|
||||
(JNIEnv* env, jclass , jlong self)
|
||||
{
|
||||
static const char method_name[] = "gpu::sharedMemPerBlock_10()";
|
||||
try {
|
||||
LOGD("%s", method_name);
|
||||
DeviceInfo* me = (DeviceInfo*) self; //TODO: check for NULL
|
||||
size_t _retval_ = me->sharedMemPerBlock( );
|
||||
return _retval_;
|
||||
} catch(const std::exception &e) {
|
||||
throwJavaException(env, &e, method_name);
|
||||
} catch (...) {
|
||||
throwJavaException(env, 0, method_name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// bool DeviceInfo::supports(cv::gpu::FeatureSet feature_set)
|
||||
//
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_opencv_gpu_DeviceInfo_supports_10 (JNIEnv*, jclass, jlong, jint);
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_opencv_gpu_DeviceInfo_supports_10
|
||||
(JNIEnv* env, jclass , jlong self, jint feature_set)
|
||||
{
|
||||
static const char method_name[] = "gpu::supports_10()";
|
||||
try {
|
||||
LOGD("%s", method_name);
|
||||
DeviceInfo* me = (DeviceInfo*) self; //TODO: check for NULL
|
||||
bool _retval_ = me->supports( (cv::gpu::FeatureSet)feature_set );
|
||||
return _retval_;
|
||||
} catch(const std::exception &e) {
|
||||
throwJavaException(env, &e, method_name);
|
||||
} catch (...) {
|
||||
throwJavaException(env, 0, method_name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// size_t DeviceInfo::totalMemory()
|
||||
//
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_org_opencv_gpu_DeviceInfo_totalMemory_10 (JNIEnv*, jclass, jlong);
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_org_opencv_gpu_DeviceInfo_totalMemory_10
|
||||
(JNIEnv* env, jclass , jlong self)
|
||||
{
|
||||
static const char method_name[] = "gpu::totalMemory_10()";
|
||||
try {
|
||||
LOGD("%s", method_name);
|
||||
DeviceInfo* me = (DeviceInfo*) self; //TODO: check for NULL
|
||||
size_t _retval_ = me->totalMemory( );
|
||||
return _retval_;
|
||||
} catch(const std::exception &e) {
|
||||
throwJavaException(env, &e, method_name);
|
||||
} catch (...) {
|
||||
throwJavaException(env, 0, method_name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// native support for java finalize()
|
||||
// static void DeviceInfo::delete( __int64 self )
|
||||
//
|
||||
JNIEXPORT void JNICALL Java_org_opencv_gpu_DeviceInfo_delete(JNIEnv*, jclass, jlong);
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_opencv_gpu_DeviceInfo_delete
|
||||
(JNIEnv*, jclass, jlong self)
|
||||
{
|
||||
delete (DeviceInfo*) self;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// static bool TargetArchs::builtWith(cv::gpu::FeatureSet feature_set)
|
||||
//
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_opencv_gpu_TargetArchs_builtWith_10 (JNIEnv*, jclass, jint);
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_opencv_gpu_TargetArchs_builtWith_10
|
||||
(JNIEnv* env, jclass , jint feature_set)
|
||||
{
|
||||
static const char method_name[] = "gpu::builtWith_10()";
|
||||
try {
|
||||
LOGD("%s", method_name);
|
||||
|
||||
bool _retval_ = TargetArchs::builtWith( (cv::gpu::FeatureSet)feature_set );
|
||||
return _retval_;
|
||||
} catch(const std::exception &e) {
|
||||
throwJavaException(env, &e, method_name);
|
||||
} catch (...) {
|
||||
throwJavaException(env, 0, method_name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// static bool TargetArchs::has(int major, int minor)
|
||||
//
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_opencv_gpu_TargetArchs_has_10 (JNIEnv*, jclass, jint, jint);
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_opencv_gpu_TargetArchs_has_10
|
||||
(JNIEnv* env, jclass , jint major, jint minor)
|
||||
{
|
||||
static const char method_name[] = "gpu::has_10()";
|
||||
try {
|
||||
LOGD("%s", method_name);
|
||||
|
||||
bool _retval_ = TargetArchs::has( (int)major, (int)minor );
|
||||
return _retval_;
|
||||
} catch(const std::exception &e) {
|
||||
throwJavaException(env, &e, method_name);
|
||||
} catch (...) {
|
||||
throwJavaException(env, 0, method_name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// static bool TargetArchs::hasBin(int major, int minor)
|
||||
//
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_opencv_gpu_TargetArchs_hasBin_10 (JNIEnv*, jclass, jint, jint);
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_opencv_gpu_TargetArchs_hasBin_10
|
||||
(JNIEnv* env, jclass , jint major, jint minor)
|
||||
{
|
||||
static const char method_name[] = "gpu::hasBin_10()";
|
||||
try {
|
||||
LOGD("%s", method_name);
|
||||
|
||||
bool _retval_ = TargetArchs::hasBin( (int)major, (int)minor );
|
||||
return _retval_;
|
||||
} catch(const std::exception &e) {
|
||||
throwJavaException(env, &e, method_name);
|
||||
} catch (...) {
|
||||
throwJavaException(env, 0, method_name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// static bool TargetArchs::hasEqualOrGreater(int major, int minor)
|
||||
//
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_opencv_gpu_TargetArchs_hasEqualOrGreater_10 (JNIEnv*, jclass, jint, jint);
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_opencv_gpu_TargetArchs_hasEqualOrGreater_10
|
||||
(JNIEnv* env, jclass , jint major, jint minor)
|
||||
{
|
||||
static const char method_name[] = "gpu::hasEqualOrGreater_10()";
|
||||
try {
|
||||
LOGD("%s", method_name);
|
||||
|
||||
bool _retval_ = TargetArchs::hasEqualOrGreater( (int)major, (int)minor );
|
||||
return _retval_;
|
||||
} catch(const std::exception &e) {
|
||||
throwJavaException(env, &e, method_name);
|
||||
} catch (...) {
|
||||
throwJavaException(env, 0, method_name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// static bool TargetArchs::hasEqualOrGreaterBin(int major, int minor)
|
||||
//
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_opencv_gpu_TargetArchs_hasEqualOrGreaterBin_10 (JNIEnv*, jclass, jint, jint);
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_opencv_gpu_TargetArchs_hasEqualOrGreaterBin_10
|
||||
(JNIEnv* env, jclass , jint major, jint minor)
|
||||
{
|
||||
static const char method_name[] = "gpu::hasEqualOrGreaterBin_10()";
|
||||
try {
|
||||
LOGD("%s", method_name);
|
||||
|
||||
bool _retval_ = TargetArchs::hasEqualOrGreaterBin( (int)major, (int)minor );
|
||||
return _retval_;
|
||||
} catch(const std::exception &e) {
|
||||
throwJavaException(env, &e, method_name);
|
||||
} catch (...) {
|
||||
throwJavaException(env, 0, method_name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// static bool TargetArchs::hasEqualOrGreaterPtx(int major, int minor)
|
||||
//
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_opencv_gpu_TargetArchs_hasEqualOrGreaterPtx_10 (JNIEnv*, jclass, jint, jint);
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_opencv_gpu_TargetArchs_hasEqualOrGreaterPtx_10
|
||||
(JNIEnv* env, jclass , jint major, jint minor)
|
||||
{
|
||||
static const char method_name[] = "gpu::hasEqualOrGreaterPtx_10()";
|
||||
try {
|
||||
LOGD("%s", method_name);
|
||||
|
||||
bool _retval_ = TargetArchs::hasEqualOrGreaterPtx( (int)major, (int)minor );
|
||||
return _retval_;
|
||||
} catch(const std::exception &e) {
|
||||
throwJavaException(env, &e, method_name);
|
||||
} catch (...) {
|
||||
throwJavaException(env, 0, method_name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// static bool TargetArchs::hasEqualOrLessPtx(int major, int minor)
|
||||
//
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_opencv_gpu_TargetArchs_hasEqualOrLessPtx_10 (JNIEnv*, jclass, jint, jint);
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_opencv_gpu_TargetArchs_hasEqualOrLessPtx_10
|
||||
(JNIEnv* env, jclass , jint major, jint minor)
|
||||
{
|
||||
static const char method_name[] = "gpu::hasEqualOrLessPtx_10()";
|
||||
try {
|
||||
LOGD("%s", method_name);
|
||||
|
||||
bool _retval_ = TargetArchs::hasEqualOrLessPtx( (int)major, (int)minor );
|
||||
return _retval_;
|
||||
} catch(const std::exception &e) {
|
||||
throwJavaException(env, &e, method_name);
|
||||
} catch (...) {
|
||||
throwJavaException(env, 0, method_name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// static bool TargetArchs::hasPtx(int major, int minor)
|
||||
//
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_opencv_gpu_TargetArchs_hasPtx_10 (JNIEnv*, jclass, jint, jint);
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_opencv_gpu_TargetArchs_hasPtx_10
|
||||
(JNIEnv* env, jclass , jint major, jint minor)
|
||||
{
|
||||
static const char method_name[] = "gpu::hasPtx_10()";
|
||||
try {
|
||||
LOGD("%s", method_name);
|
||||
|
||||
bool _retval_ = TargetArchs::hasPtx( (int)major, (int)minor );
|
||||
return _retval_;
|
||||
} catch(const std::exception &e) {
|
||||
throwJavaException(env, &e, method_name);
|
||||
} catch (...) {
|
||||
throwJavaException(env, 0, method_name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// native support for java finalize()
|
||||
// static void TargetArchs::delete( __int64 self )
|
||||
//
|
||||
JNIEXPORT void JNICALL Java_org_opencv_gpu_TargetArchs_delete(JNIEnv*, jclass, jlong);
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_opencv_gpu_TargetArchs_delete
|
||||
(JNIEnv*, jclass, jlong self)
|
||||
{
|
||||
delete (TargetArchs*) self;
|
||||
}
|
||||
|
||||
|
||||
} // extern "C"
|
||||
@@ -37,6 +37,10 @@ public class OpenCVLoader
|
||||
*/
|
||||
public static final String OPENCV_VERSION_2_4_7 = "2.4.7";
|
||||
|
||||
/**
|
||||
* OpenCV Library version 2.4.8.
|
||||
*/
|
||||
public static final String OPENCV_VERSION_2_4_8 = "2.4.8";
|
||||
|
||||
/**
|
||||
* Loads and initializes OpenCV library from current application package. Roughly, it's an analog of system.loadLibrary("opencv_java").
|
||||
|
||||
@@ -0,0 +1,245 @@
|
||||
package org.opencv.gpu;
|
||||
|
||||
import java.lang.String;
|
||||
|
||||
// C++: class DeviceInfo
|
||||
//javadoc: DeviceInfo
|
||||
public class DeviceInfo {
|
||||
|
||||
protected final long nativeObj;
|
||||
protected DeviceInfo(long addr) { nativeObj = addr; }
|
||||
|
||||
|
||||
//
|
||||
// C++: DeviceInfo::DeviceInfo()
|
||||
//
|
||||
|
||||
//javadoc: DeviceInfo::DeviceInfo()
|
||||
public DeviceInfo()
|
||||
{
|
||||
|
||||
nativeObj = DeviceInfo_0();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// C++: DeviceInfo::DeviceInfo(int device_id)
|
||||
//
|
||||
|
||||
//javadoc: DeviceInfo::DeviceInfo(device_id)
|
||||
public DeviceInfo(int device_id)
|
||||
{
|
||||
|
||||
nativeObj = DeviceInfo_1(device_id);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// C++: int DeviceInfo::deviceID()
|
||||
//
|
||||
|
||||
//javadoc: DeviceInfo::deviceID()
|
||||
public int deviceID()
|
||||
{
|
||||
|
||||
int retVal = deviceID_0(nativeObj);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// C++: size_t DeviceInfo::freeMemory()
|
||||
//
|
||||
|
||||
//javadoc: DeviceInfo::freeMemory()
|
||||
public long freeMemory()
|
||||
{
|
||||
|
||||
long retVal = freeMemory_0(nativeObj);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// C++: bool DeviceInfo::isCompatible()
|
||||
//
|
||||
|
||||
//javadoc: DeviceInfo::isCompatible()
|
||||
public boolean isCompatible()
|
||||
{
|
||||
|
||||
boolean retVal = isCompatible_0(nativeObj);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// C++: int DeviceInfo::majorVersion()
|
||||
//
|
||||
|
||||
//javadoc: DeviceInfo::majorVersion()
|
||||
public int majorVersion()
|
||||
{
|
||||
|
||||
int retVal = majorVersion_0(nativeObj);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// C++: int DeviceInfo::minorVersion()
|
||||
//
|
||||
|
||||
//javadoc: DeviceInfo::minorVersion()
|
||||
public int minorVersion()
|
||||
{
|
||||
|
||||
int retVal = minorVersion_0(nativeObj);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// C++: int DeviceInfo::multiProcessorCount()
|
||||
//
|
||||
|
||||
//javadoc: DeviceInfo::multiProcessorCount()
|
||||
public int multiProcessorCount()
|
||||
{
|
||||
|
||||
int retVal = multiProcessorCount_0(nativeObj);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// C++: string DeviceInfo::name()
|
||||
//
|
||||
|
||||
//javadoc: DeviceInfo::name()
|
||||
public String name()
|
||||
{
|
||||
|
||||
String retVal = name_0(nativeObj);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// C++: void DeviceInfo::queryMemory(size_t& totalMemory, size_t& freeMemory)
|
||||
//
|
||||
|
||||
//javadoc: DeviceInfo::queryMemory(totalMemory, freeMemory)
|
||||
public void queryMemory(long totalMemory, long freeMemory)
|
||||
{
|
||||
double[] totalMemory_out = new double[1];
|
||||
double[] freeMemory_out = new double[1];
|
||||
queryMemory_0(nativeObj, totalMemory_out, freeMemory_out);
|
||||
totalMemory = (long)totalMemory_out[0];
|
||||
freeMemory = (long)freeMemory_out[0];
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// C++: size_t DeviceInfo::sharedMemPerBlock()
|
||||
//
|
||||
|
||||
//javadoc: DeviceInfo::sharedMemPerBlock()
|
||||
public long sharedMemPerBlock()
|
||||
{
|
||||
|
||||
long retVal = sharedMemPerBlock_0(nativeObj);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// C++: bool DeviceInfo::supports(int feature_set)
|
||||
//
|
||||
|
||||
//javadoc: DeviceInfo::supports(feature_set)
|
||||
public boolean supports(int feature_set)
|
||||
{
|
||||
|
||||
boolean retVal = supports_0(nativeObj, feature_set);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// C++: size_t DeviceInfo::totalMemory()
|
||||
//
|
||||
|
||||
//javadoc: DeviceInfo::totalMemory()
|
||||
public long totalMemory()
|
||||
{
|
||||
|
||||
long retVal = totalMemory_0(nativeObj);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
delete(nativeObj);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// C++: DeviceInfo::DeviceInfo()
|
||||
private static native long DeviceInfo_0();
|
||||
|
||||
// C++: DeviceInfo::DeviceInfo(int device_id)
|
||||
private static native long DeviceInfo_1(int device_id);
|
||||
|
||||
// C++: int DeviceInfo::deviceID()
|
||||
private static native int deviceID_0(long nativeObj);
|
||||
|
||||
// C++: size_t DeviceInfo::freeMemory()
|
||||
private static native long freeMemory_0(long nativeObj);
|
||||
|
||||
// C++: bool DeviceInfo::isCompatible()
|
||||
private static native boolean isCompatible_0(long nativeObj);
|
||||
|
||||
// C++: int DeviceInfo::majorVersion()
|
||||
private static native int majorVersion_0(long nativeObj);
|
||||
|
||||
// C++: int DeviceInfo::minorVersion()
|
||||
private static native int minorVersion_0(long nativeObj);
|
||||
|
||||
// C++: int DeviceInfo::multiProcessorCount()
|
||||
private static native int multiProcessorCount_0(long nativeObj);
|
||||
|
||||
// C++: string DeviceInfo::name()
|
||||
private static native String name_0(long nativeObj);
|
||||
|
||||
// C++: void DeviceInfo::queryMemory(size_t& totalMemory, size_t& freeMemory)
|
||||
private static native void queryMemory_0(long nativeObj, double[] totalMemory_out, double[] freeMemory_out);
|
||||
|
||||
// C++: size_t DeviceInfo::sharedMemPerBlock()
|
||||
private static native long sharedMemPerBlock_0(long nativeObj);
|
||||
|
||||
// C++: bool DeviceInfo::supports(int feature_set)
|
||||
private static native boolean supports_0(long nativeObj, int feature_set);
|
||||
|
||||
// C++: size_t DeviceInfo::totalMemory()
|
||||
private static native long totalMemory_0(long nativeObj);
|
||||
|
||||
// native support for java finalize()
|
||||
private static native void delete(long nativeObj);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
package org.opencv.gpu;
|
||||
|
||||
public class Gpu {
|
||||
|
||||
public static final int
|
||||
FEATURE_SET_COMPUTE_10 = 10,
|
||||
FEATURE_SET_COMPUTE_11 = 11,
|
||||
FEATURE_SET_COMPUTE_12 = 12,
|
||||
FEATURE_SET_COMPUTE_13 = 13,
|
||||
FEATURE_SET_COMPUTE_20 = 20,
|
||||
FEATURE_SET_COMPUTE_21 = 21,
|
||||
FEATURE_SET_COMPUTE_30 = 30,
|
||||
FEATURE_SET_COMPUTE_35 = 35,
|
||||
GLOBAL_ATOMICS = FEATURE_SET_COMPUTE_11,
|
||||
SHARED_ATOMICS = FEATURE_SET_COMPUTE_12,
|
||||
NATIVE_DOUBLE = FEATURE_SET_COMPUTE_13,
|
||||
WARP_SHUFFLE_FUNCTIONS = FEATURE_SET_COMPUTE_30,
|
||||
DYNAMIC_PARALLELISM = FEATURE_SET_COMPUTE_35;
|
||||
|
||||
|
||||
//
|
||||
// C++: bool deviceSupports(int feature_set)
|
||||
//
|
||||
|
||||
//javadoc: deviceSupports(feature_set)
|
||||
public static boolean deviceSupports(int feature_set)
|
||||
{
|
||||
boolean retVal = deviceSupports_0(feature_set);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// C++: int getCudaEnabledDeviceCount()
|
||||
//
|
||||
|
||||
//javadoc: getCudaEnabledDeviceCount()
|
||||
public static int getCudaEnabledDeviceCount()
|
||||
{
|
||||
int retVal = getCudaEnabledDeviceCount_0();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// C++: int getDevice()
|
||||
//
|
||||
|
||||
//javadoc: getDevice()
|
||||
public static int getDevice()
|
||||
{
|
||||
int retVal = getDevice_0();
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// C++: void printCudaDeviceInfo(int device)
|
||||
//
|
||||
|
||||
//javadoc: printCudaDeviceInfo(device)
|
||||
public static void printCudaDeviceInfo(int device)
|
||||
{
|
||||
printCudaDeviceInfo_0(device);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// C++: void printShortCudaDeviceInfo(int device)
|
||||
//
|
||||
|
||||
//javadoc: printShortCudaDeviceInfo(device)
|
||||
public static void printShortCudaDeviceInfo(int device)
|
||||
{
|
||||
printShortCudaDeviceInfo_0(device);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// C++: void resetDevice()
|
||||
//
|
||||
|
||||
//javadoc: resetDevice()
|
||||
public static void resetDevice()
|
||||
{
|
||||
resetDevice_0();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// C++: void setDevice(int device)
|
||||
//
|
||||
|
||||
//javadoc: setDevice(device)
|
||||
public static void setDevice(int device)
|
||||
{
|
||||
setDevice_0(device);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// C++: bool deviceSupports(int feature_set)
|
||||
private static native boolean deviceSupports_0(int feature_set);
|
||||
|
||||
// C++: int getCudaEnabledDeviceCount()
|
||||
private static native int getCudaEnabledDeviceCount_0();
|
||||
|
||||
// C++: int getDevice()
|
||||
private static native int getDevice_0();
|
||||
|
||||
// C++: void printCudaDeviceInfo(int device)
|
||||
private static native void printCudaDeviceInfo_0(int device);
|
||||
|
||||
// C++: void printShortCudaDeviceInfo(int device)
|
||||
private static native void printShortCudaDeviceInfo_0(int device);
|
||||
|
||||
// C++: void resetDevice()
|
||||
private static native void resetDevice_0();
|
||||
|
||||
// C++: void setDevice(int device)
|
||||
private static native void setDevice_0(int device);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
package org.opencv.gpu;
|
||||
|
||||
// C++: class TargetArchs
|
||||
//javadoc: TargetArchs
|
||||
public class TargetArchs {
|
||||
|
||||
protected final long nativeObj;
|
||||
protected TargetArchs(long addr) { nativeObj = addr; }
|
||||
|
||||
|
||||
//
|
||||
// C++: static bool TargetArchs::builtWith(int feature_set)
|
||||
//
|
||||
|
||||
//javadoc: TargetArchs::builtWith(feature_set)
|
||||
public static boolean builtWith(int feature_set)
|
||||
{
|
||||
boolean retVal = builtWith_0(feature_set);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// C++: static bool TargetArchs::has(int major, int minor)
|
||||
//
|
||||
|
||||
//javadoc: TargetArchs::has(major, minor)
|
||||
public static boolean has(int major, int minor)
|
||||
{
|
||||
boolean retVal = has_0(major, minor);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// C++: static bool TargetArchs::hasBin(int major, int minor)
|
||||
//
|
||||
|
||||
//javadoc: TargetArchs::hasBin(major, minor)
|
||||
public static boolean hasBin(int major, int minor)
|
||||
{
|
||||
boolean retVal = hasBin_0(major, minor);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// C++: static bool TargetArchs::hasEqualOrGreater(int major, int minor)
|
||||
//
|
||||
|
||||
//javadoc: TargetArchs::hasEqualOrGreater(major, minor)
|
||||
public static boolean hasEqualOrGreater(int major, int minor)
|
||||
{
|
||||
boolean retVal = hasEqualOrGreater_0(major, minor);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// C++: static bool TargetArchs::hasEqualOrGreaterBin(int major, int minor)
|
||||
//
|
||||
|
||||
//javadoc: TargetArchs::hasEqualOrGreaterBin(major, minor)
|
||||
public static boolean hasEqualOrGreaterBin(int major, int minor)
|
||||
{
|
||||
boolean retVal = hasEqualOrGreaterBin_0(major, minor);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// C++: static bool TargetArchs::hasEqualOrGreaterPtx(int major, int minor)
|
||||
//
|
||||
|
||||
//javadoc: TargetArchs::hasEqualOrGreaterPtx(major, minor)
|
||||
public static boolean hasEqualOrGreaterPtx(int major, int minor)
|
||||
{
|
||||
boolean retVal = hasEqualOrGreaterPtx_0(major, minor);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// C++: static bool TargetArchs::hasEqualOrLessPtx(int major, int minor)
|
||||
//
|
||||
|
||||
//javadoc: TargetArchs::hasEqualOrLessPtx(major, minor)
|
||||
public static boolean hasEqualOrLessPtx(int major, int minor)
|
||||
{
|
||||
boolean retVal = hasEqualOrLessPtx_0(major, minor);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// C++: static bool TargetArchs::hasPtx(int major, int minor)
|
||||
//
|
||||
|
||||
//javadoc: TargetArchs::hasPtx(major, minor)
|
||||
public static boolean hasPtx(int major, int minor)
|
||||
{
|
||||
boolean retVal = hasPtx_0(major, minor);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
delete(nativeObj);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// C++: static bool TargetArchs::builtWith(int feature_set)
|
||||
private static native boolean builtWith_0(int feature_set);
|
||||
|
||||
// C++: static bool TargetArchs::has(int major, int minor)
|
||||
private static native boolean has_0(int major, int minor);
|
||||
|
||||
// C++: static bool TargetArchs::hasBin(int major, int minor)
|
||||
private static native boolean hasBin_0(int major, int minor);
|
||||
|
||||
// C++: static bool TargetArchs::hasEqualOrGreater(int major, int minor)
|
||||
private static native boolean hasEqualOrGreater_0(int major, int minor);
|
||||
|
||||
// C++: static bool TargetArchs::hasEqualOrGreaterBin(int major, int minor)
|
||||
private static native boolean hasEqualOrGreaterBin_0(int major, int minor);
|
||||
|
||||
// C++: static bool TargetArchs::hasEqualOrGreaterPtx(int major, int minor)
|
||||
private static native boolean hasEqualOrGreaterPtx_0(int major, int minor);
|
||||
|
||||
// C++: static bool TargetArchs::hasEqualOrLessPtx(int major, int minor)
|
||||
private static native boolean hasEqualOrLessPtx_0(int major, int minor);
|
||||
|
||||
// C++: static bool TargetArchs::hasPtx(int major, int minor)
|
||||
private static native boolean hasPtx_0(int major, int minor);
|
||||
|
||||
// native support for java finalize()
|
||||
private static native void delete(long nativeObj);
|
||||
|
||||
}
|
||||
@@ -4,4 +4,9 @@ endif()
|
||||
|
||||
set(the_description "Functionality with possible limitations on the use")
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wundef)
|
||||
ocv_define_module(nonfree opencv_imgproc opencv_features2d opencv_calib3d OPTIONAL opencv_gpu opencv_ocl)
|
||||
if (ENABLE_DYNAMIC_CUDA)
|
||||
set(HAVE_CUDA FALSE)
|
||||
ocv_define_module(nonfree opencv_imgproc opencv_features2d opencv_calib3d OPTIONAL opencv_ocl)
|
||||
else()
|
||||
ocv_define_module(nonfree opencv_imgproc opencv_features2d opencv_calib3d OPTIONAL opencv_gpu opencv_ocl)
|
||||
endif()
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
#include "opencv2/opencv_modules.hpp"
|
||||
|
||||
#if defined(HAVE_OPENCV_GPU)
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
|
||||
|
||||
#include "opencv2/gpu/gpu.hpp"
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
#include "opencv2/opencv_modules.hpp"
|
||||
|
||||
#ifdef HAVE_OPENCV_GPU
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
|
||||
|
||||
#include "opencv2/gpu/device/common.hpp"
|
||||
#include "opencv2/gpu/device/limits.hpp"
|
||||
|
||||
+223
-191
@@ -12,6 +12,7 @@
|
||||
//
|
||||
// Copyright (C) 2010-2012, Multicoreware, Inc., all rights reserved.
|
||||
// Copyright (C) 2010-2012, Advanced Micro Devices, Inc., all rights reserved.
|
||||
// Copyright (C) 2013, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// @Authors
|
||||
@@ -66,8 +67,8 @@ uint read_sumTex(IMAGE_INT32 img, sampler_t sam, int2 coord, int rows, int cols,
|
||||
uchar read_imgTex(IMAGE_INT8 img, sampler_t sam, float2 coord, int rows, int cols, int elemPerRow)
|
||||
{
|
||||
#ifdef DISABLE_IMAGE2D
|
||||
int x = clamp(convert_int_rte(coord.x), 0, cols - 1);
|
||||
int y = clamp(convert_int_rte(coord.y), 0, rows - 1);
|
||||
int x = clamp(round(coord.x), 0, cols - 1);
|
||||
int y = clamp(round(coord.y), 0, rows - 1);
|
||||
return img[elemPerRow * y + x];
|
||||
#else
|
||||
return (uchar)read_imageui(img, sam, coord).x;
|
||||
@@ -98,6 +99,7 @@ __constant sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAM
|
||||
#define CV_PI_F 3.14159265f
|
||||
#endif
|
||||
|
||||
|
||||
// Use integral image to calculate haar wavelets.
|
||||
// N = 2
|
||||
// for simple haar paatern
|
||||
@@ -114,10 +116,10 @@ float icvCalcHaarPatternSum_2(
|
||||
|
||||
F d = 0;
|
||||
|
||||
int2 dx1 = convert_int2_rte(ratio * src[0]);
|
||||
int2 dy1 = convert_int2_rte(ratio * src[1]);
|
||||
int2 dx2 = convert_int2_rte(ratio * src[2]);
|
||||
int2 dy2 = convert_int2_rte(ratio * src[3]);
|
||||
int2 dx1 = convert_int2(round(ratio * src[0]));
|
||||
int2 dy1 = convert_int2(round(ratio * src[1]));
|
||||
int2 dx2 = convert_int2(round(ratio * src[2]));
|
||||
int2 dy2 = convert_int2(round(ratio * src[3]));
|
||||
|
||||
F t = 0;
|
||||
t += read_sumTex( sumTex, sampler, (int2)(x + dx1.x, y + dy1.x), rows, cols, elemPerRow );
|
||||
@@ -136,106 +138,9 @@ float icvCalcHaarPatternSum_2(
|
||||
return (float)d;
|
||||
}
|
||||
|
||||
// N = 3
|
||||
float icvCalcHaarPatternSum_3(
|
||||
IMAGE_INT32 sumTex,
|
||||
__constant float4 *src,
|
||||
int oldSize,
|
||||
int newSize,
|
||||
int y, int x,
|
||||
int rows, int cols, int elemPerRow)
|
||||
{
|
||||
|
||||
float ratio = (float)newSize / oldSize;
|
||||
|
||||
F d = 0;
|
||||
|
||||
int4 dx1 = convert_int4_rte(ratio * src[0]);
|
||||
int4 dy1 = convert_int4_rte(ratio * src[1]);
|
||||
int4 dx2 = convert_int4_rte(ratio * src[2]);
|
||||
int4 dy2 = convert_int4_rte(ratio * src[3]);
|
||||
|
||||
F t = 0;
|
||||
t += read_sumTex( sumTex, sampler, (int2)(x + dx1.x, y + dy1.x), rows, cols, elemPerRow );
|
||||
t -= read_sumTex( sumTex, sampler, (int2)(x + dx1.x, y + dy2.x), rows, cols, elemPerRow );
|
||||
t -= read_sumTex( sumTex, sampler, (int2)(x + dx2.x, y + dy1.x), rows, cols, elemPerRow );
|
||||
t += read_sumTex( sumTex, sampler, (int2)(x + dx2.x, y + dy2.x), rows, cols, elemPerRow );
|
||||
d += t * src[4].x / ((dx2.x - dx1.x) * (dy2.x - dy1.x));
|
||||
|
||||
t = 0;
|
||||
t += read_sumTex( sumTex, sampler, (int2)(x + dx1.y, y + dy1.y), rows, cols, elemPerRow );
|
||||
t -= read_sumTex( sumTex, sampler, (int2)(x + dx1.y, y + dy2.y), rows, cols, elemPerRow );
|
||||
t -= read_sumTex( sumTex, sampler, (int2)(x + dx2.y, y + dy1.y), rows, cols, elemPerRow );
|
||||
t += read_sumTex( sumTex, sampler, (int2)(x + dx2.y, y + dy2.y), rows, cols, elemPerRow );
|
||||
d += t * src[4].y / ((dx2.y - dx1.y) * (dy2.y - dy1.y));
|
||||
|
||||
t = 0;
|
||||
t += read_sumTex( sumTex, sampler, (int2)(x + dx1.z, y + dy1.z), rows, cols, elemPerRow );
|
||||
t -= read_sumTex( sumTex, sampler, (int2)(x + dx1.z, y + dy2.z), rows, cols, elemPerRow );
|
||||
t -= read_sumTex( sumTex, sampler, (int2)(x + dx2.z, y + dy1.z), rows, cols, elemPerRow );
|
||||
t += read_sumTex( sumTex, sampler, (int2)(x + dx2.z, y + dy2.z), rows, cols, elemPerRow );
|
||||
d += t * src[4].z / ((dx2.z - dx1.z) * (dy2.z - dy1.z));
|
||||
|
||||
return (float)d;
|
||||
}
|
||||
|
||||
// N = 4
|
||||
float icvCalcHaarPatternSum_4(
|
||||
IMAGE_INT32 sumTex,
|
||||
__constant float4 *src,
|
||||
int oldSize,
|
||||
int newSize,
|
||||
int y, int x,
|
||||
int rows, int cols, int elemPerRow)
|
||||
{
|
||||
|
||||
float ratio = (float)newSize / oldSize;
|
||||
|
||||
F d = 0;
|
||||
|
||||
int4 dx1 = convert_int4_rte(ratio * src[0]);
|
||||
int4 dy1 = convert_int4_rte(ratio * src[1]);
|
||||
int4 dx2 = convert_int4_rte(ratio * src[2]);
|
||||
int4 dy2 = convert_int4_rte(ratio * src[3]);
|
||||
|
||||
F t = 0;
|
||||
t += read_sumTex( sumTex, sampler, (int2)(x + dx1.x, y + dy1.x), rows, cols, elemPerRow );
|
||||
t -= read_sumTex( sumTex, sampler, (int2)(x + dx1.x, y + dy2.x), rows, cols, elemPerRow );
|
||||
t -= read_sumTex( sumTex, sampler, (int2)(x + dx2.x, y + dy1.x), rows, cols, elemPerRow );
|
||||
t += read_sumTex( sumTex, sampler, (int2)(x + dx2.x, y + dy2.x), rows, cols, elemPerRow );
|
||||
d += t * src[4].x / ((dx2.x - dx1.x) * (dy2.x - dy1.x));
|
||||
|
||||
t = 0;
|
||||
t += read_sumTex( sumTex, sampler, (int2)(x + dx1.y, y + dy1.y), rows, cols, elemPerRow );
|
||||
t -= read_sumTex( sumTex, sampler, (int2)(x + dx1.y, y + dy2.y), rows, cols, elemPerRow );
|
||||
t -= read_sumTex( sumTex, sampler, (int2)(x + dx2.y, y + dy1.y), rows, cols, elemPerRow );
|
||||
t += read_sumTex( sumTex, sampler, (int2)(x + dx2.y, y + dy2.y), rows, cols, elemPerRow );
|
||||
d += t * src[4].y / ((dx2.y - dx1.y) * (dy2.y - dy1.y));
|
||||
|
||||
t = 0;
|
||||
t += read_sumTex( sumTex, sampler, (int2)(x + dx1.z, y + dy1.z), rows, cols, elemPerRow );
|
||||
t -= read_sumTex( sumTex, sampler, (int2)(x + dx1.z, y + dy2.z), rows, cols, elemPerRow );
|
||||
t -= read_sumTex( sumTex, sampler, (int2)(x + dx2.z, y + dy1.z), rows, cols, elemPerRow );
|
||||
t += read_sumTex( sumTex, sampler, (int2)(x + dx2.z, y + dy2.z), rows, cols, elemPerRow );
|
||||
d += t * src[4].z / ((dx2.z - dx1.z) * (dy2.z - dy1.z));
|
||||
|
||||
t = 0;
|
||||
t += read_sumTex( sumTex, sampler, (int2)(x + dx1.w, y + dy1.w), rows, cols, elemPerRow );
|
||||
t -= read_sumTex( sumTex, sampler, (int2)(x + dx1.w, y + dy2.w), rows, cols, elemPerRow );
|
||||
t -= read_sumTex( sumTex, sampler, (int2)(x + dx2.w, y + dy1.w), rows, cols, elemPerRow );
|
||||
t += read_sumTex( sumTex, sampler, (int2)(x + dx2.w, y + dy2.w), rows, cols, elemPerRow );
|
||||
d += t * src[4].w / ((dx2.w - dx1.w) * (dy2.w - dy1.w));
|
||||
|
||||
return (float)d;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Hessian
|
||||
|
||||
__constant float4 c_DX[5] = { (float4)(0, 3, 6, 0), (float4)(2, 2, 2, 0), (float4)(3, 6, 9, 0), (float4)(7, 7, 7, 0), (float4)(1, -2, 1, 0) };
|
||||
__constant float4 c_DY[5] = { (float4)(2, 2, 2, 0), (float4)(0, 3, 6, 0), (float4)(7, 7, 7, 0), (float4)(3, 6, 9, 0), (float4)(1, -2, 1, 0) };
|
||||
__constant float4 c_DXY[5] = { (float4)(1, 5, 1, 5), (float4)(1, 1, 5, 5), (float4)(4, 8, 4, 8), (float4)(4, 4, 8, 8), (float4)(1, -1, -1, 1) };// Use integral image to calculate haar wavelets.
|
||||
|
||||
__inline int calcSize(int octave, int layer)
|
||||
{
|
||||
/* Wavelet size at first layer of first octave. */
|
||||
@@ -250,6 +155,24 @@ __inline int calcSize(int octave, int layer)
|
||||
return (HAAR_SIZE0 + HAAR_SIZE_INC * layer) << octave;
|
||||
}
|
||||
|
||||
// Calculate a derivative in an axis-aligned direction (x or y). The "plus1"
|
||||
// boxes contribute 1 * (area), and the "minus2" box contributes -2 * (area).
|
||||
// So the final computation is plus1a + plus1b - 2 * minus2. The corners are
|
||||
// labeled A, B, C, and D, with A being the top left, B being top right, C
|
||||
// being bottom left, and D being bottom right.
|
||||
F calcAxisAlignedDerivative(
|
||||
int plus1a_A, int plus1a_B, int plus1a_C, int plus1a_D, F plus1a_scale,
|
||||
int plus1b_A, int plus1b_B, int plus1b_C, int plus1b_D, F plus1b_scale,
|
||||
int minus2_A, int minus2_B, int minus2_C, int minus2_D, F minus2_scale)
|
||||
{
|
||||
F plus1a = plus1a_A - plus1a_B - plus1a_C + plus1a_D;
|
||||
F plus1b = plus1b_A - plus1b_B - plus1b_C + plus1b_D;
|
||||
F minus2 = minus2_A - minus2_B - minus2_C + minus2_D;
|
||||
|
||||
return (plus1a / plus1a_scale -
|
||||
2.0f * minus2 / minus2_scale +
|
||||
plus1b / plus1b_scale);
|
||||
}
|
||||
|
||||
//calculate targeted layer per-pixel determinant and trace with an integral image
|
||||
__kernel void icvCalcLayerDetAndTrace(
|
||||
@@ -264,7 +187,7 @@ __kernel void icvCalcLayerDetAndTrace(
|
||||
int c_octave,
|
||||
int c_layer_rows,
|
||||
int sumTex_step
|
||||
)
|
||||
)
|
||||
{
|
||||
det_step /= sizeof(*det);
|
||||
trace_step /= sizeof(*trace);
|
||||
@@ -288,16 +211,103 @@ __kernel void icvCalcLayerDetAndTrace(
|
||||
|
||||
if (size <= c_img_rows && size <= c_img_cols && i < samples_i && j < samples_j)
|
||||
{
|
||||
const float dx = icvCalcHaarPatternSum_3(sumTex, c_DX , 9, size, i << c_octave, j << c_octave, c_img_rows, c_img_cols, sumTex_step);
|
||||
const float dy = icvCalcHaarPatternSum_3(sumTex, c_DY , 9, size, i << c_octave, j << c_octave, c_img_rows, c_img_cols, sumTex_step);
|
||||
const float dxy = icvCalcHaarPatternSum_4(sumTex, c_DXY, 9, size, i << c_octave, j << c_octave, c_img_rows, c_img_cols, sumTex_step);
|
||||
int x = j << c_octave;
|
||||
int y = i << c_octave;
|
||||
|
||||
float ratio = (float)size / 9;
|
||||
|
||||
// Precompute some commonly used values, which are used to offset
|
||||
// texture coordinates in the integral image.
|
||||
int r1 = round(ratio);
|
||||
int r2 = round(ratio * 2.0f);
|
||||
int r3 = round(ratio * 3.0f);
|
||||
int r4 = round(ratio * 4.0f);
|
||||
int r5 = round(ratio * 5.0f);
|
||||
int r6 = round(ratio * 6.0f);
|
||||
int r7 = round(ratio * 7.0f);
|
||||
int r8 = round(ratio * 8.0f);
|
||||
int r9 = round(ratio * 9.0f);
|
||||
|
||||
// Calculate the approximated derivative in the x-direction
|
||||
F d = 0;
|
||||
{
|
||||
// Some of the pixels needed to compute the derivative are
|
||||
// repeated, so we only don't duplicate the fetch here.
|
||||
int t02 = read_sumTex( sumTex, sampler, (int2)(x, y + r2), c_img_rows, c_img_cols, sumTex_step );
|
||||
int t07 = read_sumTex( sumTex, sampler, (int2)(x, y + r7), c_img_rows, c_img_cols, sumTex_step );
|
||||
int t32 = read_sumTex( sumTex, sampler, (int2)(x + r3, y + r2), c_img_rows, c_img_cols, sumTex_step );
|
||||
int t37 = read_sumTex( sumTex, sampler, (int2)(x + r3, y + r7), c_img_rows, c_img_cols, sumTex_step );
|
||||
int t62 = read_sumTex( sumTex, sampler, (int2)(x + r6, y + r2), c_img_rows, c_img_cols, sumTex_step );
|
||||
int t67 = read_sumTex( sumTex, sampler, (int2)(x + r6, y + r7), c_img_rows, c_img_cols, sumTex_step );
|
||||
int t92 = read_sumTex( sumTex, sampler, (int2)(x + r9, y + r2), c_img_rows, c_img_cols, sumTex_step );
|
||||
int t97 = read_sumTex( sumTex, sampler, (int2)(x + r9, y + r7), c_img_rows, c_img_cols, sumTex_step );
|
||||
|
||||
d = calcAxisAlignedDerivative(t02, t07, t32, t37, (r3) * (r7 - r2),
|
||||
t62, t67, t92, t97, (r9 - r6) * (r7 - r2),
|
||||
t32, t37, t62, t67, (r6 - r3) * (r7 - r2));
|
||||
}
|
||||
const float dx = (float)d;
|
||||
|
||||
// Calculate the approximated derivative in the y-direction
|
||||
d = 0;
|
||||
{
|
||||
// Some of the pixels needed to compute the derivative are
|
||||
// repeated, so we only don't duplicate the fetch here.
|
||||
int t20 = read_sumTex( sumTex, sampler, (int2)(x + r2, y), c_img_rows, c_img_cols, sumTex_step );
|
||||
int t23 = read_sumTex( sumTex, sampler, (int2)(x + r2, y + r3), c_img_rows, c_img_cols, sumTex_step );
|
||||
int t70 = read_sumTex( sumTex, sampler, (int2)(x + r7, y), c_img_rows, c_img_cols, sumTex_step );
|
||||
int t73 = read_sumTex( sumTex, sampler, (int2)(x + r7, y + r3), c_img_rows, c_img_cols, sumTex_step );
|
||||
int t26 = read_sumTex( sumTex, sampler, (int2)(x + r2, y + r6), c_img_rows, c_img_cols, sumTex_step );
|
||||
int t76 = read_sumTex( sumTex, sampler, (int2)(x + r7, y + r6), c_img_rows, c_img_cols, sumTex_step );
|
||||
int t29 = read_sumTex( sumTex, sampler, (int2)(x + r2, y + r9), c_img_rows, c_img_cols, sumTex_step );
|
||||
int t79 = read_sumTex( sumTex, sampler, (int2)(x + r7, y + r9), c_img_rows, c_img_cols, sumTex_step );
|
||||
|
||||
d = calcAxisAlignedDerivative(t20, t23, t70, t73, (r7 - r2) * (r3),
|
||||
t26, t29, t76, t79, (r7 - r2) * (r9 - r6),
|
||||
t23, t26, t73, t76, (r7 - r2) * (r6 - r3));
|
||||
}
|
||||
const float dy = (float)d;
|
||||
|
||||
// Calculate the approximated derivative in the xy-direction
|
||||
d = 0;
|
||||
{
|
||||
// There's no saving us here, we just have to get all of the pixels in
|
||||
// separate fetches
|
||||
F t = 0;
|
||||
t += read_sumTex( sumTex, sampler, (int2)(x + r1, y + r1), c_img_rows, c_img_cols, sumTex_step );
|
||||
t -= read_sumTex( sumTex, sampler, (int2)(x + r1, y + r4), c_img_rows, c_img_cols, sumTex_step );
|
||||
t -= read_sumTex( sumTex, sampler, (int2)(x + r4, y + r1), c_img_rows, c_img_cols, sumTex_step );
|
||||
t += read_sumTex( sumTex, sampler, (int2)(x + r4, y + r4), c_img_rows, c_img_cols, sumTex_step );
|
||||
d += t / ((r4 - r1) * (r4 - r1));
|
||||
|
||||
t = 0;
|
||||
t += read_sumTex( sumTex, sampler, (int2)(x + r5, y + r1), c_img_rows, c_img_cols, sumTex_step );
|
||||
t -= read_sumTex( sumTex, sampler, (int2)(x + r5, y + r4), c_img_rows, c_img_cols, sumTex_step );
|
||||
t -= read_sumTex( sumTex, sampler, (int2)(x + r8, y + r1), c_img_rows, c_img_cols, sumTex_step );
|
||||
t += read_sumTex( sumTex, sampler, (int2)(x + r8, y + r4), c_img_rows, c_img_cols, sumTex_step );
|
||||
d -= t / ((r8 - r5) * (r4 - r1));
|
||||
|
||||
t = 0;
|
||||
t += read_sumTex( sumTex, sampler, (int2)(x + r1, y + r5), c_img_rows, c_img_cols, sumTex_step );
|
||||
t -= read_sumTex( sumTex, sampler, (int2)(x + r1, y + r8), c_img_rows, c_img_cols, sumTex_step );
|
||||
t -= read_sumTex( sumTex, sampler, (int2)(x + r4, y + r5), c_img_rows, c_img_cols, sumTex_step );
|
||||
t += read_sumTex( sumTex, sampler, (int2)(x + r4, y + r8), c_img_rows, c_img_cols, sumTex_step );
|
||||
d -= t / ((r4 - r1) * (r8 - r5));
|
||||
|
||||
t = 0;
|
||||
t += read_sumTex( sumTex, sampler, (int2)(x + r5, y + r5), c_img_rows, c_img_cols, sumTex_step );
|
||||
t -= read_sumTex( sumTex, sampler, (int2)(x + r5, y + r8), c_img_rows, c_img_cols, sumTex_step );
|
||||
t -= read_sumTex( sumTex, sampler, (int2)(x + r8, y + r5), c_img_rows, c_img_cols, sumTex_step );
|
||||
t += read_sumTex( sumTex, sampler, (int2)(x + r8, y + r8), c_img_rows, c_img_cols, sumTex_step );
|
||||
d += t / ((r8 - r5) * (r8 - r5));
|
||||
}
|
||||
const float dxy = (float)d;
|
||||
|
||||
det [j + margin + det_step * (layer * c_layer_rows + i + margin)] = dx * dy - 0.81f * dxy * dxy;
|
||||
trace[j + margin + trace_step * (layer * c_layer_rows + i + margin)] = dx + dy;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// NONMAX
|
||||
|
||||
@@ -309,10 +319,10 @@ bool within_check(IMAGE_INT32 maskSumTex, int sum_i, int sum_j, int size, int ro
|
||||
|
||||
float d = 0;
|
||||
|
||||
int dx1 = convert_int_rte(ratio * c_DM[0]);
|
||||
int dy1 = convert_int_rte(ratio * c_DM[1]);
|
||||
int dx2 = convert_int_rte(ratio * c_DM[2]);
|
||||
int dy2 = convert_int_rte(ratio * c_DM[3]);
|
||||
int dx1 = round(ratio * c_DM[0]);
|
||||
int dy1 = round(ratio * c_DM[1]);
|
||||
int dx2 = round(ratio * c_DM[2]);
|
||||
int dy2 = round(ratio * c_DM[3]);
|
||||
|
||||
float t = 0;
|
||||
|
||||
@@ -572,7 +582,7 @@ void icvFindMaximaInLayer(
|
||||
}
|
||||
|
||||
// solve 3x3 linear system Ax=b for floating point input
|
||||
inline bool solve3x3_float(volatile __local const float4 *A, volatile __local const float *b, volatile __local float *x)
|
||||
inline bool solve3x3_float(const float4 *A, const float *b, float *x)
|
||||
{
|
||||
float det = A[0].x * (A[1].y * A[2].z - A[1].z * A[2].y)
|
||||
- A[0].y * (A[1].x * A[2].z - A[1].z * A[2].x)
|
||||
@@ -651,7 +661,7 @@ void icvInterpolateKeypoint(
|
||||
|
||||
if (get_local_id(0) == 0 && get_local_id(1) == 0 && get_local_id(2) == 0)
|
||||
{
|
||||
volatile __local float dD[3];
|
||||
float dD[3];
|
||||
|
||||
//dx
|
||||
dD[0] = -0.5f * (N9[1][1][2] - N9[1][1][0]);
|
||||
@@ -660,7 +670,7 @@ void icvInterpolateKeypoint(
|
||||
//ds
|
||||
dD[2] = -0.5f * (N9[2][1][1] - N9[0][1][1]);
|
||||
|
||||
volatile __local float4 H[3];
|
||||
float4 H[3];
|
||||
|
||||
//dxx
|
||||
H[0].x = N9[1][1][0] - 2.0f * N9[1][1][1] + N9[1][1][2];
|
||||
@@ -681,7 +691,7 @@ void icvInterpolateKeypoint(
|
||||
//dss
|
||||
H[2].z = N9[0][1][1] - 2.0f * N9[1][1][1] + N9[2][1][1];
|
||||
|
||||
volatile __local float x[3];
|
||||
float x[3];
|
||||
|
||||
if (solve3x3_float(H, dD, x))
|
||||
{
|
||||
@@ -711,7 +721,7 @@ void icvInterpolateKeypoint(
|
||||
sampled in a circle of radius 6s using wavelets of size 4s.
|
||||
We ensure the gradient wavelet size is even to ensure the
|
||||
wavelet pattern is balanced and symmetric around its center */
|
||||
const int grad_wav_size = 2 * convert_int_rte(2.0f * s);
|
||||
const int grad_wav_size = 2 * round(2.0f * s);
|
||||
|
||||
// check when grad_wav_size is too big
|
||||
if ((c_img_rows + 1) >= grad_wav_size && (c_img_cols + 1) >= grad_wav_size)
|
||||
@@ -737,9 +747,12 @@ void icvInterpolateKeypoint(
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Orientation
|
||||
|
||||
#define ORI_SEARCH_INC 5
|
||||
#define ORI_WIN 60
|
||||
#define ORI_SAMPLES 113
|
||||
#define ORI_WIN 60
|
||||
#define ORI_SAMPLES 113
|
||||
|
||||
// The distance between samples in the beginning of the the reduction
|
||||
#define ORI_RESPONSE_REDUCTION_WIDTH 48
|
||||
#define ORI_RESPONSE_ARRAY_SIZE (ORI_RESPONSE_REDUCTION_WIDTH * 2)
|
||||
|
||||
__constant float c_aptX[ORI_SAMPLES] = {-6, -5, -5, -5, -5, -5, -5, -5, -4, -4, -4, -4, -4, -4, -4, -4, -4, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 6};
|
||||
__constant float c_aptY[ORI_SAMPLES] = {0, -3, -2, -1, 0, 1, 2, 3, -4, -3, -2, -1, 0, 1, 2, 3, 4, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, -4, -3, -2, -1, 0, 1, 2, 3, 4, -3, -2, -1, 0, 1, 2, 3, 0};
|
||||
@@ -833,12 +846,15 @@ void icvCalcOrientation(
|
||||
__global float* featureDir = keypoints + ANGLE_ROW * keypoints_step;
|
||||
|
||||
|
||||
volatile __local float s_X[128];
|
||||
volatile __local float s_Y[128];
|
||||
volatile __local float s_angle[128];
|
||||
__local float s_X[ORI_SAMPLES];
|
||||
__local float s_Y[ORI_SAMPLES];
|
||||
__local float s_angle[ORI_SAMPLES];
|
||||
|
||||
volatile __local float s_sumx[32 * 4];
|
||||
volatile __local float s_sumy[32 * 4];
|
||||
// Need to allocate enough to make the reduction work without accessing
|
||||
// past the end of the array.
|
||||
__local float s_sumx[ORI_RESPONSE_ARRAY_SIZE];
|
||||
__local float s_sumy[ORI_RESPONSE_ARRAY_SIZE];
|
||||
__local float s_mod[ORI_RESPONSE_ARRAY_SIZE];
|
||||
|
||||
/* The sampling intervals and wavelet sized for selecting an orientation
|
||||
and building the keypoint descriptor are defined relative to 's' */
|
||||
@@ -849,28 +865,60 @@ void icvCalcOrientation(
|
||||
sampled in a circle of radius 6s using wavelets of size 4s.
|
||||
We ensure the gradient wavelet size is even to ensure the
|
||||
wavelet pattern is balanced and symmetric around its center */
|
||||
const int grad_wav_size = 2 * convert_int_rte(2.0f * s);
|
||||
const int grad_wav_size = 2 * round(2.0f * s);
|
||||
|
||||
// check when grad_wav_size is too big
|
||||
if ((c_img_rows + 1) < grad_wav_size || (c_img_cols + 1) < grad_wav_size)
|
||||
return;
|
||||
|
||||
// Calc X, Y, angle and store it to shared memory
|
||||
const int tid = get_local_id(1) * get_local_size(0) + get_local_id(0);
|
||||
const int tid = get_local_id(0);
|
||||
// Initialize values that are only used as part of the reduction later.
|
||||
if (tid < ORI_RESPONSE_ARRAY_SIZE - ORI_LOCAL_SIZE) {
|
||||
s_mod[tid + ORI_LOCAL_SIZE] = 0.0f;
|
||||
}
|
||||
|
||||
float X = 0.0f, Y = 0.0f, angle = 0.0f;
|
||||
float ratio = (float)grad_wav_size / 4;
|
||||
|
||||
if (tid < ORI_SAMPLES)
|
||||
int r2 = round(ratio * 2.0);
|
||||
int r4 = round(ratio * 4.0);
|
||||
for (int i = tid; i < ORI_SAMPLES; i += ORI_LOCAL_SIZE )
|
||||
{
|
||||
float X = 0.0f, Y = 0.0f, angle = 0.0f;
|
||||
const float margin = (float)(grad_wav_size - 1) / 2.0f;
|
||||
const int x = convert_int_rte(featureX[get_group_id(0)] + c_aptX[tid] * s - margin);
|
||||
const int y = convert_int_rte(featureY[get_group_id(0)] + c_aptY[tid] * s - margin);
|
||||
const int x = round(featureX[get_group_id(0)] + c_aptX[i] * s - margin);
|
||||
const int y = round(featureY[get_group_id(0)] + c_aptY[i] * s - margin);
|
||||
|
||||
if (y >= 0 && y < (c_img_rows + 1) - grad_wav_size &&
|
||||
x >= 0 && x < (c_img_cols + 1) - grad_wav_size)
|
||||
x >= 0 && x < (c_img_cols + 1) - grad_wav_size)
|
||||
{
|
||||
X = c_aptW[tid] * icvCalcHaarPatternSum_2(sumTex, c_NX, 4, grad_wav_size, y, x, c_img_rows, c_img_cols, sum_step);
|
||||
Y = c_aptW[tid] * icvCalcHaarPatternSum_2(sumTex, c_NY, 4, grad_wav_size, y, x, c_img_rows, c_img_cols, sum_step);
|
||||
|
||||
float apt = c_aptW[i];
|
||||
|
||||
// Compute the haar sum without fetching duplicate pixels.
|
||||
float t00 = read_sumTex( sumTex, sampler, (int2)(x, y), c_img_rows, c_img_cols, sum_step);
|
||||
float t02 = read_sumTex( sumTex, sampler, (int2)(x, y + r2), c_img_rows, c_img_cols, sum_step);
|
||||
float t04 = read_sumTex( sumTex, sampler, (int2)(x, y + r4), c_img_rows, c_img_cols, sum_step);
|
||||
float t20 = read_sumTex( sumTex, sampler, (int2)(x + r2, y), c_img_rows, c_img_cols, sum_step);
|
||||
float t24 = read_sumTex( sumTex, sampler, (int2)(x + r2, y + r4), c_img_rows, c_img_cols, sum_step);
|
||||
float t40 = read_sumTex( sumTex, sampler, (int2)(x + r4, y), c_img_rows, c_img_cols, sum_step);
|
||||
float t42 = read_sumTex( sumTex, sampler, (int2)(x + r4, y + r2), c_img_rows, c_img_cols, sum_step);
|
||||
float t44 = read_sumTex( sumTex, sampler, (int2)(x + r4, y + r4), c_img_rows, c_img_cols, sum_step);
|
||||
|
||||
F t = t00 - t04 - t20 + t24;
|
||||
X -= t / ((r2) * (r4));
|
||||
|
||||
t = t20 - t24 - t40 + t44;
|
||||
X += t / ((r4 - r2) * (r4));
|
||||
|
||||
t = t00 - t02 - t40 + t42;
|
||||
Y += t / ((r2) * (r4));
|
||||
|
||||
t = t02 - t04 - t42 + t44;
|
||||
Y -= t / ((r4) * (r4 - r2));
|
||||
|
||||
X = apt*X;
|
||||
Y = apt*Y;
|
||||
|
||||
angle = atan2(Y, X);
|
||||
|
||||
@@ -879,76 +927,61 @@ void icvCalcOrientation(
|
||||
angle *= 180.0f / CV_PI_F;
|
||||
|
||||
}
|
||||
|
||||
s_X[i] = X;
|
||||
s_Y[i] = Y;
|
||||
s_angle[i] = angle;
|
||||
}
|
||||
s_X[tid] = X;
|
||||
s_Y[tid] = Y;
|
||||
s_angle[tid] = angle;
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
|
||||
float bestx = 0, besty = 0, best_mod = 0;
|
||||
float sumx = 0.0f, sumy = 0.0f;
|
||||
const int dir = tid * ORI_SEARCH_INC;
|
||||
#pragma unroll
|
||||
for (int i = 0; i < ORI_SAMPLES; ++i) {
|
||||
int angle = round(s_angle[i]);
|
||||
|
||||
#pragma unroll
|
||||
for (int i = 0; i < 18; ++i)
|
||||
{
|
||||
const int dir = (i * 4 + get_local_id(1)) * ORI_SEARCH_INC;
|
||||
int d = abs(angle - dir);
|
||||
if (d < ORI_WIN / 2 || d > 360 - ORI_WIN / 2)
|
||||
{
|
||||
sumx += s_X[i];
|
||||
sumy += s_Y[i];
|
||||
}
|
||||
}
|
||||
s_sumx[tid] = sumx;
|
||||
s_sumy[tid] = sumy;
|
||||
s_mod[tid] = sumx*sumx + sumy*sumy;
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
|
||||
volatile float sumx = 0.0f, sumy = 0.0f;
|
||||
int d = abs(convert_int_rte(s_angle[get_local_id(0)]) - dir);
|
||||
if (d < ORI_WIN / 2 || d > 360 - ORI_WIN / 2)
|
||||
{
|
||||
sumx = s_X[get_local_id(0)];
|
||||
sumy = s_Y[get_local_id(0)];
|
||||
}
|
||||
d = abs(convert_int_rte(s_angle[get_local_id(0) + 32]) - dir);
|
||||
if (d < ORI_WIN / 2 || d > 360 - ORI_WIN / 2)
|
||||
{
|
||||
sumx += s_X[get_local_id(0) + 32];
|
||||
sumy += s_Y[get_local_id(0) + 32];
|
||||
}
|
||||
d = abs(convert_int_rte(s_angle[get_local_id(0) + 64]) - dir);
|
||||
if (d < ORI_WIN / 2 || d > 360 - ORI_WIN / 2)
|
||||
{
|
||||
sumx += s_X[get_local_id(0) + 64];
|
||||
sumy += s_Y[get_local_id(0) + 64];
|
||||
}
|
||||
d = abs(convert_int_rte(s_angle[get_local_id(0) + 96]) - dir);
|
||||
if (d < ORI_WIN / 2 || d > 360 - ORI_WIN / 2)
|
||||
{
|
||||
sumx += s_X[get_local_id(0) + 96];
|
||||
sumy += s_Y[get_local_id(0) + 96];
|
||||
}
|
||||
reduce_32_sum(s_sumx + get_local_id(1) * 32, &sumx, get_local_id(0));
|
||||
reduce_32_sum(s_sumy + get_local_id(1) * 32, &sumy, get_local_id(0));
|
||||
|
||||
const float temp_mod = sumx * sumx + sumy * sumy;
|
||||
if (temp_mod > best_mod)
|
||||
{
|
||||
best_mod = temp_mod;
|
||||
bestx = sumx;
|
||||
besty = sumy;
|
||||
// This reduction searches for the longest wavelet response vector. The first
|
||||
// step uses all of the work items in the workgroup to narrow the search
|
||||
// down to the three candidates. It requires s_mod to have a few more
|
||||
// elements alocated past the work-group size, which are pre-initialized to
|
||||
// 0.0f above.
|
||||
for(int t = ORI_RESPONSE_REDUCTION_WIDTH; t >= 3; t /= 2) {
|
||||
if (tid < t) {
|
||||
if (s_mod[tid] < s_mod[tid + t]) {
|
||||
s_mod[tid] = s_mod[tid + t];
|
||||
s_sumx[tid] = s_sumx[tid + t];
|
||||
s_sumy[tid] = s_sumy[tid + t];
|
||||
}
|
||||
}
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
}
|
||||
if (get_local_id(0) == 0)
|
||||
{
|
||||
s_X[get_local_id(1)] = bestx;
|
||||
s_Y[get_local_id(1)] = besty;
|
||||
s_angle[get_local_id(1)] = best_mod;
|
||||
}
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
|
||||
if (get_local_id(1) == 0 && get_local_id(0) == 0)
|
||||
// Do the final reduction and write out the result.
|
||||
if (tid == 0)
|
||||
{
|
||||
int bestIdx = 0;
|
||||
|
||||
if (s_angle[1] > s_angle[bestIdx])
|
||||
// The loop above narrowed the search of the longest vector to three
|
||||
// possibilities. Pick the best here.
|
||||
if (s_mod[1] > s_mod[bestIdx])
|
||||
bestIdx = 1;
|
||||
if (s_angle[2] > s_angle[bestIdx])
|
||||
if (s_mod[2] > s_mod[bestIdx])
|
||||
bestIdx = 2;
|
||||
if (s_angle[3] > s_angle[bestIdx])
|
||||
bestIdx = 3;
|
||||
|
||||
float kp_dir = atan2(s_Y[bestIdx], s_X[bestIdx]);
|
||||
float kp_dir = atan2(s_sumy[bestIdx], s_sumx[bestIdx]);
|
||||
if (kp_dir < 0)
|
||||
kp_dir += 2.0f * CV_PI_F;
|
||||
kp_dir *= 180.0f / CV_PI_F;
|
||||
@@ -961,7 +994,6 @@ void icvCalcOrientation(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
__kernel
|
||||
void icvSetUpright(
|
||||
__global float * keypoints,
|
||||
@@ -1035,8 +1067,8 @@ inline float linearFilter(
|
||||
|
||||
float out = 0.0f;
|
||||
|
||||
const int x1 = convert_int_rtn(x);
|
||||
const int y1 = convert_int_rtn(y);
|
||||
const int x1 = round(x);
|
||||
const int y1 = round(y);
|
||||
const int x2 = x1 + 1;
|
||||
const int y2 = y1 + 1;
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
#include "opencv2/imgproc/imgproc.hpp"
|
||||
#include "opencv2/core/internal.hpp"
|
||||
|
||||
#if defined(HAVE_OPENCV_GPU)
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
|
||||
#include "opencv2/nonfree/gpu.hpp"
|
||||
|
||||
#if defined(HAVE_CUDA)
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
|
||||
#ifdef HAVE_OPENCV_OCL
|
||||
#include <cstdio>
|
||||
#include <sstream>
|
||||
#include "opencl_kernels.hpp"
|
||||
|
||||
using namespace cv;
|
||||
@@ -55,18 +56,25 @@ namespace cv
|
||||
{
|
||||
namespace ocl
|
||||
{
|
||||
// The number of degrees between orientation samples in calcOrientation
|
||||
const static int ORI_SEARCH_INC = 5;
|
||||
// The local size of the calcOrientation kernel
|
||||
const static int ORI_LOCAL_SIZE = (360 / ORI_SEARCH_INC);
|
||||
|
||||
static void openCLExecuteKernelSURF(Context *clCxt, const cv::ocl::ProgramEntry* source, string kernelName, size_t globalThreads[3],
|
||||
size_t localThreads[3], std::vector< std::pair<size_t, const void *> > &args, int channels, int depth)
|
||||
{
|
||||
char optBuf [100] = {0};
|
||||
char * optBufPtr = optBuf;
|
||||
std::stringstream optsStr;
|
||||
optsStr << "-D ORI_LOCAL_SIZE=" << ORI_LOCAL_SIZE << " ";
|
||||
optsStr << "-D ORI_SEARCH_INC=" << ORI_SEARCH_INC << " ";
|
||||
cl_kernel kernel;
|
||||
kernel = openCLGetKernelFromSource(clCxt, source, kernelName, optBufPtr);
|
||||
kernel = openCLGetKernelFromSource(clCxt, source, kernelName, optsStr.str().c_str());
|
||||
size_t wave_size = queryWaveFrontSize(kernel);
|
||||
CV_Assert(clReleaseKernel(kernel) == CL_SUCCESS);
|
||||
sprintf(optBufPtr, "-D WAVE_SIZE=%d", static_cast<int>(wave_size));
|
||||
openCLExecuteKernel(clCxt, source, kernelName, globalThreads, localThreads, args, channels, depth, optBufPtr);
|
||||
optsStr << "-D WAVE_SIZE=" << wave_size;
|
||||
openCLExecuteKernel(clCxt, source, kernelName, globalThreads, localThreads, args, channels, depth, optsStr.str().c_str());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -594,8 +602,8 @@ void SURF_OCL_Invoker::icvCalcOrientation_gpu(const oclMat &keypoints, int nFeat
|
||||
args.push_back( std::make_pair( sizeof(cl_int), (void *)&img_cols));
|
||||
args.push_back( std::make_pair( sizeof(cl_int), (void *)&surf_.sum.step));
|
||||
|
||||
size_t localThreads[3] = {32, 4, 1};
|
||||
size_t globalThreads[3] = {nFeatures *localThreads[0], localThreads[1], 1};
|
||||
size_t localThreads[3] = {ORI_LOCAL_SIZE, 1, 1};
|
||||
size_t globalThreads[3] = {nFeatures * localThreads[0], 1, 1};
|
||||
|
||||
openCLExecuteKernelSURF(clCxt, &surf, kernelName, globalThreads, localThreads, args, -1, -1);
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
#if defined(HAVE_OPENCV_GPU)
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
|
||||
|
||||
using namespace cv;
|
||||
using namespace cv::gpu;
|
||||
@@ -422,4 +422,4 @@ void cv::gpu::SURF_GPU::releaseMemory()
|
||||
|
||||
#endif // !defined (HAVE_CUDA)
|
||||
|
||||
#endif // defined(HAVE_OPENCV_GPU)
|
||||
#endif // defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
|
||||
|
||||
@@ -335,7 +335,7 @@ icvCreateHidHaarClassifierCascade( CvHaarClassifierCascade* cascade )
|
||||
out->isStumpBased &= node_count == 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
#ifdef HAVE_IPP
|
||||
int can_use_ipp = !out->has_tilted_features && !out->is_tree && out->isStumpBased;
|
||||
|
||||
@@ -391,7 +391,7 @@ icvCreateHidHaarClassifierCascade( CvHaarClassifierCascade* cascade )
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
*/
|
||||
cascade->hid_cascade = out;
|
||||
assert( (char*)haar_node_ptr - (char*)out <= datasize );
|
||||
|
||||
|
||||
@@ -5,4 +5,7 @@ endif()
|
||||
|
||||
set(the_description "OpenCL-accelerated Computer Vision")
|
||||
ocv_define_module(ocl opencv_core opencv_imgproc opencv_features2d opencv_objdetect opencv_video opencv_calib3d opencv_ml "${OPENCL_LIBRARIES}")
|
||||
if(TARGET opencv_test_ocl)
|
||||
target_link_libraries(opencv_test_ocl "${OPENCL_LIBRARIES}")
|
||||
endif()
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wshadow)
|
||||
|
||||
@@ -287,7 +287,7 @@ ocl::createSeparableLinearFilter_GPU
|
||||
----------------------------------------
|
||||
Creates a separable linear filter engine.
|
||||
|
||||
.. ocv:function:: Ptr<FilterEngine_GPU> ocl::createSeparableLinearFilter_GPU(int srcType, int dstType, const Mat &rowKernel, const Mat &columnKernel, const Point &anchor = Point(-1, -1), double delta = 0.0, int bordertype = BORDER_DEFAULT)
|
||||
.. ocv:function:: Ptr<FilterEngine_GPU> ocl::createSeparableLinearFilter_GPU(int srcType, int dstType, const Mat &rowKernel, const Mat &columnKernel, const Point &anchor = Point(-1, -1), double delta = 0.0, int bordertype = BORDER_DEFAULT, Size imgSize = Size(-1,-1) )
|
||||
|
||||
:param srcType: Source array type. ``CV_8UC1`` , ``CV_8UC4`` , ``CV_16SC1`` , ``CV_16SC2`` , ``CV_16SC3`` , ``CV_32SC1`` , ``CV_32FC1`` source types are supported.
|
||||
|
||||
@@ -303,6 +303,8 @@ Creates a separable linear filter engine.
|
||||
|
||||
:param bordertype: Pixel extrapolation method.
|
||||
|
||||
:param imgSize: Source image size to choose optimal method for processing.
|
||||
|
||||
.. seealso:: :ocv:func:`ocl::getLinearRowFilter_GPU`, :ocv:func:`ocl::getLinearColumnFilter_GPU`, :ocv:func:`createSeparableLinearFilter`
|
||||
|
||||
|
||||
@@ -334,7 +336,7 @@ ocl::createDerivFilter_GPU
|
||||
------------------------------
|
||||
Creates a filter engine for the generalized Sobel operator.
|
||||
|
||||
.. ocv:function:: Ptr<FilterEngine_GPU> ocl::createDerivFilter_GPU( int srcType, int dstType, int dx, int dy, int ksize, int borderType = BORDER_DEFAULT )
|
||||
.. ocv:function:: Ptr<FilterEngine_GPU> ocl::createDerivFilter_GPU( int srcType, int dstType, int dx, int dy, int ksize, int borderType = BORDER_DEFAULT, Size imgSize = Size(-1,-1) )
|
||||
|
||||
:param srcType: Source image type. ``CV_8UC1`` , ``CV_8UC4`` , ``CV_16SC1`` , ``CV_16SC2`` , ``CV_16SC3`` , ``CV_32SC1`` , ``CV_32FC1`` source types are supported.
|
||||
|
||||
@@ -348,6 +350,8 @@ Creates a filter engine for the generalized Sobel operator.
|
||||
|
||||
:param borderType: Pixel extrapolation method. For details, see :ocv:func:`borderInterpolate`.
|
||||
|
||||
:param imgSize: Source image size to choose optimal method for processing.
|
||||
|
||||
.. seealso:: :ocv:func:`ocl::createSeparableLinearFilter_GPU`, :ocv:func:`createDerivFilter`
|
||||
|
||||
|
||||
@@ -405,7 +409,7 @@ ocl::createGaussianFilter_GPU
|
||||
---------------------------------
|
||||
Creates a Gaussian filter engine.
|
||||
|
||||
.. ocv:function:: Ptr<FilterEngine_GPU> ocl::createGaussianFilter_GPU(int type, Size ksize, double sigma1, double sigma2 = 0, int bordertype = BORDER_DEFAULT)
|
||||
.. ocv:function:: Ptr<FilterEngine_GPU> ocl::createGaussianFilter_GPU(int type, Size ksize, double sigma1, double sigma2 = 0, int bordertype = BORDER_DEFAULT, Size imgSize = Size(-1,-1) )
|
||||
|
||||
:param type: Source and destination image type. ``CV_8UC1`` , ``CV_8UC4`` , ``CV_16SC1`` , ``CV_16SC2`` , ``CV_16SC3`` , ``CV_32SC1`` , ``CV_32FC1`` are supported.
|
||||
|
||||
@@ -417,6 +421,8 @@ Creates a Gaussian filter engine.
|
||||
|
||||
:param bordertype: Pixel extrapolation method. For details, see :ocv:func:`borderInterpolate`.
|
||||
|
||||
:param imgSize: Source image size to choose optimal method for processing.
|
||||
|
||||
.. seealso:: :ocv:func:`ocl::createSeparableLinearFilter_GPU`, :ocv:func:`createGaussianFilter`
|
||||
|
||||
ocl::GaussianBlur
|
||||
|
||||
@@ -25,12 +25,26 @@ Returns the list of devices
|
||||
|
||||
ocl::setDevice
|
||||
--------------
|
||||
Returns void
|
||||
Initialize OpenCL computation context
|
||||
|
||||
.. ocv:function:: void ocl::setDevice( const DeviceInfo* info )
|
||||
|
||||
:param info: device info
|
||||
|
||||
ocl::initializeContext
|
||||
--------------------------------
|
||||
Alternative way to initialize OpenCL computation context.
|
||||
|
||||
.. ocv:function:: void ocl::initializeContext(void* pClPlatform, void* pClContext, void* pClDevice)
|
||||
|
||||
:param pClPlatform: selected ``platform_id`` (via pointer, parameter type is ``cl_platform_id*``)
|
||||
|
||||
:param pClContext: selected ``cl_context`` (via pointer, parameter type is ``cl_context*``)
|
||||
|
||||
:param pClDevice: selected ``cl_device_id`` (via pointer, parameter type is ``cl_device_id*``)
|
||||
|
||||
This function can be used for context initialization with D3D/OpenGL interoperability.
|
||||
|
||||
ocl::setBinaryPath
|
||||
------------------
|
||||
Returns void
|
||||
|
||||
@@ -175,6 +175,7 @@ namespace cv
|
||||
data = m.data;
|
||||
datastart = m.datastart;
|
||||
dataend = m.dataend;
|
||||
clCxt = m.clCxt;
|
||||
wholerows = m.wholerows;
|
||||
wholecols = m.wholecols;
|
||||
offset = m.offset;
|
||||
|
||||
@@ -118,6 +118,7 @@ namespace cv
|
||||
const PlatformInfo* platform;
|
||||
|
||||
DeviceInfo();
|
||||
~DeviceInfo();
|
||||
};
|
||||
|
||||
struct PlatformInfo
|
||||
@@ -136,6 +137,7 @@ namespace cv
|
||||
std::vector<const DeviceInfo*> devices;
|
||||
|
||||
PlatformInfo();
|
||||
~PlatformInfo();
|
||||
};
|
||||
|
||||
//////////////////////////////// Initialization & Info ////////////////////////
|
||||
@@ -151,6 +153,10 @@ namespace cv
|
||||
// set device you want to use
|
||||
CV_EXPORTS void setDevice(const DeviceInfo* info);
|
||||
|
||||
// Initialize from OpenCL handles directly.
|
||||
// Argument types is (pointers): cl_platform_id*, cl_context*, cl_device_id*
|
||||
CV_EXPORTS void initializeContext(void* pClPlatform, void* pClContext, void* pClDevice);
|
||||
|
||||
//////////////////////////////// Error handling ////////////////////////
|
||||
CV_EXPORTS void error(const char *error_string, const char *file, const int line, const char *func);
|
||||
|
||||
@@ -700,17 +706,17 @@ namespace cv
|
||||
|
||||
//! returns the separable linear filter engine
|
||||
CV_EXPORTS Ptr<FilterEngine_GPU> createSeparableLinearFilter_GPU(int srcType, int dstType, const Mat &rowKernel,
|
||||
const Mat &columnKernel, const Point &anchor = Point(-1, -1), double delta = 0.0, int bordertype = BORDER_DEFAULT);
|
||||
const Mat &columnKernel, const Point &anchor = Point(-1, -1), double delta = 0.0, int bordertype = BORDER_DEFAULT, Size imgSize = Size(-1,-1));
|
||||
|
||||
//! returns the separable filter engine with the specified filters
|
||||
CV_EXPORTS Ptr<FilterEngine_GPU> createSeparableFilter_GPU(const Ptr<BaseRowFilter_GPU> &rowFilter,
|
||||
const Ptr<BaseColumnFilter_GPU> &columnFilter);
|
||||
|
||||
//! returns the Gaussian filter engine
|
||||
CV_EXPORTS Ptr<FilterEngine_GPU> createGaussianFilter_GPU(int type, Size ksize, double sigma1, double sigma2 = 0, int bordertype = BORDER_DEFAULT);
|
||||
CV_EXPORTS Ptr<FilterEngine_GPU> createGaussianFilter_GPU(int type, Size ksize, double sigma1, double sigma2 = 0, int bordertype = BORDER_DEFAULT, Size imgSize = Size(-1,-1));
|
||||
|
||||
//! returns filter engine for the generalized Sobel operator
|
||||
CV_EXPORTS Ptr<FilterEngine_GPU> createDerivFilter_GPU( int srcType, int dstType, int dx, int dy, int ksize, int borderType = BORDER_DEFAULT );
|
||||
CV_EXPORTS Ptr<FilterEngine_GPU> createDerivFilter_GPU( int srcType, int dstType, int dx, int dy, int ksize, int borderType = BORDER_DEFAULT, Size imgSize = Size(-1,-1) );
|
||||
|
||||
//! applies Laplacian operator to the image
|
||||
// supports only ksize = 1 and ksize = 3
|
||||
@@ -863,7 +869,6 @@ namespace cv
|
||||
CV_EXPORTS void cornerMinEigenVal(const oclMat &src, oclMat &dst, int blockSize, int ksize, int bordertype = cv::BORDER_DEFAULT);
|
||||
CV_EXPORTS void cornerMinEigenVal_dxdy(const oclMat &src, oclMat &dst, oclMat &Dx, oclMat &Dy,
|
||||
int blockSize, int ksize, int bordertype = cv::BORDER_DEFAULT);
|
||||
|
||||
/////////////////////////////////// ML ///////////////////////////////////////////
|
||||
|
||||
//! Compute closest centers for each lines in source and lable it after center's index
|
||||
@@ -1375,8 +1380,10 @@ namespace cv
|
||||
oclMat Dx_;
|
||||
oclMat Dy_;
|
||||
oclMat eig_;
|
||||
oclMat eig_minmax_;
|
||||
oclMat minMaxbuf_;
|
||||
oclMat tmpCorners_;
|
||||
oclMat counter_;
|
||||
};
|
||||
|
||||
inline GoodFeaturesToTrackDetector_OCL::GoodFeaturesToTrackDetector_OCL(int maxCorners_, double qualityLevel_, double minDistance_,
|
||||
|
||||
+325
-186
@@ -57,6 +57,12 @@
|
||||
namespace cv {
|
||||
namespace ocl {
|
||||
|
||||
using namespace cl_utils;
|
||||
|
||||
#if defined(WIN32)
|
||||
static bool __termination = false;
|
||||
#endif
|
||||
|
||||
struct __Module
|
||||
{
|
||||
__Module();
|
||||
@@ -71,36 +77,10 @@ cv::Mutex& getInitializationMutex()
|
||||
return __module.initializationMutex;
|
||||
}
|
||||
|
||||
|
||||
struct PlatformInfoImpl
|
||||
static cv::Mutex& getCurrentContextMutex()
|
||||
{
|
||||
cl_platform_id platform_id;
|
||||
|
||||
std::vector<int> deviceIDs;
|
||||
|
||||
PlatformInfo info;
|
||||
|
||||
PlatformInfoImpl()
|
||||
: platform_id(NULL)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct DeviceInfoImpl
|
||||
{
|
||||
cl_platform_id platform_id;
|
||||
cl_device_id device_id;
|
||||
|
||||
DeviceInfo info;
|
||||
|
||||
DeviceInfoImpl()
|
||||
: platform_id(NULL), device_id(NULL)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static std::vector<PlatformInfoImpl> global_platforms;
|
||||
static std::vector<DeviceInfoImpl> global_devices;
|
||||
return __module.currentContextMutex;
|
||||
}
|
||||
|
||||
static bool parseOpenCLVersion(const std::string& versionStr, int& major, int& minor)
|
||||
{
|
||||
@@ -131,6 +111,141 @@ static bool parseOpenCLVersion(const std::string& versionStr, int& major, int& m
|
||||
return true;
|
||||
}
|
||||
|
||||
struct PlatformInfoImpl : public PlatformInfo
|
||||
{
|
||||
cl_platform_id platform_id;
|
||||
|
||||
std::vector<int> deviceIDs;
|
||||
|
||||
PlatformInfoImpl()
|
||||
: platform_id(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
void init(int id, cl_platform_id platform)
|
||||
{
|
||||
CV_Assert(platform_id == NULL);
|
||||
|
||||
this->_id = id;
|
||||
platform_id = platform;
|
||||
|
||||
openCLSafeCall(getStringInfo(clGetPlatformInfo, platform, CL_PLATFORM_PROFILE, this->platformProfile));
|
||||
openCLSafeCall(getStringInfo(clGetPlatformInfo, platform, CL_PLATFORM_VERSION, this->platformVersion));
|
||||
openCLSafeCall(getStringInfo(clGetPlatformInfo, platform, CL_PLATFORM_NAME, this->platformName));
|
||||
openCLSafeCall(getStringInfo(clGetPlatformInfo, platform, CL_PLATFORM_VENDOR, this->platformVendor));
|
||||
openCLSafeCall(getStringInfo(clGetPlatformInfo, platform, CL_PLATFORM_EXTENSIONS, this->platformExtensons));
|
||||
|
||||
parseOpenCLVersion(this->platformVersion,
|
||||
this->platformVersionMajor, this->platformVersionMinor);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct DeviceInfoImpl: public DeviceInfo
|
||||
{
|
||||
cl_platform_id platform_id;
|
||||
cl_device_id device_id;
|
||||
|
||||
DeviceInfoImpl()
|
||||
: platform_id(NULL), device_id(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
void init(int id, PlatformInfoImpl& platformInfoImpl, cl_device_id device)
|
||||
{
|
||||
CV_Assert(device_id == NULL);
|
||||
|
||||
this->_id = id;
|
||||
platform_id = platformInfoImpl.platform_id;
|
||||
device_id = device;
|
||||
|
||||
this->platform = &platformInfoImpl;
|
||||
|
||||
cl_device_type type = cl_device_type(-1);
|
||||
openCLSafeCall(getScalarInfo(clGetDeviceInfo, device, CL_DEVICE_TYPE, type));
|
||||
this->deviceType = DeviceType(type);
|
||||
|
||||
openCLSafeCall(getStringInfo(clGetDeviceInfo, device, CL_DEVICE_PROFILE, this->deviceProfile));
|
||||
openCLSafeCall(getStringInfo(clGetDeviceInfo, device, CL_DEVICE_VERSION, this->deviceVersion));
|
||||
openCLSafeCall(getStringInfo(clGetDeviceInfo, device, CL_DEVICE_NAME, this->deviceName));
|
||||
openCLSafeCall(getStringInfo(clGetDeviceInfo, device, CL_DEVICE_VENDOR, this->deviceVendor));
|
||||
cl_uint vendorID = 0;
|
||||
openCLSafeCall(getScalarInfo(clGetDeviceInfo, device, CL_DEVICE_VENDOR_ID, vendorID));
|
||||
this->deviceVendorId = vendorID;
|
||||
openCLSafeCall(getStringInfo(clGetDeviceInfo, device, CL_DRIVER_VERSION, this->deviceDriverVersion));
|
||||
openCLSafeCall(getStringInfo(clGetDeviceInfo, device, CL_DEVICE_EXTENSIONS, this->deviceExtensions));
|
||||
|
||||
parseOpenCLVersion(this->deviceVersion,
|
||||
this->deviceVersionMajor, this->deviceVersionMinor);
|
||||
|
||||
size_t maxWorkGroupSize = 0;
|
||||
openCLSafeCall(getScalarInfo(clGetDeviceInfo, device, CL_DEVICE_MAX_WORK_GROUP_SIZE, maxWorkGroupSize));
|
||||
this->maxWorkGroupSize = maxWorkGroupSize;
|
||||
|
||||
cl_uint maxDimensions = 0;
|
||||
openCLSafeCall(getScalarInfo(clGetDeviceInfo, device, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, maxDimensions));
|
||||
std::vector<size_t> maxWorkItemSizes(maxDimensions);
|
||||
openCLSafeCall(clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_ITEM_SIZES, sizeof(size_t) * maxDimensions,
|
||||
(void *)&maxWorkItemSizes[0], 0));
|
||||
this->maxWorkItemSizes = maxWorkItemSizes;
|
||||
|
||||
cl_uint maxComputeUnits = 0;
|
||||
openCLSafeCall(getScalarInfo(clGetDeviceInfo, device, CL_DEVICE_MAX_COMPUTE_UNITS, maxComputeUnits));
|
||||
this->maxComputeUnits = maxComputeUnits;
|
||||
|
||||
cl_ulong localMemorySize = 0;
|
||||
openCLSafeCall(getScalarInfo(clGetDeviceInfo, device, CL_DEVICE_LOCAL_MEM_SIZE, localMemorySize));
|
||||
this->localMemorySize = (size_t)localMemorySize;
|
||||
|
||||
cl_ulong maxMemAllocSize = 0;
|
||||
openCLSafeCall(getScalarInfo(clGetDeviceInfo, device, CL_DEVICE_MAX_MEM_ALLOC_SIZE, maxMemAllocSize));
|
||||
this->maxMemAllocSize = (size_t)maxMemAllocSize;
|
||||
|
||||
cl_bool unifiedMemory = false;
|
||||
openCLSafeCall(getScalarInfo(clGetDeviceInfo, device, CL_DEVICE_HOST_UNIFIED_MEMORY, unifiedMemory));
|
||||
this->isUnifiedMemory = unifiedMemory != 0;
|
||||
|
||||
//initialize extra options for compilation. Currently only fp64 is included.
|
||||
//Assume 4KB is enough to store all possible extensions.
|
||||
openCLSafeCall(getStringInfo(clGetDeviceInfo, device, CL_DEVICE_EXTENSIONS, this->deviceExtensions));
|
||||
|
||||
size_t fp64_khr = this->deviceExtensions.find("cl_khr_fp64");
|
||||
if(fp64_khr != std::string::npos)
|
||||
{
|
||||
this->compilationExtraOptions += "-D DOUBLE_SUPPORT";
|
||||
this->haveDoubleSupport = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->haveDoubleSupport = false;
|
||||
}
|
||||
|
||||
size_t intel_platform = platformInfoImpl.platformVendor.find("Intel");
|
||||
if(intel_platform != std::string::npos)
|
||||
{
|
||||
this->compilationExtraOptions += " -D INTEL_DEVICE";
|
||||
this->isIntelDevice = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->isIntelDevice = false;
|
||||
}
|
||||
|
||||
if (id < 0)
|
||||
{
|
||||
#ifdef CL_VERSION_1_2
|
||||
if (this->deviceVersionMajor > 1 || (this->deviceVersionMajor == 1 && this->deviceVersionMinor >= 2))
|
||||
{
|
||||
::clRetainDevice(device);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static std::vector<PlatformInfoImpl> global_platforms;
|
||||
static std::vector<DeviceInfoImpl> global_devices;
|
||||
|
||||
static void split(const std::string &s, char delim, std::vector<std::string> &elems) {
|
||||
std::stringstream ss(s);
|
||||
std::string item;
|
||||
@@ -329,8 +444,6 @@ not_found:
|
||||
static bool __initialized = false;
|
||||
static int initializeOpenCLDevices()
|
||||
{
|
||||
using namespace cl_utils;
|
||||
|
||||
assert(!__initialized);
|
||||
__initialized = true;
|
||||
|
||||
@@ -351,19 +464,9 @@ static int initializeOpenCLDevices()
|
||||
for (size_t i = 0; i < platforms.size(); ++i)
|
||||
{
|
||||
PlatformInfoImpl& platformInfo = global_platforms[i];
|
||||
platformInfo.info._id = i;
|
||||
|
||||
cl_platform_id platform = platforms[i];
|
||||
|
||||
platformInfo.platform_id = platform;
|
||||
openCLSafeCall(getStringInfo(clGetPlatformInfo, platform, CL_PLATFORM_PROFILE, platformInfo.info.platformProfile));
|
||||
openCLSafeCall(getStringInfo(clGetPlatformInfo, platform, CL_PLATFORM_VERSION, platformInfo.info.platformVersion));
|
||||
openCLSafeCall(getStringInfo(clGetPlatformInfo, platform, CL_PLATFORM_NAME, platformInfo.info.platformName));
|
||||
openCLSafeCall(getStringInfo(clGetPlatformInfo, platform, CL_PLATFORM_VENDOR, platformInfo.info.platformVendor));
|
||||
openCLSafeCall(getStringInfo(clGetPlatformInfo, platform, CL_PLATFORM_EXTENSIONS, platformInfo.info.platformExtensons));
|
||||
|
||||
parseOpenCLVersion(platformInfo.info.platformVersion,
|
||||
platformInfo.info.platformVersionMajor, platformInfo.info.platformVersionMinor);
|
||||
platformInfo.init(i, platform);
|
||||
|
||||
std::vector<cl_device_id> devices;
|
||||
cl_int status = getDevices(platform, CL_DEVICE_TYPE_ALL, devices);
|
||||
@@ -375,89 +478,15 @@ static int initializeOpenCLDevices()
|
||||
int baseIndx = global_devices.size();
|
||||
global_devices.resize(baseIndx + devices.size());
|
||||
platformInfo.deviceIDs.resize(devices.size());
|
||||
platformInfo.info.devices.resize(devices.size());
|
||||
platformInfo.devices.resize(devices.size());
|
||||
|
||||
for(size_t j = 0; j < devices.size(); ++j)
|
||||
{
|
||||
cl_device_id device = devices[j];
|
||||
|
||||
DeviceInfoImpl& deviceInfo = global_devices[baseIndx + j];
|
||||
deviceInfo.info._id = baseIndx + j;
|
||||
deviceInfo.platform_id = platform;
|
||||
deviceInfo.device_id = device;
|
||||
|
||||
deviceInfo.info.platform = &platformInfo.info;
|
||||
platformInfo.deviceIDs[j] = deviceInfo.info._id;
|
||||
|
||||
cl_device_type type = cl_device_type(-1);
|
||||
openCLSafeCall(getScalarInfo(clGetDeviceInfo, device, CL_DEVICE_TYPE, type));
|
||||
deviceInfo.info.deviceType = DeviceType(type);
|
||||
|
||||
openCLSafeCall(getStringInfo(clGetDeviceInfo, device, CL_DEVICE_PROFILE, deviceInfo.info.deviceProfile));
|
||||
openCLSafeCall(getStringInfo(clGetDeviceInfo, device, CL_DEVICE_VERSION, deviceInfo.info.deviceVersion));
|
||||
openCLSafeCall(getStringInfo(clGetDeviceInfo, device, CL_DEVICE_NAME, deviceInfo.info.deviceName));
|
||||
openCLSafeCall(getStringInfo(clGetDeviceInfo, device, CL_DEVICE_VENDOR, deviceInfo.info.deviceVendor));
|
||||
cl_uint vendorID = 0;
|
||||
openCLSafeCall(getScalarInfo(clGetDeviceInfo, device, CL_DEVICE_VENDOR_ID, vendorID));
|
||||
deviceInfo.info.deviceVendorId = vendorID;
|
||||
openCLSafeCall(getStringInfo(clGetDeviceInfo, device, CL_DRIVER_VERSION, deviceInfo.info.deviceDriverVersion));
|
||||
openCLSafeCall(getStringInfo(clGetDeviceInfo, device, CL_DEVICE_EXTENSIONS, deviceInfo.info.deviceExtensions));
|
||||
|
||||
parseOpenCLVersion(deviceInfo.info.deviceVersion,
|
||||
deviceInfo.info.deviceVersionMajor, deviceInfo.info.deviceVersionMinor);
|
||||
|
||||
size_t maxWorkGroupSize = 0;
|
||||
openCLSafeCall(getScalarInfo(clGetDeviceInfo, device, CL_DEVICE_MAX_WORK_GROUP_SIZE, maxWorkGroupSize));
|
||||
deviceInfo.info.maxWorkGroupSize = maxWorkGroupSize;
|
||||
|
||||
cl_uint maxDimensions = 0;
|
||||
openCLSafeCall(getScalarInfo(clGetDeviceInfo, device, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, maxDimensions));
|
||||
std::vector<size_t> maxWorkItemSizes(maxDimensions);
|
||||
openCLSafeCall(clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_ITEM_SIZES, sizeof(size_t) * maxDimensions,
|
||||
(void *)&maxWorkItemSizes[0], 0));
|
||||
deviceInfo.info.maxWorkItemSizes = maxWorkItemSizes;
|
||||
|
||||
cl_uint maxComputeUnits = 0;
|
||||
openCLSafeCall(getScalarInfo(clGetDeviceInfo, device, CL_DEVICE_MAX_COMPUTE_UNITS, maxComputeUnits));
|
||||
deviceInfo.info.maxComputeUnits = maxComputeUnits;
|
||||
|
||||
cl_ulong localMemorySize = 0;
|
||||
openCLSafeCall(getScalarInfo(clGetDeviceInfo, device, CL_DEVICE_LOCAL_MEM_SIZE, localMemorySize));
|
||||
deviceInfo.info.localMemorySize = (size_t)localMemorySize;
|
||||
|
||||
cl_ulong maxMemAllocSize = 0;
|
||||
openCLSafeCall(getScalarInfo(clGetDeviceInfo, device, CL_DEVICE_MAX_MEM_ALLOC_SIZE, maxMemAllocSize));
|
||||
deviceInfo.info.maxMemAllocSize = (size_t)maxMemAllocSize;
|
||||
|
||||
cl_bool unifiedMemory = false;
|
||||
openCLSafeCall(getScalarInfo(clGetDeviceInfo, device, CL_DEVICE_HOST_UNIFIED_MEMORY, unifiedMemory));
|
||||
deviceInfo.info.isUnifiedMemory = unifiedMemory != 0;
|
||||
|
||||
//initialize extra options for compilation. Currently only fp64 is included.
|
||||
//Assume 4KB is enough to store all possible extensions.
|
||||
openCLSafeCall(getStringInfo(clGetDeviceInfo, device, CL_DEVICE_EXTENSIONS, deviceInfo.info.deviceExtensions));
|
||||
|
||||
size_t fp64_khr = deviceInfo.info.deviceExtensions.find("cl_khr_fp64");
|
||||
if(fp64_khr != std::string::npos)
|
||||
{
|
||||
deviceInfo.info.compilationExtraOptions += "-D DOUBLE_SUPPORT";
|
||||
deviceInfo.info.haveDoubleSupport = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
deviceInfo.info.haveDoubleSupport = false;
|
||||
}
|
||||
|
||||
size_t intel_platform = platformInfo.info.platformVendor.find("Intel");
|
||||
if(intel_platform != std::string::npos)
|
||||
{
|
||||
deviceInfo.info.compilationExtraOptions += " -D INTEL_DEVICE";
|
||||
deviceInfo.info.isIntelDevice = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
deviceInfo.info.isIntelDevice = false;
|
||||
}
|
||||
platformInfo.deviceIDs[j] = baseIndx + j;
|
||||
deviceInfo.init(baseIndx + j, platformInfo, device);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -468,7 +497,7 @@ static int initializeOpenCLDevices()
|
||||
for(size_t j = 0; j < platformInfo.deviceIDs.size(); ++j)
|
||||
{
|
||||
DeviceInfoImpl& deviceInfo = global_devices[platformInfo.deviceIDs[j]];
|
||||
platformInfo.info.devices[j] = &deviceInfo.info;
|
||||
platformInfo.devices[j] = &deviceInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -487,6 +516,8 @@ DeviceInfo::DeviceInfo()
|
||||
// nothing
|
||||
}
|
||||
|
||||
DeviceInfo::~DeviceInfo() { }
|
||||
|
||||
PlatformInfo::PlatformInfo()
|
||||
: _id(-1),
|
||||
platformVersionMajor(0), platformVersionMinor(0)
|
||||
@@ -494,40 +525,135 @@ PlatformInfo::PlatformInfo()
|
||||
// nothing
|
||||
}
|
||||
|
||||
PlatformInfo::~PlatformInfo() { }
|
||||
|
||||
class ContextImpl;
|
||||
|
||||
struct CommandQueue
|
||||
{
|
||||
ContextImpl* context_;
|
||||
cl_command_queue clQueue_;
|
||||
|
||||
CommandQueue() : context_(NULL), clQueue_(NULL) { }
|
||||
~CommandQueue() { release(); }
|
||||
|
||||
void create(ContextImpl* context_);
|
||||
void release()
|
||||
{
|
||||
#ifdef WIN32
|
||||
// if process is on termination stage (ExitProcess was called and other threads were terminated)
|
||||
// then disable command queue release because it may cause program hang
|
||||
if (!__termination)
|
||||
#endif
|
||||
{
|
||||
if(clQueue_)
|
||||
{
|
||||
openCLSafeCall(clReleaseCommandQueue(clQueue_)); // some cleanup problems are here
|
||||
}
|
||||
|
||||
}
|
||||
clQueue_ = NULL;
|
||||
context_ = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
cv::TLSData<CommandQueue> commandQueueTLSData;
|
||||
|
||||
//////////////////////////////// OpenCL context ////////////////////////
|
||||
//This is a global singleton class used to represent a OpenCL context.
|
||||
class ContextImpl : public Context
|
||||
{
|
||||
public:
|
||||
const cl_device_id clDeviceID;
|
||||
cl_device_id clDeviceID;
|
||||
cl_context clContext;
|
||||
cl_command_queue clCmdQueue;
|
||||
const DeviceInfo& deviceInfo;
|
||||
const DeviceInfoImpl& deviceInfoImpl;
|
||||
|
||||
protected:
|
||||
ContextImpl(const DeviceInfo& deviceInfo, cl_device_id clDeviceID)
|
||||
: clDeviceID(clDeviceID), clContext(NULL), clCmdQueue(NULL), deviceInfo(deviceInfo)
|
||||
ContextImpl(const DeviceInfoImpl& _deviceInfoImpl, cl_context context)
|
||||
: clDeviceID(_deviceInfoImpl.device_id), clContext(context), deviceInfoImpl(_deviceInfoImpl)
|
||||
{
|
||||
// nothing
|
||||
#ifdef CL_VERSION_1_2
|
||||
if (supportsFeature(FEATURE_CL_VER_1_2))
|
||||
{
|
||||
openCLSafeCall(clRetainDevice(clDeviceID));
|
||||
}
|
||||
#endif
|
||||
openCLSafeCall(clRetainContext(clContext));
|
||||
|
||||
ContextImpl* old = NULL;
|
||||
{
|
||||
cv::AutoLock lock(getCurrentContextMutex());
|
||||
old = currentContext;
|
||||
currentContext = this;
|
||||
}
|
||||
if (old != NULL)
|
||||
{
|
||||
delete old;
|
||||
}
|
||||
}
|
||||
~ContextImpl()
|
||||
{
|
||||
CV_Assert(this != currentContext);
|
||||
|
||||
#ifdef CL_VERSION_1_2
|
||||
if (supportsFeature(FEATURE_CL_VER_1_2))
|
||||
{
|
||||
openCLSafeCall(clReleaseDevice(clDeviceID));
|
||||
}
|
||||
#endif
|
||||
if (deviceInfoImpl._id < 0) // not in the global registry, so we should cleanup it
|
||||
{
|
||||
#ifdef CL_VERSION_1_2
|
||||
if (supportsFeature(FEATURE_CL_VER_1_2))
|
||||
{
|
||||
openCLSafeCall(clReleaseDevice(deviceInfoImpl.device_id));
|
||||
}
|
||||
#endif
|
||||
PlatformInfoImpl* platformImpl = (PlatformInfoImpl*)(deviceInfoImpl.platform);
|
||||
delete platformImpl;
|
||||
delete const_cast<DeviceInfoImpl*>(&deviceInfoImpl);
|
||||
}
|
||||
clDeviceID = NULL;
|
||||
|
||||
#ifdef WIN32
|
||||
// if process is on termination stage (ExitProcess was called and other threads were terminated)
|
||||
// then disable command queue release because it may cause program hang
|
||||
if (!__termination)
|
||||
#endif
|
||||
{
|
||||
if(clContext)
|
||||
{
|
||||
openCLSafeCall(clReleaseContext(clContext));
|
||||
}
|
||||
}
|
||||
clContext = NULL;
|
||||
}
|
||||
~ContextImpl();
|
||||
public:
|
||||
static void setContext(const DeviceInfo* deviceInfo);
|
||||
static void initializeContext(void* pClPlatform, void* pClContext, void* pClDevice);
|
||||
|
||||
bool supportsFeature(FEATURE_TYPE featureType) const;
|
||||
|
||||
static void cleanupContext(void);
|
||||
|
||||
static ContextImpl* getContext();
|
||||
private:
|
||||
ContextImpl(const ContextImpl&); // disabled
|
||||
ContextImpl& operator=(const ContextImpl&); // disabled
|
||||
|
||||
static ContextImpl* currentContext;
|
||||
};
|
||||
|
||||
static ContextImpl* currentContext = NULL;
|
||||
ContextImpl* ContextImpl::currentContext = NULL;
|
||||
|
||||
static bool __deviceSelected = false;
|
||||
|
||||
Context* Context::getContext()
|
||||
{
|
||||
return ContextImpl::getContext();
|
||||
}
|
||||
|
||||
ContextImpl* ContextImpl::getContext()
|
||||
{
|
||||
if (currentContext == NULL)
|
||||
{
|
||||
@@ -571,7 +697,7 @@ bool Context::supportsFeature(FEATURE_TYPE featureType) const
|
||||
|
||||
const DeviceInfo& Context::getDeviceInfo() const
|
||||
{
|
||||
return ((ContextImpl*)this)->deviceInfo;
|
||||
return ((ContextImpl*)this)->deviceInfoImpl;
|
||||
}
|
||||
|
||||
const void* Context::getOpenCLContextPtr() const
|
||||
@@ -581,7 +707,13 @@ const void* Context::getOpenCLContextPtr() const
|
||||
|
||||
const void* Context::getOpenCLCommandQueuePtr() const
|
||||
{
|
||||
return &(((ContextImpl*)this)->clCmdQueue);
|
||||
ContextImpl* pThis = (ContextImpl*)this;
|
||||
CommandQueue* commandQueue = commandQueueTLSData.get();
|
||||
if (commandQueue->context_ != pThis)
|
||||
{
|
||||
commandQueue->create(pThis);
|
||||
}
|
||||
return &commandQueue->clQueue_;
|
||||
}
|
||||
|
||||
const void* Context::getOpenCLDeviceIDPtr() const
|
||||
@@ -595,44 +727,18 @@ bool ContextImpl::supportsFeature(FEATURE_TYPE featureType) const
|
||||
switch (featureType)
|
||||
{
|
||||
case FEATURE_CL_INTEL_DEVICE:
|
||||
return deviceInfo.isIntelDevice;
|
||||
return deviceInfoImpl.isIntelDevice;
|
||||
case FEATURE_CL_DOUBLE:
|
||||
return deviceInfo.haveDoubleSupport;
|
||||
return deviceInfoImpl.haveDoubleSupport;
|
||||
case FEATURE_CL_UNIFIED_MEM:
|
||||
return deviceInfo.isUnifiedMemory;
|
||||
return deviceInfoImpl.isUnifiedMemory;
|
||||
case FEATURE_CL_VER_1_2:
|
||||
return deviceInfo.deviceVersionMajor > 1 || (deviceInfo.deviceVersionMajor == 1 && deviceInfo.deviceVersionMinor >= 2);
|
||||
return deviceInfoImpl.deviceVersionMajor > 1 || (deviceInfoImpl.deviceVersionMajor == 1 && deviceInfoImpl.deviceVersionMinor >= 2);
|
||||
}
|
||||
CV_Error(CV_StsBadArg, "Invalid feature type");
|
||||
return false;
|
||||
}
|
||||
|
||||
#if defined(WIN32)
|
||||
static bool __termination = false;
|
||||
#endif
|
||||
|
||||
ContextImpl::~ContextImpl()
|
||||
{
|
||||
#ifdef WIN32
|
||||
// if process is on termination stage (ExitProcess was called and other threads were terminated)
|
||||
// then disable command queue release because it may cause program hang
|
||||
if (!__termination)
|
||||
#endif
|
||||
{
|
||||
if(clCmdQueue)
|
||||
{
|
||||
openCLSafeCall(clReleaseCommandQueue(clCmdQueue)); // some cleanup problems are here
|
||||
}
|
||||
|
||||
if(clContext)
|
||||
{
|
||||
openCLSafeCall(clReleaseContext(clContext));
|
||||
}
|
||||
}
|
||||
clCmdQueue = NULL;
|
||||
clContext = NULL;
|
||||
}
|
||||
|
||||
void fft_teardown();
|
||||
void clBlasTeardown();
|
||||
|
||||
@@ -641,50 +747,69 @@ void ContextImpl::cleanupContext(void)
|
||||
fft_teardown();
|
||||
clBlasTeardown();
|
||||
|
||||
cv::AutoLock lock(__module.currentContextMutex);
|
||||
cv::AutoLock lock(getCurrentContextMutex());
|
||||
if (currentContext)
|
||||
delete currentContext;
|
||||
currentContext = NULL;
|
||||
{
|
||||
ContextImpl* ctx = currentContext;
|
||||
currentContext = NULL;
|
||||
delete ctx;
|
||||
}
|
||||
}
|
||||
|
||||
void ContextImpl::setContext(const DeviceInfo* deviceInfo)
|
||||
{
|
||||
CV_Assert(deviceInfo->_id >= 0 && deviceInfo->_id < (int)global_devices.size());
|
||||
CV_Assert(deviceInfo->_id >= 0); // we can't specify custom devices
|
||||
CV_Assert(deviceInfo->_id < (int)global_devices.size());
|
||||
|
||||
{
|
||||
cv::AutoLock lock(__module.currentContextMutex);
|
||||
cv::AutoLock lock(getCurrentContextMutex());
|
||||
if (currentContext)
|
||||
{
|
||||
if (currentContext->deviceInfo._id == deviceInfo->_id)
|
||||
if (currentContext->deviceInfoImpl._id == deviceInfo->_id)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DeviceInfoImpl& infoImpl = global_devices[deviceInfo->_id];
|
||||
CV_Assert(deviceInfo == &infoImpl.info);
|
||||
CV_Assert(deviceInfo == &infoImpl);
|
||||
|
||||
cl_int status = 0;
|
||||
cl_context_properties cps[3] = { CL_CONTEXT_PLATFORM, (cl_context_properties)(infoImpl.platform_id), 0 };
|
||||
cl_context clContext = clCreateContext(cps, 1, &infoImpl.device_id, NULL, NULL, &status);
|
||||
openCLVerifyCall(status);
|
||||
|
||||
ContextImpl* ctx = new ContextImpl(infoImpl, clContext);
|
||||
clReleaseContext(clContext);
|
||||
(void)ctx;
|
||||
}
|
||||
|
||||
void ContextImpl::initializeContext(void* pClPlatform, void* pClContext, void* pClDevice)
|
||||
{
|
||||
CV_Assert(pClPlatform != NULL);
|
||||
CV_Assert(pClContext != NULL);
|
||||
CV_Assert(pClDevice != NULL);
|
||||
cl_platform_id platform = *(cl_platform_id*)pClPlatform;
|
||||
cl_context context = *(cl_context*)pClContext;
|
||||
cl_device_id device = *(cl_device_id*)pClDevice;
|
||||
|
||||
PlatformInfoImpl* platformInfoImpl = new PlatformInfoImpl();
|
||||
platformInfoImpl->init(-1, platform);
|
||||
DeviceInfoImpl* deviceInfoImpl = new DeviceInfoImpl();
|
||||
deviceInfoImpl->init(-1, *platformInfoImpl, device);
|
||||
|
||||
ContextImpl* ctx = new ContextImpl(*deviceInfoImpl, context);
|
||||
(void)ctx;
|
||||
}
|
||||
|
||||
void CommandQueue::create(ContextImpl* context)
|
||||
{
|
||||
release();
|
||||
cl_int status = 0;
|
||||
// TODO add CL_QUEUE_PROFILING_ENABLE
|
||||
cl_command_queue clCmdQueue = clCreateCommandQueue(clContext, infoImpl.device_id, 0, &status);
|
||||
cl_command_queue clCmdQueue = clCreateCommandQueue(context->clContext, context->clDeviceID, 0, &status);
|
||||
openCLVerifyCall(status);
|
||||
|
||||
ContextImpl* ctx = new ContextImpl(infoImpl.info, infoImpl.device_id);
|
||||
ctx->clCmdQueue = clCmdQueue;
|
||||
ctx->clContext = clContext;
|
||||
|
||||
ContextImpl* old = NULL;
|
||||
{
|
||||
cv::AutoLock lock(__module.currentContextMutex);
|
||||
old = currentContext;
|
||||
currentContext = ctx;
|
||||
}
|
||||
if (old != NULL)
|
||||
{
|
||||
delete old;
|
||||
}
|
||||
context_ = context;
|
||||
clQueue_ = clCmdQueue;
|
||||
}
|
||||
|
||||
int getOpenCLPlatforms(PlatformsInfo& platforms)
|
||||
@@ -697,7 +822,7 @@ int getOpenCLPlatforms(PlatformsInfo& platforms)
|
||||
for (size_t id = 0; id < global_platforms.size(); ++id)
|
||||
{
|
||||
PlatformInfoImpl& impl = global_platforms[id];
|
||||
platforms.push_back(&impl.info);
|
||||
platforms.push_back(&impl);
|
||||
}
|
||||
|
||||
return platforms.size();
|
||||
@@ -727,9 +852,9 @@ int getOpenCLDevices(std::vector<const DeviceInfo*> &devices, int deviceType, co
|
||||
for (size_t id = 0; id < global_devices.size(); ++id)
|
||||
{
|
||||
DeviceInfoImpl& deviceInfo = global_devices[id];
|
||||
if (((int)deviceInfo.info.deviceType & deviceType) != 0)
|
||||
if (((int)deviceInfo.deviceType & deviceType) != 0)
|
||||
{
|
||||
devices.push_back(&deviceInfo.info);
|
||||
devices.push_back(&deviceInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -762,6 +887,20 @@ void setDevice(const DeviceInfo* info)
|
||||
}
|
||||
}
|
||||
|
||||
void initializeContext(void* pClPlatform, void* pClContext, void* pClDevice)
|
||||
{
|
||||
try
|
||||
{
|
||||
ContextImpl::initializeContext(pClPlatform, pClContext, pClDevice);
|
||||
__deviceSelected = true;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
__deviceSelected = true;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
bool supportsFeature(FEATURE_TYPE featureType)
|
||||
{
|
||||
return Context::getContext()->supportsFeature(featureType);
|
||||
|
||||
+168
-18
@@ -56,8 +56,19 @@ static void fromRGB_caller(const oclMat &src, oclMat &dst, int bidx, const std::
|
||||
{
|
||||
int src_offset = src.offset / src.elemSize1(), src_step = src.step1();
|
||||
int dst_offset = dst.offset / dst.elemSize1(), dst_step = dst.step1();
|
||||
int pixels_per_work_item = 1;
|
||||
|
||||
std::string build_options = format("-D DEPTH_%d", src.depth());
|
||||
if (Context::getContext()->supportsFeature(FEATURE_CL_INTEL_DEVICE))
|
||||
{
|
||||
if ((src.cols % 4 == 0) && (src.depth() == CV_8U))
|
||||
pixels_per_work_item = 4;
|
||||
else if (src.cols % 2 == 0)
|
||||
pixels_per_work_item = 2;
|
||||
else
|
||||
pixels_per_work_item = 1;
|
||||
}
|
||||
|
||||
std::string build_options = format("-D DEPTH_%d -D scn=%d -D bidx=%d -D pixels_per_work_item=%d", src.depth(), src.oclchannels(), bidx, pixels_per_work_item);
|
||||
if (!additionalOptions.empty())
|
||||
build_options += additionalOptions;
|
||||
|
||||
@@ -66,7 +77,6 @@ static void fromRGB_caller(const oclMat &src, oclMat &dst, int bidx, const std::
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&dst.rows));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&src_step));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&dst_step));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&bidx));
|
||||
args.push_back( make_pair( sizeof(cl_mem) , (void *)&src.data));
|
||||
args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst.data));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&src_offset ));
|
||||
@@ -77,6 +87,73 @@ static void fromRGB_caller(const oclMat &src, oclMat &dst, int bidx, const std::
|
||||
if (!data2.empty())
|
||||
args.push_back( make_pair( sizeof(cl_mem) , (void *)&data2.data ));
|
||||
|
||||
size_t gt[3] = { dst.cols/pixels_per_work_item, dst.rows, 1 };
|
||||
#ifdef ANDROID
|
||||
size_t lt[3] = { 16, 10, 1 };
|
||||
#else
|
||||
size_t lt[3] = { 16, 16, 1 };
|
||||
#endif
|
||||
openCLExecuteKernel(src.clCxt, &cvt_color, kernelName.c_str(), gt, lt, args, -1, -1, build_options.c_str());
|
||||
}
|
||||
|
||||
static void toHSV_caller(const oclMat &src, oclMat &dst, int bidx, const std::string & kernelName,
|
||||
const std::string & additionalOptions = std::string(),
|
||||
const oclMat & data1 = oclMat(), const oclMat & data2 = oclMat())
|
||||
{
|
||||
int src_offset = src.offset / src.elemSize1(), src_step = src.step1();
|
||||
int dst_offset = dst.offset / dst.elemSize1(), dst_step = dst.step1();
|
||||
|
||||
std::string build_options = format("-D DEPTH_%d -D scn=%d -D bidx=%d", src.depth(), src.oclchannels(), bidx);
|
||||
if (!additionalOptions.empty())
|
||||
build_options += additionalOptions;
|
||||
|
||||
vector<pair<size_t , const void *> > args;
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&dst.cols));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&dst.rows));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&src_step));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&dst_step));
|
||||
args.push_back( make_pair( sizeof(cl_mem) , (void *)&src.data));
|
||||
args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst.data));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&src_offset ));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&dst_offset ));
|
||||
|
||||
if (!data1.empty())
|
||||
args.push_back( make_pair( sizeof(cl_mem) , (void *)&data1.data ));
|
||||
if (!data2.empty())
|
||||
args.push_back( make_pair( sizeof(cl_mem) , (void *)&data2.data ));
|
||||
|
||||
size_t gt[3] = { dst.cols, dst.rows, 1 };
|
||||
#ifdef ANDROID
|
||||
size_t lt[3] = { 16, 10, 1 };
|
||||
#else
|
||||
size_t lt[3] = { 16, 16, 1 };
|
||||
#endif
|
||||
openCLExecuteKernel(src.clCxt, &cvt_color, kernelName.c_str(), gt, lt, args, -1, -1, build_options.c_str());
|
||||
}
|
||||
|
||||
static void fromGray_caller(const oclMat &src, oclMat &dst, int bidx, const std::string & kernelName,
|
||||
const std::string & additionalOptions = std::string(), const oclMat & data = oclMat())
|
||||
{
|
||||
std::string build_options = format("-D DEPTH_%d -D dcn=%d -D bidx=%d", src.depth(), dst.channels(), bidx);
|
||||
if (!additionalOptions.empty())
|
||||
build_options += additionalOptions;
|
||||
|
||||
int src_offset = src.offset / src.elemSize1(), src_step = src.step1();
|
||||
int dst_offset = dst.offset / dst.elemSize1(), dst_step = dst.step1();
|
||||
|
||||
vector<pair<size_t , const void *> > args;
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&dst.cols));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&dst.rows));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&src_step));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&dst_step));
|
||||
args.push_back( make_pair( sizeof(cl_mem) , (void *)&src.data));
|
||||
args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst.data));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&src_offset ));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&dst_offset ));
|
||||
|
||||
if (!data.empty())
|
||||
args.push_back( make_pair( sizeof(cl_mem) , (void *)&data.data ));
|
||||
|
||||
size_t gt[3] = { dst.cols, dst.rows, 1 };
|
||||
#ifdef ANDROID
|
||||
size_t lt[3] = { 16, 10, 1 };
|
||||
@@ -89,7 +166,50 @@ static void fromRGB_caller(const oclMat &src, oclMat &dst, int bidx, const std::
|
||||
static void toRGB_caller(const oclMat &src, oclMat &dst, int bidx, const std::string & kernelName,
|
||||
const std::string & additionalOptions = std::string(), const oclMat & data = oclMat())
|
||||
{
|
||||
std::string build_options = format("-D DEPTH_%d -D dcn=%d", src.depth(), dst.channels());
|
||||
int src_offset = src.offset / src.elemSize1(), src_step = src.step1();
|
||||
int dst_offset = dst.offset / dst.elemSize1(), dst_step = dst.step1();
|
||||
int pixels_per_work_item = 1;
|
||||
|
||||
if (Context::getContext()->supportsFeature(FEATURE_CL_INTEL_DEVICE))
|
||||
{
|
||||
if ((src.cols % 4 == 0) && (src.depth() == CV_8U))
|
||||
pixels_per_work_item = 4;
|
||||
else if (src.cols % 2 == 0)
|
||||
pixels_per_work_item = 2;
|
||||
else
|
||||
pixels_per_work_item = 1;
|
||||
}
|
||||
|
||||
std::string build_options = format("-D DEPTH_%d -D dcn=%d -D bidx=%d -D pixels_per_work_item=%d", src.depth(), dst.channels(), bidx, pixels_per_work_item);
|
||||
if (!additionalOptions.empty())
|
||||
build_options += additionalOptions;
|
||||
|
||||
vector<pair<size_t , const void *> > args;
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&dst.cols));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&dst.rows));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&src_step));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&dst_step));
|
||||
args.push_back( make_pair( sizeof(cl_mem) , (void *)&src.data));
|
||||
args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst.data));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&src_offset ));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&dst_offset ));
|
||||
|
||||
if (!data.empty())
|
||||
args.push_back( make_pair( sizeof(cl_mem) , (void *)&data.data ));
|
||||
|
||||
size_t gt[3] = { dst.cols/pixels_per_work_item, dst.rows, 1 };
|
||||
#ifdef ANDROID
|
||||
size_t lt[3] = { 16, 10, 1 };
|
||||
#else
|
||||
size_t lt[3] = { 16, 16, 1 };
|
||||
#endif
|
||||
openCLExecuteKernel(src.clCxt, &cvt_color, kernelName.c_str(), gt, lt, args, -1, -1, build_options.c_str());
|
||||
}
|
||||
|
||||
static void toRGB_NV12_caller(const oclMat &src, oclMat &dst, int bidx, const std::string & kernelName,
|
||||
const std::string & additionalOptions = std::string(), const oclMat & data = oclMat())
|
||||
{
|
||||
std::string build_options = format("-D DEPTH_%d -D dcn=%d -D bidx=%d", src.depth(), dst.channels(), bidx);
|
||||
if (!additionalOptions.empty())
|
||||
build_options += additionalOptions;
|
||||
|
||||
@@ -101,7 +221,6 @@ static void toRGB_caller(const oclMat &src, oclMat &dst, int bidx, const std::st
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&dst.rows));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&src_step));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&dst_step));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&bidx));
|
||||
args.push_back( make_pair( sizeof(cl_mem) , (void *)&src.data));
|
||||
args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst.data));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&src_offset ));
|
||||
@@ -119,10 +238,13 @@ static void toRGB_caller(const oclMat &src, oclMat &dst, int bidx, const std::st
|
||||
openCLExecuteKernel(src.clCxt, &cvt_color, kernelName.c_str(), gt, lt, args, -1, -1, build_options.c_str());
|
||||
}
|
||||
|
||||
static void RGB_caller(const oclMat &src, oclMat &dst, bool reverse)
|
||||
static void fromHSV_caller(const oclMat &src, oclMat &dst, int bidx, const std::string & kernelName,
|
||||
const std::string & additionalOptions = std::string(), const oclMat & data = oclMat())
|
||||
{
|
||||
std::string build_options = format("-D DEPTH_%d -D dcn=%d -D scn=%d -D %s", src.depth(),
|
||||
dst.channels(), src.channels(), reverse ? "REVERSE" : "ORDER");
|
||||
std::string build_options = format("-D DEPTH_%d -D dcn=%d -D bidx=%d", src.depth(), dst.channels(), bidx);
|
||||
if (!additionalOptions.empty())
|
||||
build_options += additionalOptions;
|
||||
|
||||
int src_offset = src.offset / src.elemSize1(), src_step = src.step1();
|
||||
int dst_offset = dst.offset / dst.elemSize1(), dst_step = dst.step1();
|
||||
|
||||
@@ -136,6 +258,36 @@ static void RGB_caller(const oclMat &src, oclMat &dst, bool reverse)
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&src_offset ));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&dst_offset ));
|
||||
|
||||
if (!data.empty())
|
||||
args.push_back( make_pair( sizeof(cl_mem) , (void *)&data.data ));
|
||||
|
||||
size_t gt[3] = { dst.cols, dst.rows, 1 };
|
||||
#ifdef ANDROID
|
||||
size_t lt[3] = { 16, 10, 1 };
|
||||
#else
|
||||
size_t lt[3] = { 16, 16, 1 };
|
||||
#endif
|
||||
openCLExecuteKernel(src.clCxt, &cvt_color, kernelName.c_str(), gt, lt, args, -1, -1, build_options.c_str());
|
||||
}
|
||||
|
||||
static void RGB_caller(const oclMat &src, oclMat &dst, bool reverse)
|
||||
{
|
||||
int src_offset = src.offset / src.elemSize1(), src_step = src.step1();
|
||||
int dst_offset = dst.offset / dst.elemSize1(), dst_step = dst.step1();
|
||||
|
||||
std::string build_options = format("-D DEPTH_%d -D dcn=%d -D scn=%d -D %s",
|
||||
src.depth(), dst.channels(), src.channels(), reverse ? "REVERSE" : "ORDER");
|
||||
|
||||
vector<pair<size_t , const void *> > args;
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&dst.cols));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&dst.rows));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&src_step));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&dst_step));
|
||||
args.push_back( make_pair( sizeof(cl_mem) , (void *)&src.data));
|
||||
args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst.data));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&src_offset ));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&dst_offset ));
|
||||
|
||||
size_t gt[3] = { dst.cols, dst.rows, 1 };
|
||||
#ifdef ANDROID
|
||||
size_t lt[3] = { 16, 10, 1 };
|
||||
@@ -147,8 +299,8 @@ static void RGB_caller(const oclMat &src, oclMat &dst, bool reverse)
|
||||
|
||||
static void fromRGB5x5_caller(const oclMat &src, oclMat &dst, int bidx, int greenbits, const std::string & kernelName)
|
||||
{
|
||||
std::string build_options = format("-D DEPTH_%d -D greenbits=%d -D dcn=%d",
|
||||
src.depth(), greenbits, dst.channels());
|
||||
std::string build_options = format("-D DEPTH_%d -D greenbits=%d -D dcn=%d -D bidx=%d",
|
||||
src.depth(), greenbits, dst.channels(), bidx);
|
||||
int src_offset = src.offset >> 1, src_step = src.step >> 1;
|
||||
int dst_offset = dst.offset / dst.elemSize1(), dst_step = dst.step / dst.elemSize1();
|
||||
|
||||
@@ -157,7 +309,6 @@ static void fromRGB5x5_caller(const oclMat &src, oclMat &dst, int bidx, int gree
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&dst.rows));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&src_step));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&dst_step));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&bidx));
|
||||
args.push_back( make_pair( sizeof(cl_mem) , (void *)&src.data));
|
||||
args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst.data));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&src_offset ));
|
||||
@@ -174,8 +325,8 @@ static void fromRGB5x5_caller(const oclMat &src, oclMat &dst, int bidx, int gree
|
||||
|
||||
static void toRGB5x5_caller(const oclMat &src, oclMat &dst, int bidx, int greenbits, const std::string & kernelName)
|
||||
{
|
||||
std::string build_options = format("-D DEPTH_%d -D greenbits=%d -D scn=%d",
|
||||
src.depth(), greenbits, src.channels());
|
||||
std::string build_options = format("-D DEPTH_%d -D greenbits=%d -D scn=%d -D bidx=%d",
|
||||
src.depth(), greenbits, src.channels(), bidx);
|
||||
int src_offset = (int)src.offset, src_step = (int)src.step;
|
||||
int dst_offset = dst.offset >> 1, dst_step = dst.step >> 1;
|
||||
|
||||
@@ -184,7 +335,6 @@ static void toRGB5x5_caller(const oclMat &src, oclMat &dst, int bidx, int greenb
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&dst.rows));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&src_step));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&dst_step));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&bidx));
|
||||
args.push_back( make_pair( sizeof(cl_mem) , (void *)&src.data));
|
||||
args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst.data));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&src_offset ));
|
||||
@@ -272,7 +422,7 @@ static void cvtColor_caller(const oclMat &src, oclMat &dst, int code, int dcn)
|
||||
CV_Assert(scn == 1);
|
||||
dcn = code == CV_GRAY2BGRA ? 4 : 3;
|
||||
dst.create(sz, CV_MAKETYPE(depth, dcn));
|
||||
toRGB_caller(src, dst, 0, "Gray2RGB");
|
||||
fromGray_caller(src, dst, 0, "Gray2RGB");
|
||||
break;
|
||||
}
|
||||
case CV_BGR2YUV: case CV_RGB2YUV:
|
||||
@@ -303,7 +453,7 @@ static void cvtColor_caller(const oclMat &src, oclMat &dst, int code, int dcn)
|
||||
|
||||
Size dstSz(sz.width, sz.height * 2 / 3);
|
||||
dst.create(dstSz, CV_MAKETYPE(depth, dcn));
|
||||
toRGB_caller(src, dst, bidx, "YUV2RGBA_NV12");
|
||||
toRGB_NV12_caller(src, dst, bidx, "YUV2RGBA_NV12");
|
||||
break;
|
||||
}
|
||||
case CV_BGR2YCrCb: case CV_RGB2YCrCb:
|
||||
@@ -460,11 +610,11 @@ static void cvtColor_caller(const oclMat &src, oclMat &dst, int code, int dcn)
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
fromRGB_caller(src, dst, bidx, kernelName, format(" -D hrange=%d", hrange), sdiv_data, hrange == 256 ? hdiv_data256 : hdiv_data180);
|
||||
toHSV_caller(src, dst, bidx, kernelName, format(" -D hrange=%d", hrange), sdiv_data, hrange == 256 ? hdiv_data256 : hdiv_data180);
|
||||
return;
|
||||
}
|
||||
|
||||
fromRGB_caller(src, dst, bidx, kernelName, format(" -D hscale=%f", hrange*(1.f/360.f)));
|
||||
toHSV_caller(src, dst, bidx, kernelName, format(" -D hscale=%f", hrange*(1.f/360.f)));
|
||||
break;
|
||||
}
|
||||
case CV_HSV2BGR: case CV_HSV2RGB: case CV_HSV2BGR_FULL: case CV_HSV2RGB_FULL:
|
||||
@@ -483,7 +633,7 @@ static void cvtColor_caller(const oclMat &src, oclMat &dst, int code, int dcn)
|
||||
dst.create(sz, CV_MAKETYPE(depth, dcn));
|
||||
|
||||
std::string kernelName = std::string(is_hsv ? "HSV" : "HLS") + "2RGB";
|
||||
toRGB_caller(src, dst, bidx, kernelName, format(" -D hrange=%d -D hscale=%f", hrange, 6.f/hrange));
|
||||
fromHSV_caller(src, dst, bidx, kernelName, format(" -D hrange=%d -D hscale=%f", hrange, 6.f/hrange));
|
||||
break;
|
||||
}
|
||||
case CV_RGBA2mRGBA: case CV_mRGBA2RGBA:
|
||||
|
||||
+183
-10
@@ -739,6 +739,135 @@ void cv::ocl::filter2D(const oclMat &src, oclMat &dst, int ddepth, const Mat &ke
|
||||
f->apply(src, dst);
|
||||
}
|
||||
|
||||
const int optimizedSepFilterLocalSize = 16;
|
||||
static void sepFilter2D_SinglePass(const oclMat &src, oclMat &dst,
|
||||
const Mat &row_kernel, const Mat &col_kernel, int bordertype = BORDER_DEFAULT)
|
||||
{
|
||||
size_t lt2[3] = {optimizedSepFilterLocalSize, optimizedSepFilterLocalSize, 1};
|
||||
size_t gt2[3] = {lt2[0]*(1 + (src.cols-1) / lt2[0]), lt2[1]*(1 + (src.rows-1) / lt2[1]), 1};
|
||||
|
||||
unsigned int src_pitch = src.step;
|
||||
unsigned int dst_pitch = dst.step;
|
||||
|
||||
int src_offset_x = (src.offset % src.step) / src.elemSize();
|
||||
int src_offset_y = src.offset / src.step;
|
||||
|
||||
std::vector<std::pair<size_t , const void *> > args;
|
||||
args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&src.data ));
|
||||
args.push_back( std::make_pair( sizeof(cl_uint) , (void *)&src_pitch ));
|
||||
|
||||
args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src_offset_x ));
|
||||
args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src_offset_y ));
|
||||
|
||||
args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&dst.data ));
|
||||
args.push_back( std::make_pair( sizeof(cl_int) , (void *)&dst.offset ));
|
||||
args.push_back( std::make_pair( sizeof(cl_uint) , (void *)&dst_pitch ));
|
||||
|
||||
args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src.wholecols ));
|
||||
args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src.wholerows ));
|
||||
|
||||
args.push_back( std::make_pair( sizeof(cl_int) , (void *)&dst.cols ));
|
||||
args.push_back( std::make_pair( sizeof(cl_int) , (void *)&dst.rows ));
|
||||
|
||||
string option = cv::format("-D BLK_X=%d -D BLK_Y=%d -D RADIUSX=%d -D RADIUSY=%d",(int)lt2[0], (int)lt2[1],
|
||||
row_kernel.rows / 2, col_kernel.rows / 2 );
|
||||
|
||||
option += " -D KERNEL_MATRIX_X=";
|
||||
for(int i=0; i<row_kernel.rows; i++)
|
||||
option += cv::format("0x%x,", *reinterpret_cast<const unsigned int*>( &row_kernel.at<float>(i) ) );
|
||||
option += "0x0";
|
||||
|
||||
option += " -D KERNEL_MATRIX_Y=";
|
||||
for(int i=0; i<col_kernel.rows; i++)
|
||||
option += cv::format("0x%x,", *reinterpret_cast<const unsigned int*>( &col_kernel.at<float>(i) ) );
|
||||
option += "0x0";
|
||||
|
||||
switch(src.type())
|
||||
{
|
||||
case CV_8UC1:
|
||||
option += " -D SRCTYPE=uchar -D CONVERT_SRCTYPE=convert_float -D WORKTYPE=float";
|
||||
break;
|
||||
case CV_32FC1:
|
||||
option += " -D SRCTYPE=float -D CONVERT_SRCTYPE= -D WORKTYPE=float";
|
||||
break;
|
||||
case CV_8UC2:
|
||||
option += " -D SRCTYPE=uchar2 -D CONVERT_SRCTYPE=convert_float2 -D WORKTYPE=float2";
|
||||
break;
|
||||
case CV_32FC2:
|
||||
option += " -D SRCTYPE=float2 -D CONVERT_SRCTYPE= -D WORKTYPE=float2";
|
||||
break;
|
||||
case CV_8UC3:
|
||||
option += " -D SRCTYPE=uchar3 -D CONVERT_SRCTYPE=convert_float3 -D WORKTYPE=float3";
|
||||
break;
|
||||
case CV_32FC3:
|
||||
option += " -D SRCTYPE=float3 -D CONVERT_SRCTYPE= -D WORKTYPE=float3";
|
||||
break;
|
||||
case CV_8UC4:
|
||||
option += " -D SRCTYPE=uchar4 -D CONVERT_SRCTYPE=convert_float4 -D WORKTYPE=float4";
|
||||
break;
|
||||
case CV_32FC4:
|
||||
option += " -D SRCTYPE=float4 -D CONVERT_SRCTYPE= -D WORKTYPE=float4";
|
||||
break;
|
||||
default:
|
||||
CV_Error(CV_StsUnsupportedFormat, "Image type is not supported!");
|
||||
break;
|
||||
}
|
||||
switch(dst.type())
|
||||
{
|
||||
case CV_8UC1:
|
||||
option += " -D DSTTYPE=uchar -D CONVERT_DSTTYPE=convert_uchar_sat";
|
||||
break;
|
||||
case CV_8UC2:
|
||||
option += " -D DSTTYPE=uchar2 -D CONVERT_DSTTYPE=convert_uchar2_sat";
|
||||
break;
|
||||
case CV_8UC3:
|
||||
option += " -D DSTTYPE=uchar3 -D CONVERT_DSTTYPE=convert_uchar3_sat";
|
||||
break;
|
||||
case CV_8UC4:
|
||||
option += " -D DSTTYPE=uchar4 -D CONVERT_DSTTYPE=convert_uchar4_sat";
|
||||
break;
|
||||
case CV_32FC1:
|
||||
option += " -D DSTTYPE=float -D CONVERT_DSTTYPE=";
|
||||
break;
|
||||
case CV_32FC2:
|
||||
option += " -D DSTTYPE=float2 -D CONVERT_DSTTYPE=";
|
||||
break;
|
||||
case CV_32FC3:
|
||||
option += " -D DSTTYPE=float3 -D CONVERT_DSTTYPE=";
|
||||
break;
|
||||
case CV_32FC4:
|
||||
option += " -D DSTTYPE=float4 -D CONVERT_DSTTYPE=";
|
||||
break;
|
||||
default:
|
||||
CV_Error(CV_StsUnsupportedFormat, "Image type is not supported!");
|
||||
break;
|
||||
}
|
||||
switch(bordertype)
|
||||
{
|
||||
case cv::BORDER_CONSTANT:
|
||||
option += " -D BORDER_CONSTANT";
|
||||
break;
|
||||
case cv::BORDER_REPLICATE:
|
||||
option += " -D BORDER_REPLICATE";
|
||||
break;
|
||||
case cv::BORDER_REFLECT:
|
||||
option += " -D BORDER_REFLECT";
|
||||
break;
|
||||
case cv::BORDER_REFLECT101:
|
||||
option += " -D BORDER_REFLECT_101";
|
||||
break;
|
||||
case cv::BORDER_WRAP:
|
||||
option += " -D BORDER_WRAP";
|
||||
break;
|
||||
default:
|
||||
CV_Error(CV_StsBadFlag, "BORDER type is not supported!");
|
||||
break;
|
||||
}
|
||||
|
||||
openCLExecuteKernel(src.clCxt, &filtering_sep_filter_singlepass, "sep_filter_singlepass", gt2, lt2, args,
|
||||
-1, -1, option.c_str() );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SeparableFilter
|
||||
|
||||
@@ -788,6 +917,35 @@ Ptr<FilterEngine_GPU> cv::ocl::createSeparableFilter_GPU(const Ptr<BaseRowFilter
|
||||
return Ptr<FilterEngine_GPU>(new SeparableFilterEngine_GPU(rowFilter, columnFilter));
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
class SingleStepSeparableFilterEngine_GPU : public FilterEngine_GPU
|
||||
{
|
||||
public:
|
||||
SingleStepSeparableFilterEngine_GPU( const Mat &rowKernel_, const Mat &columnKernel_, const int btype )
|
||||
{
|
||||
bordertype = btype;
|
||||
rowKernel = rowKernel_;
|
||||
columnKernel = columnKernel_;
|
||||
}
|
||||
|
||||
virtual void apply(const oclMat &src, oclMat &dst, Rect roi = Rect(0, 0, -1, -1))
|
||||
{
|
||||
normalizeROI(roi, Size(rowKernel.rows, columnKernel.rows), Point(-1,-1), src.size());
|
||||
|
||||
oclMat srcROI = src(roi);
|
||||
oclMat dstROI = dst(roi);
|
||||
|
||||
sepFilter2D_SinglePass(src, dst, rowKernel, columnKernel, bordertype);
|
||||
}
|
||||
|
||||
Mat rowKernel;
|
||||
Mat columnKernel;
|
||||
int bordertype;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
static void GPUFilterBox(const oclMat &src, oclMat &dst,
|
||||
Size &ksize, const Point anchor, const int borderType)
|
||||
{
|
||||
@@ -1241,17 +1399,32 @@ Ptr<BaseColumnFilter_GPU> cv::ocl::getLinearColumnFilter_GPU(int /*bufType*/, in
|
||||
}
|
||||
|
||||
Ptr<FilterEngine_GPU> cv::ocl::createSeparableLinearFilter_GPU(int srcType, int dstType,
|
||||
const Mat &rowKernel, const Mat &columnKernel, const Point &anchor, double delta, int bordertype)
|
||||
const Mat &rowKernel, const Mat &columnKernel, const Point &anchor, double delta, int bordertype, Size imgSize )
|
||||
{
|
||||
int sdepth = CV_MAT_DEPTH(srcType), ddepth = CV_MAT_DEPTH(dstType);
|
||||
int cn = CV_MAT_CN(srcType);
|
||||
int bdepth = std::max(std::max(sdepth, ddepth), CV_32F);
|
||||
int bufType = CV_MAKETYPE(bdepth, cn);
|
||||
Context* clCxt = Context::getContext();
|
||||
|
||||
Ptr<BaseRowFilter_GPU> rowFilter = getLinearRowFilter_GPU(srcType, bufType, rowKernel, anchor.x, bordertype);
|
||||
Ptr<BaseColumnFilter_GPU> columnFilter = getLinearColumnFilter_GPU(bufType, dstType, columnKernel, anchor.y, bordertype, delta);
|
||||
//if image size is non-degenerate and large enough
|
||||
//and if filter support is reasonable to satisfy larger local memory requirements,
|
||||
//then we can use single pass routine to avoid extra runtime calls overhead
|
||||
if( clCxt && clCxt->supportsFeature(FEATURE_CL_INTEL_DEVICE) &&
|
||||
rowKernel.rows <= 21 && columnKernel.rows <= 21 &&
|
||||
(rowKernel.rows & 1) == 1 && (columnKernel.rows & 1) == 1 &&
|
||||
imgSize.width > optimizedSepFilterLocalSize + (rowKernel.rows>>1) &&
|
||||
imgSize.height > optimizedSepFilterLocalSize + (columnKernel.rows>>1) )
|
||||
{
|
||||
return Ptr<FilterEngine_GPU>(new SingleStepSeparableFilterEngine_GPU(rowKernel, columnKernel, bordertype));
|
||||
}
|
||||
else
|
||||
{
|
||||
Ptr<BaseRowFilter_GPU> rowFilter = getLinearRowFilter_GPU(srcType, bufType, rowKernel, anchor.x, bordertype);
|
||||
Ptr<BaseColumnFilter_GPU> columnFilter = getLinearColumnFilter_GPU(bufType, dstType, columnKernel, anchor.y, bordertype, delta);
|
||||
|
||||
return createSeparableFilter_GPU(rowFilter, columnFilter);
|
||||
return createSeparableFilter_GPU(rowFilter, columnFilter);
|
||||
}
|
||||
}
|
||||
|
||||
void cv::ocl::sepFilter2D(const oclMat &src, oclMat &dst, int ddepth, const Mat &kernelX, const Mat &kernelY, Point anchor, double delta, int bordertype)
|
||||
@@ -1275,16 +1448,16 @@ void cv::ocl::sepFilter2D(const oclMat &src, oclMat &dst, int ddepth, const Mat
|
||||
|
||||
dst.create(src.size(), CV_MAKETYPE(ddepth, src.channels()));
|
||||
|
||||
Ptr<FilterEngine_GPU> f = createSeparableLinearFilter_GPU(src.type(), dst.type(), kernelX, kernelY, anchor, delta, bordertype);
|
||||
Ptr<FilterEngine_GPU> f = createSeparableLinearFilter_GPU(src.type(), dst.type(), kernelX, kernelY, anchor, delta, bordertype, src.size());
|
||||
f->apply(src, dst);
|
||||
}
|
||||
|
||||
Ptr<FilterEngine_GPU> cv::ocl::createDerivFilter_GPU(int srcType, int dstType, int dx, int dy, int ksize, int borderType)
|
||||
Ptr<FilterEngine_GPU> cv::ocl::createDerivFilter_GPU(int srcType, int dstType, int dx, int dy, int ksize, int borderType, Size imgSize )
|
||||
{
|
||||
Mat kx, ky;
|
||||
getDerivKernels(kx, ky, dx, dy, ksize, false, CV_32F);
|
||||
return createSeparableLinearFilter_GPU(srcType, dstType,
|
||||
kx, ky, Point(-1, -1), 0, borderType);
|
||||
kx, ky, Point(-1, -1), 0, borderType, imgSize);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1354,7 +1527,7 @@ void cv::ocl::Laplacian(const oclMat &src, oclMat &dst, int ddepth, int ksize, d
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Gaussian Filter
|
||||
|
||||
Ptr<FilterEngine_GPU> cv::ocl::createGaussianFilter_GPU(int type, Size ksize, double sigma1, double sigma2, int bordertype)
|
||||
Ptr<FilterEngine_GPU> cv::ocl::createGaussianFilter_GPU(int type, Size ksize, double sigma1, double sigma2, int bordertype, Size imgSize)
|
||||
{
|
||||
int depth = CV_MAT_DEPTH(type);
|
||||
|
||||
@@ -1381,7 +1554,7 @@ Ptr<FilterEngine_GPU> cv::ocl::createGaussianFilter_GPU(int type, Size ksize, do
|
||||
else
|
||||
ky = getGaussianKernel(ksize.height, sigma2, std::max(depth, CV_32F));
|
||||
|
||||
return createSeparableLinearFilter_GPU(type, type, kx, ky, Point(-1, -1), 0.0, bordertype);
|
||||
return createSeparableLinearFilter_GPU(type, type, kx, ky, Point(-1, -1), 0.0, bordertype, imgSize);
|
||||
}
|
||||
|
||||
void cv::ocl::GaussianBlur(const oclMat &src, oclMat &dst, Size ksize, double sigma1, double sigma2, int bordertype)
|
||||
@@ -1417,7 +1590,7 @@ void cv::ocl::GaussianBlur(const oclMat &src, oclMat &dst, Size ksize, double si
|
||||
|
||||
dst.create(src.size(), src.type());
|
||||
|
||||
Ptr<FilterEngine_GPU> f = createGaussianFilter_GPU(src.type(), ksize, sigma1, sigma2, bordertype);
|
||||
Ptr<FilterEngine_GPU> f = createGaussianFilter_GPU(src.type(), ksize, sigma1, sigma2, bordertype, src.size());
|
||||
f->apply(src, dst);
|
||||
}
|
||||
|
||||
|
||||
+192
-170
@@ -48,154 +48,142 @@
|
||||
using namespace cv;
|
||||
using namespace cv::ocl;
|
||||
|
||||
// currently sort procedure on the host is more efficient
|
||||
static bool use_cpu_sorter = true;
|
||||
|
||||
namespace
|
||||
// compact structure for corners
|
||||
struct DefCorner
|
||||
{
|
||||
enum SortMethod
|
||||
float eig; //eigenvalue of corner
|
||||
short x; //x coordinate of corner point
|
||||
short y; //y coordinate of corner point
|
||||
} ;
|
||||
|
||||
// compare procedure for corner
|
||||
//it is used for sort on the host side
|
||||
struct DefCornerCompare
|
||||
{
|
||||
CPU_STL,
|
||||
BITONIC,
|
||||
SELECTION
|
||||
};
|
||||
|
||||
const int GROUP_SIZE = 256;
|
||||
|
||||
template<SortMethod method>
|
||||
struct Sorter
|
||||
{
|
||||
//typedef EigType;
|
||||
};
|
||||
|
||||
//TODO(pengx): optimize GPU sorter's performance thus CPU sorter is removed.
|
||||
template<>
|
||||
struct Sorter<CPU_STL>
|
||||
{
|
||||
typedef oclMat EigType;
|
||||
static cv::Mutex cs;
|
||||
static Mat mat_eig;
|
||||
|
||||
//prototype
|
||||
static int clfloat2Gt(cl_float2 pt1, cl_float2 pt2)
|
||||
bool operator()(const DefCorner a, const DefCorner b) const
|
||||
{
|
||||
float v1 = mat_eig.at<float>(cvRound(pt1.s[1]), cvRound(pt1.s[0]));
|
||||
float v2 = mat_eig.at<float>(cvRound(pt2.s[1]), cvRound(pt2.s[0]));
|
||||
return v1 > v2;
|
||||
}
|
||||
static void sortCorners_caller(const EigType& eig_tex, oclMat& corners, const int count)
|
||||
{
|
||||
cv::AutoLock lock(cs);
|
||||
//temporarily use STL's sort function
|
||||
Mat mat_corners = corners;
|
||||
mat_eig = eig_tex;
|
||||
std::sort(mat_corners.begin<cl_float2>(), mat_corners.begin<cl_float2>() + count, clfloat2Gt);
|
||||
corners = mat_corners;
|
||||
return a.eig > b.eig;
|
||||
}
|
||||
};
|
||||
cv::Mutex Sorter<CPU_STL>::cs;
|
||||
cv::Mat Sorter<CPU_STL>::mat_eig;
|
||||
|
||||
template<>
|
||||
struct Sorter<BITONIC>
|
||||
// sort corner point using opencl bitonicosrt implementation
|
||||
static void sortCorners_caller(oclMat& corners, const int count)
|
||||
{
|
||||
typedef TextureCL EigType;
|
||||
Context * cxt = Context::getContext();
|
||||
int GS = count/2;
|
||||
int LS = min(255,GS);
|
||||
size_t globalThreads[3] = {GS, 1, 1};
|
||||
size_t localThreads[3] = {LS, 1, 1};
|
||||
|
||||
static void sortCorners_caller(const EigType& eig_tex, oclMat& corners, const int count)
|
||||
// 2^numStages should be equal to count or the output is invalid
|
||||
int numStages = 0;
|
||||
for(int i = count; i > 1; i >>= 1)
|
||||
{
|
||||
Context * cxt = Context::getContext();
|
||||
size_t globalThreads[3] = {count / 2, 1, 1};
|
||||
size_t localThreads[3] = {GROUP_SIZE, 1, 1};
|
||||
|
||||
// 2^numStages should be equal to count or the output is invalid
|
||||
int numStages = 0;
|
||||
for(int i = count; i > 1; i >>= 1)
|
||||
++numStages;
|
||||
}
|
||||
const int argc = 4;
|
||||
std::vector< std::pair<size_t, const void *> > args(argc);
|
||||
std::string kernelname = "sortCorners_bitonicSort";
|
||||
args[0] = std::make_pair(sizeof(cl_mem), (void *)&corners.data);
|
||||
args[1] = std::make_pair(sizeof(cl_int), (void *)&count);
|
||||
for(int stage = 0; stage < numStages; ++stage)
|
||||
{
|
||||
args[2] = std::make_pair(sizeof(cl_int), (void *)&stage);
|
||||
for(int passOfStage = 0; passOfStage < stage + 1; ++passOfStage)
|
||||
{
|
||||
++numStages;
|
||||
}
|
||||
const int argc = 5;
|
||||
std::vector< std::pair<size_t, const void *> > args(argc);
|
||||
std::string kernelname = "sortCorners_bitonicSort";
|
||||
args[0] = std::make_pair(sizeof(cl_mem), (void *)&eig_tex);
|
||||
args[1] = std::make_pair(sizeof(cl_mem), (void *)&corners.data);
|
||||
args[2] = std::make_pair(sizeof(cl_int), (void *)&count);
|
||||
for(int stage = 0; stage < numStages; ++stage)
|
||||
{
|
||||
args[3] = std::make_pair(sizeof(cl_int), (void *)&stage);
|
||||
for(int passOfStage = 0; passOfStage < stage + 1; ++passOfStage)
|
||||
{
|
||||
args[4] = std::make_pair(sizeof(cl_int), (void *)&passOfStage);
|
||||
openCLExecuteKernel(cxt, &imgproc_gftt, kernelname, globalThreads, localThreads, args, -1, -1);
|
||||
}
|
||||
args[3] = std::make_pair(sizeof(cl_int), (void *)&passOfStage);
|
||||
openCLExecuteKernel(cxt, &imgproc_gftt, kernelname, globalThreads, localThreads, args, -1, -1);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template<>
|
||||
struct Sorter<SELECTION>
|
||||
{
|
||||
typedef TextureCL EigType;
|
||||
|
||||
static void sortCorners_caller(const EigType& eig_tex, oclMat& corners, const int count)
|
||||
{
|
||||
Context * cxt = Context::getContext();
|
||||
|
||||
size_t globalThreads[3] = {count, 1, 1};
|
||||
size_t localThreads[3] = {GROUP_SIZE, 1, 1};
|
||||
|
||||
std::vector< std::pair<size_t, const void *> > args;
|
||||
//local
|
||||
std::string kernelname = "sortCorners_selectionSortLocal";
|
||||
int lds_size = GROUP_SIZE * sizeof(cl_float2);
|
||||
args.push_back( std::make_pair( sizeof(cl_mem), (void*)&eig_tex) );
|
||||
args.push_back( std::make_pair( sizeof(cl_mem), (void*)&corners.data) );
|
||||
args.push_back( std::make_pair( sizeof(cl_int), (void*)&count) );
|
||||
args.push_back( std::make_pair( lds_size, (void*)NULL) );
|
||||
|
||||
openCLExecuteKernel(cxt, &imgproc_gftt, kernelname, globalThreads, localThreads, args, -1, -1);
|
||||
|
||||
//final
|
||||
kernelname = "sortCorners_selectionSortFinal";
|
||||
args.pop_back();
|
||||
openCLExecuteKernel(cxt, &imgproc_gftt, kernelname, globalThreads, localThreads, args, -1, -1);
|
||||
}
|
||||
};
|
||||
|
||||
int findCorners_caller(
|
||||
const TextureCL& eig,
|
||||
const float threshold,
|
||||
const oclMat& mask,
|
||||
oclMat& corners,
|
||||
const int max_count)
|
||||
// find corners on matrix and put it into array
|
||||
static void findCorners_caller(
|
||||
const oclMat& eig_mat, //input matrix worth eigenvalues
|
||||
oclMat& eigMinMax, //input with min and max values of eigenvalues
|
||||
const float qualityLevel,
|
||||
const oclMat& mask,
|
||||
oclMat& corners, //output array with detected corners
|
||||
oclMat& counter) //output value with number of detected corners, have to be 0 before call
|
||||
{
|
||||
string opt;
|
||||
std::vector<int> k;
|
||||
Context * cxt = Context::getContext();
|
||||
|
||||
std::vector< std::pair<size_t, const void*> > args;
|
||||
std::string kernelname = "findCorners";
|
||||
|
||||
const int mask_strip = mask.step / mask.elemSize1();
|
||||
|
||||
oclMat g_counter(1, 1, CV_32SC1);
|
||||
g_counter.setTo(0);
|
||||
args.push_back(make_pair( sizeof(cl_mem), (void*)&(eig_mat.data)));
|
||||
|
||||
args.push_back(make_pair( sizeof(cl_mem), (void*)&eig ));
|
||||
int src_pitch = (int)eig_mat.step;
|
||||
args.push_back(make_pair( sizeof(cl_int), (void*)&src_pitch ));
|
||||
args.push_back(make_pair( sizeof(cl_mem), (void*)&mask.data ));
|
||||
args.push_back(make_pair( sizeof(cl_mem), (void*)&corners.data ));
|
||||
args.push_back(make_pair( sizeof(cl_int), (void*)&mask_strip));
|
||||
args.push_back(make_pair( sizeof(cl_float), (void*)&threshold ));
|
||||
args.push_back(make_pair( sizeof(cl_int), (void*)&eig.rows ));
|
||||
args.push_back(make_pair( sizeof(cl_int), (void*)&eig.cols ));
|
||||
args.push_back(make_pair( sizeof(cl_int), (void*)&max_count ));
|
||||
args.push_back(make_pair( sizeof(cl_mem), (void*)&g_counter.data ));
|
||||
args.push_back(make_pair( sizeof(cl_mem), (void*)&eigMinMax.data ));
|
||||
args.push_back(make_pair( sizeof(cl_float), (void*)&qualityLevel ));
|
||||
args.push_back(make_pair( sizeof(cl_int), (void*)&eig_mat.rows ));
|
||||
args.push_back(make_pair( sizeof(cl_int), (void*)&eig_mat.cols ));
|
||||
args.push_back(make_pair( sizeof(cl_int), (void*)&corners.cols ));
|
||||
args.push_back(make_pair( sizeof(cl_mem), (void*)&counter.data ));
|
||||
|
||||
size_t globalThreads[3] = {eig.cols, eig.rows, 1};
|
||||
size_t globalThreads[3] = {eig_mat.cols, eig_mat.rows, 1};
|
||||
size_t localThreads[3] = {16, 16, 1};
|
||||
if(!mask.empty())
|
||||
opt += " -D WITH_MASK=1";
|
||||
|
||||
const char * opt = mask.empty() ? "" : "-D WITH_MASK";
|
||||
openCLExecuteKernel(cxt, &imgproc_gftt, kernelname, globalThreads, localThreads, args, -1, -1, opt);
|
||||
return std::min(Mat(g_counter).at<int>(0), max_count);
|
||||
openCLExecuteKernel(cxt, &imgproc_gftt, "findCorners", globalThreads, localThreads, args, -1, -1, opt.c_str());
|
||||
}
|
||||
|
||||
|
||||
static void minMaxEig_caller(const oclMat &src, oclMat &dst, oclMat & tozero)
|
||||
{
|
||||
size_t groupnum = src.clCxt->getDeviceInfo().maxComputeUnits;
|
||||
CV_Assert(groupnum != 0);
|
||||
|
||||
int dbsize = groupnum * 2 * src.elemSize();
|
||||
|
||||
ensureSizeIsEnough(1, dbsize, CV_8UC1, dst);
|
||||
|
||||
cl_mem dst_data = reinterpret_cast<cl_mem>(dst.data);
|
||||
|
||||
int all_cols = src.step / src.elemSize();
|
||||
int pre_cols = (src.offset % src.step) / src.elemSize();
|
||||
int sec_cols = all_cols - (src.offset % src.step + src.cols * src.elemSize() - 1) / src.elemSize() - 1;
|
||||
int invalid_cols = pre_cols + sec_cols;
|
||||
int cols = all_cols - invalid_cols , elemnum = cols * src.rows;
|
||||
int offset = src.offset / src.elemSize();
|
||||
|
||||
{// first parallel pass
|
||||
vector<pair<size_t , const void *> > args;
|
||||
args.push_back( make_pair( sizeof(cl_mem) , (void *)&src.data));
|
||||
args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst_data ));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&cols ));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&invalid_cols ));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&offset));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&elemnum));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&groupnum));
|
||||
size_t globalThreads[3] = {groupnum * 256, 1, 1};
|
||||
size_t localThreads[3] = {256, 1, 1};
|
||||
openCLExecuteKernel(src.clCxt, &arithm_minMax, "arithm_op_minMax", globalThreads, localThreads,
|
||||
args, -1, -1, "-D T=float -D DEPTH_5");
|
||||
}
|
||||
|
||||
{// run final "serial" kernel to find accumulate results from threads and reset corner counter
|
||||
vector<pair<size_t , const void *> > args;
|
||||
args.push_back( make_pair( sizeof(cl_mem) , (void *)&dst_data ));
|
||||
args.push_back( make_pair( sizeof(cl_int) , (void *)&groupnum ));
|
||||
args.push_back( make_pair( sizeof(cl_mem) , (void *)&tozero.data ));
|
||||
size_t globalThreads[3] = {1, 1, 1};
|
||||
size_t localThreads[3] = {1, 1, 1};
|
||||
openCLExecuteKernel(src.clCxt, &imgproc_gftt, "arithm_op_minMax_final", globalThreads, localThreads,
|
||||
args, -1, -1);
|
||||
}
|
||||
}
|
||||
}//unnamed namespace
|
||||
|
||||
void cv::ocl::GoodFeaturesToTrackDetector_OCL::operator ()(const oclMat& image, oclMat& corners, const oclMat& mask)
|
||||
{
|
||||
@@ -205,67 +193,99 @@ void cv::ocl::GoodFeaturesToTrackDetector_OCL::operator ()(const oclMat& image,
|
||||
ensureSizeIsEnough(image.size(), CV_32F, eig_);
|
||||
|
||||
if (useHarrisDetector)
|
||||
cornerMinEigenVal_dxdy(image, eig_, Dx_, Dy_, blockSize, 3, harrisK);
|
||||
cornerHarris_dxdy(image, eig_, Dx_, Dy_, blockSize, 3, harrisK);
|
||||
else
|
||||
cornerMinEigenVal_dxdy(image, eig_, Dx_, Dy_, blockSize, 3);
|
||||
|
||||
double maxVal = 0;
|
||||
minMax(eig_, NULL, &maxVal);
|
||||
ensureSizeIsEnough(1,1, CV_32SC1, counter_);
|
||||
|
||||
ensureSizeIsEnough(1, std::max(1000, static_cast<int>(image.size().area() * 0.05)), CV_32FC2, tmpCorners_);
|
||||
// find max eigenvalue and reset detected counters
|
||||
minMaxEig_caller(eig_,eig_minmax_,counter_);
|
||||
|
||||
Ptr<TextureCL> eig_tex = bindTexturePtr(eig_);
|
||||
int total = findCorners_caller(
|
||||
*eig_tex,
|
||||
static_cast<float>(maxVal * qualityLevel),
|
||||
// allocate buffer for kernels
|
||||
int corner_array_size = std::max(1024, static_cast<int>(image.size().area() * 0.05));
|
||||
|
||||
if(!use_cpu_sorter)
|
||||
{ // round to 2^n
|
||||
unsigned int n=1;
|
||||
for(n=1;n<(unsigned int)corner_array_size;n<<=1) ;
|
||||
corner_array_size = (int)n;
|
||||
|
||||
ensureSizeIsEnough(1, corner_array_size , CV_32FC2, tmpCorners_);
|
||||
|
||||
// set to 0 to be able use bitonic sort on whole 2^n array
|
||||
tmpCorners_.setTo(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ensureSizeIsEnough(1, corner_array_size , CV_32FC2, tmpCorners_);
|
||||
}
|
||||
|
||||
int total = tmpCorners_.cols; // by default the number of corner is full array
|
||||
vector<DefCorner> tmp(tmpCorners_.cols); // input buffer with corner for HOST part of algorithm
|
||||
|
||||
//find points with high eigenvalue and put it into the output array
|
||||
findCorners_caller(
|
||||
eig_,
|
||||
eig_minmax_,
|
||||
static_cast<float>(qualityLevel),
|
||||
mask,
|
||||
tmpCorners_,
|
||||
tmpCorners_.cols);
|
||||
counter_);
|
||||
|
||||
if(!use_cpu_sorter)
|
||||
{// sort detected corners on deivce side
|
||||
sortCorners_caller(tmpCorners_, corner_array_size);
|
||||
}
|
||||
else
|
||||
{// send non-blocking request to read real non-zero number of corners to sort it on the HOST side
|
||||
openCLVerifyCall(clEnqueueReadBuffer(getClCommandQueue(counter_.clCxt), (cl_mem)counter_.data, CL_FALSE, 0,sizeof(int), &total, 0, NULL, NULL));
|
||||
}
|
||||
|
||||
//blocking read whole corners array (sorted or not sorted)
|
||||
openCLReadBuffer(tmpCorners_.clCxt,(cl_mem)tmpCorners_.data,&tmp[0],tmpCorners_.cols*sizeof(DefCorner));
|
||||
|
||||
if (total == 0)
|
||||
{
|
||||
{// check for trivial case
|
||||
corners.release();
|
||||
return;
|
||||
}
|
||||
|
||||
if(use_cpu_sorter)
|
||||
{
|
||||
Sorter<CPU_STL>::sortCorners_caller(eig_, tmpCorners_, total);
|
||||
}
|
||||
else
|
||||
{
|
||||
//if total is power of 2
|
||||
if(((total - 1) & (total)) == 0)
|
||||
{
|
||||
Sorter<BITONIC>::sortCorners_caller(*eig_tex, tmpCorners_, total);
|
||||
}
|
||||
else
|
||||
{
|
||||
Sorter<SELECTION>::sortCorners_caller(*eig_tex, tmpCorners_, total);
|
||||
}
|
||||
{// sort detected corners on cpu side.
|
||||
tmp.resize(total);
|
||||
cv::sort(tmp,DefCornerCompare());
|
||||
}
|
||||
|
||||
//estimate maximal size of final output array
|
||||
int total_max = maxCorners > 0 ? std::min(maxCorners, total) : total;
|
||||
int D2 = (int)ceil(minDistance * minDistance);
|
||||
// allocate output buffer
|
||||
vector<Point2f> tmp2;
|
||||
tmp2.reserve(total_max);
|
||||
|
||||
|
||||
if (minDistance < 1)
|
||||
{
|
||||
Rect roi_range(0, 0, maxCorners > 0 ? std::min(maxCorners, total) : total, 1);
|
||||
tmpCorners_(roi_range).copyTo(corners);
|
||||
{// we have not distance restriction. then just copy with conversion maximal allowed points into output array
|
||||
for(int i=0;i<total_max && tmp[i].eig>0.0f;++i)
|
||||
{
|
||||
tmp2.push_back(Point2f(tmp[i].x,tmp[i].y));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vector<Point2f> tmp(total);
|
||||
downloadPoints(tmpCorners_, tmp);
|
||||
|
||||
vector<Point2f> tmp2;
|
||||
tmp2.reserve(total);
|
||||
|
||||
{// we have distance restriction. then start coping to output array from the first element and check distance for each next one
|
||||
const int cell_size = cvRound(minDistance);
|
||||
const int grid_width = (image.cols + cell_size - 1) / cell_size;
|
||||
const int grid_height = (image.rows + cell_size - 1) / cell_size;
|
||||
|
||||
std::vector< std::vector<Point2f> > grid(grid_width * grid_height);
|
||||
std::vector< std::vector<Point2i> > grid(grid_width * grid_height);
|
||||
|
||||
for (int i = 0; i < total; ++i)
|
||||
for (int i = 0; i < total ; ++i)
|
||||
{
|
||||
Point2f p = tmp[i];
|
||||
DefCorner p = tmp[i];
|
||||
|
||||
if(p.eig<=0.0f)
|
||||
break; // condition to stop that is needed for GPU bitonic sort usage.
|
||||
|
||||
bool good = true;
|
||||
|
||||
@@ -287,40 +307,42 @@ void cv::ocl::GoodFeaturesToTrackDetector_OCL::operator ()(const oclMat& image,
|
||||
{
|
||||
for (int xx = x1; xx <= x2; xx++)
|
||||
{
|
||||
vector<Point2f>& m = grid[yy * grid_width + xx];
|
||||
|
||||
if (!m.empty())
|
||||
vector<Point2i>& m = grid[yy * grid_width + xx];
|
||||
if (m.empty())
|
||||
continue;
|
||||
for(size_t j = 0; j < m.size(); j++)
|
||||
{
|
||||
for(size_t j = 0; j < m.size(); j++)
|
||||
{
|
||||
float dx = p.x - m[j].x;
|
||||
float dy = p.y - m[j].y;
|
||||
int dx = p.x - m[j].x;
|
||||
int dy = p.y - m[j].y;
|
||||
|
||||
if (dx * dx + dy * dy < minDistance * minDistance)
|
||||
{
|
||||
good = false;
|
||||
goto break_out;
|
||||
}
|
||||
if (dx * dx + dy * dy < D2)
|
||||
{
|
||||
good = false;
|
||||
goto break_out_;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break_out:
|
||||
break_out_:
|
||||
|
||||
if(good)
|
||||
{
|
||||
grid[y_cell * grid_width + x_cell].push_back(p);
|
||||
grid[y_cell * grid_width + x_cell].push_back(Point2i(p.x,p.y));
|
||||
|
||||
tmp2.push_back(p);
|
||||
tmp2.push_back(Point2f(p.x,p.y));
|
||||
|
||||
if (maxCorners > 0 && tmp2.size() == static_cast<size_t>(maxCorners))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
corners.upload(Mat(1, static_cast<int>(tmp2.size()), CV_32FC2, &tmp2[0]));
|
||||
}
|
||||
int final_size = static_cast<int>(tmp2.size());
|
||||
if(final_size>0)
|
||||
corners.upload(Mat(1, final_size, CV_32FC2, &tmp2[0]));
|
||||
else
|
||||
corners.release();
|
||||
}
|
||||
void cv::ocl::GoodFeaturesToTrackDetector_OCL::downloadPoints(const oclMat &points, vector<Point2f> &points_v)
|
||||
{
|
||||
|
||||
+49
-20
@@ -866,16 +866,17 @@ CvSeq *cv::ocl::OclCascadeClassifier::oclHaarDetectObjects( oclMat &gimg, CvMemS
|
||||
|
||||
if(gcascade->is_stump_based && gsum.clCxt->supportsFeature(FEATURE_CL_INTEL_DEVICE))
|
||||
{
|
||||
//setup local group size
|
||||
localThreads[0] = 8;
|
||||
localThreads[1] = 16;
|
||||
//setup local group size for "pixel step" = 1
|
||||
localThreads[0] = 16;
|
||||
localThreads[1] = 32;
|
||||
localThreads[2] = 1;
|
||||
|
||||
//init maximal number of workgroups
|
||||
//calc maximal number of workgroups
|
||||
int WGNumX = 1+(sizev[0].width /(localThreads[0]));
|
||||
int WGNumY = 1+(sizev[0].height/(localThreads[1]));
|
||||
int WGNumZ = loopcount;
|
||||
int WGNum = 0; //accurate number of non -empty workgroups
|
||||
int WGNumTotal = 0; //accurate number of non-empty workgroups
|
||||
int WGNumSampled = 0; //accurate number of workgroups processed only 1/4 part of all pixels. it is made for large images with scale <= 2
|
||||
oclMat oclWGInfo(1,sizeof(cl_int4) * WGNumX*WGNumY*WGNumZ,CV_8U);
|
||||
{
|
||||
cl_int4* pWGInfo = (cl_int4*)clEnqueueMapBuffer(getClCommandQueue(oclWGInfo.clCxt),(cl_mem)oclWGInfo.datastart,true,CL_MAP_WRITE, 0, oclWGInfo.step, 0,0,0,&status);
|
||||
@@ -895,12 +896,16 @@ CvSeq *cv::ocl::OclCascadeClassifier::oclHaarDetectObjects( oclMat &gimg, CvMemS
|
||||
if(gx>=(Width-cascade->orig_window_size.width))
|
||||
continue; // no data to process
|
||||
|
||||
if(scaleinfo[z].factor<=2)
|
||||
{
|
||||
WGNumSampled++;
|
||||
}
|
||||
// save no-empty workgroup info into array
|
||||
pWGInfo[WGNum].s[0] = scaleinfo[z].width_height;
|
||||
pWGInfo[WGNum].s[1] = (gx << 16) | gy;
|
||||
pWGInfo[WGNum].s[2] = scaleinfo[z].imgoff;
|
||||
memcpy(&(pWGInfo[WGNum].s[3]),&(scaleinfo[z].factor),sizeof(float));
|
||||
WGNum++;
|
||||
pWGInfo[WGNumTotal].s[0] = scaleinfo[z].width_height;
|
||||
pWGInfo[WGNumTotal].s[1] = (gx << 16) | gy;
|
||||
pWGInfo[WGNumTotal].s[2] = scaleinfo[z].imgoff;
|
||||
memcpy(&(pWGInfo[WGNumTotal].s[3]),&(scaleinfo[z].factor),sizeof(float));
|
||||
WGNumTotal++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -908,13 +913,8 @@ CvSeq *cv::ocl::OclCascadeClassifier::oclHaarDetectObjects( oclMat &gimg, CvMemS
|
||||
pWGInfo = NULL;
|
||||
}
|
||||
|
||||
// setup global sizes to have linear array of workgroups with WGNum size
|
||||
globalThreads[0] = localThreads[0]*WGNum;
|
||||
globalThreads[1] = localThreads[1];
|
||||
globalThreads[2] = 1;
|
||||
|
||||
#define NODE_SIZE 12
|
||||
// pack node info to have less memory loads
|
||||
// pack node info to have less memory loads on the device side
|
||||
oclMat oclNodesPK(1,sizeof(cl_int) * NODE_SIZE * nodenum,CV_8U);
|
||||
{
|
||||
cl_int status;
|
||||
@@ -963,8 +963,6 @@ CvSeq *cv::ocl::OclCascadeClassifier::oclHaarDetectObjects( oclMat &gimg, CvMemS
|
||||
options += format(" -D WND_SIZE_X=%d",cascade->orig_window_size.width);
|
||||
options += format(" -D WND_SIZE_Y=%d",cascade->orig_window_size.height);
|
||||
options += format(" -D STUMP_BASED=%d",gcascade->is_stump_based);
|
||||
options += format(" -D LSx=%d",localThreads[0]);
|
||||
options += format(" -D LSy=%d",localThreads[1]);
|
||||
options += format(" -D SPLITNODE=%d",splitnode);
|
||||
options += format(" -D SPLITSTAGE=%d",splitstage);
|
||||
options += format(" -D OUTPUTSZ=%d",outputsz);
|
||||
@@ -972,8 +970,39 @@ CvSeq *cv::ocl::OclCascadeClassifier::oclHaarDetectObjects( oclMat &gimg, CvMemS
|
||||
// init candiate global count by 0
|
||||
int pattern = 0;
|
||||
openCLSafeCall(clEnqueueWriteBuffer(qu, candidatebuffer, 1, 0, 1 * sizeof(pattern),&pattern, 0, NULL, NULL));
|
||||
// execute face detector
|
||||
openCLExecuteKernel(gsum.clCxt, &haarobjectdetect, "gpuRunHaarClassifierCascadePacked", globalThreads, localThreads, args, -1, -1, options.c_str());
|
||||
|
||||
if(WGNumTotal>WGNumSampled)
|
||||
{// small images and each pixel is processed
|
||||
// setup global sizes to have linear array of workgroups with WGNum size
|
||||
int pixelstep = 1;
|
||||
size_t LS[3]={localThreads[0]/pixelstep,localThreads[1]/pixelstep,1};
|
||||
globalThreads[0] = LS[0]*(WGNumTotal-WGNumSampled);
|
||||
globalThreads[1] = LS[1];
|
||||
globalThreads[2] = 1;
|
||||
string options1 = options;
|
||||
options1 += format(" -D PIXEL_STEP=%d",pixelstep);
|
||||
options1 += format(" -D WGSTART=%d",WGNumSampled);
|
||||
options1 += format(" -D LSx=%d",LS[0]);
|
||||
options1 += format(" -D LSy=%d",LS[1]);
|
||||
// execute face detector
|
||||
openCLExecuteKernel(gsum.clCxt, &haarobjectdetect, "gpuRunHaarClassifierCascadePacked", globalThreads, LS, args, -1, -1, options1.c_str());
|
||||
}
|
||||
if(WGNumSampled>0)
|
||||
{// large images each 4th pixel is processed
|
||||
// setup global sizes to have linear array of workgroups with WGNum size
|
||||
int pixelstep = 2;
|
||||
size_t LS[3]={localThreads[0]/pixelstep,localThreads[1]/pixelstep,1};
|
||||
globalThreads[0] = LS[0]*WGNumSampled;
|
||||
globalThreads[1] = LS[1];
|
||||
globalThreads[2] = 1;
|
||||
string options2 = options;
|
||||
options2 += format(" -D PIXEL_STEP=%d",pixelstep);
|
||||
options2 += format(" -D WGSTART=%d",0);
|
||||
options2 += format(" -D LSx=%d",LS[0]);
|
||||
options2 += format(" -D LSy=%d",LS[1]);
|
||||
// execute face detector
|
||||
openCLExecuteKernel(gsum.clCxt, &haarobjectdetect, "gpuRunHaarClassifierCascadePacked", globalThreads, LS, args, -1, -1, options2.c_str());
|
||||
}
|
||||
//read candidate buffer back and put it into host list
|
||||
openCLReadBuffer( gsum.clCxt, candidatebuffer, candidate, 4 * sizeof(int)*outputsz );
|
||||
assert(candidate[0]<outputsz);
|
||||
|
||||
+20
-4
@@ -76,6 +76,11 @@ namespace cv
|
||||
int cdescr_width;
|
||||
int cdescr_height;
|
||||
|
||||
// A shift value and type that allows qangle to be different
|
||||
// sizes on different hardware
|
||||
int qangle_step_shift;
|
||||
int qangle_type;
|
||||
|
||||
void set_up_constants(int nbins, int block_stride_x, int block_stride_y,
|
||||
int nblocks_win_x, int nblocks_win_y);
|
||||
|
||||
@@ -153,6 +158,7 @@ cv::ocl::HOGDescriptor::HOGDescriptor(Size win_size_, Size block_size_, Size blo
|
||||
hog_device_cpu = true;
|
||||
else
|
||||
hog_device_cpu = false;
|
||||
|
||||
}
|
||||
|
||||
size_t cv::ocl::HOGDescriptor::getDescriptorSize() const
|
||||
@@ -213,7 +219,7 @@ void cv::ocl::HOGDescriptor::init_buffer(const oclMat &img, Size win_stride)
|
||||
effect_size = img.size();
|
||||
|
||||
grad.create(img.size(), CV_32FC2);
|
||||
qangle.create(img.size(), CV_8UC2);
|
||||
qangle.create(img.size(), hog::qangle_type);
|
||||
|
||||
const size_t block_hist_size = getBlockHistogramSize();
|
||||
const Size blocks_per_img = numPartsWithin(img.size(), block_size, block_stride);
|
||||
@@ -1607,6 +1613,16 @@ void cv::ocl::device::hog::set_up_constants(int nbins,
|
||||
|
||||
int descr_size = descr_width * nblocks_win_y;
|
||||
cdescr_size = descr_size;
|
||||
|
||||
qangle_type = CV_8UC2;
|
||||
qangle_step_shift = 0;
|
||||
// Some Intel devices have low single-byte access performance,
|
||||
// so we change the datatype here.
|
||||
if (Context::getContext()->supportsFeature(FEATURE_CL_INTEL_DEVICE))
|
||||
{
|
||||
qangle_type = CV_32SC2;
|
||||
qangle_step_shift = 2;
|
||||
}
|
||||
}
|
||||
|
||||
void cv::ocl::device::hog::compute_hists(int nbins,
|
||||
@@ -1628,7 +1644,7 @@ void cv::ocl::device::hog::compute_hists(int nbins,
|
||||
int blocks_total = img_block_width * img_block_height;
|
||||
|
||||
int grad_quadstep = grad.step >> 2;
|
||||
int qangle_step = qangle.step;
|
||||
int qangle_step = qangle.step >> qangle_step_shift;
|
||||
|
||||
int blocks_in_group = 4;
|
||||
size_t localThreads[3] = { blocks_in_group * 24, 2, 1 };
|
||||
@@ -1892,7 +1908,7 @@ void cv::ocl::device::hog::compute_gradients_8UC1(int height, int width,
|
||||
char correctGamma = (correct_gamma) ? 1 : 0;
|
||||
int img_step = img.step;
|
||||
int grad_quadstep = grad.step >> 3;
|
||||
int qangle_step = qangle.step >> 1;
|
||||
int qangle_step = qangle.step >> (1 + qangle_step_shift);
|
||||
|
||||
args.push_back( make_pair( sizeof(cl_int), (void *)&height));
|
||||
args.push_back( make_pair( sizeof(cl_int), (void *)&width));
|
||||
@@ -1927,7 +1943,7 @@ void cv::ocl::device::hog::compute_gradients_8UC4(int height, int width,
|
||||
char correctGamma = (correct_gamma) ? 1 : 0;
|
||||
int img_step = img.step >> 2;
|
||||
int grad_quadstep = grad.step >> 3;
|
||||
int qangle_step = qangle.step >> 1;
|
||||
int qangle_step = qangle.step >> (1 + qangle_step_shift);
|
||||
|
||||
args.push_back( make_pair( sizeof(cl_int), (void *)&height));
|
||||
args.push_back( make_pair( sizeof(cl_int), (void *)&width));
|
||||
|
||||
+104
-54
@@ -1033,67 +1033,117 @@ namespace cv
|
||||
else
|
||||
scale = 1. / scale;
|
||||
|
||||
if (ksize > 0)
|
||||
const int sobel_lsz = 16;
|
||||
if((src.type() == CV_8UC1 || src.type() == CV_32FC1) &&
|
||||
(ksize==3 || ksize==5 || ksize==7 || ksize==-1) &&
|
||||
src.wholerows > sobel_lsz + (ksize>>1) &&
|
||||
src.wholecols > sobel_lsz + (ksize>>1))
|
||||
{
|
||||
Context* clCxt = Context::getContext();
|
||||
if(clCxt->supportsFeature(FEATURE_CL_INTEL_DEVICE) && src.type() == CV_8UC1 &&
|
||||
src.cols % 8 == 0 && src.rows % 8 == 0 &&
|
||||
ksize==3 &&
|
||||
(borderType ==cv::BORDER_REFLECT ||
|
||||
borderType == cv::BORDER_REPLICATE ||
|
||||
borderType ==cv::BORDER_REFLECT101 ||
|
||||
borderType ==cv::BORDER_WRAP))
|
||||
Dx.create(src.size(), CV_32FC1);
|
||||
Dy.create(src.size(), CV_32FC1);
|
||||
|
||||
CV_Assert(Dx.rows == Dy.rows && Dx.cols == Dy.cols);
|
||||
|
||||
size_t lt2[3] = {sobel_lsz, sobel_lsz, 1};
|
||||
size_t gt2[3] = {lt2[0]*(1 + (src.cols-1) / lt2[0]), lt2[1]*(1 + (src.rows-1) / lt2[1]), 1};
|
||||
|
||||
unsigned int src_pitch = src.step;
|
||||
unsigned int Dx_pitch = Dx.step;
|
||||
unsigned int Dy_pitch = Dy.step;
|
||||
|
||||
int src_offset_x = (src.offset % src.step) / src.elemSize();
|
||||
int src_offset_y = src.offset / src.step;
|
||||
|
||||
float _scale = scale;
|
||||
|
||||
std::vector<std::pair<size_t , const void *> > args;
|
||||
args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&src.data ));
|
||||
args.push_back( std::make_pair( sizeof(cl_uint) , (void *)&src_pitch ));
|
||||
|
||||
args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src_offset_x ));
|
||||
args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src_offset_y ));
|
||||
|
||||
args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&Dx.data ));
|
||||
args.push_back( std::make_pair( sizeof(cl_int) , (void *)&Dx.offset ));
|
||||
args.push_back( std::make_pair( sizeof(cl_uint) , (void *)&Dx_pitch ));
|
||||
args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&Dy.data ));
|
||||
args.push_back( std::make_pair( sizeof(cl_int) , (void *)&Dy.offset ));
|
||||
args.push_back( std::make_pair( sizeof(cl_uint) , (void *)&Dy_pitch ));
|
||||
|
||||
args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src.wholecols ));
|
||||
args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src.wholerows ));
|
||||
|
||||
args.push_back( std::make_pair( sizeof(cl_int) , (void *)&Dx.cols ));
|
||||
args.push_back( std::make_pair( sizeof(cl_int) , (void *)&Dx.rows ));
|
||||
|
||||
args.push_back( std::make_pair( sizeof(cl_float), (void *)&_scale ));
|
||||
|
||||
string option = cv::format("-D BLK_X=%d -D BLK_Y=%d",(int)lt2[0],(int)lt2[1]);
|
||||
switch(src.type())
|
||||
{
|
||||
Dx.create(src.size(), CV_32FC1);
|
||||
Dy.create(src.size(), CV_32FC1);
|
||||
|
||||
const unsigned int block_x = 8;
|
||||
const unsigned int block_y = 8;
|
||||
|
||||
unsigned int src_pitch = src.step;
|
||||
unsigned int dst_pitch = Dx.cols;
|
||||
|
||||
float _scale = scale;
|
||||
|
||||
std::vector<std::pair<size_t , const void *> > args;
|
||||
args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&src.data ));
|
||||
args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&Dx.data ));
|
||||
args.push_back( std::make_pair( sizeof(cl_mem) , (void *)&Dy.data ));
|
||||
args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src.cols ));
|
||||
args.push_back( std::make_pair( sizeof(cl_int) , (void *)&src.rows ));
|
||||
args.push_back( std::make_pair( sizeof(cl_uint) , (void *)&src_pitch ));
|
||||
args.push_back( std::make_pair( sizeof(cl_uint) , (void *)&dst_pitch ));
|
||||
args.push_back( std::make_pair( sizeof(cl_float) , (void *)&_scale ));
|
||||
size_t gt2[3] = {src.cols, src.rows, 1}, lt2[3] = {block_x, block_y, 1};
|
||||
|
||||
string option = "-D BLK_X=8 -D BLK_Y=8";
|
||||
switch(borderType)
|
||||
{
|
||||
case cv::BORDER_REPLICATE:
|
||||
option += " -D BORDER_REPLICATE";
|
||||
break;
|
||||
case cv::BORDER_REFLECT:
|
||||
option += " -D BORDER_REFLECT";
|
||||
break;
|
||||
case cv::BORDER_REFLECT101:
|
||||
option += " -D BORDER_REFLECT101";
|
||||
break;
|
||||
case cv::BORDER_WRAP:
|
||||
option += " -D BORDER_WRAP";
|
||||
break;
|
||||
}
|
||||
openCLExecuteKernel(src.clCxt, &imgproc_sobel3, "sobel3", gt2, lt2, args, -1, -1, option.c_str() );
|
||||
case CV_8UC1:
|
||||
option += " -D SRCTYPE=uchar";
|
||||
break;
|
||||
case CV_32FC1:
|
||||
option += " -D SRCTYPE=float";
|
||||
break;
|
||||
}
|
||||
else
|
||||
switch(borderType)
|
||||
{
|
||||
case cv::BORDER_CONSTANT:
|
||||
option += " -D BORDER_CONSTANT";
|
||||
break;
|
||||
case cv::BORDER_REPLICATE:
|
||||
option += " -D BORDER_REPLICATE";
|
||||
break;
|
||||
case cv::BORDER_REFLECT:
|
||||
option += " -D BORDER_REFLECT";
|
||||
break;
|
||||
case cv::BORDER_REFLECT101:
|
||||
option += " -D BORDER_REFLECT_101";
|
||||
break;
|
||||
case cv::BORDER_WRAP:
|
||||
option += " -D BORDER_WRAP";
|
||||
break;
|
||||
default:
|
||||
CV_Error(CV_StsBadFlag, "BORDER type is not supported!");
|
||||
break;
|
||||
}
|
||||
|
||||
string kernel_name;
|
||||
switch(ksize)
|
||||
{
|
||||
case -1:
|
||||
option += " -D SCHARR";
|
||||
kernel_name = "sobel3";
|
||||
break;
|
||||
case 3:
|
||||
kernel_name = "sobel3";
|
||||
break;
|
||||
case 5:
|
||||
kernel_name = "sobel5";
|
||||
break;
|
||||
case 7:
|
||||
kernel_name = "sobel7";
|
||||
break;
|
||||
default:
|
||||
CV_Error(CV_StsBadFlag, "Kernel size is not supported!");
|
||||
break;
|
||||
}
|
||||
openCLExecuteKernel(src.clCxt, &imgproc_sobel3, kernel_name, gt2, lt2, args, -1, -1, option.c_str() );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ksize > 0)
|
||||
{
|
||||
Sobel(src, Dx, CV_32F, 1, 0, ksize, scale, 0, borderType);
|
||||
Sobel(src, Dy, CV_32F, 0, 1, ksize, scale, 0, borderType);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Scharr(src, Dx, CV_32F, 1, 0, scale, 0, borderType);
|
||||
Scharr(src, Dy, CV_32F, 0, 1, scale, 0, borderType);
|
||||
else
|
||||
{
|
||||
Scharr(src, Dx, CV_32F, 1, 0, scale, 0, borderType);
|
||||
Scharr(src, Dy, CV_32F, 0, 1, scale, 0, borderType);
|
||||
}
|
||||
}
|
||||
CV_Assert(Dx.offset == 0 && Dy.offset == 0);
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ inline float sum(float val)
|
||||
return val;
|
||||
}
|
||||
|
||||
static float clamp1(float var, float learningRate, float diff, float minVar)
|
||||
inline float clamp1(float var, float learningRate, float diff, float minVar)
|
||||
{
|
||||
return fmax(var + learningRate * (diff * diff - var), minVar);
|
||||
}
|
||||
@@ -96,7 +96,7 @@ inline float sum(const float4 val)
|
||||
return (val.x + val.y + val.z);
|
||||
}
|
||||
|
||||
static void swap4(__global float4* ptr, int x, int y, int k, int rows, int ptr_step)
|
||||
inline void swap4(__global float4* ptr, int x, int y, int k, int rows, int ptr_step)
|
||||
{
|
||||
float4 val = ptr[(k * rows + y) * ptr_step + x];
|
||||
ptr[(k * rows + y) * ptr_step + x] = ptr[((k + 1) * rows + y) * ptr_step + x];
|
||||
@@ -104,7 +104,7 @@ static void swap4(__global float4* ptr, int x, int y, int k, int rows, int ptr_s
|
||||
}
|
||||
|
||||
|
||||
static float4 clamp1(const float4 var, float learningRate, const float4 diff, float minVar)
|
||||
inline float4 clamp1(const float4 var, float learningRate, const float4 diff, float minVar)
|
||||
{
|
||||
float4 result;
|
||||
result.x = fmax(var.x + learningRate * (diff.x * diff.x - var.x), minVar);
|
||||
@@ -128,7 +128,7 @@ typedef struct
|
||||
uchar c_shadowVal;
|
||||
} con_srtuct_t;
|
||||
|
||||
static void swap(__global float* ptr, int x, int y, int k, int rows, int ptr_step)
|
||||
inline void swap(__global float* ptr, int x, int y, int k, int rows, int ptr_step)
|
||||
{
|
||||
float val = ptr[(k * rows + y) * ptr_step + x];
|
||||
ptr[(k * rows + y) * ptr_step + x] = ptr[((k + 1) * rows + y) * ptr_step + x];
|
||||
|
||||
+713
-131
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,185 @@
|
||||
/*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) 2013, 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 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*/
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////Macro for border type////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef BORDER_CONSTANT
|
||||
//CCCCCC|abcdefgh|CCCCCCC
|
||||
#define EXTRAPOLATE(x, maxV)
|
||||
#elif defined BORDER_REPLICATE
|
||||
//aaaaaa|abcdefgh|hhhhhhh
|
||||
#define EXTRAPOLATE(x, maxV) \
|
||||
{ \
|
||||
(x) = max(min((x), (maxV) - 1), 0); \
|
||||
}
|
||||
#elif defined BORDER_WRAP
|
||||
//cdefgh|abcdefgh|abcdefg
|
||||
#define EXTRAPOLATE(x, maxV) \
|
||||
{ \
|
||||
(x) = ( (x) + (maxV) ) % (maxV); \
|
||||
}
|
||||
#elif defined BORDER_REFLECT
|
||||
//fedcba|abcdefgh|hgfedcb
|
||||
#define EXTRAPOLATE(x, maxV) \
|
||||
{ \
|
||||
(x) = min(((maxV)-1)*2-(x)+1, max((x),-(x)-1) ); \
|
||||
}
|
||||
#elif defined BORDER_REFLECT_101
|
||||
//gfedcb|abcdefgh|gfedcba
|
||||
#define EXTRAPOLATE(x, maxV) \
|
||||
{ \
|
||||
(x) = min(((maxV)-1)*2-(x), max((x),-(x)) ); \
|
||||
}
|
||||
#else
|
||||
#error No extrapolation method
|
||||
#endif
|
||||
|
||||
#define SRC(_x,_y) CONVERT_SRCTYPE(((global SRCTYPE*)(Src+(_y)*SrcPitch))[_x])
|
||||
|
||||
#ifdef BORDER_CONSTANT
|
||||
//CCCCCC|abcdefgh|CCCCCCC
|
||||
#define ELEM(_x,_y,r_edge,t_edge,const_v) (_x)<0 | (_x) >= (r_edge) | (_y)<0 | (_y) >= (t_edge) ? (const_v) : SRC((_x),(_y))
|
||||
#else
|
||||
#define ELEM(_x,_y,r_edge,t_edge,const_v) SRC((_x),(_y))
|
||||
#endif
|
||||
|
||||
#define DST(_x,_y) (((global DSTTYPE*)(Dst+DstOffset+(_y)*DstPitch))[_x])
|
||||
|
||||
//horizontal and vertical filter kernels
|
||||
//should be defined on host during compile time to avoid overhead
|
||||
__constant uint mat_kernelX[] = {KERNEL_MATRIX_X};
|
||||
__constant uint mat_kernelY[] = {KERNEL_MATRIX_Y};
|
||||
|
||||
__kernel __attribute__((reqd_work_group_size(BLK_X,BLK_Y,1))) void sep_filter_singlepass
|
||||
(
|
||||
__global uchar* Src,
|
||||
const uint SrcPitch,
|
||||
const int srcOffsetX,
|
||||
const int srcOffsetY,
|
||||
__global uchar* Dst,
|
||||
const int DstOffset,
|
||||
const uint DstPitch,
|
||||
int width,
|
||||
int height,
|
||||
int dstWidth,
|
||||
int dstHeight
|
||||
)
|
||||
{
|
||||
//RADIUSX, RADIUSY are filter dimensions
|
||||
//BLK_X, BLK_Y are local wrogroup sizes
|
||||
//all these should be defined on host during compile time
|
||||
//first lsmem array for source pixels used in first pass,
|
||||
//second lsmemDy for storing first pass results
|
||||
__local WORKTYPE lsmem[BLK_Y+2*RADIUSY][BLK_X+2*RADIUSX];
|
||||
__local WORKTYPE lsmemDy[BLK_Y][BLK_X+2*RADIUSX];
|
||||
|
||||
//get local and global ids - used as image and local memory array indexes
|
||||
int lix = get_local_id(0);
|
||||
int liy = get_local_id(1);
|
||||
|
||||
int x = (int)get_global_id(0);
|
||||
int y = (int)get_global_id(1);
|
||||
|
||||
//calculate pixel position in source image taking image offset into account
|
||||
int srcX = x + srcOffsetX - RADIUSX;
|
||||
int srcY = y + srcOffsetY - RADIUSY;
|
||||
int xb = srcX;
|
||||
int yb = srcY;
|
||||
|
||||
//extrapolate coordinates, if needed
|
||||
//and read my own source pixel into local memory
|
||||
//with account for extra border pixels, which will be read by starting workitems
|
||||
int clocY = liy;
|
||||
int cSrcY = srcY;
|
||||
do
|
||||
{
|
||||
int yb = cSrcY;
|
||||
EXTRAPOLATE(yb, (height));
|
||||
|
||||
int clocX = lix;
|
||||
int cSrcX = srcX;
|
||||
do
|
||||
{
|
||||
int xb = cSrcX;
|
||||
EXTRAPOLATE(xb,(width));
|
||||
lsmem[clocY][clocX] = ELEM(xb, yb, (width), (height), 0 );
|
||||
|
||||
clocX += BLK_X;
|
||||
cSrcX += BLK_X;
|
||||
}
|
||||
while(clocX < BLK_X+(RADIUSX*2));
|
||||
|
||||
clocY += BLK_Y;
|
||||
cSrcY += BLK_Y;
|
||||
}
|
||||
while(clocY < BLK_Y+(RADIUSY*2));
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
|
||||
//do vertical filter pass
|
||||
//and store intermediate results to second local memory array
|
||||
int i;
|
||||
WORKTYPE sum = 0.0f;
|
||||
int clocX = lix;
|
||||
do
|
||||
{
|
||||
sum = 0.0f;
|
||||
for(i=0; i<=2*RADIUSY; i++)
|
||||
sum = mad(lsmem[liy+i][clocX], as_float(mat_kernelY[i]), sum);
|
||||
lsmemDy[liy][clocX] = sum;
|
||||
clocX += BLK_X;
|
||||
}
|
||||
while(clocX < BLK_X+(RADIUSX*2));
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
|
||||
//if this pixel happened to be out of image borders because of global size rounding,
|
||||
//then just return
|
||||
if( x >= dstWidth || y >=dstHeight ) return;
|
||||
|
||||
//do second horizontal filter pass
|
||||
//and calculate final result
|
||||
sum = 0.0f;
|
||||
for(i=0; i<=2*RADIUSX; i++)
|
||||
sum = mad(lsmemDy[liy][lix+i], as_float(mat_kernelX[i]), sum);
|
||||
|
||||
//store result into destination image
|
||||
DST(x,y) = CONVERT_DSTTYPE(sum);
|
||||
}
|
||||
@@ -126,13 +126,11 @@ __kernel void gpuRunHaarClassifierCascadePacked(
|
||||
)
|
||||
|
||||
{
|
||||
// this version used information provided for each workgroup
|
||||
// no empty WG
|
||||
int gid = (int)get_group_id(0);
|
||||
int lid_x = (int)get_local_id(0);
|
||||
int lid_y = (int)get_local_id(1);
|
||||
int lid = lid_y*LSx+lid_x;
|
||||
int4 WGInfo = pWGInfo[gid];
|
||||
int4 WGInfo = pWGInfo[WGSTART+gid];
|
||||
int GroupX = (WGInfo.y >> 16)&0xFFFF;
|
||||
int GroupY = (WGInfo.y >> 0 )& 0xFFFF;
|
||||
int Width = (WGInfo.x >> 16)&0xFFFF;
|
||||
@@ -140,8 +138,8 @@ __kernel void gpuRunHaarClassifierCascadePacked(
|
||||
int ImgOffset = WGInfo.z;
|
||||
float ScaleFactor = as_float(WGInfo.w);
|
||||
|
||||
#define DATA_SIZE_X (LSx+WND_SIZE_X)
|
||||
#define DATA_SIZE_Y (LSy+WND_SIZE_Y)
|
||||
#define DATA_SIZE_X (PIXEL_STEP*LSx+WND_SIZE_X)
|
||||
#define DATA_SIZE_Y (PIXEL_STEP*LSy+WND_SIZE_Y)
|
||||
#define DATA_SIZE (DATA_SIZE_X*DATA_SIZE_Y)
|
||||
|
||||
local int SumL[DATA_SIZE];
|
||||
@@ -165,9 +163,11 @@ __kernel void gpuRunHaarClassifierCascadePacked(
|
||||
int4 info1 = p;
|
||||
int4 info2 = pq;
|
||||
|
||||
{
|
||||
int xl = lid_x;
|
||||
int yl = lid_y;
|
||||
// calc processed ROI coordinate in local mem
|
||||
int xl = lid_x*PIXEL_STEP;
|
||||
int yl = lid_y*PIXEL_STEP;
|
||||
|
||||
{// calc variance_norm_factor for all stages
|
||||
int OffsetLocal = yl * DATA_SIZE_X + xl;
|
||||
int OffsetGlobal = (GroupY+yl)* pixelstep + (GroupX+xl);
|
||||
|
||||
@@ -194,13 +194,13 @@ __kernel void gpuRunHaarClassifierCascadePacked(
|
||||
|
||||
int result = (1.0f>0.0f);
|
||||
for(int stageloop = start_stage; (stageloop < end_stage) && result; stageloop++ )
|
||||
{// iterate until candidate is exist
|
||||
{// iterate until candidate is valid
|
||||
float stage_sum = 0.0f;
|
||||
__global GpuHidHaarStageClassifier* stageinfo = (__global GpuHidHaarStageClassifier*)
|
||||
((__global uchar*)stagecascadeptr+stageloop*sizeof(GpuHidHaarStageClassifier));
|
||||
int lcl_off = (yl*DATA_SIZE_X)+(xl);
|
||||
int stagecount = stageinfo->count;
|
||||
float stagethreshold = stageinfo->threshold;
|
||||
int lcl_off = (lid_y*DATA_SIZE_X)+(lid_x);
|
||||
for(int nodeloop = 0; nodeloop < stagecount; nodecounter++,nodeloop++ )
|
||||
{
|
||||
// simple macro to extract shorts from int
|
||||
@@ -212,7 +212,7 @@ __kernel void gpuRunHaarClassifierCascadePacked(
|
||||
int4 n1 = pN[1];
|
||||
int4 n2 = pN[2];
|
||||
float nodethreshold = as_float(n2.y) * variance_norm_factor;
|
||||
// calc sum of intensity pixels according to node information
|
||||
// calc sum of intensity pixels according to classifier node information
|
||||
float classsum =
|
||||
(SumL[M0(n0.x)+lcl_off] - SumL[M1(n0.x)+lcl_off] - SumL[M0(n0.y)+lcl_off] + SumL[M1(n0.y)+lcl_off]) * as_float(n1.z) +
|
||||
(SumL[M0(n0.z)+lcl_off] - SumL[M1(n0.z)+lcl_off] - SumL[M0(n0.w)+lcl_off] + SumL[M1(n0.w)+lcl_off]) * as_float(n1.w) +
|
||||
@@ -228,8 +228,8 @@ __kernel void gpuRunHaarClassifierCascadePacked(
|
||||
int index = 1+atomic_inc((volatile global int*)candidate); //get index to write global data with face info
|
||||
if(index<OUTPUTSZ)
|
||||
{
|
||||
int x = GroupX+lid_x;
|
||||
int y = GroupY+lid_y;
|
||||
int x = GroupX+xl;
|
||||
int y = GroupY+yl;
|
||||
int4 candidate_result;
|
||||
candidate_result.x = convert_int_rtn(x*ScaleFactor);
|
||||
candidate_result.y = convert_int_rtn(y*ScaleFactor);
|
||||
|
||||
@@ -381,8 +381,8 @@ struct PtrStepSz {
|
||||
int step;
|
||||
int rows, cols;
|
||||
};
|
||||
inline int get(struct PtrStepSz data, int y, int x) { return *((__global int *)((__global char*)data.ptr + data.step * y + sizeof(int) * x)); }
|
||||
inline void set(struct PtrStepSz data, int y, int x, int value) { *((__global int *)((__global char*)data.ptr + data.step * y + sizeof(int) * x)) = value; }
|
||||
inline int get(struct PtrStepSz data, int y, int x) { return *((__global int *)((__global char*)data.ptr + data.step * (y + 1) + sizeof(int) * (x + 1))); }
|
||||
inline void set(struct PtrStepSz data, int y, int x, int value) { *((__global int *)((__global char*)data.ptr + data.step * (y + 1) + sizeof(int) * (x + 1))) = value; }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// do Hysteresis for pixel whose edge type is 1
|
||||
@@ -494,7 +494,7 @@ edgesHysteresisLocal
|
||||
}
|
||||
}
|
||||
#else
|
||||
struct PtrStepSz map = {((__global int *)((__global char*)map_ptr + map_offset)), map_step, rows, cols};
|
||||
struct PtrStepSz map = {((__global int *)((__global char*)map_ptr + map_offset)), map_step, rows + 1, cols + 1};
|
||||
|
||||
__local int smem[18][18];
|
||||
|
||||
@@ -507,13 +507,13 @@ edgesHysteresisLocal
|
||||
|
||||
smem[threadIdx.y + 1][threadIdx.x + 1] = x < map.cols && y < map.rows ? get(map, y, x) : 0;
|
||||
if (threadIdx.y == 0)
|
||||
smem[0][threadIdx.x + 1] = y > 0 ? get(map, y - 1, x) : 0;
|
||||
smem[0][threadIdx.x + 1] = x < map.cols ? get(map, y - 1, x) : 0;
|
||||
if (threadIdx.y == blockDim.y - 1)
|
||||
smem[blockDim.y + 1][threadIdx.x + 1] = y + 1 < map.rows ? get(map, y + 1, x) : 0;
|
||||
if (threadIdx.x == 0)
|
||||
smem[threadIdx.y + 1][0] = x > 0 ? get(map, y, x - 1) : 0;
|
||||
smem[threadIdx.y + 1][0] = y < map.rows ? get(map, y, x - 1) : 0;
|
||||
if (threadIdx.x == blockDim.x - 1)
|
||||
smem[threadIdx.y + 1][blockDim.x + 1] = x + 1 < map.cols ? get(map, y, x + 1) : 0;
|
||||
smem[threadIdx.y + 1][blockDim.x + 1] = x + 1 < map.cols && y < map.rows ? get(map, y, x + 1) : 0;
|
||||
if (threadIdx.x == 0 && threadIdx.y == 0)
|
||||
smem[0][0] = y > 0 && x > 0 ? get(map, y - 1, x - 1) : 0;
|
||||
if (threadIdx.x == blockDim.x - 1 && threadIdx.y == 0)
|
||||
@@ -525,7 +525,7 @@ edgesHysteresisLocal
|
||||
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
|
||||
if (x >= map.cols || y >= map.rows)
|
||||
if (x >= cols || y >= rows)
|
||||
return;
|
||||
|
||||
int n;
|
||||
@@ -576,7 +576,7 @@ edgesHysteresisLocal
|
||||
if (n > 0)
|
||||
{
|
||||
const int ind = atomic_inc(counter);
|
||||
st[ind] = (ushort2)(x, y);
|
||||
st[ind] = (ushort2)(x + 1, y + 1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -46,33 +46,26 @@
|
||||
#ifndef WITH_MASK
|
||||
#define WITH_MASK 0
|
||||
#endif
|
||||
|
||||
__constant sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_NEAREST;
|
||||
|
||||
inline float ELEM_INT2(image2d_t _eig, int _x, int _y)
|
||||
{
|
||||
return read_imagef(_eig, sampler, (int2)(_x, _y)).x;
|
||||
}
|
||||
|
||||
inline float ELEM_FLT2(image2d_t _eig, float2 pt)
|
||||
{
|
||||
return read_imagef(_eig, sampler, pt).x;
|
||||
}
|
||||
//macro to read eigenvalue matrix
|
||||
#define GET_SRC_32F(_x, _y) ((__global const float*)(eig + (_y)*eig_pitch))[_x]
|
||||
|
||||
__kernel
|
||||
void findCorners
|
||||
(
|
||||
image2d_t eig,
|
||||
__global const char * mask,
|
||||
__global float2 * corners,
|
||||
const int mask_strip,// in pixels
|
||||
const float threshold,
|
||||
const int rows,
|
||||
const int cols,
|
||||
const int max_count,
|
||||
__global int * g_counter
|
||||
__global const char* eig,
|
||||
const int eig_pitch,
|
||||
__global const char* mask,
|
||||
__global float2* corners,
|
||||
const int mask_strip,// in pixels
|
||||
__global const float* pMinMax,
|
||||
const float qualityLevel,
|
||||
const int rows,
|
||||
const int cols,
|
||||
const int max_count,
|
||||
__global int* g_counter
|
||||
)
|
||||
{
|
||||
float threshold = qualityLevel*pMinMax[1];
|
||||
const int j = get_global_id(0);
|
||||
const int i = get_global_id(1);
|
||||
|
||||
@@ -82,39 +75,42 @@ __kernel
|
||||
#endif
|
||||
)
|
||||
{
|
||||
const float val = ELEM_INT2(eig, j, i);
|
||||
const float val = GET_SRC_32F(j, i);
|
||||
|
||||
if (val > threshold)
|
||||
{
|
||||
float maxVal = val;
|
||||
maxVal = fmax(GET_SRC_32F(j - 1, i - 1), maxVal);
|
||||
maxVal = fmax(GET_SRC_32F(j , i - 1), maxVal);
|
||||
maxVal = fmax(GET_SRC_32F(j + 1, i - 1), maxVal);
|
||||
|
||||
maxVal = fmax(ELEM_INT2(eig, j - 1, i - 1), maxVal);
|
||||
maxVal = fmax(ELEM_INT2(eig, j , i - 1), maxVal);
|
||||
maxVal = fmax(ELEM_INT2(eig, j + 1, i - 1), maxVal);
|
||||
maxVal = fmax(GET_SRC_32F(j - 1, i), maxVal);
|
||||
maxVal = fmax(GET_SRC_32F(j + 1, i), maxVal);
|
||||
|
||||
maxVal = fmax(ELEM_INT2(eig, j - 1, i), maxVal);
|
||||
maxVal = fmax(ELEM_INT2(eig, j + 1, i), maxVal);
|
||||
|
||||
maxVal = fmax(ELEM_INT2(eig, j - 1, i + 1), maxVal);
|
||||
maxVal = fmax(ELEM_INT2(eig, j , i + 1), maxVal);
|
||||
maxVal = fmax(ELEM_INT2(eig, j + 1, i + 1), maxVal);
|
||||
maxVal = fmax(GET_SRC_32F(j - 1, i + 1), maxVal);
|
||||
maxVal = fmax(GET_SRC_32F(j , i + 1), maxVal);
|
||||
maxVal = fmax(GET_SRC_32F(j + 1, i + 1), maxVal);
|
||||
|
||||
if (val == maxVal)
|
||||
{
|
||||
const int ind = atomic_inc(g_counter);
|
||||
|
||||
if (ind < max_count)
|
||||
corners[ind] = (float2)(j, i);
|
||||
{// pack and store eigenvalue and its coordinates
|
||||
corners[ind].x = val;
|
||||
corners[ind].y = as_float(j|(i<<16));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef GET_SRC_32F
|
||||
|
||||
|
||||
//bitonic sort
|
||||
__kernel
|
||||
void sortCorners_bitonicSort
|
||||
(
|
||||
image2d_t eig,
|
||||
__global float2 * corners,
|
||||
const int count,
|
||||
const int stage,
|
||||
@@ -140,8 +136,8 @@ __kernel
|
||||
const float2 leftPt = corners[leftId];
|
||||
const float2 rightPt = corners[rightId];
|
||||
|
||||
const float leftVal = ELEM_FLT2(eig, leftPt);
|
||||
const float rightVal = ELEM_FLT2(eig, rightPt);
|
||||
const float leftVal = leftPt.x;
|
||||
const float rightVal = rightPt.x;
|
||||
|
||||
const bool compareResult = leftVal > rightVal;
|
||||
|
||||
@@ -152,124 +148,22 @@ __kernel
|
||||
corners[rightId] = sortOrder ? greater : lesser;
|
||||
}
|
||||
|
||||
//selection sort for gfft
|
||||
//kernel is ported from Bolt library:
|
||||
//https://github.com/HSA-Libraries/Bolt/blob/master/include/bolt/cl/sort_kernels.cl
|
||||
// Local sort will firstly sort elements of each workgroup using selection sort
|
||||
// its performance is O(n)
|
||||
__kernel
|
||||
void sortCorners_selectionSortLocal
|
||||
(
|
||||
image2d_t eig,
|
||||
__global float2 * corners,
|
||||
const int count,
|
||||
__local float2 * scratch
|
||||
)
|
||||
// this is simple short serial kernel that makes some short reduction and initialization work
|
||||
// it makes HOST like work to avoid additional sync with HOST to do this short work
|
||||
// data - input/output float2.
|
||||
// input data are sevral (min,max) pairs
|
||||
// output data is one reduced (min,max) pair
|
||||
// g_counter - counter that have to be initialized by 0 for next findCorner call.
|
||||
__kernel void arithm_op_minMax_final(__global float * data, int groupnum,__global int * g_counter)
|
||||
{
|
||||
int i = get_local_id(0); // index in workgroup
|
||||
int numOfGroups = get_num_groups(0); // index in workgroup
|
||||
int groupID = get_group_id(0);
|
||||
int wg = get_local_size(0); // workgroup size = block size
|
||||
int n; // number of elements to be processed for this work group
|
||||
|
||||
int offset = groupID * wg;
|
||||
int same = 0;
|
||||
corners += offset;
|
||||
n = (groupID == (numOfGroups-1))? (count - wg*(numOfGroups-1)) : wg;
|
||||
float2 pt1, pt2;
|
||||
|
||||
pt1 = corners[min(i, n)];
|
||||
scratch[i] = pt1;
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
|
||||
if(i >= n)
|
||||
g_counter[0] = 0;
|
||||
float minVal = data[0];
|
||||
float maxVal = data[groupnum];
|
||||
for(int i=1;i<groupnum;++i)
|
||||
{
|
||||
return;
|
||||
minVal = min(minVal,data[i]);
|
||||
maxVal = max(maxVal,data[i+groupnum]);
|
||||
}
|
||||
|
||||
float val1 = ELEM_FLT2(eig, pt1);
|
||||
float val2;
|
||||
|
||||
int pos = 0;
|
||||
for (int j=0;j<n;++j)
|
||||
{
|
||||
pt2 = scratch[j];
|
||||
val2 = ELEM_FLT2(eig, pt2);
|
||||
if(val2 > val1)
|
||||
pos++;//calculate the rank of this element in this work group
|
||||
else
|
||||
{
|
||||
if(val1 > val2)
|
||||
continue;
|
||||
else
|
||||
{
|
||||
// val1 and val2 are same
|
||||
same++;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int j=0; j< same; j++)
|
||||
corners[pos + j] = pt1;
|
||||
}
|
||||
__kernel
|
||||
void sortCorners_selectionSortFinal
|
||||
(
|
||||
image2d_t eig,
|
||||
__global float2 * corners,
|
||||
const int count
|
||||
)
|
||||
{
|
||||
const int i = get_local_id(0); // index in workgroup
|
||||
const int numOfGroups = get_num_groups(0); // index in workgroup
|
||||
const int groupID = get_group_id(0);
|
||||
const int wg = get_local_size(0); // workgroup size = block size
|
||||
int pos = 0, same = 0;
|
||||
const int offset = get_group_id(0) * wg;
|
||||
const int remainder = count - wg*(numOfGroups-1);
|
||||
|
||||
if((offset + i ) >= count)
|
||||
return;
|
||||
float2 pt1, pt2;
|
||||
pt1 = corners[groupID*wg + i];
|
||||
|
||||
float val1 = ELEM_FLT2(eig, pt1);
|
||||
float val2;
|
||||
|
||||
for(int j=0; j<numOfGroups-1; j++ )
|
||||
{
|
||||
for(int k=0; k<wg; k++)
|
||||
{
|
||||
pt2 = corners[j*wg + k];
|
||||
val2 = ELEM_FLT2(eig, pt2);
|
||||
if(val1 > val2)
|
||||
break;
|
||||
else
|
||||
{
|
||||
//Increment only if the value is not the same.
|
||||
if( val2 > val1 )
|
||||
pos++;
|
||||
else
|
||||
same++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(int k=0; k<remainder; k++)
|
||||
{
|
||||
pt2 = corners[(numOfGroups-1)*wg + k];
|
||||
val2 = ELEM_FLT2(eig, pt2);
|
||||
if(val1 > val2)
|
||||
break;
|
||||
else
|
||||
{
|
||||
//Don't increment if the value is the same.
|
||||
//Two elements are same if (*userComp)(jData, iData) and (*userComp)(iData, jData) are both false
|
||||
if(val2 > val1)
|
||||
pos++;
|
||||
else
|
||||
same++;
|
||||
}
|
||||
}
|
||||
for (int j=0; j< same; j++)
|
||||
corners[pos + j] = pt1;
|
||||
}
|
||||
data[0] = minVal;
|
||||
data[1] = maxVal;
|
||||
}
|
||||
@@ -1,45 +1,97 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////Macro for border type////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#ifdef BORDER_REPLICATE
|
||||
//BORDER_REPLICATE: aaaaaa|abcdefgh|hhhhhhh
|
||||
#define ADDR_L(i, l_edge, r_edge) ((i) < (l_edge) ? (l_edge) : (i))
|
||||
#define ADDR_R(i, r_edge, addr) ((i) >= (r_edge) ? (r_edge)-1 : (addr))
|
||||
#define ADDR_H(i, t_edge, b_edge) ((i) < (t_edge) ? (t_edge) :(i))
|
||||
#define ADDR_B(i, b_edge, addr) ((i) >= (b_edge) ? (b_edge)-1 :(addr))
|
||||
|
||||
#ifdef BORDER_CONSTANT
|
||||
//CCCCCC|abcdefgh|CCCCCCC
|
||||
#define EXTRAPOLATE(x, maxV)
|
||||
#elif defined BORDER_REPLICATE
|
||||
//aaaaaa|abcdefgh|hhhhhhh
|
||||
#define EXTRAPOLATE(x, maxV) \
|
||||
{ \
|
||||
(x) = max(min((x), (maxV) - 1), 0); \
|
||||
}
|
||||
#elif defined BORDER_WRAP
|
||||
//cdefgh|abcdefgh|abcdefg
|
||||
#define EXTRAPOLATE(x, maxV) \
|
||||
{ \
|
||||
(x) = ( (x) + (maxV) ) % (maxV); \
|
||||
}
|
||||
#elif defined BORDER_REFLECT
|
||||
//fedcba|abcdefgh|hgfedcb
|
||||
#define EXTRAPOLATE(x, maxV) \
|
||||
{ \
|
||||
(x) = min( mad24((maxV)-1,2,-(x))+1 , max((x),-(x)-1) ); \
|
||||
}
|
||||
#elif defined BORDER_REFLECT_101
|
||||
//gfedcb|abcdefgh|gfedcba
|
||||
#define EXTRAPOLATE(x, maxV) \
|
||||
{ \
|
||||
(x) = min( mad24((maxV)-1,2,-(x)), max((x),-(x)) ); \
|
||||
}
|
||||
#else
|
||||
#error No extrapolation method
|
||||
#endif
|
||||
|
||||
#ifdef BORDER_REFLECT
|
||||
//BORDER_REFLECT: fedcba|abcdefgh|hgfedcb
|
||||
#define ADDR_L(i, l_edge, r_edge) ((i) < (l_edge) ? -(i)-1 : (i))
|
||||
#define ADDR_R(i, r_edge, addr) ((i) >= (r_edge) ? -(i)-1+((r_edge)<<1) : (addr))
|
||||
#define ADDR_H(i, t_edge, b_edge) ((i) < (t_edge) ? -(i)-1 : (i))
|
||||
#define ADDR_B(i, b_edge, addr) ((i) >= (b_edge) ? -(i)-1+((b_edge)<<1) : (addr))
|
||||
#define SRC(_x,_y) convert_float(((global SRCTYPE*)(Src+(_y)*SrcPitch))[_x])
|
||||
|
||||
#ifdef BORDER_CONSTANT
|
||||
//CCCCCC|abcdefgh|CCCCCCC
|
||||
#define ELEM(_x,_y,r_edge,t_edge,const_v) (_x)<0 | (_x) >= (r_edge) | (_y)<0 | (_y) >= (t_edge) ? (const_v) : SRC((_x),(_y))
|
||||
#else
|
||||
#define ELEM(_x,_y,r_edge,t_edge,const_v) SRC((_x),(_y))
|
||||
#endif
|
||||
|
||||
#ifdef BORDER_REFLECT101
|
||||
//BORDER_REFLECT101: gfedcb|abcdefgh|gfedcba
|
||||
#define ADDR_L(i, l_edge, r_edge) ((i) < (l_edge) ? -(i) : (i))
|
||||
#define ADDR_R(i, r_edge, addr) ((i) >= (r_edge) ? -(i)-2+((r_edge)<<1) : (addr))
|
||||
#define ADDR_H(i, t_edge, b_edge) ((i) < (t_edge) ? -(i) : (i))
|
||||
#define ADDR_B(i, b_edge, addr) ((i) >= (b_edge) ? -(i)-2+((b_edge)<<1) : (addr))
|
||||
#endif
|
||||
#define DSTX(_x,_y) (((global float*)(DstX+DstXOffset+(_y)*DstXPitch))[_x])
|
||||
#define DSTY(_x,_y) (((global float*)(DstY+DstYOffset+(_y)*DstYPitch))[_x])
|
||||
|
||||
#ifdef BORDER_WRAP
|
||||
//BORDER_WRAP: cdefgh|abcdefgh|abcdefg
|
||||
#define ADDR_L(i, l_edge, r_edge) ((i) < (l_edge) ? (i)+(r_edge) : (i))
|
||||
#define ADDR_R(i, r_edge, addr) ((i) >= (r_edge) ? (i)-(r_edge) : (addr))
|
||||
#define ADDR_H(i, t_edge, b_edge) ((i) < (t_edge) ? (i)+(b_edge) : (i))
|
||||
#define ADDR_B(i, b_edge, addr) ((i) >= (b_edge) ? (i)-(b_edge) : (addr))
|
||||
#endif
|
||||
#define INIT_AND_READ_LOCAL_SOURCE(width, height, fill_const, kernel_border) \
|
||||
int srcX = x + srcOffsetX - (kernel_border); \
|
||||
int srcY = y + srcOffsetY - (kernel_border); \
|
||||
int xb = srcX; \
|
||||
int yb = srcY; \
|
||||
\
|
||||
EXTRAPOLATE(xb, (width)); \
|
||||
EXTRAPOLATE(yb, (height)); \
|
||||
lsmem[liy][lix] = ELEM(xb, yb, (width), (height), (fill_const) ); \
|
||||
\
|
||||
if(lix < ((kernel_border)*2)) \
|
||||
{ \
|
||||
int xb = srcX+BLK_X; \
|
||||
EXTRAPOLATE(xb,(width)); \
|
||||
lsmem[liy][lix+BLK_X] = ELEM(xb, yb, (width), (height), (fill_const) ); \
|
||||
} \
|
||||
if(liy< ((kernel_border)*2)) \
|
||||
{ \
|
||||
int yb = srcY+BLK_Y; \
|
||||
EXTRAPOLATE(yb, (height)); \
|
||||
lsmem[liy+BLK_Y][lix] = ELEM(xb, yb, (width), (height), (fill_const) ); \
|
||||
} \
|
||||
if(lix<((kernel_border)*2) && liy<((kernel_border)*2)) \
|
||||
{ \
|
||||
int xb = srcX+BLK_X; \
|
||||
int yb = srcY+BLK_Y; \
|
||||
EXTRAPOLATE(xb,(width)); \
|
||||
EXTRAPOLATE(yb,(height)); \
|
||||
lsmem[liy+BLK_Y][lix+BLK_X] = ELEM(xb, yb, (width), (height), (fill_const) ); \
|
||||
}
|
||||
|
||||
__kernel void sobel3(
|
||||
__global uchar* Src,
|
||||
__global float* DstX,
|
||||
__global float* DstY,
|
||||
int width, int height,
|
||||
uint srcStride, uint dstStride,
|
||||
float scale
|
||||
const uint SrcPitch,
|
||||
const int srcOffsetX,
|
||||
const int srcOffsetY,
|
||||
__global uchar* DstX,
|
||||
const int DstXOffset,
|
||||
const uint DstXPitch,
|
||||
__global uchar* DstY,
|
||||
const int DstYOffset,
|
||||
const uint DstYPitch,
|
||||
int width,
|
||||
int height,
|
||||
int dstWidth,
|
||||
int dstHeight,
|
||||
float scale
|
||||
)
|
||||
{
|
||||
__local float lsmem[BLK_Y+2][BLK_X+2];
|
||||
@@ -47,62 +99,249 @@ __kernel void sobel3(
|
||||
int lix = get_local_id(0);
|
||||
int liy = get_local_id(1);
|
||||
|
||||
int gix = get_group_id(0);
|
||||
int giy = get_group_id(1);
|
||||
|
||||
int id_x = get_global_id(0);
|
||||
int id_y = get_global_id(1);
|
||||
|
||||
lsmem[liy+1][lix+1] = convert_float(Src[ id_y * srcStride + id_x ]);
|
||||
|
||||
int id_y_h = ADDR_H(id_y-1, 0,height);
|
||||
int id_y_b = ADDR_B(id_y+1, height,id_y+1);
|
||||
|
||||
int id_x_l = ADDR_L(id_x-1, 0,width);
|
||||
int id_x_r = ADDR_R(id_x+1, width,id_x+1);
|
||||
|
||||
if(liy==0)
|
||||
{
|
||||
lsmem[0][lix+1]=convert_float(Src[ id_y_h * srcStride + id_x ]);
|
||||
|
||||
if(lix==0)
|
||||
lsmem[0][0]=convert_float(Src[ id_y_h * srcStride + id_x_l ]);
|
||||
else if(lix==BLK_X-1)
|
||||
lsmem[0][BLK_X+1]=convert_float(Src[ id_y_h * srcStride + id_x_r ]);
|
||||
}
|
||||
else if(liy==BLK_Y-1)
|
||||
{
|
||||
lsmem[BLK_Y+1][lix+1]=convert_float(Src[ id_y_b * srcStride + id_x ]);
|
||||
|
||||
if(lix==0)
|
||||
lsmem[BLK_Y+1][0]=convert_float(Src[ id_y_b * srcStride + id_x_l ]);
|
||||
else if(lix==BLK_X-1)
|
||||
lsmem[BLK_Y+1][BLK_X+1]=convert_float(Src[ id_y_b * srcStride + id_x_r ]);
|
||||
}
|
||||
|
||||
if(lix==0)
|
||||
lsmem[liy+1][0] = convert_float(Src[ id_y * srcStride + id_x_l ]);
|
||||
else if(lix==BLK_X-1)
|
||||
lsmem[liy+1][BLK_X+1] = convert_float(Src[ id_y * srcStride + id_x_r ]);
|
||||
int x = (int)get_global_id(0);
|
||||
int y = (int)get_global_id(1);
|
||||
|
||||
INIT_AND_READ_LOCAL_SOURCE(width, height, 0, 1)
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
|
||||
if( x >= dstWidth || y >=dstHeight ) return;
|
||||
|
||||
float u1 = lsmem[liy][lix];
|
||||
float u2 = lsmem[liy][lix+1];
|
||||
float u3 = lsmem[liy][lix+2];
|
||||
|
||||
float m1 = lsmem[liy+1][lix];
|
||||
float m2 = lsmem[liy+1][lix+1];
|
||||
float m3 = lsmem[liy+1][lix+2];
|
||||
|
||||
float b1 = lsmem[liy+2][lix];
|
||||
float b2 = lsmem[liy+2][lix+1];
|
||||
float b3 = lsmem[liy+2][lix+2];
|
||||
|
||||
//m2 * scale;//
|
||||
float dx = mad(2.0f, m3 - m1, u3 - u1 + b3 - b1 );
|
||||
DstX[ id_y * dstStride + id_x ] = dx * scale;
|
||||
//calc and store dx and dy;//
|
||||
#ifdef SCHARR
|
||||
DSTX(x,y) = mad(10.0f, m3 - m1, 3.0f * (u3 - u1 + b3 - b1)) * scale;
|
||||
DSTY(x,y) = mad(10.0f, b2 - u2, 3.0f * (b1 - u1 + b3 - u3)) * scale;
|
||||
#else
|
||||
DSTX(x,y) = mad(2.0f, m3 - m1, u3 - u1 + b3 - b1) * scale;
|
||||
DSTY(x,y) = mad(2.0f, b2 - u2, b1 - u1 + b3 - u3) * scale;
|
||||
#endif
|
||||
}
|
||||
|
||||
float dy = mad(2.0f, b2 - u2, b1 - u1 + b3 - u3);
|
||||
DstY[ id_y * dstStride + id_x ] = dy * scale;
|
||||
}
|
||||
__kernel void sobel5(
|
||||
__global uchar* Src,
|
||||
const uint SrcPitch,
|
||||
const int srcOffsetX,
|
||||
const int srcOffsetY,
|
||||
__global uchar* DstX,
|
||||
const int DstXOffset,
|
||||
const uint DstXPitch,
|
||||
__global uchar* DstY,
|
||||
const int DstYOffset,
|
||||
const uint DstYPitch,
|
||||
int width,
|
||||
int height,
|
||||
int dstWidth,
|
||||
int dstHeight,
|
||||
float scale
|
||||
)
|
||||
{
|
||||
__local float lsmem[BLK_Y+4][BLK_X+4];
|
||||
|
||||
int lix = get_local_id(0);
|
||||
int liy = get_local_id(1);
|
||||
|
||||
int x = (int)get_global_id(0);
|
||||
int y = (int)get_global_id(1);
|
||||
|
||||
INIT_AND_READ_LOCAL_SOURCE(width, height, 0, 2)
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
|
||||
if( x >= dstWidth || y >=dstHeight ) return;
|
||||
|
||||
float t1 = lsmem[liy][lix];
|
||||
float t2 = lsmem[liy][lix+1];
|
||||
float t3 = lsmem[liy][lix+2];
|
||||
float t4 = lsmem[liy][lix+3];
|
||||
float t5 = lsmem[liy][lix+4];
|
||||
|
||||
float u1 = lsmem[liy+1][lix];
|
||||
float u2 = lsmem[liy+1][lix+1];
|
||||
float u3 = lsmem[liy+1][lix+2];
|
||||
float u4 = lsmem[liy+1][lix+3];
|
||||
float u5 = lsmem[liy+1][lix+4];
|
||||
|
||||
float m1 = lsmem[liy+2][lix];
|
||||
float m2 = lsmem[liy+2][lix+1];
|
||||
float m4 = lsmem[liy+2][lix+3];
|
||||
float m5 = lsmem[liy+2][lix+4];
|
||||
|
||||
float l1 = lsmem[liy+3][lix];
|
||||
float l2 = lsmem[liy+3][lix+1];
|
||||
float l3 = lsmem[liy+3][lix+2];
|
||||
float l4 = lsmem[liy+3][lix+3];
|
||||
float l5 = lsmem[liy+3][lix+4];
|
||||
|
||||
float b1 = lsmem[liy+4][lix];
|
||||
float b2 = lsmem[liy+4][lix+1];
|
||||
float b3 = lsmem[liy+4][lix+2];
|
||||
float b4 = lsmem[liy+4][lix+3];
|
||||
float b5 = lsmem[liy+4][lix+4];
|
||||
|
||||
//calc and store dx and dy;//
|
||||
DSTX(x,y) = scale *
|
||||
mad(12.0f, m4 - m2,
|
||||
mad(6.0f, m5 - m1,
|
||||
mad(8.0f, u4 - u2 + l4 - l2,
|
||||
mad(4.0f, u5 - u1 + l5 - l1,
|
||||
mad(2.0f, t4 - t2 + b4 - b2, t5 - t1 + b5 - b1 )
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
DSTY(x,y) = scale *
|
||||
mad(12.0f, l3 - u3,
|
||||
mad(6.0f, b3 - t3,
|
||||
mad(8.0f, l2 - u2 + l4 - u4,
|
||||
mad(4.0f, b2 - t2 + b4 - t4,
|
||||
mad(2.0f, l1 - u1 + l5 - u5, b1 - t1 + b5 - t5 )
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
__kernel void sobel7(
|
||||
__global uchar* Src,
|
||||
const uint SrcPitch,
|
||||
const int srcOffsetX,
|
||||
const int srcOffsetY,
|
||||
__global uchar* DstX,
|
||||
const int DstXOffset,
|
||||
const uint DstXPitch,
|
||||
__global uchar* DstY,
|
||||
const int DstYOffset,
|
||||
const uint DstYPitch,
|
||||
int width,
|
||||
int height,
|
||||
int dstWidth,
|
||||
int dstHeight,
|
||||
float scale
|
||||
)
|
||||
{
|
||||
__local float lsmem[BLK_Y+6][BLK_X+6];
|
||||
|
||||
int lix = get_local_id(0);
|
||||
int liy = get_local_id(1);
|
||||
|
||||
int x = (int)get_global_id(0);
|
||||
int y = (int)get_global_id(1);
|
||||
|
||||
INIT_AND_READ_LOCAL_SOURCE(width, height, 0, 3)
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
|
||||
if( x >= dstWidth || y >=dstHeight ) return;
|
||||
|
||||
float tt1 = lsmem[liy][lix];
|
||||
float tt2 = lsmem[liy][lix+1];
|
||||
float tt3 = lsmem[liy][lix+2];
|
||||
float tt4 = lsmem[liy][lix+3];
|
||||
float tt5 = lsmem[liy][lix+4];
|
||||
float tt6 = lsmem[liy][lix+5];
|
||||
float tt7 = lsmem[liy][lix+6];
|
||||
|
||||
float t1 = lsmem[liy+1][lix];
|
||||
float t2 = lsmem[liy+1][lix+1];
|
||||
float t3 = lsmem[liy+1][lix+2];
|
||||
float t4 = lsmem[liy+1][lix+3];
|
||||
float t5 = lsmem[liy+1][lix+4];
|
||||
float t6 = lsmem[liy+1][lix+5];
|
||||
float t7 = lsmem[liy+1][lix+6];
|
||||
|
||||
float u1 = lsmem[liy+2][lix];
|
||||
float u2 = lsmem[liy+2][lix+1];
|
||||
float u3 = lsmem[liy+2][lix+2];
|
||||
float u4 = lsmem[liy+2][lix+3];
|
||||
float u5 = lsmem[liy+2][lix+4];
|
||||
float u6 = lsmem[liy+2][lix+5];
|
||||
float u7 = lsmem[liy+2][lix+6];
|
||||
|
||||
float m1 = lsmem[liy+3][lix];
|
||||
float m2 = lsmem[liy+3][lix+1];
|
||||
float m3 = lsmem[liy+3][lix+2];
|
||||
float m5 = lsmem[liy+3][lix+4];
|
||||
float m6 = lsmem[liy+3][lix+5];
|
||||
float m7 = lsmem[liy+3][lix+6];
|
||||
|
||||
float l1 = lsmem[liy+4][lix];
|
||||
float l2 = lsmem[liy+4][lix+1];
|
||||
float l3 = lsmem[liy+4][lix+2];
|
||||
float l4 = lsmem[liy+4][lix+3];
|
||||
float l5 = lsmem[liy+4][lix+4];
|
||||
float l6 = lsmem[liy+4][lix+5];
|
||||
float l7 = lsmem[liy+4][lix+6];
|
||||
|
||||
float b1 = lsmem[liy+5][lix];
|
||||
float b2 = lsmem[liy+5][lix+1];
|
||||
float b3 = lsmem[liy+5][lix+2];
|
||||
float b4 = lsmem[liy+5][lix+3];
|
||||
float b5 = lsmem[liy+5][lix+4];
|
||||
float b6 = lsmem[liy+5][lix+5];
|
||||
float b7 = lsmem[liy+5][lix+6];
|
||||
|
||||
float bb1 = lsmem[liy+6][lix];
|
||||
float bb2 = lsmem[liy+6][lix+1];
|
||||
float bb3 = lsmem[liy+6][lix+2];
|
||||
float bb4 = lsmem[liy+6][lix+3];
|
||||
float bb5 = lsmem[liy+6][lix+4];
|
||||
float bb6 = lsmem[liy+6][lix+5];
|
||||
float bb7 = lsmem[liy+6][lix+6];
|
||||
|
||||
//calc and store dx and dy
|
||||
DSTX(x,y) = scale *
|
||||
mad(100.0f, m5 - m3,
|
||||
mad(80.0f, m6 - m2,
|
||||
mad(20.0f, m7 - m1,
|
||||
mad(75.0f, u5 - u3 + l5 - l3,
|
||||
mad(60.0f, u6 - u2 + l6 - l2,
|
||||
mad(15.0f, u7 - u1 + l7 - l1,
|
||||
mad(30.0f, t5 - t3 + b5 - b3,
|
||||
mad(24.0f, t6 - t2 + b6 - b2,
|
||||
mad(6.0f, t7 - t1 + b7 - b1,
|
||||
mad(5.0f, tt5 - tt3 + bb5 - bb3,
|
||||
mad(4.0f, tt6 - tt2 + bb6 - bb2, tt7 - tt1 + bb7 - bb1 )
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
DSTY(x,y) = scale *
|
||||
mad(100.0f, l4 - u4,
|
||||
mad(80.0f, b4 - t4,
|
||||
mad(20.0f, bb4 - tt4,
|
||||
mad(75.0f, l5 - u5 + l3 - u3,
|
||||
mad(60.0f, b5 - t5 + b3 - t3,
|
||||
mad(15.0f, bb5 - tt5 + bb3 - tt3,
|
||||
mad(30.0f, l6 - u6 + l2 - u2,
|
||||
mad(24.0f, b6 - t6 + b2 - t2,
|
||||
mad(6.0f, bb6 - tt6 + bb2 - tt2,
|
||||
mad(5.0f, l7 - u7 + l1 - u1,
|
||||
mad(4.0f, b7 - t7 + b1 - t1, bb7 - tt7 + bb1 - tt1 )
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
//
|
||||
//M*/
|
||||
|
||||
static float distance_(__global const float * center, __global const float * src, int feature_length)
|
||||
inline float distance_(__global const float * center, __global const float * src, int feature_length)
|
||||
{
|
||||
float res = 0;
|
||||
float4 v0, v1, v2;
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
//
|
||||
//M*/
|
||||
|
||||
static short2 do_mean_shift(int x0, int y0, __global uchar4* out,int out_step,
|
||||
inline short2 do_mean_shift(int x0, int y0, __global uchar4* out,int out_step,
|
||||
__global uchar4* in, int in_step, int dst_off, int src_off,
|
||||
int cols, int rows, int sp, int sr, int maxIter, float eps)
|
||||
{
|
||||
|
||||
@@ -50,6 +50,14 @@
|
||||
#define NTHREADS 256
|
||||
#define CV_PI_F 3.1415926535897932384626433832795f
|
||||
|
||||
#ifdef INTEL_DEVICE
|
||||
#define QANGLE_TYPE int
|
||||
#define QANGLE_TYPE2 int2
|
||||
#else
|
||||
#define QANGLE_TYPE uchar
|
||||
#define QANGLE_TYPE2 uchar2
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Histogram computation
|
||||
// 12 threads for a cell, 12x4 threads per block
|
||||
@@ -59,7 +67,7 @@ __kernel void compute_hists_lut_kernel(
|
||||
const int cnbins, const int cblock_hist_size, const int img_block_width,
|
||||
const int blocks_in_group, const int blocks_total,
|
||||
const int grad_quadstep, const int qangle_step,
|
||||
__global const float* grad, __global const uchar* qangle,
|
||||
__global const float* grad, __global const QANGLE_TYPE* qangle,
|
||||
__global const float* gauss_w_lut,
|
||||
__global float* block_hists, __local float* smem)
|
||||
{
|
||||
@@ -86,7 +94,7 @@ __kernel void compute_hists_lut_kernel(
|
||||
|
||||
__global const float* grad_ptr = (gid < blocks_total) ?
|
||||
grad + offset_y * grad_quadstep + (offset_x << 1) : grad;
|
||||
__global const uchar* qangle_ptr = (gid < blocks_total) ?
|
||||
__global const QANGLE_TYPE* qangle_ptr = (gid < blocks_total) ?
|
||||
qangle + offset_y * qangle_step + (offset_x << 1) : qangle;
|
||||
|
||||
__local float* hist = hists + 12 * (cell_y * CELLS_PER_BLOCK_Y + cell_x) +
|
||||
@@ -101,7 +109,7 @@ __kernel void compute_hists_lut_kernel(
|
||||
for (int dist_y = dist_y_begin; dist_y < dist_y_begin + 12; ++dist_y)
|
||||
{
|
||||
float2 vote = (float2) (grad_ptr[0], grad_ptr[1]);
|
||||
uchar2 bin = (uchar2) (qangle_ptr[0], qangle_ptr[1]);
|
||||
QANGLE_TYPE2 bin = (QANGLE_TYPE2) (qangle_ptr[0], qangle_ptr[1]);
|
||||
|
||||
grad_ptr += grad_quadstep;
|
||||
qangle_ptr += qangle_step;
|
||||
@@ -200,7 +208,7 @@ __kernel void normalize_hists_36_kernel(__global float* block_hists,
|
||||
//-------------------------------------------------------------
|
||||
// Normalization of histograms via L2Hys_norm
|
||||
//
|
||||
static float reduce_smem(volatile __local float* smem, int size)
|
||||
inline float reduce_smem(volatile __local float* smem, int size)
|
||||
{
|
||||
unsigned int tid = get_local_id(0);
|
||||
float sum = smem[tid];
|
||||
@@ -558,7 +566,7 @@ __kernel void extract_descrs_by_cols_kernel(
|
||||
__kernel void compute_gradients_8UC4_kernel(
|
||||
const int height, const int width,
|
||||
const int img_step, const int grad_quadstep, const int qangle_step,
|
||||
const __global uchar4 * img, __global float * grad, __global uchar * qangle,
|
||||
const __global uchar4 * img, __global float * grad, __global QANGLE_TYPE * qangle,
|
||||
const float angle_scale, const char correct_gamma, const int cnbins)
|
||||
{
|
||||
const int x = get_global_id(0);
|
||||
@@ -660,7 +668,7 @@ __kernel void compute_gradients_8UC4_kernel(
|
||||
__kernel void compute_gradients_8UC1_kernel(
|
||||
const int height, const int width,
|
||||
const int img_step, const int grad_quadstep, const int qangle_step,
|
||||
__global const uchar * img, __global float * grad, __global uchar * qangle,
|
||||
__global const uchar * img, __global float * grad, __global QANGLE_TYPE * qangle,
|
||||
const float angle_scale, const char correct_gamma, const int cnbins)
|
||||
{
|
||||
const int x = get_global_id(0);
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
#endif
|
||||
#ifdef CPU
|
||||
|
||||
static void reduce3(float val1, float val2, float val3, __local float* smem1, __local float* smem2, __local float* smem3, int tid)
|
||||
inline void reduce3(float val1, float val2, float val3, __local float* smem1, __local float* smem2, __local float* smem3, int tid)
|
||||
{
|
||||
smem1[tid] = val1;
|
||||
smem2[tid] = val2;
|
||||
@@ -71,7 +71,7 @@ static void reduce3(float val1, float val2, float val3, __local float* smem1,
|
||||
}
|
||||
}
|
||||
|
||||
static void reduce2(float val1, float val2, volatile __local float* smem1, volatile __local float* smem2, int tid)
|
||||
inline void reduce2(float val1, float val2, volatile __local float* smem1, volatile __local float* smem2, int tid)
|
||||
{
|
||||
smem1[tid] = val1;
|
||||
smem2[tid] = val2;
|
||||
@@ -88,7 +88,7 @@ static void reduce2(float val1, float val2, volatile __local float* smem1, volat
|
||||
}
|
||||
}
|
||||
|
||||
static void reduce1(float val1, volatile __local float* smem1, int tid)
|
||||
inline void reduce1(float val1, volatile __local float* smem1, int tid)
|
||||
{
|
||||
smem1[tid] = val1;
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
@@ -103,7 +103,7 @@ static void reduce1(float val1, volatile __local float* smem1, int tid)
|
||||
}
|
||||
}
|
||||
#else
|
||||
static void reduce3(float val1, float val2, float val3,
|
||||
inline void reduce3(float val1, float val2, float val3,
|
||||
__local volatile float* smem1, __local volatile float* smem2, __local volatile float* smem3, int tid)
|
||||
{
|
||||
smem1[tid] = val1;
|
||||
@@ -150,7 +150,7 @@ static void reduce3(float val1, float val2, float val3,
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
}
|
||||
|
||||
static void reduce2(float val1, float val2, __local volatile float* smem1, __local volatile float* smem2, int tid)
|
||||
inline void reduce2(float val1, float val2, __local volatile float* smem1, __local volatile float* smem2, int tid)
|
||||
{
|
||||
smem1[tid] = val1;
|
||||
smem2[tid] = val2;
|
||||
@@ -189,7 +189,7 @@ static void reduce2(float val1, float val2, __local volatile float* smem1, __loc
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
}
|
||||
|
||||
static void reduce1(float val1, __local volatile float* smem1, int tid)
|
||||
inline void reduce1(float val1, __local volatile float* smem1, int tid)
|
||||
{
|
||||
smem1[tid] = val1;
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
@@ -225,7 +225,7 @@ static void reduce1(float val1, __local volatile float* smem1, int tid)
|
||||
// Image read mode
|
||||
__constant sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP_TO_EDGE | CLK_FILTER_LINEAR;
|
||||
|
||||
static void SetPatch(image2d_t I, float x, float y,
|
||||
inline void SetPatch(image2d_t I, float x, float y,
|
||||
float* Pch, float* Dx, float* Dy,
|
||||
float* A11, float* A12, float* A22)
|
||||
{
|
||||
@@ -262,7 +262,7 @@ inline void GetError(image2d_t J, const float x, const float y, const float* Pch
|
||||
*errval += fabs(diff);
|
||||
}
|
||||
|
||||
static void SetPatch4(image2d_t I, const float x, const float y,
|
||||
inline void SetPatch4(image2d_t I, const float x, const float y,
|
||||
float4* Pch, float4* Dx, float4* Dy,
|
||||
float* A11, float* A12, float* A22)
|
||||
{
|
||||
@@ -285,7 +285,7 @@ static void SetPatch4(image2d_t I, const float x, const float y,
|
||||
*A22 += sqIdx.x + sqIdx.y + sqIdx.z;
|
||||
}
|
||||
|
||||
static void GetPatch4(image2d_t J, const float x, const float y,
|
||||
inline void GetPatch4(image2d_t J, const float x, const float y,
|
||||
const float4* Pch, const float4* Dx, const float4* Dy,
|
||||
float* b1, float* b2)
|
||||
{
|
||||
@@ -297,7 +297,7 @@ static void GetPatch4(image2d_t J, const float x, const float y,
|
||||
*b2 += xdiff.x + xdiff.y + xdiff.z;
|
||||
}
|
||||
|
||||
static void GetError4(image2d_t J, const float x, const float y, const float4* Pch, float* errval)
|
||||
inline void GetError4(image2d_t J, const float x, const float y, const float4* Pch, float* errval)
|
||||
{
|
||||
float4 diff = read_imagef(J, sampler, (float2)(x,y))-*Pch;
|
||||
*errval += fabs(diff.x) + fabs(diff.y) + fabs(diff.z);
|
||||
|
||||
@@ -97,7 +97,7 @@ inline float pix_diff_1(const uchar4 l, __global const uchar *rs)
|
||||
return abs((int)(l.x) - *rs);
|
||||
}
|
||||
|
||||
static float pix_diff_4(const uchar4 l, __global const uchar *rs)
|
||||
inline float pix_diff_4(const uchar4 l, __global const uchar *rs)
|
||||
{
|
||||
uchar4 r;
|
||||
r = *((__global uchar4 *)rs);
|
||||
@@ -233,7 +233,7 @@ __kernel void level_up_message(__global T *src, int src_rows, int src_step,
|
||||
///////////////////////////////////////////////////////////////
|
||||
//////////////////// calc all iterations /////////////////////
|
||||
///////////////////////////////////////////////////////////////
|
||||
static void message(__global T *us_, __global T *ds_, __global T *ls_, __global T *rs_,
|
||||
inline void message(__global T *us_, __global T *ds_, __global T *ls_, __global T *rs_,
|
||||
const __global T *dt,
|
||||
int u_step, int msg_disp_step, int data_disp_step,
|
||||
float4 cmax_disc_term, float4 cdisc_single_jump)
|
||||
|
||||
@@ -62,7 +62,7 @@ __kernel void centeredGradientKernel(__global const float* src, int src_col, int
|
||||
|
||||
}
|
||||
|
||||
static float bicubicCoeff(float x_)
|
||||
inline float bicubicCoeff(float x_)
|
||||
{
|
||||
|
||||
float x = fabs(x_);
|
||||
@@ -156,7 +156,7 @@ __kernel void warpBackwardKernel(__global const float* I0, int I0_step, int I0_c
|
||||
|
||||
}
|
||||
|
||||
static float readImage(__global float *image, int x, int y, int rows, int cols, int elemCntPerRow)
|
||||
inline float readImage(__global float *image, int x, int y, int rows, int cols, int elemCntPerRow)
|
||||
{
|
||||
int i0 = clamp(x, 0, cols - 1);
|
||||
int j0 = clamp(y, 0, rows - 1);
|
||||
@@ -284,7 +284,7 @@ __kernel void estimateDualVariablesKernel(__global const float* u1, int u1_col,
|
||||
|
||||
}
|
||||
|
||||
static float divergence(__global const float* v1, __global const float* v2, int y, int x, int v1_step, int v2_step)
|
||||
inline float divergence(__global const float* v1, __global const float* v2, int y, int x, int v1_step, int v2_step)
|
||||
{
|
||||
|
||||
if (x > 0 && y > 0)
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
//M*/
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
#include "opencv2/ocl/cl_runtime/cl_runtime.hpp" // for OpenCL types: cl_mem
|
||||
#include "opencv2/ocl/cl_runtime/cl_runtime.hpp" // for OpenCL types & functions
|
||||
|
||||
TEST(TestAPI, openCLExecuteKernelInterop)
|
||||
{
|
||||
@@ -78,3 +78,87 @@ TEST(TestAPI, openCLExecuteKernelInterop)
|
||||
|
||||
EXPECT_LE(checkNorm(cpuMat, dst), 1e-3);
|
||||
}
|
||||
|
||||
// This test must be DISABLED by default!
|
||||
// (We can't restore original context for other tests)
|
||||
TEST(TestAPI, DISABLED_InitializationFromHandles)
|
||||
{
|
||||
#define MAX_PLATFORMS 16
|
||||
cl_platform_id platforms[MAX_PLATFORMS] = { NULL };
|
||||
cl_uint numPlatforms = 0;
|
||||
cl_int status = ::clGetPlatformIDs(MAX_PLATFORMS, &platforms[0], &numPlatforms);
|
||||
ASSERT_EQ(CL_SUCCESS, status) << "clGetPlatformIDs";
|
||||
ASSERT_NE(0, (int)numPlatforms);
|
||||
|
||||
int selectedPlatform = 0;
|
||||
cl_platform_id platform = platforms[selectedPlatform];
|
||||
|
||||
ASSERT_NE((void*)NULL, platform);
|
||||
|
||||
cl_device_id device = NULL;
|
||||
status = ::clGetDeviceIDs(platform, CL_DEVICE_TYPE_ALL, 1, &device, NULL);
|
||||
ASSERT_EQ(CL_SUCCESS, status) << "clGetDeviceIDs";
|
||||
ASSERT_NE((void*)NULL, device);
|
||||
|
||||
cl_context_properties cps[3] = { CL_CONTEXT_PLATFORM, (cl_context_properties)(platform), 0 };
|
||||
cl_context context = ::clCreateContext(cps, 1, &device, NULL, NULL, &status);
|
||||
ASSERT_EQ(CL_SUCCESS, status) << "clCreateContext";
|
||||
ASSERT_NE((void*)NULL, context);
|
||||
|
||||
ASSERT_NO_THROW(cv::ocl::initializeContext(&platform, &context, &device));
|
||||
|
||||
status = ::clReleaseContext(context);
|
||||
ASSERT_EQ(CL_SUCCESS, status) << "clReleaseContext";
|
||||
|
||||
#ifdef CL_VERSION_1_2
|
||||
#if 1
|
||||
{
|
||||
cv::ocl::Context* ctx = cv::ocl::Context::getContext();
|
||||
ASSERT_NE((void*)NULL, ctx);
|
||||
if (ctx->supportsFeature(cv::ocl::FEATURE_CL_VER_1_2)) // device supports OpenCL 1.2+
|
||||
{
|
||||
status = ::clReleaseDevice(device);
|
||||
ASSERT_EQ(CL_SUCCESS, status) << "clReleaseDevice";
|
||||
}
|
||||
}
|
||||
#else // code below doesn't work on Linux (SEGFAULTs on 1.1- devices are not handled via exceptions)
|
||||
try
|
||||
{
|
||||
status = ::clReleaseDevice(device); // NOTE This works only with !DEVICES! that supports OpenCL 1.2
|
||||
(void)status; // no check
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// nothing, there is no problem
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// print the name of current device
|
||||
cv::ocl::Context* ctx = cv::ocl::Context::getContext();
|
||||
ASSERT_NE((void*)NULL, ctx);
|
||||
const cv::ocl::DeviceInfo& deviceInfo = ctx->getDeviceInfo();
|
||||
std::cout << "Device name: " << deviceInfo.deviceName << std::endl;
|
||||
std::cout << "Platform name: " << deviceInfo.platform->platformName << std::endl;
|
||||
|
||||
ASSERT_EQ(context, *(cl_context*)ctx->getOpenCLContextPtr());
|
||||
ASSERT_EQ(device, *(cl_device_id*)ctx->getOpenCLDeviceIDPtr());
|
||||
|
||||
// do some calculations and check results
|
||||
cv::RNG rng;
|
||||
Size sz(100, 100);
|
||||
cv::Mat srcMat = cvtest::randomMat(rng, sz, CV_32FC4, -10, 10, false);
|
||||
cv::Mat dstMat;
|
||||
|
||||
cv::ocl::oclMat srcGpuMat(srcMat);
|
||||
cv::ocl::oclMat dstGpuMat;
|
||||
|
||||
cv::Scalar v = cv::Scalar::all(1);
|
||||
cv::add(srcMat, v, dstMat);
|
||||
cv::ocl::add(srcGpuMat, v, dstGpuMat);
|
||||
|
||||
cv::Mat dstGpuMatMap;
|
||||
dstGpuMat.download(dstGpuMatMap);
|
||||
|
||||
EXPECT_LE(checkNorm(dstMat, dstGpuMatMap), 1e-3);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1800)
|
||||
// eliminating duplicated round() declaration
|
||||
#define HAVE_ROUND
|
||||
#endif
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
#if !PYTHON_USE_NUMPY
|
||||
|
||||
@@ -1,2 +1,6 @@
|
||||
set(the_description "Images stitching")
|
||||
ocv_define_module(stitching opencv_imgproc opencv_features2d opencv_calib3d opencv_objdetect OPTIONAL opencv_gpu opencv_nonfree)
|
||||
if (ENABLE_DYNAMIC_CUDA)
|
||||
ocv_define_module(stitching opencv_imgproc opencv_features2d opencv_calib3d opencv_objdetect OPTIONAL opencv_nonfree)
|
||||
else()
|
||||
ocv_define_module(stitching opencv_imgproc opencv_features2d opencv_calib3d opencv_objdetect OPTIONAL opencv_gpu opencv_nonfree)
|
||||
endif()
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
#include "opencv2/opencv_modules.hpp"
|
||||
|
||||
#if defined(HAVE_OPENCV_NONFREE) && defined(HAVE_OPENCV_GPU)
|
||||
#if defined(HAVE_OPENCV_NONFREE) && defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
|
||||
#include "opencv2/nonfree/gpu.hpp"
|
||||
#endif
|
||||
|
||||
@@ -104,7 +104,7 @@ private:
|
||||
};
|
||||
|
||||
|
||||
#if defined(HAVE_OPENCV_NONFREE) && defined(HAVE_OPENCV_GPU)
|
||||
#if defined(HAVE_OPENCV_NONFREE) && defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
|
||||
class CV_EXPORTS SurfFeaturesFinderGpu : public FeaturesFinder
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -227,7 +227,7 @@ private:
|
||||
};
|
||||
|
||||
|
||||
#ifdef HAVE_OPENCV_GPU
|
||||
#if defined(HAVE_OPENCV_GPU) && !defined(ANDROID)
|
||||
class CV_EXPORTS GraphCutSeamFinderGpu : public GraphCutSeamFinderBase, public PairwiseSeamFinder
|
||||
{
|
||||
public:
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user