mirror of https://gitee.com/openkylin/opencv.git
Import Upstream version 4.2.0+dfsg
This commit is contained in:
commit
f706766715
|
@ -0,0 +1,31 @@
|
|||
# https://editorconfig.org/
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[{CMakeLists.*,*.cmake}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[Makefile]
|
||||
indent_style = tab
|
||||
|
||||
[*.{bat,cmd,cmd.*}]
|
||||
end_of_line = crlf
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.{ps1,ps1.*}]
|
||||
end_of_line = crlf
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.{md,markdown}]
|
||||
indent_size = 2
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,3 @@
|
|||
## Contributing guidelines
|
||||
|
||||
All guidelines for contributing to the OpenCV repository can be found at [`How to contribute guideline`](https://github.com/opencv/opencv/wiki/How_to_contribute).
|
|
@ -0,0 +1,42 @@
|
|||
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
|
||||
(3-clause BSD License)
|
||||
|
||||
Copyright (C) 2000-2019, Intel Corporation, all rights reserved.
|
||||
Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
|
||||
Copyright (C) 2009-2016, NVIDIA Corporation, all rights reserved.
|
||||
Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved.
|
||||
Copyright (C) 2015-2016, OpenCV Foundation, all rights reserved.
|
||||
Copyright (C) 2015-2016, Itseez Inc., all rights reserved.
|
||||
Copyright (C) 2019, Xperience AI, 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:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the names of the copyright holders nor the names of the contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
This software is provided by the copyright holders and contributors "as is" and
|
||||
any express or implied warranties, including, but not limited to, the implied
|
||||
warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
In no event shall copyright holders 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.
|
|
@ -0,0 +1,20 @@
|
|||
## OpenCV: Open Source Computer Vision Library
|
||||
|
||||
### Resources
|
||||
|
||||
* Homepage: <https://opencv.org>
|
||||
* Docs: <https://docs.opencv.org/master/>
|
||||
* Q&A forum: <http://answers.opencv.org>
|
||||
* Issue tracking: <https://github.com/opencv/opencv/issues>
|
||||
|
||||
### Contributing
|
||||
|
||||
Please read the [contribution guidelines](https://github.com/opencv/opencv/wiki/How_to_contribute) before starting work on a pull request.
|
||||
|
||||
#### Summary of the guidelines:
|
||||
|
||||
* One pull request per issue;
|
||||
* Choose the right base branch;
|
||||
* Include tests and documentation;
|
||||
* Clean up "oops" commits before submitting;
|
||||
* Follow the [coding style guide](https://github.com/opencv/opencv/wiki/Coding_Style_Guide).
|
|
@ -0,0 +1,74 @@
|
|||
# Security Policy
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
If you have information about a security issue or vulnerability in OpenCV, please send an e-mail to security@opencv.org.
|
||||
|
||||
Please provide as much information as possible:
|
||||
|
||||
- A detailed description of the vulnerability we can use to reproduce your findings.
|
||||
|
||||
- Who can exploit this vulnerability and what would they gain. An attack scenario.
|
||||
|
||||
- Information about known exploits if any.
|
||||
|
||||
A member of the Security Team will review your e-mail and contact you to collaborate on resolving the issue.
|
||||
|
||||
## PGP Key
|
||||
|
||||
If a security vulnerability report has extremely sensitive information you may encrypt it using our PGP public key:
|
||||
|
||||
```
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mQINBF3D4kMBEADMujKXgYtH1RFA25OTz+AFVZJlsQj8vC9WqKxvx7lluU33J8H0
|
||||
QUTwqysupVKmeLLdhWLrhMdN22qV33rn/Ba4VaosIkjBs6TSJg752J9qK07C+ps5
|
||||
4a8DDiqUV5B5aOO1ZI82rcw0EB4uTyJdsynY2zs1ylfNA3UothN30nSmv8HK22wO
|
||||
rt7R0/W29AoREihDWiGsTm6PxPA/jGN9WawqzVZF4Iv5kC6jFSojoyj1vVDn/55l
|
||||
JcjjRD88tSvjLeJE4vVgoN5LzvaNnwHOv8z+wDakt7cc/BLO0GdUOZvo5iBqv9sF
|
||||
y/6G4SULEY+LD1ByTEjajZCkfzURq7qVdRehseplOO5qPLDYU1PumzFYMqhkGRcu
|
||||
yH0q1bnqzKilARYCDUjlfPinQR6ko1CZ6aFCVPXHjs6btJ3kiP7SohjO8maO8IXD
|
||||
DvHS/qzxQ4NiqunSd8/Nh54WhckV3t+u1UUY7sesN+BDFHcpPOwvjubSpmoBT1TC
|
||||
lSduVUfR754uxiZTkNB19+J8omWCg6lJsXysZjRwypGv5cUUFiv+HM+4m2Th4Hpx
|
||||
hVvTwzwkhWDq91DkuHwtfpyikhSaCqMrvZ+cJ6QCUSssYwR3unPbhJ7E7HVUA114
|
||||
KgBHBcx9ZBJXcuYeztC4sRPOcvPc7s9ODzT1zSJpyqxJ1XMwjH4tir311QARAQAB
|
||||
tCVPcGVuQ1YgU2VjdXJpdHkgPHNlY3VyaXR5QG9wZW5jdi5vcmc+iQJOBBMBCgA4
|
||||
FiEEWsPgWpOWlzgrzgzn8YQhBPGCecsFAl3D4kMCGwMFCwkIBwIGFQoJCAsCBBYC
|
||||
AwECHgECF4AACgkQ8YQhBPGCecsweBAAl2dWcAJuLvLFDrQsTfYy8SgUvr88SZai
|
||||
uxOkAfdmYeuttE6pONb9/u4zngZM9cVkDAKP4M8C852QaO4TryKT4q5LGwYtAIjF
|
||||
OBFVUebAuf+huL/e6YCI9FDWy3hj4aeMdWg8lphNe7niNfICYJ5nTSIvly3rWFUm
|
||||
aWTV9kVJVT0oH9Cw96+XLahOdAWsFDurBy0prLcqjYuNd6bO/j3hqm+GCrMZTbKG
|
||||
21oNYoKO4+6T12Fy9ZCxnQWcguNdIpeDJ93O18R3A92zwxQlYchcyzqcSAXzQZGs
|
||||
nctYrxqTOcrOV0HoYRTQSct5hoUPK6v9gOP9CJ1rzHf5l88/mD0cqT12IbpYPXYg
|
||||
/AldZBUljTatjDy74v2GX4wktkuDhT2NN0sJJ6deFQuqoBbG8ODo8XemOKENc/kA
|
||||
VvUeroI7Jc6P1eIfTM9rOCR6w/wCl9YM+2v3pV0eQ/yn2SLEYH6uT/fCzCEYY+Kh
|
||||
G/uw5e4BjKjMgqIyDO/QiFaQIcTgpxgt8hze6U2lHTEoNvVbd7Xw99x+aN9BYeNz
|
||||
DGNao+gwDAo+jZrcg99+nwW/+ecFRAmHZ0iCDRJISR55j4CKLMaGKvnNF4P43FqU
|
||||
Ug++9lv7gPWFU96o+p58omfkamVT6lp+LgZHr+YTBgCOMjD1ljaIES4rvVolCNLv
|
||||
3pXe63k8J5y5Ag0EXcPiQwEQALkUn+px7kTTKdHY8HRTakgoj1FD0sRS8O1r8Y1b
|
||||
UJ2lZCkHlJc1zsyR0EnZascsW3IMlzeU1mcogR9HPogFkotd0pmkwheXKPWfwhfJ
|
||||
EQ48p8oYwtTzwcd6+Fd6nYs9Uj1fSlnkQ7aAxSOhxZsUwYuAUMZPTK4caFENneGO
|
||||
8lsjrC8aS3/DE1QMdafxd2mYDqigMarVU7UfZi5db5rb6NwUOhE65qmXC7cCrGRw
|
||||
uC7AMr/xybND0pWgWMWFPNOdKKS0Vsx6Wm3uJANXHz/28d4ozhn+midht+BBHFLa
|
||||
kzs0eA2dygVNoVqthjWZoT7fDQJ1t9BGH6oQQVJIhPNkM0LZt0Egpq3K025F9GW7
|
||||
JMlUG78ptKogroaVqQcFBGOxMS6J2axHXyd7NFulzucH48y0HCkJi2CyavNabHAF
|
||||
Nr5d+1M1az4AzFHoeMD1OcUSO2klnZqSR5X4JJm4gBeNAAPOJ9nNyo7lQOgG50Kq
|
||||
buwwEY1rBFDfi55pF+RzvqbKUxPyvaz5LoK7ZJWWlYmf7r61c7IeE+vmXGLcqbRh
|
||||
IViJMCh+l22EdjYyX/A4QW6fuYDPgJR9CD97mMK5SsTZnxGAKO+qOqD/D7SWh7sR
|
||||
MV3dJ0M+230kykA0Rdb3COOFmrw4oae9yUVFUN90hklB7ulK0uBXWfrvHmporD/z
|
||||
/AK3ABEBAAGJAjYEGAEKACAWIQRaw+Bak5aXOCvODOfxhCEE8YJ5ywUCXcPiQwIb
|
||||
DAAKCRDxhCEE8YJ5y0AqD/97VKV3aLihstSfZtnDo1kiafEmmoRX4uFRh2pqcuVn
|
||||
Ex8bqKTljy0jHCZfS4W+/imB2o6mubfygdjB/sKCUAknehyuuPTTFGIMUTvx5WJe
|
||||
S3c3Gdg9r3zCIge3lXw2lhGIn+obo2Y069/8CBVKSEoFl9mtoyXIVHe/E6tqzkb4
|
||||
3xPnjXbUt0jsWGqDJf5qPN4kjcwBpYXs6ayZy8LCm1i4IwMj1PtbkKPmXAGe6wJi
|
||||
5aGBxtMFiNcEH3+bW8vE8RIe/7dy3G/1n/VfhEBL05HCwxmM6I6S6tgZ1vE0k101
|
||||
3jL5a/9RDEYk9abHb1eXEwWUk2FVrzC87qH76OU6TXU8pV8Xp8dLv4U3meA5aNqm
|
||||
vkAv1If6/TR1yTqMDVD1mRkBL+dawRAUWtSed4QZeJf83AF+zFPGRn5TMB98AvTg
|
||||
QE3FDdxdkygOb9jx5reJ4SO1N0pMy8Enb8Xoe/dHIYmTncceQkMlQWMaBvYEzuVh
|
||||
mZd5GRHeogRx14tGxlRSc95wW9o0UN4fXxFBDDJDjrJVQQ3DqzK2Ca7Y53DzGODK
|
||||
d++Epc3Ef7lPex4eIIbqyup8X0SNiQelV91j3IyUEi3NZxSX9LQzSzG705gohpCz
|
||||
9va7NjxWCjwrE3x9PJD6KYdgcaNlbPaeQMLt2/fJKEBraJDHTU8buBaJJaC4psIj
|
||||
7Q==
|
||||
=Mdna
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
```
|
|
@ -0,0 +1,57 @@
|
|||
add_definitions(-D__OPENCV_BUILD=1)
|
||||
add_definitions(-D__OPENCV_APPS=1)
|
||||
|
||||
# Unified function for creating OpenCV applications:
|
||||
# ocv_add_application(tgt [MODULES <m1> [<m2> ...]] SRCS <src1> [<src2> ...])
|
||||
function(ocv_add_application the_target)
|
||||
cmake_parse_arguments(APP "" "" "MODULES;SRCS" ${ARGN})
|
||||
ocv_check_dependencies(${APP_MODULES})
|
||||
if(NOT OCV_DEPENDENCIES_FOUND)
|
||||
return()
|
||||
endif()
|
||||
|
||||
project(${the_target})
|
||||
ocv_target_include_modules_recurse(${the_target} ${APP_MODULES})
|
||||
ocv_target_include_directories(${the_target} PRIVATE "${OpenCV_SOURCE_DIR}/include/opencv")
|
||||
ocv_add_executable(${the_target} ${APP_SRCS})
|
||||
ocv_target_link_libraries(${the_target} ${APP_MODULES})
|
||||
set_target_properties(${the_target} PROPERTIES
|
||||
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
|
||||
ARCHIVE_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}
|
||||
RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}
|
||||
OUTPUT_NAME "${the_target}")
|
||||
|
||||
if(ENABLE_SOLUTION_FOLDERS)
|
||||
set_target_properties(${the_target} PROPERTIES FOLDER "applications")
|
||||
endif()
|
||||
|
||||
if(INSTALL_CREATE_DISTRIB)
|
||||
if(BUILD_SHARED_LIBS)
|
||||
install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} CONFIGURATIONS Release COMPONENT dev)
|
||||
endif()
|
||||
else()
|
||||
install(TARGETS ${the_target} RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT dev)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
link_libraries(${OPENCV_LINKER_LIBS})
|
||||
|
||||
macro(ocv_add_app directory)
|
||||
if(DEFINED BUILD_APPS_LIST)
|
||||
list(FIND BUILD_APPS_LIST ${directory} _index)
|
||||
if (${_index} GREATER -1)
|
||||
add_subdirectory(${directory})
|
||||
else()
|
||||
message(STATUS "Skip OpenCV app: ${directory}")
|
||||
endif()
|
||||
else()
|
||||
add_subdirectory(${directory})
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
#ocv_add_app(traincascade)
|
||||
#ocv_add_app(createsamples)
|
||||
ocv_add_app(annotation)
|
||||
ocv_add_app(visualisation)
|
||||
ocv_add_app(interactive-calibration)
|
||||
ocv_add_app(version)
|
|
@ -0,0 +1,3 @@
|
|||
ocv_add_application(opencv_annotation
|
||||
MODULES opencv_core opencv_highgui opencv_imgproc opencv_imgcodecs opencv_videoio
|
||||
SRCS opencv_annotation.cpp)
|
|
@ -0,0 +1,317 @@
|
|||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*****************************************************************************************************
|
||||
USAGE:
|
||||
./opencv_annotation -images <folder location> -annotations <output file>
|
||||
|
||||
Created by: Puttemans Steven - February 2015
|
||||
Adapted by: Puttemans Steven - April 2016 - Vectorize the process to enable better processing
|
||||
+ early leave and store by pressing an ESC key
|
||||
+ enable delete `d` button, to remove last annotation
|
||||
*****************************************************************************************************/
|
||||
|
||||
#include <opencv2/core.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include <opencv2/imgcodecs.hpp>
|
||||
#include <opencv2/videoio.hpp>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
// Function prototypes
|
||||
void on_mouse(int, int, int, int, void*);
|
||||
vector<Rect> get_annotations(Mat);
|
||||
|
||||
// Public parameters
|
||||
Mat image;
|
||||
int roi_x0 = 0, roi_y0 = 0, roi_x1 = 0, roi_y1 = 0, num_of_rec = 0;
|
||||
bool start_draw = false, stop = false;
|
||||
|
||||
// Window name for visualisation purposes
|
||||
const string window_name = "OpenCV Based Annotation Tool";
|
||||
|
||||
// FUNCTION : Mouse response for selecting objects in images
|
||||
// If left button is clicked, start drawing a rectangle as long as mouse moves
|
||||
// Stop drawing once a new left click is detected by the on_mouse function
|
||||
void on_mouse(int event, int x, int y, int , void * )
|
||||
{
|
||||
// Action when left button is clicked
|
||||
if(event == EVENT_LBUTTONDOWN)
|
||||
{
|
||||
if(!start_draw)
|
||||
{
|
||||
roi_x0 = x;
|
||||
roi_y0 = y;
|
||||
start_draw = true;
|
||||
} else {
|
||||
roi_x1 = x;
|
||||
roi_y1 = y;
|
||||
start_draw = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Action when mouse is moving and drawing is enabled
|
||||
if((event == EVENT_MOUSEMOVE) && start_draw)
|
||||
{
|
||||
// Redraw bounding box for annotation
|
||||
Mat current_view;
|
||||
image.copyTo(current_view);
|
||||
rectangle(current_view, Point(roi_x0,roi_y0), Point(x,y), Scalar(0,0,255));
|
||||
imshow(window_name, current_view);
|
||||
}
|
||||
}
|
||||
|
||||
// FUNCTION : returns a vector of Rect objects given an image containing positive object instances
|
||||
vector<Rect> get_annotations(Mat input_image)
|
||||
{
|
||||
vector<Rect> current_annotations;
|
||||
|
||||
// Make it possible to exit the annotation process
|
||||
stop = false;
|
||||
|
||||
// Init window interface and couple mouse actions
|
||||
namedWindow(window_name, WINDOW_AUTOSIZE);
|
||||
setMouseCallback(window_name, on_mouse);
|
||||
|
||||
image = input_image;
|
||||
imshow(window_name, image);
|
||||
int key_pressed = 0;
|
||||
|
||||
do
|
||||
{
|
||||
// Get a temporary image clone
|
||||
Mat temp_image = input_image.clone();
|
||||
Rect currentRect(0, 0, 0, 0);
|
||||
|
||||
// Keys for processing
|
||||
// You need to select one for confirming a selection and one to continue to the next image
|
||||
// Based on the universal ASCII code of the keystroke: http://www.asciitable.com/
|
||||
// c = 99 add rectangle to current image
|
||||
// n = 110 save added rectangles and show next image
|
||||
// d = 100 delete the last annotation made
|
||||
// <ESC> = 27 exit program
|
||||
key_pressed = 0xFF & waitKey(0);
|
||||
switch( key_pressed )
|
||||
{
|
||||
case 27:
|
||||
stop = true;
|
||||
break;
|
||||
case 99:
|
||||
// Draw initiated from top left corner
|
||||
if(roi_x0<roi_x1 && roi_y0<roi_y1)
|
||||
{
|
||||
currentRect.x = roi_x0;
|
||||
currentRect.y = roi_y0;
|
||||
currentRect.width = roi_x1-roi_x0;
|
||||
currentRect.height = roi_y1-roi_y0;
|
||||
}
|
||||
// Draw initiated from bottom right corner
|
||||
if(roi_x0>roi_x1 && roi_y0>roi_y1)
|
||||
{
|
||||
currentRect.x = roi_x1;
|
||||
currentRect.y = roi_y1;
|
||||
currentRect.width = roi_x0-roi_x1;
|
||||
currentRect.height = roi_y0-roi_y1;
|
||||
}
|
||||
// Draw initiated from top right corner
|
||||
if(roi_x0>roi_x1 && roi_y0<roi_y1)
|
||||
{
|
||||
currentRect.x = roi_x1;
|
||||
currentRect.y = roi_y0;
|
||||
currentRect.width = roi_x0-roi_x1;
|
||||
currentRect.height = roi_y1-roi_y0;
|
||||
}
|
||||
// Draw initiated from bottom left corner
|
||||
if(roi_x0<roi_x1 && roi_y0>roi_y1)
|
||||
{
|
||||
currentRect.x = roi_x0;
|
||||
currentRect.y = roi_y1;
|
||||
currentRect.width = roi_x1-roi_x0;
|
||||
currentRect.height = roi_y0-roi_y1;
|
||||
}
|
||||
// Draw the rectangle on the canvas
|
||||
// Add the rectangle to the vector of annotations
|
||||
current_annotations.push_back(currentRect);
|
||||
break;
|
||||
case 100:
|
||||
// Remove the last annotation
|
||||
if(current_annotations.size() > 0){
|
||||
current_annotations.pop_back();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Default case --> do nothing at all
|
||||
// Other keystrokes can simply be ignored
|
||||
break;
|
||||
}
|
||||
|
||||
// Check if escape has been pressed
|
||||
if(stop)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// Draw all the current rectangles onto the top image and make sure that the global image is linked
|
||||
for(int i=0; i < (int)current_annotations.size(); i++){
|
||||
rectangle(temp_image, current_annotations[i], Scalar(0,255,0), 1);
|
||||
}
|
||||
image = temp_image;
|
||||
|
||||
// Force an explicit redraw of the canvas --> necessary to visualize delete correctly
|
||||
imshow(window_name, image);
|
||||
}
|
||||
// Continue as long as the next image key has not been pressed
|
||||
while(key_pressed != 110);
|
||||
|
||||
// Close down the window
|
||||
destroyWindow(window_name);
|
||||
|
||||
// Return the data
|
||||
return current_annotations;
|
||||
}
|
||||
|
||||
int main( int argc, const char** argv )
|
||||
{
|
||||
// Use the cmdlineparser to process input arguments
|
||||
CommandLineParser parser(argc, argv,
|
||||
"{ help h usage ? | | show this message }"
|
||||
"{ images i | | (required) path to image folder [example - /data/testimages/] }"
|
||||
"{ annotations a | | (required) path to annotations txt file [example - /data/annotations.txt] }"
|
||||
"{ maxWindowHeight m | -1 | (optional) images larger in height than this value will be scaled down }"
|
||||
"{ resizeFactor r | 2 | (optional) factor for scaling down [default = half the size] }"
|
||||
);
|
||||
// Read in the input arguments
|
||||
if (parser.has("help")){
|
||||
parser.printMessage();
|
||||
cerr << "TIP: Use absolute paths to avoid any problems with the software!" << endl;
|
||||
return 0;
|
||||
}
|
||||
string image_folder(parser.get<string>("images"));
|
||||
string annotations_file(parser.get<string>("annotations"));
|
||||
if (image_folder.empty() || annotations_file.empty()){
|
||||
parser.printMessage();
|
||||
cerr << "TIP: Use absolute paths to avoid any problems with the software!" << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int resizeFactor = parser.get<int>("resizeFactor");
|
||||
int const maxWindowHeight = parser.get<int>("maxWindowHeight") > 0 ? parser.get<int>("maxWindowHeight") : -1;
|
||||
|
||||
// Start by processing the data
|
||||
// Return the image filenames inside the image folder
|
||||
map< String, vector<Rect> > annotations;
|
||||
vector<String> filenames;
|
||||
String folder(image_folder);
|
||||
glob(folder, filenames);
|
||||
|
||||
// Add key tips on how to use the software when running it
|
||||
cout << "* mark rectangles with the left mouse button," << endl;
|
||||
cout << "* press 'c' to accept a selection," << endl;
|
||||
cout << "* press 'd' to delete the latest selection," << endl;
|
||||
cout << "* press 'n' to proceed with next image," << endl;
|
||||
cout << "* press 'esc' to stop." << endl;
|
||||
|
||||
// Loop through each image stored in the images folder
|
||||
// Create and temporarily store the annotations
|
||||
// At the end write everything to the annotations file
|
||||
for (size_t i = 0; i < filenames.size(); i++){
|
||||
// Read in an image
|
||||
Mat current_image = imread(filenames[i]);
|
||||
bool const resize_bool = (maxWindowHeight > 0) && (current_image.rows > maxWindowHeight);
|
||||
|
||||
// Check if the image is actually read - avoid other files in the folder, because glob() takes them all
|
||||
// If not then simply skip this iteration
|
||||
if(current_image.empty()){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(resize_bool){
|
||||
resize(current_image, current_image, Size(current_image.cols/resizeFactor, current_image.rows/resizeFactor), 0, 0, INTER_LINEAR_EXACT);
|
||||
}
|
||||
|
||||
// Perform annotations & store the result inside the vectorized structure
|
||||
// If the image was resized before, then resize the found annotations back to original dimensions
|
||||
vector<Rect> current_annotations = get_annotations(current_image);
|
||||
if(resize_bool){
|
||||
for(int j =0; j < (int)current_annotations.size(); j++){
|
||||
current_annotations[j].x = current_annotations[j].x * resizeFactor;
|
||||
current_annotations[j].y = current_annotations[j].y * resizeFactor;
|
||||
current_annotations[j].width = current_annotations[j].width * resizeFactor;
|
||||
current_annotations[j].height = current_annotations[j].height * resizeFactor;
|
||||
}
|
||||
}
|
||||
annotations[filenames[i]] = current_annotations;
|
||||
|
||||
// Check if the ESC key was hit, then exit earlier then expected
|
||||
if(stop){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// When all data is processed, store the data gathered inside the proper file
|
||||
// This now even gets called when the ESC button was hit to store preliminary results
|
||||
ofstream output(annotations_file.c_str());
|
||||
if ( !output.is_open() ){
|
||||
cerr << "The path for the output file contains an error and could not be opened. Please check again!" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Store the annotations, write to the output file
|
||||
for(map<String, vector<Rect> >::iterator it = annotations.begin(); it != annotations.end(); it++){
|
||||
vector<Rect> &anno = it->second;
|
||||
output << it->first << " " << anno.size();
|
||||
for(size_t j=0; j < anno.size(); j++){
|
||||
Rect temp = anno[j];
|
||||
output << " " << temp.x << " " << temp.y << " " << temp.width << " " << temp.height;
|
||||
}
|
||||
output << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
file(GLOB SRCS *.cpp)
|
||||
ocv_add_application(opencv_createsamples
|
||||
MODULES opencv_core opencv_imgproc opencv_objdetect opencv_imgcodecs opencv_highgui opencv_calib3d opencv_features2d opencv_videoio
|
||||
SRCS ${SRCS})
|
|
@ -0,0 +1,258 @@
|
|||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of Intel Corporation may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
/*
|
||||
* createsamples.cpp
|
||||
*
|
||||
* Create test/training samples
|
||||
*/
|
||||
|
||||
#include "opencv2/core.hpp"
|
||||
#include "utility.hpp"
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <cmath>
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
int i = 0;
|
||||
char* nullname = (char*)"(NULL)";
|
||||
char* vecname = NULL; /* .vec file name */
|
||||
char* infoname = NULL; /* file name with marked up image descriptions */
|
||||
char* imagename = NULL; /* single sample image */
|
||||
char* bgfilename = NULL; /* background */
|
||||
int num = 1000;
|
||||
int bgcolor = 0;
|
||||
int bgthreshold = 80;
|
||||
int invert = 0;
|
||||
int maxintensitydev = 40;
|
||||
double maxxangle = 1.1;
|
||||
double maxyangle = 1.1;
|
||||
double maxzangle = 0.5;
|
||||
int showsamples = 0;
|
||||
/* the samples are adjusted to this scale in the sample preview window */
|
||||
double scale = 4.0;
|
||||
int width = 24;
|
||||
int height = 24;
|
||||
double maxscale = -1.0;
|
||||
int rngseed = 12345;
|
||||
|
||||
if( argc == 1 )
|
||||
{
|
||||
printf( "Usage: %s\n [-info <collection_file_name>]\n"
|
||||
" [-img <image_file_name>]\n"
|
||||
" [-vec <vec_file_name>]\n"
|
||||
" [-bg <background_file_name>]\n [-num <number_of_samples = %d>]\n"
|
||||
" [-bgcolor <background_color = %d>]\n"
|
||||
" [-inv] [-randinv] [-bgthresh <background_color_threshold = %d>]\n"
|
||||
" [-maxidev <max_intensity_deviation = %d>]\n"
|
||||
" [-maxxangle <max_x_rotation_angle = %f>]\n"
|
||||
" [-maxyangle <max_y_rotation_angle = %f>]\n"
|
||||
" [-maxzangle <max_z_rotation_angle = %f>]\n"
|
||||
" [-show [<scale = %f>]]\n"
|
||||
" [-w <sample_width = %d>]\n [-h <sample_height = %d>]\n"
|
||||
" [-maxscale <max sample scale = %f>]\n"
|
||||
" [-rngseed <rng seed = %d>]\n",
|
||||
argv[0], num, bgcolor, bgthreshold, maxintensitydev,
|
||||
maxxangle, maxyangle, maxzangle, scale, width, height, maxscale, rngseed );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
for( i = 1; i < argc; ++i )
|
||||
{
|
||||
if( !strcmp( argv[i], "-info" ) )
|
||||
{
|
||||
infoname = argv[++i];
|
||||
}
|
||||
else if( !strcmp( argv[i], "-img" ) )
|
||||
{
|
||||
imagename = argv[++i];
|
||||
}
|
||||
else if( !strcmp( argv[i], "-vec" ) )
|
||||
{
|
||||
vecname = argv[++i];
|
||||
}
|
||||
else if( !strcmp( argv[i], "-bg" ) )
|
||||
{
|
||||
bgfilename = argv[++i];
|
||||
}
|
||||
else if( !strcmp( argv[i], "-num" ) )
|
||||
{
|
||||
num = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-bgcolor" ) )
|
||||
{
|
||||
bgcolor = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-bgthresh" ) )
|
||||
{
|
||||
bgthreshold = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-inv" ) )
|
||||
{
|
||||
invert = 1;
|
||||
}
|
||||
else if( !strcmp( argv[i], "-randinv" ) )
|
||||
{
|
||||
invert = CV_RANDOM_INVERT;
|
||||
}
|
||||
else if( !strcmp( argv[i], "-maxidev" ) )
|
||||
{
|
||||
maxintensitydev = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-maxxangle" ) )
|
||||
{
|
||||
maxxangle = atof( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-maxyangle" ) )
|
||||
{
|
||||
maxyangle = atof( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-maxzangle" ) )
|
||||
{
|
||||
maxzangle = atof( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-show" ) )
|
||||
{
|
||||
showsamples = 1;
|
||||
if( i+1 < argc && strlen( argv[i+1] ) > 0 && argv[i+1][0] != '-' )
|
||||
{
|
||||
double d;
|
||||
d = strtod( argv[i+1], 0 );
|
||||
if( d != -HUGE_VAL && d != HUGE_VAL && d > 0 ) scale = d;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
else if( !strcmp( argv[i], "-w" ) )
|
||||
{
|
||||
width = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-h" ) )
|
||||
{
|
||||
height = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-maxscale" ) )
|
||||
{
|
||||
maxscale = atof( argv[++i] );
|
||||
}
|
||||
else if (!strcmp(argv[i], "-rngseed"))
|
||||
{
|
||||
rngseed = atoi(argv[++i]);
|
||||
}
|
||||
}
|
||||
|
||||
cv::setRNGSeed( rngseed );
|
||||
|
||||
printf( "Info file name: %s\n", ((infoname == NULL) ? nullname : infoname ) );
|
||||
printf( "Img file name: %s\n", ((imagename == NULL) ? nullname : imagename ) );
|
||||
printf( "Vec file name: %s\n", ((vecname == NULL) ? nullname : vecname ) );
|
||||
printf( "BG file name: %s\n", ((bgfilename == NULL) ? nullname : bgfilename ) );
|
||||
printf( "Num: %d\n", num );
|
||||
printf( "BG color: %d\n", bgcolor );
|
||||
printf( "BG threshold: %d\n", bgthreshold );
|
||||
printf( "Invert: %s\n", (invert == CV_RANDOM_INVERT) ? "RANDOM"
|
||||
: ( (invert) ? "TRUE" : "FALSE" ) );
|
||||
printf( "Max intensity deviation: %d\n", maxintensitydev );
|
||||
printf( "Max x angle: %g\n", maxxangle );
|
||||
printf( "Max y angle: %g\n", maxyangle );
|
||||
printf( "Max z angle: %g\n", maxzangle );
|
||||
printf( "Show samples: %s\n", (showsamples) ? "TRUE" : "FALSE" );
|
||||
if( showsamples )
|
||||
{
|
||||
printf( "Scale: %g\n", scale );
|
||||
}
|
||||
printf( "Width: %d\n", width );
|
||||
printf( "Height: %d\n", height );
|
||||
printf( "Max Scale: %g\n", maxscale );
|
||||
printf( "RNG Seed: %d\n", rngseed );
|
||||
|
||||
/* determine action */
|
||||
if( imagename && vecname )
|
||||
{
|
||||
printf( "Create training samples from single image applying distortions...\n" );
|
||||
|
||||
cvCreateTrainingSamples( vecname, imagename, bgcolor, bgthreshold, bgfilename,
|
||||
num, invert, maxintensitydev,
|
||||
maxxangle, maxyangle, maxzangle,
|
||||
showsamples, width, height );
|
||||
|
||||
printf( "Done\n" );
|
||||
}
|
||||
else if( imagename && bgfilename && infoname )
|
||||
{
|
||||
printf( "Create test samples from single image applying distortions...\n" );
|
||||
|
||||
cvCreateTestSamples( infoname, imagename, bgcolor, bgthreshold, bgfilename, num,
|
||||
invert, maxintensitydev,
|
||||
maxxangle, maxyangle, maxzangle, showsamples, width, height, maxscale);
|
||||
|
||||
printf( "Done\n" );
|
||||
}
|
||||
else if( infoname && vecname )
|
||||
{
|
||||
int total;
|
||||
|
||||
printf( "Create training samples from images collection...\n" );
|
||||
|
||||
total = cvCreateTrainingSamplesFromInfo( infoname, vecname, num, showsamples,
|
||||
width, height );
|
||||
|
||||
printf( "Done. Created %d samples\n", total );
|
||||
}
|
||||
else if( vecname )
|
||||
{
|
||||
printf( "View samples from vec file (press ESC to exit)...\n" );
|
||||
|
||||
cvShowVecSamples( vecname, width, height, scale );
|
||||
|
||||
printf( "Done\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "Nothing to do\n" );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,124 @@
|
|||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of Intel Corporation may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef __CREATESAMPLES_UTILITY_HPP__
|
||||
#define __CREATESAMPLES_UTILITY_HPP__
|
||||
|
||||
#define CV_VERBOSE 1
|
||||
|
||||
/*
|
||||
* cvCreateTrainingSamples
|
||||
*
|
||||
* Create training samples applying random distortions to sample image and
|
||||
* store them in .vec file
|
||||
*
|
||||
* filename - .vec file name
|
||||
* imgfilename - sample image file name
|
||||
* bgcolor - background color for sample image
|
||||
* bgthreshold - background color threshold. Pixels those colors are in range
|
||||
* [bgcolor-bgthreshold, bgcolor+bgthreshold] are considered as transparent
|
||||
* bgfilename - background description file name. If not NULL samples
|
||||
* will be put on arbitrary background
|
||||
* count - desired number of samples
|
||||
* invert - if not 0 sample foreground pixels will be inverted
|
||||
* if invert == CV_RANDOM_INVERT then samples will be inverted randomly
|
||||
* maxintensitydev - desired max intensity deviation of foreground samples pixels
|
||||
* maxxangle - max rotation angles
|
||||
* maxyangle
|
||||
* maxzangle
|
||||
* showsamples - if not 0 samples will be shown
|
||||
* winwidth - desired samples width
|
||||
* winheight - desired samples height
|
||||
*/
|
||||
#define CV_RANDOM_INVERT 0x7FFFFFFF
|
||||
|
||||
void cvCreateTrainingSamples( const char* filename,
|
||||
const char* imgfilename, int bgcolor, int bgthreshold,
|
||||
const char* bgfilename, int count,
|
||||
int invert = 0, int maxintensitydev = 40,
|
||||
double maxxangle = 1.1,
|
||||
double maxyangle = 1.1,
|
||||
double maxzangle = 0.5,
|
||||
int showsamples = 0,
|
||||
int winwidth = 24, int winheight = 24 );
|
||||
|
||||
void cvCreateTestSamples( const char* infoname,
|
||||
const char* imgfilename, int bgcolor, int bgthreshold,
|
||||
const char* bgfilename, int count,
|
||||
int invert, int maxintensitydev,
|
||||
double maxxangle, double maxyangle, double maxzangle,
|
||||
int showsamples,
|
||||
int winwidth, int winheight, double maxscale );
|
||||
|
||||
/*
|
||||
* cvCreateTrainingSamplesFromInfo
|
||||
*
|
||||
* Create training samples from a set of marked up images and store them into .vec file
|
||||
* infoname - file in which marked up image descriptions are stored
|
||||
* num - desired number of samples
|
||||
* showsamples - if not 0 samples will be shown
|
||||
* winwidth - sample width
|
||||
* winheight - sample height
|
||||
*
|
||||
* Return number of successfully created samples
|
||||
*/
|
||||
int cvCreateTrainingSamplesFromInfo( const char* infoname, const char* vecfilename,
|
||||
int num,
|
||||
int showsamples,
|
||||
int winwidth, int winheight );
|
||||
|
||||
/*
|
||||
* cvShowVecSamples
|
||||
*
|
||||
* Shows samples stored in .vec file
|
||||
*
|
||||
* filename
|
||||
* .vec file name
|
||||
* winwidth
|
||||
* sample width
|
||||
* winheight
|
||||
* sample height
|
||||
* scale
|
||||
* the scale each sample is adjusted to
|
||||
*/
|
||||
void cvShowVecSamples( const char* filename, int winwidth, int winheight, double scale );
|
||||
|
||||
#endif //__CREATESAMPLES_UTILITY_HPP__
|
|
@ -0,0 +1,6 @@
|
|||
set(DEPS opencv_core opencv_imgproc opencv_features2d opencv_highgui opencv_calib3d opencv_videoio)
|
||||
if(${BUILD_opencv_aruco})
|
||||
list(APPEND DEPS opencv_aruco)
|
||||
endif()
|
||||
file(GLOB SRCS *.cpp)
|
||||
ocv_add_application(opencv_interactive-calibration MODULES ${DEPS} SRCS ${SRCS})
|
|
@ -0,0 +1,123 @@
|
|||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#ifndef CALIB_COMMON_HPP
|
||||
#define CALIB_COMMON_HPP
|
||||
|
||||
#include <opencv2/core.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace calib
|
||||
{
|
||||
#define OVERLAY_DELAY 1000
|
||||
#define IMAGE_MAX_WIDTH 1280
|
||||
#define IMAGE_MAX_HEIGHT 960
|
||||
|
||||
bool showOverlayMessage(const std::string& message);
|
||||
|
||||
enum InputType { Video, Pictures };
|
||||
enum InputVideoSource { Camera, File };
|
||||
enum TemplateType { AcirclesGrid, Chessboard, chAruco, DoubleAcirclesGrid };
|
||||
|
||||
static const std::string mainWindowName = "Calibration";
|
||||
static const std::string gridWindowName = "Board locations";
|
||||
static const std::string consoleHelp = "Hot keys:\nesc - exit application\n"
|
||||
"s - save current data to .xml file\n"
|
||||
"r - delete last frame\n"
|
||||
"u - enable/disable applying undistortion\n"
|
||||
"d - delete all frames\n"
|
||||
"v - switch visualization";
|
||||
|
||||
static const double sigmaMult = 1.96;
|
||||
|
||||
struct calibrationData
|
||||
{
|
||||
cv::Mat cameraMatrix;
|
||||
cv::Mat distCoeffs;
|
||||
cv::Mat stdDeviations;
|
||||
cv::Mat perViewErrors;
|
||||
std::vector<cv::Mat> rvecs;
|
||||
std::vector<cv::Mat> tvecs;
|
||||
double totalAvgErr;
|
||||
cv::Size imageSize;
|
||||
|
||||
std::vector<std::vector<cv::Point2f> > imagePoints;
|
||||
std::vector< std::vector<cv::Point3f> > objectPoints;
|
||||
|
||||
std::vector<cv::Mat> allCharucoCorners;
|
||||
std::vector<cv::Mat> allCharucoIds;
|
||||
|
||||
cv::Mat undistMap1, undistMap2;
|
||||
|
||||
calibrationData()
|
||||
{
|
||||
imageSize = cv::Size(IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT);
|
||||
}
|
||||
};
|
||||
|
||||
struct cameraParameters
|
||||
{
|
||||
cv::Mat cameraMatrix;
|
||||
cv::Mat distCoeffs;
|
||||
cv::Mat stdDeviations;
|
||||
double avgError;
|
||||
|
||||
cameraParameters(){}
|
||||
cameraParameters(cv::Mat& _cameraMatrix, cv::Mat& _distCoeffs, cv::Mat& _stdDeviations, double _avgError = 0) :
|
||||
cameraMatrix(_cameraMatrix), distCoeffs(_distCoeffs), stdDeviations(_stdDeviations), avgError(_avgError)
|
||||
{}
|
||||
};
|
||||
|
||||
struct captureParameters
|
||||
{
|
||||
InputType captureMethod;
|
||||
InputVideoSource source;
|
||||
TemplateType board;
|
||||
cv::Size boardSize;
|
||||
int charucoDictName;
|
||||
int calibrationStep;
|
||||
float charucoSquareLenght, charucoMarkerSize;
|
||||
float captureDelay;
|
||||
float squareSize;
|
||||
float templDst;
|
||||
std::string videoFileName;
|
||||
bool flipVertical;
|
||||
int camID;
|
||||
int fps;
|
||||
cv::Size cameraResolution;
|
||||
int maxFramesNum;
|
||||
int minFramesNum;
|
||||
|
||||
captureParameters()
|
||||
{
|
||||
calibrationStep = 1;
|
||||
captureDelay = 500.f;
|
||||
maxFramesNum = 30;
|
||||
minFramesNum = 10;
|
||||
fps = 30;
|
||||
cameraResolution = cv::Size(IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT);
|
||||
}
|
||||
};
|
||||
|
||||
struct internalParameters
|
||||
{
|
||||
double solverEps;
|
||||
int solverMaxIters;
|
||||
bool fastSolving;
|
||||
double filterAlpha;
|
||||
|
||||
internalParameters()
|
||||
{
|
||||
solverEps = 1e-7;
|
||||
solverMaxIters = 30;
|
||||
fastSolving = false;
|
||||
filterAlpha = 0.1;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,334 @@
|
|||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#include "calibController.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <ctime>
|
||||
|
||||
#include <opencv2/calib3d.hpp>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
|
||||
double calib::calibController::estimateCoverageQuality()
|
||||
{
|
||||
int gridSize = 10;
|
||||
int xGridStep = mCalibData->imageSize.width / gridSize;
|
||||
int yGridStep = mCalibData->imageSize.height / gridSize;
|
||||
std::vector<int> pointsInCell(gridSize*gridSize);
|
||||
|
||||
std::fill(pointsInCell.begin(), pointsInCell.end(), 0);
|
||||
|
||||
for(std::vector<std::vector<cv::Point2f> >::iterator it = mCalibData->imagePoints.begin(); it != mCalibData->imagePoints.end(); ++it)
|
||||
for(std::vector<cv::Point2f>::iterator pointIt = (*it).begin(); pointIt != (*it).end(); ++pointIt) {
|
||||
int i = (int)((*pointIt).x / xGridStep);
|
||||
int j = (int)((*pointIt).y / yGridStep);
|
||||
pointsInCell[i*gridSize + j]++;
|
||||
}
|
||||
|
||||
for(std::vector<cv::Mat>::iterator it = mCalibData->allCharucoCorners.begin(); it != mCalibData->allCharucoCorners.end(); ++it)
|
||||
for(int l = 0; l < (*it).size[0]; l++) {
|
||||
int i = (int)((*it).at<float>(l, 0) / xGridStep);
|
||||
int j = (int)((*it).at<float>(l, 1) / yGridStep);
|
||||
pointsInCell[i*gridSize + j]++;
|
||||
}
|
||||
|
||||
cv::Mat mean, stdDev;
|
||||
cv::meanStdDev(pointsInCell, mean, stdDev);
|
||||
|
||||
return mean.at<double>(0) / (stdDev.at<double>(0) + 1e-7);
|
||||
}
|
||||
|
||||
calib::calibController::calibController()
|
||||
{
|
||||
mCalibFlags = 0;
|
||||
}
|
||||
|
||||
calib::calibController::calibController(cv::Ptr<calib::calibrationData> data, int initialFlags, bool autoTuning, int minFramesNum) :
|
||||
mCalibData(data)
|
||||
{
|
||||
mCalibFlags = initialFlags;
|
||||
mNeedTuning = autoTuning;
|
||||
mMinFramesNum = minFramesNum;
|
||||
mConfIntervalsState = false;
|
||||
mCoverageQualityState = false;
|
||||
}
|
||||
|
||||
void calib::calibController::updateState()
|
||||
{
|
||||
if(mCalibData->cameraMatrix.total()) {
|
||||
const double relErrEps = 0.05;
|
||||
bool fConfState = false, cConfState = false, dConfState = true;
|
||||
if(sigmaMult*mCalibData->stdDeviations.at<double>(0) / mCalibData->cameraMatrix.at<double>(0,0) < relErrEps &&
|
||||
sigmaMult*mCalibData->stdDeviations.at<double>(1) / mCalibData->cameraMatrix.at<double>(1,1) < relErrEps)
|
||||
fConfState = true;
|
||||
if(sigmaMult*mCalibData->stdDeviations.at<double>(2) / mCalibData->cameraMatrix.at<double>(0,2) < relErrEps &&
|
||||
sigmaMult*mCalibData->stdDeviations.at<double>(3) / mCalibData->cameraMatrix.at<double>(1,2) < relErrEps)
|
||||
cConfState = true;
|
||||
|
||||
for(int i = 0; i < 5; i++)
|
||||
if(mCalibData->stdDeviations.at<double>(4+i) / fabs(mCalibData->distCoeffs.at<double>(i)) > 1)
|
||||
dConfState = false;
|
||||
|
||||
mConfIntervalsState = fConfState && cConfState && dConfState;
|
||||
}
|
||||
|
||||
if(getFramesNumberState())
|
||||
mCoverageQualityState = estimateCoverageQuality() > 1.8 ? true : false;
|
||||
|
||||
if (getFramesNumberState() && mNeedTuning) {
|
||||
if( !(mCalibFlags & cv::CALIB_FIX_ASPECT_RATIO) &&
|
||||
mCalibData->cameraMatrix.total()) {
|
||||
double fDiff = fabs(mCalibData->cameraMatrix.at<double>(0,0) -
|
||||
mCalibData->cameraMatrix.at<double>(1,1));
|
||||
|
||||
if (fDiff < 3*mCalibData->stdDeviations.at<double>(0) &&
|
||||
fDiff < 3*mCalibData->stdDeviations.at<double>(1)) {
|
||||
mCalibFlags |= cv::CALIB_FIX_ASPECT_RATIO;
|
||||
mCalibData->cameraMatrix.at<double>(0,0) =
|
||||
mCalibData->cameraMatrix.at<double>(1,1);
|
||||
}
|
||||
}
|
||||
|
||||
if(!(mCalibFlags & cv::CALIB_ZERO_TANGENT_DIST)) {
|
||||
const double eps = 0.005;
|
||||
if(fabs(mCalibData->distCoeffs.at<double>(2)) < eps &&
|
||||
fabs(mCalibData->distCoeffs.at<double>(3)) < eps)
|
||||
mCalibFlags |= cv::CALIB_ZERO_TANGENT_DIST;
|
||||
}
|
||||
|
||||
if(!(mCalibFlags & cv::CALIB_FIX_K1)) {
|
||||
const double eps = 0.005;
|
||||
if(fabs(mCalibData->distCoeffs.at<double>(0)) < eps)
|
||||
mCalibFlags |= cv::CALIB_FIX_K1;
|
||||
}
|
||||
|
||||
if(!(mCalibFlags & cv::CALIB_FIX_K2)) {
|
||||
const double eps = 0.005;
|
||||
if(fabs(mCalibData->distCoeffs.at<double>(1)) < eps)
|
||||
mCalibFlags |= cv::CALIB_FIX_K2;
|
||||
}
|
||||
|
||||
if(!(mCalibFlags & cv::CALIB_FIX_K3)) {
|
||||
const double eps = 0.005;
|
||||
if(fabs(mCalibData->distCoeffs.at<double>(4)) < eps)
|
||||
mCalibFlags |= cv::CALIB_FIX_K3;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool calib::calibController::getCommonCalibrationState() const
|
||||
{
|
||||
int rating = (int)getFramesNumberState() + (int)getConfidenceIntrervalsState() +
|
||||
(int)getRMSState() + (int)mCoverageQualityState;
|
||||
return rating == 4;
|
||||
}
|
||||
|
||||
bool calib::calibController::getFramesNumberState() const
|
||||
{
|
||||
return std::max(mCalibData->imagePoints.size(), mCalibData->allCharucoCorners.size()) > mMinFramesNum;
|
||||
}
|
||||
|
||||
bool calib::calibController::getConfidenceIntrervalsState() const
|
||||
{
|
||||
return mConfIntervalsState;
|
||||
}
|
||||
|
||||
bool calib::calibController::getRMSState() const
|
||||
{
|
||||
return mCalibData->totalAvgErr < 0.5;
|
||||
}
|
||||
|
||||
int calib::calibController::getNewFlags() const
|
||||
{
|
||||
return mCalibFlags;
|
||||
}
|
||||
|
||||
|
||||
//////////////////// calibDataController
|
||||
|
||||
double calib::calibDataController::estimateGridSubsetQuality(size_t excludedIndex)
|
||||
{
|
||||
{
|
||||
int gridSize = 10;
|
||||
int xGridStep = mCalibData->imageSize.width / gridSize;
|
||||
int yGridStep = mCalibData->imageSize.height / gridSize;
|
||||
std::vector<int> pointsInCell(gridSize*gridSize);
|
||||
|
||||
std::fill(pointsInCell.begin(), pointsInCell.end(), 0);
|
||||
|
||||
for(size_t k = 0; k < mCalibData->imagePoints.size(); k++)
|
||||
if(k != excludedIndex)
|
||||
for(std::vector<cv::Point2f>::iterator pointIt = mCalibData->imagePoints[k].begin(); pointIt != mCalibData->imagePoints[k].end(); ++pointIt) {
|
||||
int i = (int)((*pointIt).x / xGridStep);
|
||||
int j = (int)((*pointIt).y / yGridStep);
|
||||
pointsInCell[i*gridSize + j]++;
|
||||
}
|
||||
|
||||
for(size_t k = 0; k < mCalibData->allCharucoCorners.size(); k++)
|
||||
if(k != excludedIndex)
|
||||
for(int l = 0; l < mCalibData->allCharucoCorners[k].size[0]; l++) {
|
||||
int i = (int)(mCalibData->allCharucoCorners[k].at<float>(l, 0) / xGridStep);
|
||||
int j = (int)(mCalibData->allCharucoCorners[k].at<float>(l, 1) / yGridStep);
|
||||
pointsInCell[i*gridSize + j]++;
|
||||
}
|
||||
|
||||
cv::Mat mean, stdDev;
|
||||
cv::meanStdDev(pointsInCell, mean, stdDev);
|
||||
|
||||
return mean.at<double>(0) / (stdDev.at<double>(0) + 1e-7);
|
||||
}
|
||||
}
|
||||
|
||||
calib::calibDataController::calibDataController(cv::Ptr<calib::calibrationData> data, int maxFrames, double convParameter) :
|
||||
mCalibData(data), mParamsFileName("CamParams.xml")
|
||||
{
|
||||
mMaxFramesNum = maxFrames;
|
||||
mAlpha = convParameter;
|
||||
}
|
||||
|
||||
calib::calibDataController::calibDataController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void calib::calibDataController::filterFrames()
|
||||
{
|
||||
size_t numberOfFrames = std::max(mCalibData->allCharucoIds.size(), mCalibData->imagePoints.size());
|
||||
CV_Assert(numberOfFrames == mCalibData->perViewErrors.total());
|
||||
if(numberOfFrames >= mMaxFramesNum) {
|
||||
|
||||
double worstValue = -HUGE_VAL, maxQuality = estimateGridSubsetQuality(numberOfFrames);
|
||||
size_t worstElemIndex = 0;
|
||||
for(size_t i = 0; i < numberOfFrames; i++) {
|
||||
double gridQDelta = estimateGridSubsetQuality(i) - maxQuality;
|
||||
double currentValue = mCalibData->perViewErrors.at<double>((int)i)*mAlpha + gridQDelta*(1. - mAlpha);
|
||||
if(currentValue > worstValue) {
|
||||
worstValue = currentValue;
|
||||
worstElemIndex = i;
|
||||
}
|
||||
}
|
||||
showOverlayMessage(cv::format("Frame %zu is worst", worstElemIndex + 1));
|
||||
|
||||
if(mCalibData->imagePoints.size()) {
|
||||
mCalibData->imagePoints.erase(mCalibData->imagePoints.begin() + worstElemIndex);
|
||||
mCalibData->objectPoints.erase(mCalibData->objectPoints.begin() + worstElemIndex);
|
||||
}
|
||||
else {
|
||||
mCalibData->allCharucoCorners.erase(mCalibData->allCharucoCorners.begin() + worstElemIndex);
|
||||
mCalibData->allCharucoIds.erase(mCalibData->allCharucoIds.begin() + worstElemIndex);
|
||||
}
|
||||
|
||||
cv::Mat newErrorsVec = cv::Mat((int)numberOfFrames - 1, 1, CV_64F);
|
||||
std::copy(mCalibData->perViewErrors.ptr<double>(0),
|
||||
mCalibData->perViewErrors.ptr<double>((int)worstElemIndex), newErrorsVec.ptr<double>(0));
|
||||
if((int)worstElemIndex < (int)numberOfFrames-1) {
|
||||
std::copy(mCalibData->perViewErrors.ptr<double>((int)worstElemIndex + 1), mCalibData->perViewErrors.ptr<double>((int)numberOfFrames),
|
||||
newErrorsVec.ptr<double>((int)worstElemIndex));
|
||||
}
|
||||
mCalibData->perViewErrors = newErrorsVec;
|
||||
}
|
||||
}
|
||||
|
||||
void calib::calibDataController::setParametersFileName(const std::string &name)
|
||||
{
|
||||
mParamsFileName = name;
|
||||
}
|
||||
|
||||
void calib::calibDataController::deleteLastFrame()
|
||||
{
|
||||
if( !mCalibData->imagePoints.empty()) {
|
||||
mCalibData->imagePoints.pop_back();
|
||||
mCalibData->objectPoints.pop_back();
|
||||
}
|
||||
|
||||
if (!mCalibData->allCharucoCorners.empty()) {
|
||||
mCalibData->allCharucoCorners.pop_back();
|
||||
mCalibData->allCharucoIds.pop_back();
|
||||
}
|
||||
|
||||
if(!mParamsStack.empty()) {
|
||||
mCalibData->cameraMatrix = (mParamsStack.top()).cameraMatrix;
|
||||
mCalibData->distCoeffs = (mParamsStack.top()).distCoeffs;
|
||||
mCalibData->stdDeviations = (mParamsStack.top()).stdDeviations;
|
||||
mCalibData->totalAvgErr = (mParamsStack.top()).avgError;
|
||||
mParamsStack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
void calib::calibDataController::rememberCurrentParameters()
|
||||
{
|
||||
cv::Mat oldCameraMat, oldDistcoeefs, oldStdDevs;
|
||||
mCalibData->cameraMatrix.copyTo(oldCameraMat);
|
||||
mCalibData->distCoeffs.copyTo(oldDistcoeefs);
|
||||
mCalibData->stdDeviations.copyTo(oldStdDevs);
|
||||
mParamsStack.push(cameraParameters(oldCameraMat, oldDistcoeefs, oldStdDevs, mCalibData->totalAvgErr));
|
||||
}
|
||||
|
||||
void calib::calibDataController::deleteAllData()
|
||||
{
|
||||
mCalibData->imagePoints.clear();
|
||||
mCalibData->objectPoints.clear();
|
||||
mCalibData->allCharucoCorners.clear();
|
||||
mCalibData->allCharucoIds.clear();
|
||||
mCalibData->cameraMatrix = mCalibData->distCoeffs = cv::Mat();
|
||||
mParamsStack = std::stack<cameraParameters>();
|
||||
rememberCurrentParameters();
|
||||
}
|
||||
|
||||
bool calib::calibDataController::saveCurrentCameraParameters() const
|
||||
{
|
||||
bool success = false;
|
||||
if(mCalibData->cameraMatrix.total()) {
|
||||
cv::FileStorage parametersWriter(mParamsFileName, cv::FileStorage::WRITE);
|
||||
if(parametersWriter.isOpened()) {
|
||||
time_t rawtime;
|
||||
time(&rawtime);
|
||||
char buf[256];
|
||||
strftime(buf, sizeof(buf)-1, "%c", localtime(&rawtime));
|
||||
|
||||
parametersWriter << "calibrationDate" << buf;
|
||||
parametersWriter << "framesCount" << std::max((int)mCalibData->objectPoints.size(), (int)mCalibData->allCharucoCorners.size());
|
||||
parametersWriter << "cameraResolution" << mCalibData->imageSize;
|
||||
parametersWriter << "cameraMatrix" << mCalibData->cameraMatrix;
|
||||
parametersWriter << "cameraMatrix_std_dev" << mCalibData->stdDeviations.rowRange(cv::Range(0, 4));
|
||||
parametersWriter << "dist_coeffs" << mCalibData->distCoeffs;
|
||||
parametersWriter << "dist_coeffs_std_dev" << mCalibData->stdDeviations.rowRange(cv::Range(4, 9));
|
||||
parametersWriter << "avg_reprojection_error" << mCalibData->totalAvgErr;
|
||||
|
||||
parametersWriter.release();
|
||||
success = true;
|
||||
}
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
void calib::calibDataController::printParametersToConsole(std::ostream &output) const
|
||||
{
|
||||
const char* border = "---------------------------------------------------";
|
||||
output << border << std::endl;
|
||||
output << "Frames used for calibration: " << std::max(mCalibData->objectPoints.size(), mCalibData->allCharucoCorners.size())
|
||||
<< " \t RMS = " << mCalibData->totalAvgErr << std::endl;
|
||||
if(mCalibData->cameraMatrix.at<double>(0,0) == mCalibData->cameraMatrix.at<double>(1,1))
|
||||
output << "F = " << mCalibData->cameraMatrix.at<double>(1,1) << " +- " << sigmaMult*mCalibData->stdDeviations.at<double>(1) << std::endl;
|
||||
else
|
||||
output << "Fx = " << mCalibData->cameraMatrix.at<double>(0,0) << " +- " << sigmaMult*mCalibData->stdDeviations.at<double>(0) << " \t "
|
||||
<< "Fy = " << mCalibData->cameraMatrix.at<double>(1,1) << " +- " << sigmaMult*mCalibData->stdDeviations.at<double>(1) << std::endl;
|
||||
output << "Cx = " << mCalibData->cameraMatrix.at<double>(0,2) << " +- " << sigmaMult*mCalibData->stdDeviations.at<double>(2) << " \t"
|
||||
<< "Cy = " << mCalibData->cameraMatrix.at<double>(1,2) << " +- " << sigmaMult*mCalibData->stdDeviations.at<double>(3) << std::endl;
|
||||
output << "K1 = " << mCalibData->distCoeffs.at<double>(0) << " +- " << sigmaMult*mCalibData->stdDeviations.at<double>(4) << std::endl;
|
||||
output << "K2 = " << mCalibData->distCoeffs.at<double>(1) << " +- " << sigmaMult*mCalibData->stdDeviations.at<double>(5) << std::endl;
|
||||
output << "K3 = " << mCalibData->distCoeffs.at<double>(4) << " +- " << sigmaMult*mCalibData->stdDeviations.at<double>(8) << std::endl;
|
||||
output << "TD1 = " << mCalibData->distCoeffs.at<double>(2) << " +- " << sigmaMult*mCalibData->stdDeviations.at<double>(6) << std::endl;
|
||||
output << "TD2 = " << mCalibData->distCoeffs.at<double>(3) << " +- " << sigmaMult*mCalibData->stdDeviations.at<double>(7) << std::endl;
|
||||
}
|
||||
|
||||
void calib::calibDataController::updateUndistortMap()
|
||||
{
|
||||
cv::initUndistortRectifyMap(mCalibData->cameraMatrix, mCalibData->distCoeffs, cv::noArray(),
|
||||
cv::getOptimalNewCameraMatrix(mCalibData->cameraMatrix, mCalibData->distCoeffs, mCalibData->imageSize, 0.0, mCalibData->imageSize),
|
||||
mCalibData->imageSize, CV_16SC2, mCalibData->undistMap1, mCalibData->undistMap2);
|
||||
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#ifndef CALIB_CONTROLLER_HPP
|
||||
#define CALIB_CONTROLLER_HPP
|
||||
|
||||
#include "calibCommon.hpp"
|
||||
|
||||
#include <stack>
|
||||
#include <string>
|
||||
#include <ostream>
|
||||
|
||||
namespace calib {
|
||||
|
||||
class calibController
|
||||
{
|
||||
protected:
|
||||
cv::Ptr<calibrationData> mCalibData;
|
||||
int mCalibFlags;
|
||||
unsigned mMinFramesNum;
|
||||
bool mNeedTuning;
|
||||
bool mConfIntervalsState;
|
||||
bool mCoverageQualityState;
|
||||
|
||||
double estimateCoverageQuality();
|
||||
public:
|
||||
calibController();
|
||||
calibController(cv::Ptr<calibrationData> data, int initialFlags, bool autoTuning,
|
||||
int minFramesNum);
|
||||
|
||||
void updateState();
|
||||
|
||||
bool getCommonCalibrationState() const;
|
||||
|
||||
bool getFramesNumberState() const;
|
||||
bool getConfidenceIntrervalsState() const;
|
||||
bool getRMSState() const;
|
||||
bool getPointsCoverageState() const;
|
||||
int getNewFlags() const;
|
||||
};
|
||||
|
||||
class calibDataController
|
||||
{
|
||||
protected:
|
||||
cv::Ptr<calibrationData> mCalibData;
|
||||
std::stack<cameraParameters> mParamsStack;
|
||||
std::string mParamsFileName;
|
||||
unsigned mMaxFramesNum;
|
||||
double mAlpha;
|
||||
|
||||
double estimateGridSubsetQuality(size_t excludedIndex);
|
||||
public:
|
||||
calibDataController(cv::Ptr<calibrationData> data, int maxFrames, double convParameter);
|
||||
calibDataController();
|
||||
|
||||
void filterFrames();
|
||||
void setParametersFileName(const std::string& name);
|
||||
void deleteLastFrame();
|
||||
void rememberCurrentParameters();
|
||||
void deleteAllData();
|
||||
bool saveCurrentCameraParameters() const;
|
||||
void printParametersToConsole(std::ostream &output) const;
|
||||
void updateUndistortMap();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,97 @@
|
|||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#include "calibPipeline.hpp"
|
||||
|
||||
#include <opencv2/highgui.hpp>
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
using namespace calib;
|
||||
|
||||
#define CAP_DELAY 10
|
||||
|
||||
cv::Size CalibPipeline::getCameraResolution()
|
||||
{
|
||||
mCapture.set(cv::CAP_PROP_FRAME_WIDTH, 10000);
|
||||
mCapture.set(cv::CAP_PROP_FRAME_HEIGHT, 10000);
|
||||
int w = (int)mCapture.get(cv::CAP_PROP_FRAME_WIDTH);
|
||||
int h = (int)mCapture.get(cv::CAP_PROP_FRAME_HEIGHT);
|
||||
return cv::Size(w,h);
|
||||
}
|
||||
|
||||
CalibPipeline::CalibPipeline(captureParameters params) :
|
||||
mCaptureParams(params)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PipelineExitStatus CalibPipeline::start(std::vector<cv::Ptr<FrameProcessor> > processors)
|
||||
{
|
||||
if(mCaptureParams.source == Camera && !mCapture.isOpened())
|
||||
{
|
||||
mCapture.open(mCaptureParams.camID);
|
||||
cv::Size maxRes = getCameraResolution();
|
||||
cv::Size neededRes = mCaptureParams.cameraResolution;
|
||||
|
||||
if(maxRes.width < neededRes.width) {
|
||||
double aR = (double)maxRes.width / maxRes.height;
|
||||
mCapture.set(cv::CAP_PROP_FRAME_WIDTH, neededRes.width);
|
||||
mCapture.set(cv::CAP_PROP_FRAME_HEIGHT, neededRes.width/aR);
|
||||
}
|
||||
else if(maxRes.height < neededRes.height) {
|
||||
double aR = (double)maxRes.width / maxRes.height;
|
||||
mCapture.set(cv::CAP_PROP_FRAME_HEIGHT, neededRes.height);
|
||||
mCapture.set(cv::CAP_PROP_FRAME_WIDTH, neededRes.height*aR);
|
||||
}
|
||||
else {
|
||||
mCapture.set(cv::CAP_PROP_FRAME_HEIGHT, neededRes.height);
|
||||
mCapture.set(cv::CAP_PROP_FRAME_WIDTH, neededRes.width);
|
||||
}
|
||||
mCapture.set(cv::CAP_PROP_AUTOFOCUS, 0);
|
||||
}
|
||||
else if (mCaptureParams.source == File && !mCapture.isOpened())
|
||||
mCapture.open(mCaptureParams.videoFileName);
|
||||
mImageSize = cv::Size((int)mCapture.get(cv::CAP_PROP_FRAME_WIDTH), (int)mCapture.get(cv::CAP_PROP_FRAME_HEIGHT));
|
||||
|
||||
if(!mCapture.isOpened())
|
||||
throw std::runtime_error("Unable to open video source");
|
||||
|
||||
cv::Mat frame, processedFrame;
|
||||
while(mCapture.grab()) {
|
||||
mCapture.retrieve(frame);
|
||||
if(mCaptureParams.flipVertical)
|
||||
cv::flip(frame, frame, -1);
|
||||
|
||||
frame.copyTo(processedFrame);
|
||||
for (std::vector<cv::Ptr<FrameProcessor> >::iterator it = processors.begin(); it != processors.end(); ++it)
|
||||
processedFrame = (*it)->processFrame(processedFrame);
|
||||
cv::imshow(mainWindowName, processedFrame);
|
||||
char key = (char)cv::waitKey(CAP_DELAY);
|
||||
|
||||
if(key == 27) // esc
|
||||
return Finished;
|
||||
else if (key == 114) // r
|
||||
return DeleteLastFrame;
|
||||
else if (key == 100) // d
|
||||
return DeleteAllFrames;
|
||||
else if (key == 115) // s
|
||||
return SaveCurrentData;
|
||||
else if (key == 117) // u
|
||||
return SwitchUndistort;
|
||||
else if (key == 118) // v
|
||||
return SwitchVisualisation;
|
||||
|
||||
for (std::vector<cv::Ptr<FrameProcessor> >::iterator it = processors.begin(); it != processors.end(); ++it)
|
||||
if((*it)->isProcessed())
|
||||
return Calibrate;
|
||||
}
|
||||
|
||||
return Finished;
|
||||
}
|
||||
|
||||
cv::Size CalibPipeline::getImageSize() const
|
||||
{
|
||||
return mImageSize;
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
|
||||
#ifndef CALIB_PIPELINE_HPP
|
||||
#define CALIB_PIPELINE_HPP
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <opencv2/highgui.hpp>
|
||||
|
||||
#include "calibCommon.hpp"
|
||||
#include "frameProcessor.hpp"
|
||||
|
||||
namespace calib
|
||||
{
|
||||
|
||||
enum PipelineExitStatus { Finished,
|
||||
DeleteLastFrame,
|
||||
Calibrate,
|
||||
DeleteAllFrames,
|
||||
SaveCurrentData,
|
||||
SwitchUndistort,
|
||||
SwitchVisualisation
|
||||
};
|
||||
|
||||
class CalibPipeline
|
||||
{
|
||||
protected:
|
||||
captureParameters mCaptureParams;
|
||||
cv::Size mImageSize;
|
||||
cv::VideoCapture mCapture;
|
||||
|
||||
cv::Size getCameraResolution();
|
||||
|
||||
public:
|
||||
CalibPipeline(captureParameters params);
|
||||
PipelineExitStatus start(std::vector<cv::Ptr<FrameProcessor> > processors);
|
||||
cv::Size getImageSize() const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0"?>
|
||||
<opencv_storage>
|
||||
<charuco_dict>0</charuco_dict>
|
||||
<charuco_square_lenght>200</charuco_square_lenght>
|
||||
<charuco_marker_size>100</charuco_marker_size>
|
||||
<calibration_step>1</calibration_step>
|
||||
<max_frames_num>30</max_frames_num>
|
||||
<min_frames_num>10</min_frames_num>
|
||||
<solver_eps>1e-7</solver_eps>
|
||||
<solver_max_iters>30</solver_max_iters>
|
||||
<fast_solver>0</fast_solver>
|
||||
<frame_filter_conv_param>0.1</frame_filter_conv_param>
|
||||
<camera_resolution>800 600</camera_resolution>
|
||||
</opencv_storage>
|
|
@ -0,0 +1,530 @@
|
|||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#include "frameProcessor.hpp"
|
||||
#include "rotationConverters.hpp"
|
||||
|
||||
#include <opencv2/calib3d.hpp>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
using namespace calib;
|
||||
|
||||
#define VIDEO_TEXT_SIZE 4
|
||||
#define POINT_SIZE 5
|
||||
|
||||
static cv::SimpleBlobDetector::Params getDetectorParams()
|
||||
{
|
||||
cv::SimpleBlobDetector::Params detectorParams;
|
||||
|
||||
detectorParams.thresholdStep = 40;
|
||||
detectorParams.minThreshold = 20;
|
||||
detectorParams.maxThreshold = 500;
|
||||
detectorParams.minRepeatability = 2;
|
||||
detectorParams.minDistBetweenBlobs = 5;
|
||||
|
||||
detectorParams.filterByColor = true;
|
||||
detectorParams.blobColor = 0;
|
||||
|
||||
detectorParams.filterByArea = true;
|
||||
detectorParams.minArea = 5;
|
||||
detectorParams.maxArea = 5000;
|
||||
|
||||
detectorParams.filterByCircularity = false;
|
||||
detectorParams.minCircularity = 0.8f;
|
||||
detectorParams.maxCircularity = std::numeric_limits<float>::max();
|
||||
|
||||
detectorParams.filterByInertia = true;
|
||||
detectorParams.minInertiaRatio = 0.1f;
|
||||
detectorParams.maxInertiaRatio = std::numeric_limits<float>::max();
|
||||
|
||||
detectorParams.filterByConvexity = true;
|
||||
detectorParams.minConvexity = 0.8f;
|
||||
detectorParams.maxConvexity = std::numeric_limits<float>::max();
|
||||
|
||||
return detectorParams;
|
||||
}
|
||||
|
||||
FrameProcessor::~FrameProcessor()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool CalibProcessor::detectAndParseChessboard(const cv::Mat &frame)
|
||||
{
|
||||
int chessBoardFlags = cv::CALIB_CB_ADAPTIVE_THRESH | cv::CALIB_CB_NORMALIZE_IMAGE | cv::CALIB_CB_FAST_CHECK;
|
||||
bool isTemplateFound = cv::findChessboardCorners(frame, mBoardSize, mCurrentImagePoints, chessBoardFlags);
|
||||
|
||||
if (isTemplateFound) {
|
||||
cv::Mat viewGray;
|
||||
cv::cvtColor(frame, viewGray, cv::COLOR_BGR2GRAY);
|
||||
cv::cornerSubPix(viewGray, mCurrentImagePoints, cv::Size(11,11),
|
||||
cv::Size(-1,-1), cv::TermCriteria( cv::TermCriteria::EPS+cv::TermCriteria::COUNT, 30, 0.1 ));
|
||||
cv::drawChessboardCorners(frame, mBoardSize, cv::Mat(mCurrentImagePoints), isTemplateFound);
|
||||
mTemplateLocations.insert(mTemplateLocations.begin(), mCurrentImagePoints[0]);
|
||||
}
|
||||
return isTemplateFound;
|
||||
}
|
||||
|
||||
bool CalibProcessor::detectAndParseChAruco(const cv::Mat &frame)
|
||||
{
|
||||
#ifdef HAVE_OPENCV_ARUCO
|
||||
cv::Ptr<cv::aruco::Board> board = mCharucoBoard.staticCast<cv::aruco::Board>();
|
||||
|
||||
std::vector<std::vector<cv::Point2f> > corners, rejected;
|
||||
std::vector<int> ids;
|
||||
cv::aruco::detectMarkers(frame, mArucoDictionary, corners, ids, cv::aruco::DetectorParameters::create(), rejected);
|
||||
cv::aruco::refineDetectedMarkers(frame, board, corners, ids, rejected);
|
||||
cv::Mat currentCharucoCorners, currentCharucoIds;
|
||||
if(ids.size() > 0)
|
||||
cv::aruco::interpolateCornersCharuco(corners, ids, frame, mCharucoBoard, currentCharucoCorners,
|
||||
currentCharucoIds);
|
||||
if(ids.size() > 0) cv::aruco::drawDetectedMarkers(frame, corners);
|
||||
|
||||
if(currentCharucoCorners.total() > 3) {
|
||||
float centerX = 0, centerY = 0;
|
||||
for (int i = 0; i < currentCharucoCorners.size[0]; i++) {
|
||||
centerX += currentCharucoCorners.at<float>(i, 0);
|
||||
centerY += currentCharucoCorners.at<float>(i, 1);
|
||||
}
|
||||
centerX /= currentCharucoCorners.size[0];
|
||||
centerY /= currentCharucoCorners.size[0];
|
||||
|
||||
mTemplateLocations.insert(mTemplateLocations.begin(), cv::Point2f(centerX, centerY));
|
||||
cv::aruco::drawDetectedCornersCharuco(frame, currentCharucoCorners, currentCharucoIds);
|
||||
mCurrentCharucoCorners = currentCharucoCorners;
|
||||
mCurrentCharucoIds = currentCharucoIds;
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
CV_UNUSED(frame);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CalibProcessor::detectAndParseACircles(const cv::Mat &frame)
|
||||
{
|
||||
bool isTemplateFound = findCirclesGrid(frame, mBoardSize, mCurrentImagePoints, cv::CALIB_CB_ASYMMETRIC_GRID, mBlobDetectorPtr);
|
||||
if(isTemplateFound) {
|
||||
mTemplateLocations.insert(mTemplateLocations.begin(), mCurrentImagePoints[0]);
|
||||
cv::drawChessboardCorners(frame, mBoardSize, cv::Mat(mCurrentImagePoints), isTemplateFound);
|
||||
}
|
||||
return isTemplateFound;
|
||||
}
|
||||
|
||||
bool CalibProcessor::detectAndParseDualACircles(const cv::Mat &frame)
|
||||
{
|
||||
std::vector<cv::Point2f> blackPointbuf;
|
||||
|
||||
cv::Mat invertedView;
|
||||
cv::bitwise_not(frame, invertedView);
|
||||
bool isWhiteGridFound = cv::findCirclesGrid(frame, mBoardSize, mCurrentImagePoints, cv::CALIB_CB_ASYMMETRIC_GRID, mBlobDetectorPtr);
|
||||
if(!isWhiteGridFound)
|
||||
return false;
|
||||
bool isBlackGridFound = cv::findCirclesGrid(invertedView, mBoardSize, blackPointbuf, cv::CALIB_CB_ASYMMETRIC_GRID, mBlobDetectorPtr);
|
||||
|
||||
if(!isBlackGridFound)
|
||||
{
|
||||
mCurrentImagePoints.clear();
|
||||
return false;
|
||||
}
|
||||
cv::drawChessboardCorners(frame, mBoardSize, cv::Mat(mCurrentImagePoints), isWhiteGridFound);
|
||||
cv::drawChessboardCorners(frame, mBoardSize, cv::Mat(blackPointbuf), isBlackGridFound);
|
||||
mCurrentImagePoints.insert(mCurrentImagePoints.end(), blackPointbuf.begin(), blackPointbuf.end());
|
||||
mTemplateLocations.insert(mTemplateLocations.begin(), mCurrentImagePoints[0]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CalibProcessor::saveFrameData()
|
||||
{
|
||||
std::vector<cv::Point3f> objectPoints;
|
||||
|
||||
switch(mBoardType)
|
||||
{
|
||||
case Chessboard:
|
||||
objectPoints.reserve(mBoardSize.height*mBoardSize.width);
|
||||
for( int i = 0; i < mBoardSize.height; ++i )
|
||||
for( int j = 0; j < mBoardSize.width; ++j )
|
||||
objectPoints.push_back(cv::Point3f(j*mSquareSize, i*mSquareSize, 0));
|
||||
mCalibData->imagePoints.push_back(mCurrentImagePoints);
|
||||
mCalibData->objectPoints.push_back(objectPoints);
|
||||
break;
|
||||
case chAruco:
|
||||
mCalibData->allCharucoCorners.push_back(mCurrentCharucoCorners);
|
||||
mCalibData->allCharucoIds.push_back(mCurrentCharucoIds);
|
||||
break;
|
||||
case AcirclesGrid:
|
||||
objectPoints.reserve(mBoardSize.height*mBoardSize.width);
|
||||
for( int i = 0; i < mBoardSize.height; i++ )
|
||||
for( int j = 0; j < mBoardSize.width; j++ )
|
||||
objectPoints.push_back(cv::Point3f((2*j + i % 2)*mSquareSize, i*mSquareSize, 0));
|
||||
mCalibData->imagePoints.push_back(mCurrentImagePoints);
|
||||
mCalibData->objectPoints.push_back(objectPoints);
|
||||
break;
|
||||
case DoubleAcirclesGrid:
|
||||
{
|
||||
float gridCenterX = (2*((float)mBoardSize.width - 1) + 1)*mSquareSize + mTemplDist / 2;
|
||||
float gridCenterY = (mBoardSize.height - 1)*mSquareSize / 2;
|
||||
objectPoints.reserve(2*mBoardSize.height*mBoardSize.width);
|
||||
|
||||
//white part
|
||||
for( int i = 0; i < mBoardSize.height; i++ )
|
||||
for( int j = 0; j < mBoardSize.width; j++ )
|
||||
objectPoints.push_back(
|
||||
cv::Point3f(-float((2*j + i % 2)*mSquareSize + mTemplDist +
|
||||
(2*(mBoardSize.width - 1) + 1)*mSquareSize - gridCenterX),
|
||||
-float(i*mSquareSize) - gridCenterY,
|
||||
0));
|
||||
//black part
|
||||
for( int i = 0; i < mBoardSize.height; i++ )
|
||||
for( int j = 0; j < mBoardSize.width; j++ )
|
||||
objectPoints.push_back(cv::Point3f(-float((2*j + i % 2)*mSquareSize - gridCenterX),
|
||||
-float(i*mSquareSize) - gridCenterY, 0));
|
||||
|
||||
mCalibData->imagePoints.push_back(mCurrentImagePoints);
|
||||
mCalibData->objectPoints.push_back(objectPoints);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CalibProcessor::showCaptureMessage(const cv::Mat& frame, const std::string &message)
|
||||
{
|
||||
cv::Point textOrigin(100, 100);
|
||||
double textSize = VIDEO_TEXT_SIZE * frame.cols / (double) IMAGE_MAX_WIDTH;
|
||||
cv::bitwise_not(frame, frame);
|
||||
cv::putText(frame, message, textOrigin, 1, textSize, cv::Scalar(0,0,255), 2, cv::LINE_AA);
|
||||
cv::imshow(mainWindowName, frame);
|
||||
cv::waitKey(300);
|
||||
}
|
||||
|
||||
bool CalibProcessor::checkLastFrame()
|
||||
{
|
||||
bool isFrameBad = false;
|
||||
cv::Mat tmpCamMatrix;
|
||||
const double badAngleThresh = 40;
|
||||
|
||||
if(!mCalibData->cameraMatrix.total()) {
|
||||
tmpCamMatrix = cv::Mat::eye(3, 3, CV_64F);
|
||||
tmpCamMatrix.at<double>(0,0) = 20000;
|
||||
tmpCamMatrix.at<double>(1,1) = 20000;
|
||||
tmpCamMatrix.at<double>(0,2) = mCalibData->imageSize.height/2;
|
||||
tmpCamMatrix.at<double>(1,2) = mCalibData->imageSize.width/2;
|
||||
}
|
||||
else
|
||||
mCalibData->cameraMatrix.copyTo(tmpCamMatrix);
|
||||
|
||||
if(mBoardType != chAruco) {
|
||||
cv::Mat r, t, angles;
|
||||
cv::solvePnP(mCalibData->objectPoints.back(), mCurrentImagePoints, tmpCamMatrix, mCalibData->distCoeffs, r, t);
|
||||
RodriguesToEuler(r, angles, CALIB_DEGREES);
|
||||
|
||||
if(fabs(angles.at<double>(0)) > badAngleThresh || fabs(angles.at<double>(1)) > badAngleThresh) {
|
||||
mCalibData->objectPoints.pop_back();
|
||||
mCalibData->imagePoints.pop_back();
|
||||
isFrameBad = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef HAVE_OPENCV_ARUCO
|
||||
cv::Mat r, t, angles;
|
||||
std::vector<cv::Point3f> allObjPoints;
|
||||
allObjPoints.reserve(mCurrentCharucoIds.total());
|
||||
for(size_t i = 0; i < mCurrentCharucoIds.total(); i++) {
|
||||
int pointID = mCurrentCharucoIds.at<int>((int)i);
|
||||
CV_Assert(pointID >= 0 && pointID < (int)mCharucoBoard->chessboardCorners.size());
|
||||
allObjPoints.push_back(mCharucoBoard->chessboardCorners[pointID]);
|
||||
}
|
||||
|
||||
cv::solvePnP(allObjPoints, mCurrentCharucoCorners, tmpCamMatrix, mCalibData->distCoeffs, r, t);
|
||||
RodriguesToEuler(r, angles, CALIB_DEGREES);
|
||||
|
||||
if(180.0 - fabs(angles.at<double>(0)) > badAngleThresh || fabs(angles.at<double>(1)) > badAngleThresh) {
|
||||
isFrameBad = true;
|
||||
mCalibData->allCharucoCorners.pop_back();
|
||||
mCalibData->allCharucoIds.pop_back();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return isFrameBad;
|
||||
}
|
||||
|
||||
CalibProcessor::CalibProcessor(cv::Ptr<calibrationData> data, captureParameters &capParams) :
|
||||
mCalibData(data), mBoardType(capParams.board), mBoardSize(capParams.boardSize)
|
||||
{
|
||||
mCapuredFrames = 0;
|
||||
mNeededFramesNum = capParams.calibrationStep;
|
||||
mDelayBetweenCaptures = static_cast<int>(capParams.captureDelay * capParams.fps);
|
||||
mMaxTemplateOffset = std::sqrt(static_cast<float>(mCalibData->imageSize.height * mCalibData->imageSize.height) +
|
||||
static_cast<float>(mCalibData->imageSize.width * mCalibData->imageSize.width)) / 20.0;
|
||||
mSquareSize = capParams.squareSize;
|
||||
mTemplDist = capParams.templDst;
|
||||
|
||||
switch(mBoardType)
|
||||
{
|
||||
case chAruco:
|
||||
#ifdef HAVE_OPENCV_ARUCO
|
||||
mArucoDictionary = cv::aruco::getPredefinedDictionary(
|
||||
cv::aruco::PREDEFINED_DICTIONARY_NAME(capParams.charucoDictName));
|
||||
mCharucoBoard = cv::aruco::CharucoBoard::create(mBoardSize.width, mBoardSize.height, capParams.charucoSquareLenght,
|
||||
capParams.charucoMarkerSize, mArucoDictionary);
|
||||
#endif
|
||||
break;
|
||||
case AcirclesGrid:
|
||||
mBlobDetectorPtr = cv::SimpleBlobDetector::create();
|
||||
break;
|
||||
case DoubleAcirclesGrid:
|
||||
mBlobDetectorPtr = cv::SimpleBlobDetector::create(getDetectorParams());
|
||||
break;
|
||||
case Chessboard:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cv::Mat CalibProcessor::processFrame(const cv::Mat &frame)
|
||||
{
|
||||
cv::Mat frameCopy;
|
||||
frame.copyTo(frameCopy);
|
||||
bool isTemplateFound = false;
|
||||
mCurrentImagePoints.clear();
|
||||
|
||||
switch(mBoardType)
|
||||
{
|
||||
case Chessboard:
|
||||
isTemplateFound = detectAndParseChessboard(frameCopy);
|
||||
break;
|
||||
case chAruco:
|
||||
isTemplateFound = detectAndParseChAruco(frameCopy);
|
||||
break;
|
||||
case AcirclesGrid:
|
||||
isTemplateFound = detectAndParseACircles(frameCopy);
|
||||
break;
|
||||
case DoubleAcirclesGrid:
|
||||
isTemplateFound = detectAndParseDualACircles(frameCopy);
|
||||
break;
|
||||
}
|
||||
|
||||
if(mTemplateLocations.size() > mDelayBetweenCaptures)
|
||||
mTemplateLocations.pop_back();
|
||||
if(mTemplateLocations.size() == mDelayBetweenCaptures && isTemplateFound) {
|
||||
if(cv::norm(mTemplateLocations.front() - mTemplateLocations.back()) < mMaxTemplateOffset) {
|
||||
saveFrameData();
|
||||
bool isFrameBad = checkLastFrame();
|
||||
if (!isFrameBad) {
|
||||
std::string displayMessage = cv::format("Frame # %zu captured", std::max(mCalibData->imagePoints.size(),
|
||||
mCalibData->allCharucoCorners.size()));
|
||||
if(!showOverlayMessage(displayMessage))
|
||||
showCaptureMessage(frame, displayMessage);
|
||||
mCapuredFrames++;
|
||||
}
|
||||
else {
|
||||
std::string displayMessage = "Frame rejected";
|
||||
if(!showOverlayMessage(displayMessage))
|
||||
showCaptureMessage(frame, displayMessage);
|
||||
}
|
||||
mTemplateLocations.clear();
|
||||
mTemplateLocations.reserve(mDelayBetweenCaptures);
|
||||
}
|
||||
}
|
||||
|
||||
return frameCopy;
|
||||
}
|
||||
|
||||
bool CalibProcessor::isProcessed() const
|
||||
{
|
||||
if(mCapuredFrames < mNeededFramesNum)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
void CalibProcessor::resetState()
|
||||
{
|
||||
mCapuredFrames = 0;
|
||||
mTemplateLocations.clear();
|
||||
}
|
||||
|
||||
CalibProcessor::~CalibProcessor()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////
|
||||
|
||||
void ShowProcessor::drawBoard(cv::Mat &img, cv::InputArray points)
|
||||
{
|
||||
cv::Mat tmpView = cv::Mat::zeros(img.rows, img.cols, CV_8UC3);
|
||||
std::vector<cv::Point2f> templateHull;
|
||||
std::vector<cv::Point> poly;
|
||||
cv::convexHull(points, templateHull);
|
||||
poly.resize(templateHull.size());
|
||||
for(size_t i=0; i<templateHull.size();i++)
|
||||
poly[i] = cv::Point((int)(templateHull[i].x*mGridViewScale), (int)(templateHull[i].y*mGridViewScale));
|
||||
cv::fillConvexPoly(tmpView, poly, cv::Scalar(0, 255, 0), cv::LINE_AA);
|
||||
cv::addWeighted(tmpView, .2, img, 1, 0, img);
|
||||
}
|
||||
|
||||
void ShowProcessor::drawGridPoints(const cv::Mat &frame)
|
||||
{
|
||||
if(mBoardType != chAruco)
|
||||
for(std::vector<std::vector<cv::Point2f> >::iterator it = mCalibdata->imagePoints.begin(); it != mCalibdata->imagePoints.end(); ++it)
|
||||
for(std::vector<cv::Point2f>::iterator pointIt = (*it).begin(); pointIt != (*it).end(); ++pointIt)
|
||||
cv::circle(frame, *pointIt, POINT_SIZE, cv::Scalar(0, 255, 0), 1, cv::LINE_AA);
|
||||
else
|
||||
for(std::vector<cv::Mat>::iterator it = mCalibdata->allCharucoCorners.begin(); it != mCalibdata->allCharucoCorners.end(); ++it)
|
||||
for(int i = 0; i < (*it).size[0]; i++)
|
||||
cv::circle(frame, cv::Point((int)(*it).at<float>(i, 0), (int)(*it).at<float>(i, 1)),
|
||||
POINT_SIZE, cv::Scalar(0, 255, 0), 1, cv::LINE_AA);
|
||||
}
|
||||
|
||||
ShowProcessor::ShowProcessor(cv::Ptr<calibrationData> data, cv::Ptr<calibController> controller, TemplateType board) :
|
||||
mCalibdata(data), mController(controller), mBoardType(board)
|
||||
{
|
||||
mNeedUndistort = true;
|
||||
mVisMode = Grid;
|
||||
mGridViewScale = 0.5;
|
||||
mTextSize = VIDEO_TEXT_SIZE;
|
||||
}
|
||||
|
||||
cv::Mat ShowProcessor::processFrame(const cv::Mat &frame)
|
||||
{
|
||||
if (!mCalibdata->cameraMatrix.empty() && !mCalibdata->distCoeffs.empty())
|
||||
{
|
||||
mTextSize = VIDEO_TEXT_SIZE * (double) frame.cols / IMAGE_MAX_WIDTH;
|
||||
cv::Scalar textColor = cv::Scalar(0,0,255);
|
||||
cv::Mat frameCopy;
|
||||
|
||||
if (mNeedUndistort && mController->getFramesNumberState()) {
|
||||
if(mVisMode == Grid)
|
||||
drawGridPoints(frame);
|
||||
cv::remap(frame, frameCopy, mCalibdata->undistMap1, mCalibdata->undistMap2, cv::INTER_LINEAR);
|
||||
int baseLine = 100;
|
||||
cv::Size textSize = cv::getTextSize("Undistorted view", 1, mTextSize, 2, &baseLine);
|
||||
cv::Point textOrigin(baseLine, frame.rows - (int)(2.5*textSize.height));
|
||||
cv::putText(frameCopy, "Undistorted view", textOrigin, 1, mTextSize, textColor, 2, cv::LINE_AA);
|
||||
}
|
||||
else {
|
||||
frame.copyTo(frameCopy);
|
||||
if(mVisMode == Grid)
|
||||
drawGridPoints(frameCopy);
|
||||
}
|
||||
std::string displayMessage;
|
||||
if(mCalibdata->stdDeviations.at<double>(0) == 0)
|
||||
displayMessage = cv::format("F = %d RMS = %.3f", (int)mCalibdata->cameraMatrix.at<double>(0,0), mCalibdata->totalAvgErr);
|
||||
else
|
||||
displayMessage = cv::format("Fx = %d Fy = %d RMS = %.3f", (int)mCalibdata->cameraMatrix.at<double>(0,0),
|
||||
(int)mCalibdata->cameraMatrix.at<double>(1,1), mCalibdata->totalAvgErr);
|
||||
if(mController->getRMSState() && mController->getFramesNumberState())
|
||||
displayMessage.append(" OK");
|
||||
|
||||
int baseLine = 100;
|
||||
cv::Size textSize = cv::getTextSize(displayMessage, 1, mTextSize - 1, 2, &baseLine);
|
||||
cv::Point textOrigin = cv::Point(baseLine, 2*textSize.height);
|
||||
cv::putText(frameCopy, displayMessage, textOrigin, 1, mTextSize - 1, textColor, 2, cv::LINE_AA);
|
||||
|
||||
if(mCalibdata->stdDeviations.at<double>(0) == 0)
|
||||
displayMessage = cv::format("DF = %.2f", mCalibdata->stdDeviations.at<double>(1)*sigmaMult);
|
||||
else
|
||||
displayMessage = cv::format("DFx = %.2f DFy = %.2f", mCalibdata->stdDeviations.at<double>(0)*sigmaMult,
|
||||
mCalibdata->stdDeviations.at<double>(1)*sigmaMult);
|
||||
if(mController->getConfidenceIntrervalsState() && mController->getFramesNumberState())
|
||||
displayMessage.append(" OK");
|
||||
cv::putText(frameCopy, displayMessage, cv::Point(baseLine, 4*textSize.height), 1, mTextSize - 1, textColor, 2, cv::LINE_AA);
|
||||
|
||||
if(mController->getCommonCalibrationState()) {
|
||||
displayMessage = cv::format("Calibration is done");
|
||||
cv::putText(frameCopy, displayMessage, cv::Point(baseLine, 6*textSize.height), 1, mTextSize - 1, textColor, 2, cv::LINE_AA);
|
||||
}
|
||||
int calibFlags = mController->getNewFlags();
|
||||
displayMessage = "";
|
||||
if(!(calibFlags & cv::CALIB_FIX_ASPECT_RATIO))
|
||||
displayMessage.append(cv::format("AR=%.3f ", mCalibdata->cameraMatrix.at<double>(0,0)/mCalibdata->cameraMatrix.at<double>(1,1)));
|
||||
if(calibFlags & cv::CALIB_ZERO_TANGENT_DIST)
|
||||
displayMessage.append("TD=0 ");
|
||||
displayMessage.append(cv::format("K1=%.2f K2=%.2f K3=%.2f", mCalibdata->distCoeffs.at<double>(0), mCalibdata->distCoeffs.at<double>(1),
|
||||
mCalibdata->distCoeffs.at<double>(4)));
|
||||
cv::putText(frameCopy, displayMessage, cv::Point(baseLine, frameCopy.rows - (int)(1.5*textSize.height)),
|
||||
1, mTextSize - 1, textColor, 2, cv::LINE_AA);
|
||||
return frameCopy;
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
bool ShowProcessor::isProcessed() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void ShowProcessor::resetState()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ShowProcessor::setVisualizationMode(visualisationMode mode)
|
||||
{
|
||||
mVisMode = mode;
|
||||
}
|
||||
|
||||
void ShowProcessor::switchVisualizationMode()
|
||||
{
|
||||
if(mVisMode == Grid) {
|
||||
mVisMode = Window;
|
||||
updateBoardsView();
|
||||
}
|
||||
else {
|
||||
mVisMode = Grid;
|
||||
cv::destroyWindow(gridWindowName);
|
||||
}
|
||||
}
|
||||
|
||||
void ShowProcessor::clearBoardsView()
|
||||
{
|
||||
cv::imshow(gridWindowName, cv::Mat());
|
||||
}
|
||||
|
||||
void ShowProcessor::updateBoardsView()
|
||||
{
|
||||
if(mVisMode == Window) {
|
||||
cv::Size originSize = mCalibdata->imageSize;
|
||||
cv::Mat altGridView = cv::Mat::zeros((int)(originSize.height*mGridViewScale), (int)(originSize.width*mGridViewScale), CV_8UC3);
|
||||
if(mBoardType != chAruco)
|
||||
for(std::vector<std::vector<cv::Point2f> >::iterator it = mCalibdata->imagePoints.begin(); it != mCalibdata->imagePoints.end(); ++it)
|
||||
if(mBoardType != DoubleAcirclesGrid)
|
||||
drawBoard(altGridView, *it);
|
||||
else {
|
||||
size_t pointsNum = (*it).size()/2;
|
||||
std::vector<cv::Point2f> points(pointsNum);
|
||||
std::copy((*it).begin(), (*it).begin() + pointsNum, points.begin());
|
||||
drawBoard(altGridView, points);
|
||||
std::copy((*it).begin() + pointsNum, (*it).begin() + 2*pointsNum, points.begin());
|
||||
drawBoard(altGridView, points);
|
||||
}
|
||||
else
|
||||
for(std::vector<cv::Mat>::iterator it = mCalibdata->allCharucoCorners.begin(); it != mCalibdata->allCharucoCorners.end(); ++it)
|
||||
drawBoard(altGridView, *it);
|
||||
cv::imshow(gridWindowName, altGridView);
|
||||
}
|
||||
}
|
||||
|
||||
void ShowProcessor::switchUndistort()
|
||||
{
|
||||
mNeedUndistort = !mNeedUndistort;
|
||||
}
|
||||
|
||||
void ShowProcessor::setUndistort(bool isEnabled)
|
||||
{
|
||||
mNeedUndistort = isEnabled;
|
||||
}
|
||||
|
||||
ShowProcessor::~ShowProcessor()
|
||||
{
|
||||
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#ifndef FRAME_PROCESSOR_HPP
|
||||
#define FRAME_PROCESSOR_HPP
|
||||
|
||||
#include <opencv2/core.hpp>
|
||||
#include <opencv2/calib3d.hpp>
|
||||
#ifdef HAVE_OPENCV_ARUCO
|
||||
#include <opencv2/aruco/charuco.hpp>
|
||||
#endif
|
||||
|
||||
#include "calibCommon.hpp"
|
||||
#include "calibController.hpp"
|
||||
|
||||
namespace calib
|
||||
{
|
||||
class FrameProcessor
|
||||
{
|
||||
protected:
|
||||
|
||||
public:
|
||||
virtual ~FrameProcessor();
|
||||
virtual cv::Mat processFrame(const cv::Mat& frame) = 0;
|
||||
virtual bool isProcessed() const = 0;
|
||||
virtual void resetState() = 0;
|
||||
};
|
||||
|
||||
class CalibProcessor : public FrameProcessor
|
||||
{
|
||||
protected:
|
||||
cv::Ptr<calibrationData> mCalibData;
|
||||
TemplateType mBoardType;
|
||||
cv::Size mBoardSize;
|
||||
std::vector<cv::Point2f> mTemplateLocations;
|
||||
std::vector<cv::Point2f> mCurrentImagePoints;
|
||||
cv::Mat mCurrentCharucoCorners;
|
||||
cv::Mat mCurrentCharucoIds;
|
||||
|
||||
cv::Ptr<cv::SimpleBlobDetector> mBlobDetectorPtr;
|
||||
#ifdef HAVE_OPENCV_ARUCO
|
||||
cv::Ptr<cv::aruco::Dictionary> mArucoDictionary;
|
||||
cv::Ptr<cv::aruco::CharucoBoard> mCharucoBoard;
|
||||
#endif
|
||||
|
||||
int mNeededFramesNum;
|
||||
unsigned mDelayBetweenCaptures;
|
||||
int mCapuredFrames;
|
||||
double mMaxTemplateOffset;
|
||||
float mSquareSize;
|
||||
float mTemplDist;
|
||||
|
||||
bool detectAndParseChessboard(const cv::Mat& frame);
|
||||
bool detectAndParseChAruco(const cv::Mat& frame);
|
||||
bool detectAndParseACircles(const cv::Mat& frame);
|
||||
bool detectAndParseDualACircles(const cv::Mat& frame);
|
||||
void saveFrameData();
|
||||
void showCaptureMessage(const cv::Mat &frame, const std::string& message);
|
||||
bool checkLastFrame();
|
||||
|
||||
public:
|
||||
CalibProcessor(cv::Ptr<calibrationData> data, captureParameters& capParams);
|
||||
virtual cv::Mat processFrame(const cv::Mat& frame) CV_OVERRIDE;
|
||||
virtual bool isProcessed() const CV_OVERRIDE;
|
||||
virtual void resetState() CV_OVERRIDE;
|
||||
~CalibProcessor() CV_OVERRIDE;
|
||||
};
|
||||
|
||||
enum visualisationMode {Grid, Window};
|
||||
|
||||
class ShowProcessor : public FrameProcessor
|
||||
{
|
||||
protected:
|
||||
cv::Ptr<calibrationData> mCalibdata;
|
||||
cv::Ptr<calibController> mController;
|
||||
TemplateType mBoardType;
|
||||
visualisationMode mVisMode;
|
||||
bool mNeedUndistort;
|
||||
double mGridViewScale;
|
||||
double mTextSize;
|
||||
|
||||
void drawBoard(cv::Mat& img, cv::InputArray points);
|
||||
void drawGridPoints(const cv::Mat& frame);
|
||||
public:
|
||||
ShowProcessor(cv::Ptr<calibrationData> data, cv::Ptr<calibController> controller, TemplateType board);
|
||||
virtual cv::Mat processFrame(const cv::Mat& frame) CV_OVERRIDE;
|
||||
virtual bool isProcessed() const CV_OVERRIDE;
|
||||
virtual void resetState() CV_OVERRIDE;
|
||||
|
||||
void setVisualizationMode(visualisationMode mode);
|
||||
void switchVisualizationMode();
|
||||
void clearBoardsView();
|
||||
void updateBoardsView();
|
||||
|
||||
void switchUndistort();
|
||||
void setUndistort(bool isEnabled);
|
||||
~ShowProcessor() CV_OVERRIDE;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,225 @@
|
|||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#include <opencv2/core.hpp>
|
||||
#include <opencv2/calib3d.hpp>
|
||||
#include <opencv2/cvconfig.h>
|
||||
#include <opencv2/highgui.hpp>
|
||||
|
||||
#ifdef HAVE_OPENCV_ARUCO
|
||||
#include <opencv2/aruco/charuco.hpp>
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
#include "calibCommon.hpp"
|
||||
#include "calibPipeline.hpp"
|
||||
#include "frameProcessor.hpp"
|
||||
#include "calibController.hpp"
|
||||
#include "parametersController.hpp"
|
||||
#include "rotationConverters.hpp"
|
||||
|
||||
using namespace calib;
|
||||
|
||||
const std::string keys =
|
||||
"{v | | Input from video file }"
|
||||
"{ci | 0 | Default camera id }"
|
||||
"{flip | false | Vertical flip of input frames }"
|
||||
"{t | circles | Template for calibration (circles, chessboard, dualCircles, charuco) }"
|
||||
"{sz | 16.3 | Distance between two nearest centers of circles or squares on calibration board}"
|
||||
"{dst | 295 | Distance between white and black parts of daulCircles template}"
|
||||
"{w | | Width of template (in corners or circles)}"
|
||||
"{h | | Height of template (in corners or circles)}"
|
||||
"{of | cameraParameters.xml | Output file name}"
|
||||
"{ft | true | Auto tuning of calibration flags}"
|
||||
"{vis | grid | Captured boards visualisation (grid, window)}"
|
||||
"{d | 0.8 | Min delay between captures}"
|
||||
"{pf | defaultConfig.xml| Advanced application parameters}"
|
||||
"{help | | Print help}";
|
||||
|
||||
bool calib::showOverlayMessage(const std::string& message)
|
||||
{
|
||||
#ifdef HAVE_QT
|
||||
cv::displayOverlay(mainWindowName, message, OVERLAY_DELAY);
|
||||
return true;
|
||||
#else
|
||||
std::cout << message << std::endl;
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void deleteButton(int, void* data)
|
||||
{
|
||||
(static_cast<cv::Ptr<calibDataController>*>(data))->get()->deleteLastFrame();
|
||||
calib::showOverlayMessage("Last frame deleted");
|
||||
}
|
||||
|
||||
static void deleteAllButton(int, void* data)
|
||||
{
|
||||
(static_cast<cv::Ptr<calibDataController>*>(data))->get()->deleteAllData();
|
||||
calib::showOverlayMessage("All frames deleted");
|
||||
}
|
||||
|
||||
static void saveCurrentParamsButton(int, void* data)
|
||||
{
|
||||
if((static_cast<cv::Ptr<calibDataController>*>(data))->get()->saveCurrentCameraParameters())
|
||||
calib::showOverlayMessage("Calibration parameters saved");
|
||||
}
|
||||
|
||||
#ifdef HAVE_QT
|
||||
static void switchVisualizationModeButton(int, void* data)
|
||||
{
|
||||
ShowProcessor* processor = static_cast<ShowProcessor*>(((cv::Ptr<FrameProcessor>*)data)->get());
|
||||
processor->switchVisualizationMode();
|
||||
}
|
||||
|
||||
static void undistortButton(int state, void* data)
|
||||
{
|
||||
ShowProcessor* processor = static_cast<ShowProcessor*>(((cv::Ptr<FrameProcessor>*)data)->get());
|
||||
processor->setUndistort(static_cast<bool>(state));
|
||||
calib::showOverlayMessage(std::string("Undistort is ") +
|
||||
(static_cast<bool>(state) ? std::string("on") : std::string("off")));
|
||||
}
|
||||
#endif //HAVE_QT
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
cv::CommandLineParser parser(argc, argv, keys);
|
||||
if(parser.has("help")) {
|
||||
parser.printMessage();
|
||||
return 0;
|
||||
}
|
||||
std::cout << consoleHelp << std::endl;
|
||||
parametersController paramsController;
|
||||
|
||||
if(!paramsController.loadFromParser(parser))
|
||||
return 0;
|
||||
|
||||
captureParameters capParams = paramsController.getCaptureParameters();
|
||||
internalParameters intParams = paramsController.getInternalParameters();
|
||||
#ifndef HAVE_OPENCV_ARUCO
|
||||
if(capParams.board == chAruco)
|
||||
CV_Error(cv::Error::StsNotImplemented, "Aruco module is disabled in current build configuration."
|
||||
" Consider usage of another calibration pattern\n");
|
||||
#endif
|
||||
|
||||
cv::TermCriteria solverTermCrit = cv::TermCriteria(cv::TermCriteria::COUNT+cv::TermCriteria::EPS,
|
||||
intParams.solverMaxIters, intParams.solverEps);
|
||||
cv::Ptr<calibrationData> globalData(new calibrationData);
|
||||
if(!parser.has("v")) globalData->imageSize = capParams.cameraResolution;
|
||||
|
||||
int calibrationFlags = 0;
|
||||
if(intParams.fastSolving) calibrationFlags |= cv::CALIB_USE_QR;
|
||||
cv::Ptr<calibController> controller(new calibController(globalData, calibrationFlags,
|
||||
parser.get<bool>("ft"), capParams.minFramesNum));
|
||||
cv::Ptr<calibDataController> dataController(new calibDataController(globalData, capParams.maxFramesNum,
|
||||
intParams.filterAlpha));
|
||||
dataController->setParametersFileName(parser.get<std::string>("of"));
|
||||
|
||||
cv::Ptr<FrameProcessor> capProcessor, showProcessor;
|
||||
capProcessor = cv::Ptr<FrameProcessor>(new CalibProcessor(globalData, capParams));
|
||||
showProcessor = cv::Ptr<FrameProcessor>(new ShowProcessor(globalData, controller, capParams.board));
|
||||
|
||||
if(parser.get<std::string>("vis").find("window") == 0) {
|
||||
static_cast<ShowProcessor*>(showProcessor.get())->setVisualizationMode(Window);
|
||||
cv::namedWindow(gridWindowName);
|
||||
cv::moveWindow(gridWindowName, 1280, 500);
|
||||
}
|
||||
|
||||
cv::Ptr<CalibPipeline> pipeline(new CalibPipeline(capParams));
|
||||
std::vector<cv::Ptr<FrameProcessor> > processors;
|
||||
processors.push_back(capProcessor);
|
||||
processors.push_back(showProcessor);
|
||||
|
||||
cv::namedWindow(mainWindowName);
|
||||
cv::moveWindow(mainWindowName, 10, 10);
|
||||
#ifdef HAVE_QT
|
||||
cv::createButton("Delete last frame", deleteButton, &dataController,
|
||||
cv::QT_PUSH_BUTTON | cv::QT_NEW_BUTTONBAR);
|
||||
cv::createButton("Delete all frames", deleteAllButton, &dataController,
|
||||
cv::QT_PUSH_BUTTON | cv::QT_NEW_BUTTONBAR);
|
||||
cv::createButton("Undistort", undistortButton, &showProcessor,
|
||||
cv::QT_CHECKBOX | cv::QT_NEW_BUTTONBAR, false);
|
||||
cv::createButton("Save current parameters", saveCurrentParamsButton, &dataController,
|
||||
cv::QT_PUSH_BUTTON | cv::QT_NEW_BUTTONBAR);
|
||||
cv::createButton("Switch visualisation mode", switchVisualizationModeButton, &showProcessor,
|
||||
cv::QT_PUSH_BUTTON | cv::QT_NEW_BUTTONBAR);
|
||||
#endif //HAVE_QT
|
||||
try {
|
||||
bool pipelineFinished = false;
|
||||
while(!pipelineFinished)
|
||||
{
|
||||
PipelineExitStatus exitStatus = pipeline->start(processors);
|
||||
if (exitStatus == Finished) {
|
||||
if(controller->getCommonCalibrationState())
|
||||
saveCurrentParamsButton(0, &dataController);
|
||||
pipelineFinished = true;
|
||||
continue;
|
||||
}
|
||||
else if (exitStatus == Calibrate) {
|
||||
|
||||
dataController->rememberCurrentParameters();
|
||||
globalData->imageSize = pipeline->getImageSize();
|
||||
calibrationFlags = controller->getNewFlags();
|
||||
|
||||
if(capParams.board != chAruco) {
|
||||
globalData->totalAvgErr =
|
||||
cv::calibrateCamera(globalData->objectPoints, globalData->imagePoints,
|
||||
globalData->imageSize, globalData->cameraMatrix,
|
||||
globalData->distCoeffs, cv::noArray(), cv::noArray(),
|
||||
globalData->stdDeviations, cv::noArray(), globalData->perViewErrors,
|
||||
calibrationFlags, solverTermCrit);
|
||||
}
|
||||
else {
|
||||
#ifdef HAVE_OPENCV_ARUCO
|
||||
cv::Ptr<cv::aruco::Dictionary> dictionary =
|
||||
cv::aruco::getPredefinedDictionary(cv::aruco::PREDEFINED_DICTIONARY_NAME(capParams.charucoDictName));
|
||||
cv::Ptr<cv::aruco::CharucoBoard> charucoboard =
|
||||
cv::aruco::CharucoBoard::create(capParams.boardSize.width, capParams.boardSize.height,
|
||||
capParams.charucoSquareLenght, capParams.charucoMarkerSize, dictionary);
|
||||
globalData->totalAvgErr =
|
||||
cv::aruco::calibrateCameraCharuco(globalData->allCharucoCorners, globalData->allCharucoIds,
|
||||
charucoboard, globalData->imageSize,
|
||||
globalData->cameraMatrix, globalData->distCoeffs,
|
||||
cv::noArray(), cv::noArray(), globalData->stdDeviations, cv::noArray(),
|
||||
globalData->perViewErrors, calibrationFlags, solverTermCrit);
|
||||
#endif
|
||||
}
|
||||
dataController->updateUndistortMap();
|
||||
dataController->printParametersToConsole(std::cout);
|
||||
controller->updateState();
|
||||
for(int j = 0; j < capParams.calibrationStep; j++)
|
||||
dataController->filterFrames();
|
||||
static_cast<ShowProcessor*>(showProcessor.get())->updateBoardsView();
|
||||
}
|
||||
else if (exitStatus == DeleteLastFrame) {
|
||||
deleteButton(0, &dataController);
|
||||
static_cast<ShowProcessor*>(showProcessor.get())->updateBoardsView();
|
||||
}
|
||||
else if (exitStatus == DeleteAllFrames) {
|
||||
deleteAllButton(0, &dataController);
|
||||
static_cast<ShowProcessor*>(showProcessor.get())->updateBoardsView();
|
||||
}
|
||||
else if (exitStatus == SaveCurrentData) {
|
||||
saveCurrentParamsButton(0, &dataController);
|
||||
}
|
||||
else if (exitStatus == SwitchUndistort)
|
||||
static_cast<ShowProcessor*>(showProcessor.get())->switchUndistort();
|
||||
else if (exitStatus == SwitchVisualisation)
|
||||
static_cast<ShowProcessor*>(showProcessor.get())->switchVisualizationMode();
|
||||
|
||||
for (std::vector<cv::Ptr<FrameProcessor> >::iterator it = processors.begin(); it != processors.end(); ++it)
|
||||
(*it)->resetState();
|
||||
}
|
||||
}
|
||||
catch (const std::runtime_error& exp) {
|
||||
std::cout << exp.what() << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#include "parametersController.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
template <typename T>
|
||||
static bool readFromNode(cv::FileNode node, T& value)
|
||||
{
|
||||
if(!node.isNone()) {
|
||||
node >> value;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool checkAssertion(bool value, const std::string& msg)
|
||||
{
|
||||
if(!value)
|
||||
std::cerr << "Error: " << msg << std::endl;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
bool calib::parametersController::loadFromFile(const std::string &inputFileName)
|
||||
{
|
||||
cv::FileStorage reader;
|
||||
reader.open(inputFileName, cv::FileStorage::READ);
|
||||
|
||||
if(!reader.isOpened()) {
|
||||
std::cerr << "Warning: Unable to open " << inputFileName <<
|
||||
" Applicatioin stated with default advanced parameters" << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
readFromNode(reader["charuco_dict"], mCapParams.charucoDictName);
|
||||
readFromNode(reader["charuco_square_lenght"], mCapParams.charucoSquareLenght);
|
||||
readFromNode(reader["charuco_marker_size"], mCapParams.charucoMarkerSize);
|
||||
readFromNode(reader["camera_resolution"], mCapParams.cameraResolution);
|
||||
readFromNode(reader["calibration_step"], mCapParams.calibrationStep);
|
||||
readFromNode(reader["max_frames_num"], mCapParams.maxFramesNum);
|
||||
readFromNode(reader["min_frames_num"], mCapParams.minFramesNum);
|
||||
readFromNode(reader["solver_eps"], mInternalParameters.solverEps);
|
||||
readFromNode(reader["solver_max_iters"], mInternalParameters.solverMaxIters);
|
||||
readFromNode(reader["fast_solver"], mInternalParameters.fastSolving);
|
||||
readFromNode(reader["frame_filter_conv_param"], mInternalParameters.filterAlpha);
|
||||
|
||||
bool retValue =
|
||||
checkAssertion(mCapParams.charucoDictName >= 0, "Dict name must be >= 0") &&
|
||||
checkAssertion(mCapParams.charucoMarkerSize > 0, "Marker size must be positive") &&
|
||||
checkAssertion(mCapParams.charucoSquareLenght > 0, "Square size must be positive") &&
|
||||
checkAssertion(mCapParams.minFramesNum > 1, "Minimal number of frames for calibration < 1") &&
|
||||
checkAssertion(mCapParams.calibrationStep > 0, "Calibration step must be positive") &&
|
||||
checkAssertion(mCapParams.maxFramesNum > mCapParams.minFramesNum, "maxFramesNum < minFramesNum") &&
|
||||
checkAssertion(mInternalParameters.solverEps > 0, "Solver precision must be positive") &&
|
||||
checkAssertion(mInternalParameters.solverMaxIters > 0, "Max solver iterations number must be positive") &&
|
||||
checkAssertion(mInternalParameters.filterAlpha >=0 && mInternalParameters.filterAlpha <=1 ,
|
||||
"Frame filter convolution parameter must be in [0,1] interval") &&
|
||||
checkAssertion(mCapParams.cameraResolution.width > 0 && mCapParams.cameraResolution.height > 0,
|
||||
"Wrong camera resolution values");
|
||||
|
||||
reader.release();
|
||||
return retValue;
|
||||
}
|
||||
|
||||
calib::parametersController::parametersController()
|
||||
{
|
||||
}
|
||||
|
||||
calib::captureParameters calib::parametersController::getCaptureParameters() const
|
||||
{
|
||||
return mCapParams;
|
||||
}
|
||||
|
||||
calib::internalParameters calib::parametersController::getInternalParameters() const
|
||||
{
|
||||
return mInternalParameters;
|
||||
}
|
||||
|
||||
bool calib::parametersController::loadFromParser(cv::CommandLineParser &parser)
|
||||
{
|
||||
mCapParams.flipVertical = parser.get<bool>("flip");
|
||||
mCapParams.captureDelay = parser.get<float>("d");
|
||||
mCapParams.squareSize = parser.get<float>("sz");
|
||||
mCapParams.templDst = parser.get<float>("dst");
|
||||
|
||||
if(!checkAssertion(mCapParams.squareSize > 0, "Distance between corners or circles must be positive"))
|
||||
return false;
|
||||
if(!checkAssertion(mCapParams.templDst > 0, "Distance between parts of dual template must be positive"))
|
||||
return false;
|
||||
|
||||
if (parser.has("v")) {
|
||||
mCapParams.source = File;
|
||||
mCapParams.videoFileName = parser.get<std::string>("v");
|
||||
}
|
||||
else {
|
||||
mCapParams.source = Camera;
|
||||
mCapParams.camID = parser.get<int>("ci");
|
||||
}
|
||||
|
||||
std::string templateType = parser.get<std::string>("t");
|
||||
|
||||
if(templateType.find("circles", 0) == 0) {
|
||||
mCapParams.board = AcirclesGrid;
|
||||
mCapParams.boardSize = cv::Size(4, 11);
|
||||
}
|
||||
else if(templateType.find("chessboard", 0) == 0) {
|
||||
mCapParams.board = Chessboard;
|
||||
mCapParams.boardSize = cv::Size(7, 7);
|
||||
}
|
||||
else if(templateType.find("dualcircles", 0) == 0) {
|
||||
mCapParams.board = DoubleAcirclesGrid;
|
||||
mCapParams.boardSize = cv::Size(4, 11);
|
||||
}
|
||||
else if(templateType.find("charuco", 0) == 0) {
|
||||
mCapParams.board = chAruco;
|
||||
mCapParams.boardSize = cv::Size(6, 8);
|
||||
mCapParams.charucoDictName = 0;
|
||||
mCapParams.charucoSquareLenght = 200;
|
||||
mCapParams.charucoMarkerSize = 100;
|
||||
}
|
||||
else {
|
||||
std::cerr << "Wrong template name\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
if(parser.has("w") && parser.has("h")) {
|
||||
mCapParams.boardSize = cv::Size(parser.get<int>("w"), parser.get<int>("h"));
|
||||
if(!checkAssertion(mCapParams.boardSize.width > 0 || mCapParams.boardSize.height > 0,
|
||||
"Board size must be positive"))
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!checkAssertion(parser.get<std::string>("of").find(".xml") > 0,
|
||||
"Wrong output file name: correct format is [name].xml"))
|
||||
return false;
|
||||
|
||||
loadFromFile(parser.get<std::string>("pf"));
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#ifndef PARAMETERS_CONTROLLER_HPP
|
||||
#define PARAMETERS_CONTROLLER_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <opencv2/core.hpp>
|
||||
|
||||
#include "calibCommon.hpp"
|
||||
|
||||
namespace calib {
|
||||
|
||||
class parametersController
|
||||
{
|
||||
protected:
|
||||
captureParameters mCapParams;
|
||||
internalParameters mInternalParameters;
|
||||
|
||||
bool loadFromFile(const std::string& inputFileName);
|
||||
public:
|
||||
parametersController();
|
||||
parametersController(cv::Ptr<captureParameters> params);
|
||||
|
||||
captureParameters getCaptureParameters() const;
|
||||
internalParameters getInternalParameters() const;
|
||||
|
||||
bool loadFromParser(cv::CommandLineParser& parser);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,126 @@
|
|||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#include "rotationConverters.hpp"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <opencv2/calib3d.hpp>
|
||||
#include <opencv2/core.hpp>
|
||||
|
||||
#define CALIB_PI 3.14159265358979323846
|
||||
#define CALIB_PI_2 1.57079632679489661923
|
||||
|
||||
void calib::Euler(const cv::Mat& src, cv::Mat& dst, int argType)
|
||||
{
|
||||
if((src.rows == 3) && (src.cols == 3))
|
||||
{
|
||||
//convert rotation matrix to 3 angles (pitch, yaw, roll)
|
||||
dst = cv::Mat(3, 1, CV_64F);
|
||||
double pitch, yaw, roll;
|
||||
|
||||
if(src.at<double>(0,2) < -0.998)
|
||||
{
|
||||
pitch = -atan2(src.at<double>(1,0), src.at<double>(1,1));
|
||||
yaw = -CALIB_PI_2;
|
||||
roll = 0.;
|
||||
}
|
||||
else if(src.at<double>(0,2) > 0.998)
|
||||
{
|
||||
pitch = atan2(src.at<double>(1,0), src.at<double>(1,1));
|
||||
yaw = CALIB_PI_2;
|
||||
roll = 0.;
|
||||
}
|
||||
else
|
||||
{
|
||||
pitch = atan2(-src.at<double>(1,2), src.at<double>(2,2));
|
||||
yaw = asin(src.at<double>(0,2));
|
||||
roll = atan2(-src.at<double>(0,1), src.at<double>(0,0));
|
||||
}
|
||||
|
||||
if(argType == CALIB_DEGREES)
|
||||
{
|
||||
pitch *= 180./CALIB_PI;
|
||||
yaw *= 180./CALIB_PI;
|
||||
roll *= 180./CALIB_PI;
|
||||
}
|
||||
else if(argType != CALIB_RADIANS)
|
||||
CV_Error(cv::Error::StsBadFlag, "Invalid argument type");
|
||||
|
||||
dst.at<double>(0,0) = pitch;
|
||||
dst.at<double>(1,0) = yaw;
|
||||
dst.at<double>(2,0) = roll;
|
||||
}
|
||||
else if( (src.cols == 1 && src.rows == 3) ||
|
||||
(src.cols == 3 && src.rows == 1 ) )
|
||||
{
|
||||
//convert vector which contains 3 angles (pitch, yaw, roll) to rotation matrix
|
||||
double pitch, yaw, roll;
|
||||
if(src.cols == 1 && src.rows == 3)
|
||||
{
|
||||
pitch = src.at<double>(0,0);
|
||||
yaw = src.at<double>(1,0);
|
||||
roll = src.at<double>(2,0);
|
||||
}
|
||||
else{
|
||||
pitch = src.at<double>(0,0);
|
||||
yaw = src.at<double>(0,1);
|
||||
roll = src.at<double>(0,2);
|
||||
}
|
||||
|
||||
if(argType == CALIB_DEGREES)
|
||||
{
|
||||
pitch *= CALIB_PI / 180.;
|
||||
yaw *= CALIB_PI / 180.;
|
||||
roll *= CALIB_PI / 180.;
|
||||
}
|
||||
else if(argType != CALIB_RADIANS)
|
||||
CV_Error(cv::Error::StsBadFlag, "Invalid argument type");
|
||||
|
||||
dst = cv::Mat(3, 3, CV_64F);
|
||||
cv::Mat M(3, 3, CV_64F);
|
||||
cv::Mat i = cv::Mat::eye(3, 3, CV_64F);
|
||||
i.copyTo(dst);
|
||||
i.copyTo(M);
|
||||
|
||||
double* pR = dst.ptr<double>();
|
||||
pR[4] = cos(pitch);
|
||||
pR[7] = sin(pitch);
|
||||
pR[8] = pR[4];
|
||||
pR[5] = -pR[7];
|
||||
|
||||
double* pM = M.ptr<double>();
|
||||
pM[0] = cos(yaw);
|
||||
pM[2] = sin(yaw);
|
||||
pM[8] = pM[0];
|
||||
pM[6] = -pM[2];
|
||||
|
||||
dst *= M;
|
||||
i.copyTo(M);
|
||||
pM[0] = cos(roll);
|
||||
pM[3] = sin(roll);
|
||||
pM[4] = pM[0];
|
||||
pM[1] = -pM[3];
|
||||
|
||||
dst *= M;
|
||||
}
|
||||
else
|
||||
CV_Error(cv::Error::StsBadFlag, "Input matrix must be 1x3, 3x1 or 3x3" );
|
||||
}
|
||||
|
||||
void calib::RodriguesToEuler(const cv::Mat& src, cv::Mat& dst, int argType)
|
||||
{
|
||||
CV_Assert((src.cols == 1 && src.rows == 3) || (src.cols == 3 && src.rows == 1));
|
||||
cv::Mat R;
|
||||
cv::Rodrigues(src, R);
|
||||
Euler(R, dst, argType);
|
||||
}
|
||||
|
||||
void calib::EulerToRodrigues(const cv::Mat& src, cv::Mat& dst, int argType)
|
||||
{
|
||||
CV_Assert((src.cols == 1 && src.rows == 3) || (src.cols == 3 && src.rows == 1));
|
||||
cv::Mat R;
|
||||
Euler(src, R, argType);
|
||||
cv::Rodrigues(R, dst);
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#ifndef ROTATION_CONVERTERS_HPP
|
||||
#define ROTATION_CONVERTERS_HPP
|
||||
|
||||
#include <opencv2/core.hpp>
|
||||
|
||||
namespace calib
|
||||
{
|
||||
#define CALIB_RADIANS 0
|
||||
#define CALIB_DEGREES 1
|
||||
|
||||
void Euler(const cv::Mat& src, cv::Mat& dst, int argType = CALIB_RADIANS);
|
||||
void RodriguesToEuler(const cv::Mat& src, cv::Mat& dst, int argType = CALIB_RADIANS);
|
||||
void EulerToRodrigues(const cv::Mat& src, cv::Mat& dst, int argType = CALIB_RADIANS);
|
||||
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,5 @@
|
|||
ocv_warnings_disable(CMAKE_CXX_FLAGS -Woverloaded-virtual -Winconsistent-missing-override -Wsuggest-override)
|
||||
file(GLOB SRCS *.cpp)
|
||||
ocv_add_application(opencv_traincascade
|
||||
MODULES opencv_core opencv_imgproc opencv_objdetect opencv_imgcodecs opencv_highgui opencv_calib3d opencv_features2d
|
||||
SRCS ${SRCS})
|
|
@ -0,0 +1,250 @@
|
|||
#include "opencv2/core.hpp"
|
||||
#include "opencv2/imgproc.hpp"
|
||||
|
||||
#include "HOGfeatures.h"
|
||||
#include "cascadeclassifier.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
CvHOGFeatureParams::CvHOGFeatureParams()
|
||||
{
|
||||
maxCatCount = 0;
|
||||
name = HOGF_NAME;
|
||||
featSize = N_BINS * N_CELLS;
|
||||
}
|
||||
|
||||
void CvHOGEvaluator::init(const CvFeatureParams *_featureParams, int _maxSampleCount, Size _winSize)
|
||||
{
|
||||
CV_Assert( _maxSampleCount > 0);
|
||||
int cols = (_winSize.width + 1) * (_winSize.height + 1);
|
||||
for (int bin = 0; bin < N_BINS; bin++)
|
||||
{
|
||||
hist.push_back(Mat(_maxSampleCount, cols, CV_32FC1));
|
||||
}
|
||||
normSum.create( (int)_maxSampleCount, cols, CV_32FC1 );
|
||||
CvFeatureEvaluator::init( _featureParams, _maxSampleCount, _winSize );
|
||||
}
|
||||
|
||||
void CvHOGEvaluator::setImage(const Mat &img, uchar clsLabel, int idx)
|
||||
{
|
||||
CV_DbgAssert( !hist.empty());
|
||||
CvFeatureEvaluator::setImage( img, clsLabel, idx );
|
||||
vector<Mat> integralHist;
|
||||
for (int bin = 0; bin < N_BINS; bin++)
|
||||
{
|
||||
integralHist.push_back( Mat(winSize.height + 1, winSize.width + 1, hist[bin].type(), hist[bin].ptr<float>((int)idx)) );
|
||||
}
|
||||
Mat integralNorm(winSize.height + 1, winSize.width + 1, normSum.type(), normSum.ptr<float>((int)idx));
|
||||
integralHistogram(img, integralHist, integralNorm, (int)N_BINS);
|
||||
}
|
||||
|
||||
//void CvHOGEvaluator::writeFeatures( FileStorage &fs, const Mat& featureMap ) const
|
||||
//{
|
||||
// _writeFeatures( features, fs, featureMap );
|
||||
//}
|
||||
|
||||
void CvHOGEvaluator::writeFeatures( FileStorage &fs, const Mat& featureMap ) const
|
||||
{
|
||||
int featIdx;
|
||||
int componentIdx;
|
||||
const Mat_<int>& featureMap_ = (const Mat_<int>&)featureMap;
|
||||
fs << FEATURES << "[";
|
||||
for ( int fi = 0; fi < featureMap.cols; fi++ )
|
||||
if ( featureMap_(0, fi) >= 0 )
|
||||
{
|
||||
fs << "{";
|
||||
featIdx = fi / getFeatureSize();
|
||||
componentIdx = fi % getFeatureSize();
|
||||
features[featIdx].write( fs, componentIdx );
|
||||
fs << "}";
|
||||
}
|
||||
fs << "]";
|
||||
}
|
||||
|
||||
void CvHOGEvaluator::generateFeatures()
|
||||
{
|
||||
int offset = winSize.width + 1;
|
||||
Size blockStep;
|
||||
int x, y, t, w, h;
|
||||
|
||||
for (t = 8; t <= winSize.width/2; t+=8) //t = size of a cell. blocksize = 4*cellSize
|
||||
{
|
||||
blockStep = Size(4,4);
|
||||
w = 2*t; //width of a block
|
||||
h = 2*t; //height of a block
|
||||
for (x = 0; x <= winSize.width - w; x += blockStep.width)
|
||||
{
|
||||
for (y = 0; y <= winSize.height - h; y += blockStep.height)
|
||||
{
|
||||
features.push_back(Feature(offset, x, y, t, t));
|
||||
}
|
||||
}
|
||||
w = 2*t;
|
||||
h = 4*t;
|
||||
for (x = 0; x <= winSize.width - w; x += blockStep.width)
|
||||
{
|
||||
for (y = 0; y <= winSize.height - h; y += blockStep.height)
|
||||
{
|
||||
features.push_back(Feature(offset, x, y, t, 2*t));
|
||||
}
|
||||
}
|
||||
w = 4*t;
|
||||
h = 2*t;
|
||||
for (x = 0; x <= winSize.width - w; x += blockStep.width)
|
||||
{
|
||||
for (y = 0; y <= winSize.height - h; y += blockStep.height)
|
||||
{
|
||||
features.push_back(Feature(offset, x, y, 2*t, t));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
numFeatures = (int)features.size();
|
||||
}
|
||||
|
||||
CvHOGEvaluator::Feature::Feature()
|
||||
{
|
||||
for (int i = 0; i < N_CELLS; i++)
|
||||
{
|
||||
rect[i] = Rect(0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
CvHOGEvaluator::Feature::Feature( int offset, int x, int y, int cellW, int cellH )
|
||||
{
|
||||
rect[0] = Rect(x, y, cellW, cellH); //cell0
|
||||
rect[1] = Rect(x+cellW, y, cellW, cellH); //cell1
|
||||
rect[2] = Rect(x, y+cellH, cellW, cellH); //cell2
|
||||
rect[3] = Rect(x+cellW, y+cellH, cellW, cellH); //cell3
|
||||
|
||||
for (int i = 0; i < N_CELLS; i++)
|
||||
{
|
||||
CV_SUM_OFFSETS(fastRect[i].p0, fastRect[i].p1, fastRect[i].p2, fastRect[i].p3, rect[i], offset);
|
||||
}
|
||||
}
|
||||
|
||||
void CvHOGEvaluator::Feature::write(FileStorage &fs) const
|
||||
{
|
||||
fs << CC_RECTS << "[";
|
||||
for( int i = 0; i < N_CELLS; i++ )
|
||||
{
|
||||
fs << "[:" << rect[i].x << rect[i].y << rect[i].width << rect[i].height << "]";
|
||||
}
|
||||
fs << "]";
|
||||
}
|
||||
|
||||
//cell and bin idx writing
|
||||
//void CvHOGEvaluator::Feature::write(FileStorage &fs, int varIdx) const
|
||||
//{
|
||||
// int featComponent = varIdx % (N_CELLS * N_BINS);
|
||||
// int cellIdx = featComponent / N_BINS;
|
||||
// int binIdx = featComponent % N_BINS;
|
||||
//
|
||||
// fs << CC_RECTS << "[:" << rect[cellIdx].x << rect[cellIdx].y <<
|
||||
// rect[cellIdx].width << rect[cellIdx].height << binIdx << "]";
|
||||
//}
|
||||
|
||||
//cell[0] and featComponent idx writing. By cell[0] it's possible to recover all block
|
||||
//All block is necessary for block normalization
|
||||
void CvHOGEvaluator::Feature::write(FileStorage &fs, int featComponentIdx) const
|
||||
{
|
||||
fs << CC_RECT << "[:" << rect[0].x << rect[0].y <<
|
||||
rect[0].width << rect[0].height << featComponentIdx << "]";
|
||||
}
|
||||
|
||||
|
||||
void CvHOGEvaluator::integralHistogram(const Mat &img, vector<Mat> &histogram, Mat &norm, int nbins) const
|
||||
{
|
||||
CV_Assert( img.type() == CV_8U || img.type() == CV_8UC3 );
|
||||
int x, y, binIdx;
|
||||
|
||||
Size gradSize(img.size());
|
||||
Size histSize(histogram[0].size());
|
||||
Mat grad(gradSize, CV_32F);
|
||||
Mat qangle(gradSize, CV_8U);
|
||||
|
||||
AutoBuffer<int> mapbuf(gradSize.width + gradSize.height + 4);
|
||||
int* xmap = mapbuf.data() + 1;
|
||||
int* ymap = xmap + gradSize.width + 2;
|
||||
|
||||
const int borderType = (int)BORDER_REPLICATE;
|
||||
|
||||
for( x = -1; x < gradSize.width + 1; x++ )
|
||||
xmap[x] = borderInterpolate(x, gradSize.width, borderType);
|
||||
for( y = -1; y < gradSize.height + 1; y++ )
|
||||
ymap[y] = borderInterpolate(y, gradSize.height, borderType);
|
||||
|
||||
int width = gradSize.width;
|
||||
AutoBuffer<float> _dbuf(width*4);
|
||||
float* dbuf = _dbuf.data();
|
||||
Mat Dx(1, width, CV_32F, dbuf);
|
||||
Mat Dy(1, width, CV_32F, dbuf + width);
|
||||
Mat Mag(1, width, CV_32F, dbuf + width*2);
|
||||
Mat Angle(1, width, CV_32F, dbuf + width*3);
|
||||
|
||||
float angleScale = (float)(nbins/CV_PI);
|
||||
|
||||
for( y = 0; y < gradSize.height; y++ )
|
||||
{
|
||||
const uchar* currPtr = img.ptr(ymap[y]);
|
||||
const uchar* prevPtr = img.ptr(ymap[y-1]);
|
||||
const uchar* nextPtr = img.ptr(ymap[y+1]);
|
||||
float* gradPtr = grad.ptr<float>(y);
|
||||
uchar* qanglePtr = qangle.ptr(y);
|
||||
|
||||
for( x = 0; x < width; x++ )
|
||||
{
|
||||
dbuf[x] = (float)(currPtr[xmap[x+1]] - currPtr[xmap[x-1]]);
|
||||
dbuf[width + x] = (float)(nextPtr[xmap[x]] - prevPtr[xmap[x]]);
|
||||
}
|
||||
cartToPolar( Dx, Dy, Mag, Angle, false );
|
||||
for( x = 0; x < width; x++ )
|
||||
{
|
||||
float mag = dbuf[x+width*2];
|
||||
float angle = dbuf[x+width*3];
|
||||
angle = angle*angleScale - 0.5f;
|
||||
int bidx = cvFloor(angle);
|
||||
angle -= bidx;
|
||||
if( bidx < 0 )
|
||||
bidx += nbins;
|
||||
else if( bidx >= nbins )
|
||||
bidx -= nbins;
|
||||
|
||||
qanglePtr[x] = (uchar)bidx;
|
||||
gradPtr[x] = mag;
|
||||
}
|
||||
}
|
||||
integral(grad, norm, grad.depth());
|
||||
|
||||
float* histBuf;
|
||||
const float* magBuf;
|
||||
const uchar* binsBuf;
|
||||
|
||||
int binsStep = (int)( qangle.step / sizeof(uchar) );
|
||||
int histStep = (int)( histogram[0].step / sizeof(float) );
|
||||
int magStep = (int)( grad.step / sizeof(float) );
|
||||
for( binIdx = 0; binIdx < nbins; binIdx++ )
|
||||
{
|
||||
histBuf = histogram[binIdx].ptr<float>();
|
||||
magBuf = grad.ptr<float>();
|
||||
binsBuf = qangle.ptr();
|
||||
|
||||
memset( histBuf, 0, histSize.width * sizeof(histBuf[0]) );
|
||||
histBuf += histStep + 1;
|
||||
for( y = 0; y < qangle.rows; y++ )
|
||||
{
|
||||
histBuf[-1] = 0.f;
|
||||
float strSum = 0.f;
|
||||
for( x = 0; x < qangle.cols; x++ )
|
||||
{
|
||||
if( binsBuf[x] == binIdx )
|
||||
strSum += magBuf[x];
|
||||
histBuf[x] = histBuf[-histStep + x] + strSum;
|
||||
}
|
||||
histBuf += histStep;
|
||||
binsBuf += binsStep;
|
||||
magBuf += magStep;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
#ifndef _OPENCV_HOGFEATURES_H_
|
||||
#define _OPENCV_HOGFEATURES_H_
|
||||
|
||||
#include "traincascade_features.h"
|
||||
|
||||
//#define TEST_INTHIST_BUILD
|
||||
//#define TEST_FEAT_CALC
|
||||
|
||||
#define N_BINS 9
|
||||
#define N_CELLS 4
|
||||
|
||||
#define HOGF_NAME "HOGFeatureParams"
|
||||
struct CvHOGFeatureParams : public CvFeatureParams
|
||||
{
|
||||
CvHOGFeatureParams();
|
||||
};
|
||||
|
||||
class CvHOGEvaluator : public CvFeatureEvaluator
|
||||
{
|
||||
public:
|
||||
virtual ~CvHOGEvaluator() {}
|
||||
virtual void init(const CvFeatureParams *_featureParams,
|
||||
int _maxSampleCount, cv::Size _winSize );
|
||||
virtual void setImage(const cv::Mat& img, uchar clsLabel, int idx);
|
||||
virtual float operator()(int varIdx, int sampleIdx) const;
|
||||
virtual void writeFeatures( cv::FileStorage &fs, const cv::Mat& featureMap ) const;
|
||||
protected:
|
||||
virtual void generateFeatures();
|
||||
virtual void integralHistogram(const cv::Mat &img, std::vector<cv::Mat> &histogram, cv::Mat &norm, int nbins) const;
|
||||
class Feature
|
||||
{
|
||||
public:
|
||||
Feature();
|
||||
Feature( int offset, int x, int y, int cellW, int cellH );
|
||||
float calc( const std::vector<cv::Mat> &_hists, const cv::Mat &_normSum, size_t y, int featComponent ) const;
|
||||
void write( cv::FileStorage &fs ) const;
|
||||
void write( cv::FileStorage &fs, int varIdx ) const;
|
||||
|
||||
cv::Rect rect[N_CELLS]; //cells
|
||||
|
||||
struct
|
||||
{
|
||||
int p0, p1, p2, p3;
|
||||
} fastRect[N_CELLS];
|
||||
};
|
||||
std::vector<Feature> features;
|
||||
|
||||
cv::Mat normSum; //for nomalization calculation (L1 or L2)
|
||||
std::vector<cv::Mat> hist;
|
||||
};
|
||||
|
||||
inline float CvHOGEvaluator::operator()(int varIdx, int sampleIdx) const
|
||||
{
|
||||
int featureIdx = varIdx / (N_BINS * N_CELLS);
|
||||
int componentIdx = varIdx % (N_BINS * N_CELLS);
|
||||
//return features[featureIdx].calc( hist, sampleIdx, componentIdx);
|
||||
return features[featureIdx].calc( hist, normSum, sampleIdx, componentIdx);
|
||||
}
|
||||
|
||||
inline float CvHOGEvaluator::Feature::calc( const std::vector<cv::Mat>& _hists, const cv::Mat& _normSum, size_t y, int featComponent ) const
|
||||
{
|
||||
float normFactor;
|
||||
float res;
|
||||
|
||||
int binIdx = featComponent % N_BINS;
|
||||
int cellIdx = featComponent / N_BINS;
|
||||
|
||||
const float *phist = _hists[binIdx].ptr<float>((int)y);
|
||||
res = phist[fastRect[cellIdx].p0] - phist[fastRect[cellIdx].p1] - phist[fastRect[cellIdx].p2] + phist[fastRect[cellIdx].p3];
|
||||
|
||||
const float *pnormSum = _normSum.ptr<float>((int)y);
|
||||
normFactor = (float)(pnormSum[fastRect[0].p0] - pnormSum[fastRect[1].p1] - pnormSum[fastRect[2].p2] + pnormSum[fastRect[3].p3]);
|
||||
res = (res > 0.001f) ? ( res / (normFactor + 0.001f) ) : 0.f; //for cutting negative values, which apper due to floating precision
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif // _OPENCV_HOGFEATURES_H_
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,86 @@
|
|||
#ifndef _OPENCV_BOOST_H_
|
||||
#define _OPENCV_BOOST_H_
|
||||
|
||||
#include "traincascade_features.h"
|
||||
#include "old_ml.hpp"
|
||||
|
||||
struct CvCascadeBoostParams : CvBoostParams
|
||||
{
|
||||
float minHitRate;
|
||||
float maxFalseAlarm;
|
||||
|
||||
CvCascadeBoostParams();
|
||||
CvCascadeBoostParams( int _boostType, float _minHitRate, float _maxFalseAlarm,
|
||||
double _weightTrimRate, int _maxDepth, int _maxWeakCount );
|
||||
virtual ~CvCascadeBoostParams() {}
|
||||
void write( cv::FileStorage &fs ) const;
|
||||
bool read( const cv::FileNode &node );
|
||||
virtual void printDefaults() const;
|
||||
virtual void printAttrs() const;
|
||||
virtual bool scanAttr( const std::string prmName, const std::string val);
|
||||
};
|
||||
|
||||
struct CvCascadeBoostTrainData : CvDTreeTrainData
|
||||
{
|
||||
CvCascadeBoostTrainData( const CvFeatureEvaluator* _featureEvaluator,
|
||||
const CvDTreeParams& _params );
|
||||
CvCascadeBoostTrainData( const CvFeatureEvaluator* _featureEvaluator,
|
||||
int _numSamples, int _precalcValBufSize, int _precalcIdxBufSize,
|
||||
const CvDTreeParams& _params = CvDTreeParams() );
|
||||
virtual void setData( const CvFeatureEvaluator* _featureEvaluator,
|
||||
int _numSamples, int _precalcValBufSize, int _precalcIdxBufSize,
|
||||
const CvDTreeParams& _params=CvDTreeParams() );
|
||||
void precalculate();
|
||||
|
||||
virtual CvDTreeNode* subsample_data( const CvMat* _subsample_idx );
|
||||
|
||||
virtual const int* get_class_labels( CvDTreeNode* n, int* labelsBuf );
|
||||
virtual const int* get_cv_labels( CvDTreeNode* n, int* labelsBuf);
|
||||
virtual const int* get_sample_indices( CvDTreeNode* n, int* indicesBuf );
|
||||
|
||||
virtual void get_ord_var_data( CvDTreeNode* n, int vi, float* ordValuesBuf, int* sortedIndicesBuf,
|
||||
const float** ordValues, const int** sortedIndices, int* sampleIndicesBuf );
|
||||
virtual const int* get_cat_var_data( CvDTreeNode* n, int vi, int* catValuesBuf );
|
||||
virtual float getVarValue( int vi, int si );
|
||||
virtual void free_train_data();
|
||||
|
||||
const CvFeatureEvaluator* featureEvaluator;
|
||||
cv::Mat valCache; // precalculated feature values (CV_32FC1)
|
||||
CvMat _resp; // for casting
|
||||
int numPrecalcVal, numPrecalcIdx;
|
||||
};
|
||||
|
||||
class CvCascadeBoostTree : public CvBoostTree
|
||||
{
|
||||
public:
|
||||
virtual CvDTreeNode* predict( int sampleIdx ) const;
|
||||
void write( cv::FileStorage &fs, const cv::Mat& featureMap );
|
||||
void read( const cv::FileNode &node, CvBoost* _ensemble, CvDTreeTrainData* _data );
|
||||
void markFeaturesInMap( cv::Mat& featureMap );
|
||||
protected:
|
||||
virtual void split_node_data( CvDTreeNode* n );
|
||||
};
|
||||
|
||||
class CvCascadeBoost : public CvBoost
|
||||
{
|
||||
public:
|
||||
virtual bool train( const CvFeatureEvaluator* _featureEvaluator,
|
||||
int _numSamples, int _precalcValBufSize, int _precalcIdxBufSize,
|
||||
const CvCascadeBoostParams& _params=CvCascadeBoostParams() );
|
||||
virtual float predict( int sampleIdx, bool returnSum = false ) const;
|
||||
|
||||
float getThreshold() const { return threshold; }
|
||||
void write( cv::FileStorage &fs, const cv::Mat& featureMap ) const;
|
||||
bool read( const cv::FileNode &node, const CvFeatureEvaluator* _featureEvaluator,
|
||||
const CvCascadeBoostParams& _params );
|
||||
void markUsedFeaturesInMap( cv::Mat& featureMap );
|
||||
protected:
|
||||
virtual bool set_params( const CvBoostParams& _params );
|
||||
virtual void update_weights( CvBoostTree* tree );
|
||||
virtual bool isErrDesired();
|
||||
|
||||
float threshold;
|
||||
float minHitRate, maxFalseAlarm;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,571 @@
|
|||
#include "opencv2/core.hpp"
|
||||
|
||||
#include "cascadeclassifier.h"
|
||||
#include <queue>
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
static const char* stageTypes[] = { CC_BOOST };
|
||||
static const char* featureTypes[] = { CC_HAAR, CC_LBP, CC_HOG };
|
||||
|
||||
CvCascadeParams::CvCascadeParams() : stageType( defaultStageType ),
|
||||
featureType( defaultFeatureType ), winSize( cvSize(24, 24) )
|
||||
{
|
||||
name = CC_CASCADE_PARAMS;
|
||||
}
|
||||
CvCascadeParams::CvCascadeParams( int _stageType, int _featureType ) : stageType( _stageType ),
|
||||
featureType( _featureType ), winSize( cvSize(24, 24) )
|
||||
{
|
||||
name = CC_CASCADE_PARAMS;
|
||||
}
|
||||
|
||||
//---------------------------- CascadeParams --------------------------------------
|
||||
|
||||
void CvCascadeParams::write( FileStorage &fs ) const
|
||||
{
|
||||
string stageTypeStr = stageType == BOOST ? CC_BOOST : string();
|
||||
CV_Assert( !stageTypeStr.empty() );
|
||||
fs << CC_STAGE_TYPE << stageTypeStr;
|
||||
string featureTypeStr = featureType == CvFeatureParams::HAAR ? CC_HAAR :
|
||||
featureType == CvFeatureParams::LBP ? CC_LBP :
|
||||
featureType == CvFeatureParams::HOG ? CC_HOG :
|
||||
0;
|
||||
CV_Assert( !stageTypeStr.empty() );
|
||||
fs << CC_FEATURE_TYPE << featureTypeStr;
|
||||
fs << CC_HEIGHT << winSize.height;
|
||||
fs << CC_WIDTH << winSize.width;
|
||||
}
|
||||
|
||||
bool CvCascadeParams::read( const FileNode &node )
|
||||
{
|
||||
if ( node.empty() )
|
||||
return false;
|
||||
string stageTypeStr, featureTypeStr;
|
||||
FileNode rnode = node[CC_STAGE_TYPE];
|
||||
if ( !rnode.isString() )
|
||||
return false;
|
||||
rnode >> stageTypeStr;
|
||||
stageType = !stageTypeStr.compare( CC_BOOST ) ? BOOST : -1;
|
||||
if (stageType == -1)
|
||||
return false;
|
||||
rnode = node[CC_FEATURE_TYPE];
|
||||
if ( !rnode.isString() )
|
||||
return false;
|
||||
rnode >> featureTypeStr;
|
||||
featureType = !featureTypeStr.compare( CC_HAAR ) ? CvFeatureParams::HAAR :
|
||||
!featureTypeStr.compare( CC_LBP ) ? CvFeatureParams::LBP :
|
||||
!featureTypeStr.compare( CC_HOG ) ? CvFeatureParams::HOG :
|
||||
-1;
|
||||
if (featureType == -1)
|
||||
return false;
|
||||
node[CC_HEIGHT] >> winSize.height;
|
||||
node[CC_WIDTH] >> winSize.width;
|
||||
return winSize.height > 0 && winSize.width > 0;
|
||||
}
|
||||
|
||||
void CvCascadeParams::printDefaults() const
|
||||
{
|
||||
CvParams::printDefaults();
|
||||
cout << " [-stageType <";
|
||||
for( int i = 0; i < (int)(sizeof(stageTypes)/sizeof(stageTypes[0])); i++ )
|
||||
{
|
||||
cout << (i ? " | " : "") << stageTypes[i];
|
||||
if ( i == defaultStageType )
|
||||
cout << "(default)";
|
||||
}
|
||||
cout << ">]" << endl;
|
||||
|
||||
cout << " [-featureType <{";
|
||||
for( int i = 0; i < (int)(sizeof(featureTypes)/sizeof(featureTypes[0])); i++ )
|
||||
{
|
||||
cout << (i ? ", " : "") << featureTypes[i];
|
||||
if ( i == defaultStageType )
|
||||
cout << "(default)";
|
||||
}
|
||||
cout << "}>]" << endl;
|
||||
cout << " [-w <sampleWidth = " << winSize.width << ">]" << endl;
|
||||
cout << " [-h <sampleHeight = " << winSize.height << ">]" << endl;
|
||||
}
|
||||
|
||||
void CvCascadeParams::printAttrs() const
|
||||
{
|
||||
cout << "stageType: " << stageTypes[stageType] << endl;
|
||||
cout << "featureType: " << featureTypes[featureType] << endl;
|
||||
cout << "sampleWidth: " << winSize.width << endl;
|
||||
cout << "sampleHeight: " << winSize.height << endl;
|
||||
}
|
||||
|
||||
bool CvCascadeParams::scanAttr( const string prmName, const string val )
|
||||
{
|
||||
bool res = true;
|
||||
if( !prmName.compare( "-stageType" ) )
|
||||
{
|
||||
for( int i = 0; i < (int)(sizeof(stageTypes)/sizeof(stageTypes[0])); i++ )
|
||||
if( !val.compare( stageTypes[i] ) )
|
||||
stageType = i;
|
||||
}
|
||||
else if( !prmName.compare( "-featureType" ) )
|
||||
{
|
||||
for( int i = 0; i < (int)(sizeof(featureTypes)/sizeof(featureTypes[0])); i++ )
|
||||
if( !val.compare( featureTypes[i] ) )
|
||||
featureType = i;
|
||||
}
|
||||
else if( !prmName.compare( "-w" ) )
|
||||
{
|
||||
winSize.width = atoi( val.c_str() );
|
||||
}
|
||||
else if( !prmName.compare( "-h" ) )
|
||||
{
|
||||
winSize.height = atoi( val.c_str() );
|
||||
}
|
||||
else
|
||||
res = false;
|
||||
return res;
|
||||
}
|
||||
|
||||
//---------------------------- CascadeClassifier --------------------------------------
|
||||
|
||||
bool CvCascadeClassifier::train( const string _cascadeDirName,
|
||||
const string _posFilename,
|
||||
const string _negFilename,
|
||||
int _numPos, int _numNeg,
|
||||
int _precalcValBufSize, int _precalcIdxBufSize,
|
||||
int _numStages,
|
||||
const CvCascadeParams& _cascadeParams,
|
||||
const CvFeatureParams& _featureParams,
|
||||
const CvCascadeBoostParams& _stageParams,
|
||||
bool baseFormatSave,
|
||||
double acceptanceRatioBreakValue )
|
||||
{
|
||||
// Start recording clock ticks for training time output
|
||||
double time = (double)getTickCount();
|
||||
|
||||
if( _cascadeDirName.empty() || _posFilename.empty() || _negFilename.empty() )
|
||||
CV_Error( CV_StsBadArg, "_cascadeDirName or _bgfileName or _vecFileName is NULL" );
|
||||
|
||||
string dirName;
|
||||
if (_cascadeDirName.find_last_of("/\\") == (_cascadeDirName.length() - 1) )
|
||||
dirName = _cascadeDirName;
|
||||
else
|
||||
dirName = _cascadeDirName + '/';
|
||||
|
||||
numPos = _numPos;
|
||||
numNeg = _numNeg;
|
||||
numStages = _numStages;
|
||||
if ( !imgReader.create( _posFilename, _negFilename, _cascadeParams.winSize ) )
|
||||
{
|
||||
cout << "Image reader can not be created from -vec " << _posFilename
|
||||
<< " and -bg " << _negFilename << "." << endl;
|
||||
return false;
|
||||
}
|
||||
if ( !load( dirName ) )
|
||||
{
|
||||
cascadeParams = _cascadeParams;
|
||||
featureParams = CvFeatureParams::create(cascadeParams.featureType);
|
||||
featureParams->init(_featureParams);
|
||||
stageParams = makePtr<CvCascadeBoostParams>();
|
||||
*stageParams = _stageParams;
|
||||
featureEvaluator = CvFeatureEvaluator::create(cascadeParams.featureType);
|
||||
featureEvaluator->init( featureParams, numPos + numNeg, cascadeParams.winSize );
|
||||
stageClassifiers.reserve( numStages );
|
||||
}else{
|
||||
// Make sure that if model parameters are preloaded, that people are aware of this,
|
||||
// even when passing other parameters to the training command
|
||||
cout << "---------------------------------------------------------------------------------" << endl;
|
||||
cout << "Training parameters are pre-loaded from the parameter file in data folder!" << endl;
|
||||
cout << "Please empty this folder if you want to use a NEW set of training parameters." << endl;
|
||||
cout << "---------------------------------------------------------------------------------" << endl;
|
||||
}
|
||||
cout << "PARAMETERS:" << endl;
|
||||
cout << "cascadeDirName: " << _cascadeDirName << endl;
|
||||
cout << "vecFileName: " << _posFilename << endl;
|
||||
cout << "bgFileName: " << _negFilename << endl;
|
||||
cout << "numPos: " << _numPos << endl;
|
||||
cout << "numNeg: " << _numNeg << endl;
|
||||
cout << "numStages: " << numStages << endl;
|
||||
cout << "precalcValBufSize[Mb] : " << _precalcValBufSize << endl;
|
||||
cout << "precalcIdxBufSize[Mb] : " << _precalcIdxBufSize << endl;
|
||||
cout << "acceptanceRatioBreakValue : " << acceptanceRatioBreakValue << endl;
|
||||
cascadeParams.printAttrs();
|
||||
stageParams->printAttrs();
|
||||
featureParams->printAttrs();
|
||||
cout << "Number of unique features given windowSize [" << _cascadeParams.winSize.width << "," << _cascadeParams.winSize.height << "] : " << featureEvaluator->getNumFeatures() << "" << endl;
|
||||
|
||||
int startNumStages = (int)stageClassifiers.size();
|
||||
if ( startNumStages > 1 )
|
||||
cout << endl << "Stages 0-" << startNumStages-1 << " are loaded" << endl;
|
||||
else if ( startNumStages == 1)
|
||||
cout << endl << "Stage 0 is loaded" << endl;
|
||||
|
||||
double requiredLeafFARate = pow( (double) stageParams->maxFalseAlarm, (double) numStages ) /
|
||||
(double)stageParams->max_depth;
|
||||
double tempLeafFARate;
|
||||
|
||||
for( int i = startNumStages; i < numStages; i++ )
|
||||
{
|
||||
cout << endl << "===== TRAINING " << i << "-stage =====" << endl;
|
||||
cout << "<BEGIN" << endl;
|
||||
|
||||
if ( !updateTrainingSet( requiredLeafFARate, tempLeafFARate ) )
|
||||
{
|
||||
cout << "Train dataset for temp stage can not be filled. "
|
||||
"Branch training terminated." << endl;
|
||||
break;
|
||||
}
|
||||
if( tempLeafFARate <= requiredLeafFARate )
|
||||
{
|
||||
cout << "Required leaf false alarm rate achieved. "
|
||||
"Branch training terminated." << endl;
|
||||
break;
|
||||
}
|
||||
if( (tempLeafFARate <= acceptanceRatioBreakValue) && (acceptanceRatioBreakValue >= 0) ){
|
||||
cout << "The required acceptanceRatio for the model has been reached to avoid overfitting of trainingdata. "
|
||||
"Branch training terminated." << endl;
|
||||
break;
|
||||
}
|
||||
|
||||
Ptr<CvCascadeBoost> tempStage = makePtr<CvCascadeBoost>();
|
||||
bool isStageTrained = tempStage->train( featureEvaluator,
|
||||
curNumSamples, _precalcValBufSize, _precalcIdxBufSize,
|
||||
*stageParams );
|
||||
cout << "END>" << endl;
|
||||
|
||||
if(!isStageTrained)
|
||||
break;
|
||||
|
||||
stageClassifiers.push_back( tempStage );
|
||||
|
||||
// save params
|
||||
if( i == 0)
|
||||
{
|
||||
std::string paramsFilename = dirName + CC_PARAMS_FILENAME;
|
||||
FileStorage fs( paramsFilename, FileStorage::WRITE);
|
||||
if ( !fs.isOpened() )
|
||||
{
|
||||
cout << "Parameters can not be written, because file " << paramsFilename
|
||||
<< " can not be opened." << endl;
|
||||
return false;
|
||||
}
|
||||
fs << FileStorage::getDefaultObjectName(paramsFilename) << "{";
|
||||
writeParams( fs );
|
||||
fs << "}";
|
||||
}
|
||||
// save current stage
|
||||
char buf[10];
|
||||
sprintf(buf, "%s%d", "stage", i );
|
||||
string stageFilename = dirName + buf + ".xml";
|
||||
FileStorage fs( stageFilename, FileStorage::WRITE );
|
||||
if ( !fs.isOpened() )
|
||||
{
|
||||
cout << "Current stage can not be written, because file " << stageFilename
|
||||
<< " can not be opened." << endl;
|
||||
return false;
|
||||
}
|
||||
fs << FileStorage::getDefaultObjectName(stageFilename) << "{";
|
||||
tempStage->write( fs, Mat() );
|
||||
fs << "}";
|
||||
|
||||
// Output training time up till now
|
||||
double seconds = ( (double)getTickCount() - time)/ getTickFrequency();
|
||||
int days = int(seconds) / 60 / 60 / 24;
|
||||
int hours = (int(seconds) / 60 / 60) % 24;
|
||||
int minutes = (int(seconds) / 60) % 60;
|
||||
int seconds_left = int(seconds) % 60;
|
||||
cout << "Training until now has taken " << days << " days " << hours << " hours " << minutes << " minutes " << seconds_left <<" seconds." << endl;
|
||||
}
|
||||
|
||||
if(stageClassifiers.size() == 0)
|
||||
{
|
||||
cout << "Cascade classifier can't be trained. Check the used training parameters." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
save( dirName + CC_CASCADE_FILENAME, baseFormatSave );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int CvCascadeClassifier::predict( int sampleIdx )
|
||||
{
|
||||
CV_DbgAssert( sampleIdx < numPos + numNeg );
|
||||
for (vector< Ptr<CvCascadeBoost> >::iterator it = stageClassifiers.begin();
|
||||
it != stageClassifiers.end();++it )
|
||||
{
|
||||
if ( (*it)->predict( sampleIdx ) == 0.f )
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool CvCascadeClassifier::updateTrainingSet( double minimumAcceptanceRatio, double& acceptanceRatio)
|
||||
{
|
||||
int64 posConsumed = 0, negConsumed = 0;
|
||||
imgReader.restart();
|
||||
int posCount = fillPassedSamples( 0, numPos, true, 0, posConsumed );
|
||||
if( !posCount )
|
||||
return false;
|
||||
cout << "POS count : consumed " << posCount << " : " << (int)posConsumed << endl;
|
||||
|
||||
int proNumNeg = cvRound( ( ((double)numNeg) * ((double)posCount) ) / numPos ); // apply only a fraction of negative samples. double is required since overflow is possible
|
||||
int negCount = fillPassedSamples( posCount, proNumNeg, false, minimumAcceptanceRatio, negConsumed );
|
||||
if ( !negCount )
|
||||
if ( !(negConsumed > 0 && ((double)negCount+1)/(double)negConsumed <= minimumAcceptanceRatio) )
|
||||
return false;
|
||||
|
||||
curNumSamples = posCount + negCount;
|
||||
acceptanceRatio = negConsumed == 0 ? 0 : ( (double)negCount/(double)(int64)negConsumed );
|
||||
cout << "NEG count : acceptanceRatio " << negCount << " : " << acceptanceRatio << endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
int CvCascadeClassifier::fillPassedSamples( int first, int count, bool isPositive, double minimumAcceptanceRatio, int64& consumed )
|
||||
{
|
||||
int getcount = 0;
|
||||
Mat img(cascadeParams.winSize, CV_8UC1);
|
||||
for( int i = first; i < first + count; i++ )
|
||||
{
|
||||
for( ; ; )
|
||||
{
|
||||
if( consumed != 0 && ((double)getcount+1)/(double)(int64)consumed <= minimumAcceptanceRatio )
|
||||
return getcount;
|
||||
|
||||
bool isGetImg = isPositive ? imgReader.getPos( img ) :
|
||||
imgReader.getNeg( img );
|
||||
if( !isGetImg )
|
||||
return getcount;
|
||||
consumed++;
|
||||
|
||||
featureEvaluator->setImage( img, isPositive ? 1 : 0, i );
|
||||
if( predict( i ) == 1 )
|
||||
{
|
||||
getcount++;
|
||||
printf("%s current samples: %d\r", isPositive ? "POS":"NEG", getcount);
|
||||
fflush(stdout);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return getcount;
|
||||
}
|
||||
|
||||
void CvCascadeClassifier::writeParams( FileStorage &fs ) const
|
||||
{
|
||||
cascadeParams.write( fs );
|
||||
fs << CC_STAGE_PARAMS << "{"; stageParams->write( fs ); fs << "}";
|
||||
fs << CC_FEATURE_PARAMS << "{"; featureParams->write( fs ); fs << "}";
|
||||
}
|
||||
|
||||
void CvCascadeClassifier::writeFeatures( FileStorage &fs, const Mat& featureMap ) const
|
||||
{
|
||||
featureEvaluator->writeFeatures( fs, featureMap );
|
||||
}
|
||||
|
||||
void CvCascadeClassifier::writeStages( FileStorage &fs, const Mat& featureMap ) const
|
||||
{
|
||||
char cmnt[30];
|
||||
int i = 0;
|
||||
fs << CC_STAGES << "[";
|
||||
for( vector< Ptr<CvCascadeBoost> >::const_iterator it = stageClassifiers.begin();
|
||||
it != stageClassifiers.end();++it, ++i )
|
||||
{
|
||||
sprintf( cmnt, "stage %d", i );
|
||||
cvWriteComment( fs.fs, cmnt, 0 );
|
||||
fs << "{";
|
||||
(*it)->write( fs, featureMap );
|
||||
fs << "}";
|
||||
}
|
||||
fs << "]";
|
||||
}
|
||||
|
||||
bool CvCascadeClassifier::readParams( const FileNode &node )
|
||||
{
|
||||
if ( !node.isMap() || !cascadeParams.read( node ) )
|
||||
return false;
|
||||
|
||||
stageParams = makePtr<CvCascadeBoostParams>();
|
||||
FileNode rnode = node[CC_STAGE_PARAMS];
|
||||
if ( !stageParams->read( rnode ) )
|
||||
return false;
|
||||
|
||||
featureParams = CvFeatureParams::create(cascadeParams.featureType);
|
||||
rnode = node[CC_FEATURE_PARAMS];
|
||||
if ( !featureParams->read( rnode ) )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CvCascadeClassifier::readStages( const FileNode &node)
|
||||
{
|
||||
FileNode rnode = node[CC_STAGES];
|
||||
if (!rnode.empty() || !rnode.isSeq())
|
||||
return false;
|
||||
stageClassifiers.reserve(numStages);
|
||||
FileNodeIterator it = rnode.begin();
|
||||
for( int i = 0; i < min( (int)rnode.size(), numStages ); i++, it++ )
|
||||
{
|
||||
Ptr<CvCascadeBoost> tempStage = makePtr<CvCascadeBoost>();
|
||||
if ( !tempStage->read( *it, featureEvaluator, *stageParams) )
|
||||
return false;
|
||||
stageClassifiers.push_back(tempStage);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// For old Haar Classifier file saving
|
||||
#define ICV_HAAR_TYPE_ID "opencv-haar-classifier"
|
||||
#define ICV_HAAR_SIZE_NAME "size"
|
||||
#define ICV_HAAR_STAGES_NAME "stages"
|
||||
#define ICV_HAAR_TREES_NAME "trees"
|
||||
#define ICV_HAAR_FEATURE_NAME "feature"
|
||||
#define ICV_HAAR_RECTS_NAME "rects"
|
||||
#define ICV_HAAR_TILTED_NAME "tilted"
|
||||
#define ICV_HAAR_THRESHOLD_NAME "threshold"
|
||||
#define ICV_HAAR_LEFT_NODE_NAME "left_node"
|
||||
#define ICV_HAAR_LEFT_VAL_NAME "left_val"
|
||||
#define ICV_HAAR_RIGHT_NODE_NAME "right_node"
|
||||
#define ICV_HAAR_RIGHT_VAL_NAME "right_val"
|
||||
#define ICV_HAAR_STAGE_THRESHOLD_NAME "stage_threshold"
|
||||
#define ICV_HAAR_PARENT_NAME "parent"
|
||||
#define ICV_HAAR_NEXT_NAME "next"
|
||||
|
||||
void CvCascadeClassifier::save( const string filename, bool baseFormat )
|
||||
{
|
||||
FileStorage fs( filename, FileStorage::WRITE );
|
||||
|
||||
if ( !fs.isOpened() )
|
||||
return;
|
||||
|
||||
fs << FileStorage::getDefaultObjectName(filename);
|
||||
if ( !baseFormat )
|
||||
{
|
||||
Mat featureMap;
|
||||
getUsedFeaturesIdxMap( featureMap );
|
||||
fs << "{";
|
||||
writeParams( fs );
|
||||
fs << CC_STAGE_NUM << (int)stageClassifiers.size();
|
||||
writeStages( fs, featureMap );
|
||||
writeFeatures( fs, featureMap );
|
||||
}
|
||||
else
|
||||
{
|
||||
//char buf[256];
|
||||
CvSeq* weak;
|
||||
if ( cascadeParams.featureType != CvFeatureParams::HAAR )
|
||||
CV_Error( CV_StsBadFunc, "old file format is used for Haar-like features only");
|
||||
fs << "{:" ICV_HAAR_TYPE_ID;
|
||||
fs << ICV_HAAR_SIZE_NAME << "[:" << cascadeParams.winSize.width <<
|
||||
cascadeParams.winSize.height << "]";
|
||||
fs << ICV_HAAR_STAGES_NAME << "[";
|
||||
for( size_t si = 0; si < stageClassifiers.size(); si++ )
|
||||
{
|
||||
fs << "{"; //stage
|
||||
/*sprintf( buf, "stage %d", si );
|
||||
CV_CALL( cvWriteComment( fs, buf, 1 ) );*/
|
||||
weak = stageClassifiers[si]->get_weak_predictors();
|
||||
fs << ICV_HAAR_TREES_NAME << "[";
|
||||
for( int wi = 0; wi < weak->total; wi++ )
|
||||
{
|
||||
int inner_node_idx = -1, total_inner_node_idx = -1;
|
||||
queue<const CvDTreeNode*> inner_nodes_queue;
|
||||
CvCascadeBoostTree* tree = *((CvCascadeBoostTree**) cvGetSeqElem( weak, wi ));
|
||||
|
||||
fs << "[";
|
||||
/*sprintf( buf, "tree %d", wi );
|
||||
CV_CALL( cvWriteComment( fs, buf, 1 ) );*/
|
||||
|
||||
const CvDTreeNode* tempNode;
|
||||
|
||||
inner_nodes_queue.push( tree->get_root() );
|
||||
total_inner_node_idx++;
|
||||
|
||||
while (!inner_nodes_queue.empty())
|
||||
{
|
||||
tempNode = inner_nodes_queue.front();
|
||||
inner_node_idx++;
|
||||
|
||||
fs << "{";
|
||||
fs << ICV_HAAR_FEATURE_NAME << "{";
|
||||
((CvHaarEvaluator*)featureEvaluator.get())->writeFeature( fs, tempNode->split->var_idx );
|
||||
fs << "}";
|
||||
|
||||
fs << ICV_HAAR_THRESHOLD_NAME << tempNode->split->ord.c;
|
||||
|
||||
if( tempNode->left->left || tempNode->left->right )
|
||||
{
|
||||
inner_nodes_queue.push( tempNode->left );
|
||||
total_inner_node_idx++;
|
||||
fs << ICV_HAAR_LEFT_NODE_NAME << total_inner_node_idx;
|
||||
}
|
||||
else
|
||||
fs << ICV_HAAR_LEFT_VAL_NAME << tempNode->left->value;
|
||||
|
||||
if( tempNode->right->left || tempNode->right->right )
|
||||
{
|
||||
inner_nodes_queue.push( tempNode->right );
|
||||
total_inner_node_idx++;
|
||||
fs << ICV_HAAR_RIGHT_NODE_NAME << total_inner_node_idx;
|
||||
}
|
||||
else
|
||||
fs << ICV_HAAR_RIGHT_VAL_NAME << tempNode->right->value;
|
||||
fs << "}"; // ICV_HAAR_FEATURE_NAME
|
||||
inner_nodes_queue.pop();
|
||||
}
|
||||
fs << "]";
|
||||
}
|
||||
fs << "]"; //ICV_HAAR_TREES_NAME
|
||||
fs << ICV_HAAR_STAGE_THRESHOLD_NAME << stageClassifiers[si]->getThreshold();
|
||||
fs << ICV_HAAR_PARENT_NAME << (int)si-1 << ICV_HAAR_NEXT_NAME << -1;
|
||||
fs << "}"; //stage
|
||||
} /* for each stage */
|
||||
fs << "]"; //ICV_HAAR_STAGES_NAME
|
||||
}
|
||||
fs << "}";
|
||||
}
|
||||
|
||||
bool CvCascadeClassifier::load( const string cascadeDirName )
|
||||
{
|
||||
FileStorage fs( cascadeDirName + CC_PARAMS_FILENAME, FileStorage::READ );
|
||||
if ( !fs.isOpened() )
|
||||
return false;
|
||||
FileNode node = fs.getFirstTopLevelNode();
|
||||
if ( !readParams( node ) )
|
||||
return false;
|
||||
featureEvaluator = CvFeatureEvaluator::create(cascadeParams.featureType);
|
||||
featureEvaluator->init( featureParams, numPos + numNeg, cascadeParams.winSize );
|
||||
fs.release();
|
||||
|
||||
char buf[16] = {0};
|
||||
for ( int si = 0; si < numStages; si++ )
|
||||
{
|
||||
sprintf( buf, "%s%d", "stage", si);
|
||||
fs.open( cascadeDirName + buf + ".xml", FileStorage::READ );
|
||||
node = fs.getFirstTopLevelNode();
|
||||
if ( !fs.isOpened() )
|
||||
break;
|
||||
Ptr<CvCascadeBoost> tempStage = makePtr<CvCascadeBoost>();
|
||||
|
||||
if ( !tempStage->read( node, featureEvaluator, *stageParams ))
|
||||
{
|
||||
fs.release();
|
||||
break;
|
||||
}
|
||||
stageClassifiers.push_back(tempStage);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CvCascadeClassifier::getUsedFeaturesIdxMap( Mat& featureMap )
|
||||
{
|
||||
int varCount = featureEvaluator->getNumFeatures() * featureEvaluator->getFeatureSize();
|
||||
featureMap.create( 1, varCount, CV_32SC1 );
|
||||
featureMap.setTo(Scalar(-1));
|
||||
|
||||
for( vector< Ptr<CvCascadeBoost> >::const_iterator it = stageClassifiers.begin();
|
||||
it != stageClassifiers.end();++it )
|
||||
(*it)->markUsedFeaturesInMap( featureMap );
|
||||
|
||||
for( int fi = 0, idx = 0; fi < varCount; fi++ )
|
||||
if ( featureMap.at<int>(0, fi) >= 0 )
|
||||
featureMap.ptr<int>(0)[fi] = idx++;
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
#ifndef _OPENCV_CASCADECLASSIFIER_H_
|
||||
#define _OPENCV_CASCADECLASSIFIER_H_
|
||||
|
||||
#include <ctime>
|
||||
#include "traincascade_features.h"
|
||||
#include "haarfeatures.h"
|
||||
#include "lbpfeatures.h"
|
||||
#include "HOGfeatures.h" //new
|
||||
#include "boost.h"
|
||||
|
||||
#define CC_CASCADE_FILENAME "cascade.xml"
|
||||
#define CC_PARAMS_FILENAME "params.xml"
|
||||
|
||||
#define CC_CASCADE_PARAMS "cascadeParams"
|
||||
#define CC_STAGE_TYPE "stageType"
|
||||
#define CC_FEATURE_TYPE "featureType"
|
||||
#define CC_HEIGHT "height"
|
||||
#define CC_WIDTH "width"
|
||||
|
||||
#define CC_STAGE_NUM "stageNum"
|
||||
#define CC_STAGES "stages"
|
||||
#define CC_STAGE_PARAMS "stageParams"
|
||||
|
||||
#define CC_BOOST "BOOST"
|
||||
#define CC_BOOST_TYPE "boostType"
|
||||
#define CC_DISCRETE_BOOST "DAB"
|
||||
#define CC_REAL_BOOST "RAB"
|
||||
#define CC_LOGIT_BOOST "LB"
|
||||
#define CC_GENTLE_BOOST "GAB"
|
||||
#define CC_MINHITRATE "minHitRate"
|
||||
#define CC_MAXFALSEALARM "maxFalseAlarm"
|
||||
#define CC_TRIM_RATE "weightTrimRate"
|
||||
#define CC_MAX_DEPTH "maxDepth"
|
||||
#define CC_WEAK_COUNT "maxWeakCount"
|
||||
#define CC_STAGE_THRESHOLD "stageThreshold"
|
||||
#define CC_WEAK_CLASSIFIERS "weakClassifiers"
|
||||
#define CC_INTERNAL_NODES "internalNodes"
|
||||
#define CC_LEAF_VALUES "leafValues"
|
||||
|
||||
#define CC_FEATURES FEATURES
|
||||
#define CC_FEATURE_PARAMS "featureParams"
|
||||
#define CC_MAX_CAT_COUNT "maxCatCount"
|
||||
#define CC_FEATURE_SIZE "featSize"
|
||||
|
||||
#define CC_HAAR "HAAR"
|
||||
#define CC_MODE "mode"
|
||||
#define CC_MODE_BASIC "BASIC"
|
||||
#define CC_MODE_CORE "CORE"
|
||||
#define CC_MODE_ALL "ALL"
|
||||
#define CC_RECTS "rects"
|
||||
#define CC_TILTED "tilted"
|
||||
|
||||
#define CC_LBP "LBP"
|
||||
#define CC_RECT "rect"
|
||||
|
||||
#define CC_HOG "HOG"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define TIME( arg ) (((double) clock()) / CLOCKS_PER_SEC)
|
||||
#else
|
||||
#define TIME( arg ) (time( arg ))
|
||||
#endif
|
||||
|
||||
class CvCascadeParams : public CvParams
|
||||
{
|
||||
public:
|
||||
enum { BOOST = 0 };
|
||||
static const int defaultStageType = BOOST;
|
||||
static const int defaultFeatureType = CvFeatureParams::HAAR;
|
||||
|
||||
CvCascadeParams();
|
||||
CvCascadeParams( int _stageType, int _featureType );
|
||||
void write( cv::FileStorage &fs ) const;
|
||||
bool read( const cv::FileNode &node );
|
||||
|
||||
void printDefaults() const;
|
||||
void printAttrs() const;
|
||||
bool scanAttr( const std::string prmName, const std::string val );
|
||||
|
||||
int stageType;
|
||||
int featureType;
|
||||
cv::Size winSize;
|
||||
};
|
||||
|
||||
class CvCascadeClassifier
|
||||
{
|
||||
public:
|
||||
bool train( const std::string _cascadeDirName,
|
||||
const std::string _posFilename,
|
||||
const std::string _negFilename,
|
||||
int _numPos, int _numNeg,
|
||||
int _precalcValBufSize, int _precalcIdxBufSize,
|
||||
int _numStages,
|
||||
const CvCascadeParams& _cascadeParams,
|
||||
const CvFeatureParams& _featureParams,
|
||||
const CvCascadeBoostParams& _stageParams,
|
||||
bool baseFormatSave = false,
|
||||
double acceptanceRatioBreakValue = -1.0 );
|
||||
private:
|
||||
int predict( int sampleIdx );
|
||||
void save( const std::string cascadeDirName, bool baseFormat = false );
|
||||
bool load( const std::string cascadeDirName );
|
||||
bool updateTrainingSet( double minimumAcceptanceRatio, double& acceptanceRatio );
|
||||
int fillPassedSamples( int first, int count, bool isPositive, double requiredAcceptanceRatio, int64& consumed );
|
||||
|
||||
void writeParams( cv::FileStorage &fs ) const;
|
||||
void writeStages( cv::FileStorage &fs, const cv::Mat& featureMap ) const;
|
||||
void writeFeatures( cv::FileStorage &fs, const cv::Mat& featureMap ) const;
|
||||
bool readParams( const cv::FileNode &node );
|
||||
bool readStages( const cv::FileNode &node );
|
||||
|
||||
void getUsedFeaturesIdxMap( cv::Mat& featureMap );
|
||||
|
||||
CvCascadeParams cascadeParams;
|
||||
cv::Ptr<CvFeatureParams> featureParams;
|
||||
cv::Ptr<CvCascadeBoostParams> stageParams;
|
||||
|
||||
cv::Ptr<CvFeatureEvaluator> featureEvaluator;
|
||||
std::vector< cv::Ptr<CvCascadeBoost> > stageClassifiers;
|
||||
CvCascadeImageReader imgReader;
|
||||
int numStages, curNumSamples;
|
||||
int numPos, numNeg;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,93 @@
|
|||
#include "opencv2/core.hpp"
|
||||
|
||||
#include "traincascade_features.h"
|
||||
#include "cascadeclassifier.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
float calcNormFactor( const Mat& sum, const Mat& sqSum )
|
||||
{
|
||||
CV_DbgAssert( sum.cols > 3 && sqSum.rows > 3 );
|
||||
Rect normrect( 1, 1, sum.cols - 3, sum.rows - 3 );
|
||||
size_t p0, p1, p2, p3;
|
||||
CV_SUM_OFFSETS( p0, p1, p2, p3, normrect, sum.step1() )
|
||||
double area = normrect.width * normrect.height;
|
||||
const int *sp = sum.ptr<int>();
|
||||
int valSum = sp[p0] - sp[p1] - sp[p2] + sp[p3];
|
||||
const double *sqp = sqSum.ptr<double>();
|
||||
double valSqSum = sqp[p0] - sqp[p1] - sqp[p2] + sqp[p3];
|
||||
return (float) sqrt( (double) (area * valSqSum - (double)valSum * valSum) );
|
||||
}
|
||||
|
||||
CvParams::CvParams() : name( "params" ) {}
|
||||
void CvParams::printDefaults() const
|
||||
{ cout << "--" << name << "--" << endl; }
|
||||
void CvParams::printAttrs() const {}
|
||||
bool CvParams::scanAttr( const string, const string ) { return false; }
|
||||
|
||||
|
||||
//---------------------------- FeatureParams --------------------------------------
|
||||
|
||||
CvFeatureParams::CvFeatureParams() : maxCatCount( 0 ), featSize( 1 )
|
||||
{
|
||||
name = CC_FEATURE_PARAMS;
|
||||
}
|
||||
|
||||
void CvFeatureParams::init( const CvFeatureParams& fp )
|
||||
{
|
||||
maxCatCount = fp.maxCatCount;
|
||||
featSize = fp.featSize;
|
||||
}
|
||||
|
||||
void CvFeatureParams::write( FileStorage &fs ) const
|
||||
{
|
||||
fs << CC_MAX_CAT_COUNT << maxCatCount;
|
||||
fs << CC_FEATURE_SIZE << featSize;
|
||||
}
|
||||
|
||||
bool CvFeatureParams::read( const FileNode &node )
|
||||
{
|
||||
if ( node.empty() )
|
||||
return false;
|
||||
maxCatCount = node[CC_MAX_CAT_COUNT];
|
||||
featSize = node[CC_FEATURE_SIZE];
|
||||
return ( maxCatCount >= 0 && featSize >= 1 );
|
||||
}
|
||||
|
||||
Ptr<CvFeatureParams> CvFeatureParams::create( int featureType )
|
||||
{
|
||||
return featureType == HAAR ? Ptr<CvFeatureParams>(new CvHaarFeatureParams) :
|
||||
featureType == LBP ? Ptr<CvFeatureParams>(new CvLBPFeatureParams) :
|
||||
featureType == HOG ? Ptr<CvFeatureParams>(new CvHOGFeatureParams) :
|
||||
Ptr<CvFeatureParams>();
|
||||
}
|
||||
|
||||
//------------------------------------- FeatureEvaluator ---------------------------------------
|
||||
|
||||
void CvFeatureEvaluator::init(const CvFeatureParams *_featureParams,
|
||||
int _maxSampleCount, Size _winSize )
|
||||
{
|
||||
CV_Assert(_maxSampleCount > 0);
|
||||
featureParams = (CvFeatureParams *)_featureParams;
|
||||
winSize = _winSize;
|
||||
numFeatures = 0;
|
||||
cls.create( (int)_maxSampleCount, 1, CV_32FC1 );
|
||||
generateFeatures();
|
||||
}
|
||||
|
||||
void CvFeatureEvaluator::setImage(const Mat &img, uchar clsLabel, int idx)
|
||||
{
|
||||
CV_Assert(img.cols == winSize.width);
|
||||
CV_Assert(img.rows == winSize.height);
|
||||
CV_Assert(idx < cls.rows);
|
||||
cls.ptr<float>(idx)[0] = clsLabel;
|
||||
}
|
||||
|
||||
Ptr<CvFeatureEvaluator> CvFeatureEvaluator::create(int type)
|
||||
{
|
||||
return type == CvFeatureParams::HAAR ? Ptr<CvFeatureEvaluator>(new CvHaarEvaluator) :
|
||||
type == CvFeatureParams::LBP ? Ptr<CvFeatureEvaluator>(new CvLBPEvaluator) :
|
||||
type == CvFeatureParams::HOG ? Ptr<CvFeatureEvaluator>(new CvHOGEvaluator) :
|
||||
Ptr<CvFeatureEvaluator>();
|
||||
}
|
|
@ -0,0 +1,312 @@
|
|||
#include "opencv2/core.hpp"
|
||||
#include "opencv2/imgproc.hpp"
|
||||
|
||||
#include "haarfeatures.h"
|
||||
#include "cascadeclassifier.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
CvHaarFeatureParams::CvHaarFeatureParams() : mode(BASIC)
|
||||
{
|
||||
name = HFP_NAME;
|
||||
}
|
||||
|
||||
CvHaarFeatureParams::CvHaarFeatureParams( int _mode ) : mode( _mode )
|
||||
{
|
||||
name = HFP_NAME;
|
||||
}
|
||||
|
||||
void CvHaarFeatureParams::init( const CvFeatureParams& fp )
|
||||
{
|
||||
CvFeatureParams::init( fp );
|
||||
mode = ((const CvHaarFeatureParams&)fp).mode;
|
||||
}
|
||||
|
||||
void CvHaarFeatureParams::write( FileStorage &fs ) const
|
||||
{
|
||||
CvFeatureParams::write( fs );
|
||||
string modeStr = mode == BASIC ? CC_MODE_BASIC :
|
||||
mode == CORE ? CC_MODE_CORE :
|
||||
mode == ALL ? CC_MODE_ALL : string();
|
||||
CV_Assert( !modeStr.empty() );
|
||||
fs << CC_MODE << modeStr;
|
||||
}
|
||||
|
||||
bool CvHaarFeatureParams::read( const FileNode &node )
|
||||
{
|
||||
if( !CvFeatureParams::read( node ) )
|
||||
return false;
|
||||
|
||||
FileNode rnode = node[CC_MODE];
|
||||
if( !rnode.isString() )
|
||||
return false;
|
||||
string modeStr;
|
||||
rnode >> modeStr;
|
||||
mode = !modeStr.compare( CC_MODE_BASIC ) ? BASIC :
|
||||
!modeStr.compare( CC_MODE_CORE ) ? CORE :
|
||||
!modeStr.compare( CC_MODE_ALL ) ? ALL : -1;
|
||||
return (mode >= 0);
|
||||
}
|
||||
|
||||
void CvHaarFeatureParams::printDefaults() const
|
||||
{
|
||||
CvFeatureParams::printDefaults();
|
||||
cout << " [-mode <" CC_MODE_BASIC << "(default) | "
|
||||
<< CC_MODE_CORE <<" | " << CC_MODE_ALL << endl;
|
||||
}
|
||||
|
||||
void CvHaarFeatureParams::printAttrs() const
|
||||
{
|
||||
CvFeatureParams::printAttrs();
|
||||
string mode_str = mode == BASIC ? CC_MODE_BASIC :
|
||||
mode == CORE ? CC_MODE_CORE :
|
||||
mode == ALL ? CC_MODE_ALL : 0;
|
||||
cout << "mode: " << mode_str << endl;
|
||||
}
|
||||
|
||||
bool CvHaarFeatureParams::scanAttr( const string prmName, const string val)
|
||||
{
|
||||
if ( !CvFeatureParams::scanAttr( prmName, val ) )
|
||||
{
|
||||
if( !prmName.compare("-mode") )
|
||||
{
|
||||
mode = !val.compare( CC_MODE_CORE ) ? CORE :
|
||||
!val.compare( CC_MODE_ALL ) ? ALL :
|
||||
!val.compare( CC_MODE_BASIC ) ? BASIC : -1;
|
||||
if (mode == -1)
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------- HaarFeatureEvaluator ----------------
|
||||
|
||||
void CvHaarEvaluator::init(const CvFeatureParams *_featureParams,
|
||||
int _maxSampleCount, Size _winSize )
|
||||
{
|
||||
CV_Assert(_maxSampleCount > 0);
|
||||
int cols = (_winSize.width + 1) * (_winSize.height + 1);
|
||||
sum.create((int)_maxSampleCount, cols, CV_32SC1);
|
||||
tilted.create((int)_maxSampleCount, cols, CV_32SC1);
|
||||
normfactor.create(1, (int)_maxSampleCount, CV_32FC1);
|
||||
CvFeatureEvaluator::init( _featureParams, _maxSampleCount, _winSize );
|
||||
}
|
||||
|
||||
void CvHaarEvaluator::setImage(const Mat& img, uchar clsLabel, int idx)
|
||||
{
|
||||
CV_DbgAssert( !sum.empty() && !tilted.empty() && !normfactor.empty() );
|
||||
CvFeatureEvaluator::setImage( img, clsLabel, idx);
|
||||
Mat innSum(winSize.height + 1, winSize.width + 1, sum.type(), sum.ptr<int>((int)idx));
|
||||
Mat innSqSum;
|
||||
if (((const CvHaarFeatureParams*)featureParams)->mode == CvHaarFeatureParams::ALL)
|
||||
{
|
||||
Mat innTilted(winSize.height + 1, winSize.width + 1, tilted.type(), tilted.ptr<int>((int)idx));
|
||||
integral(img, innSum, innSqSum, innTilted);
|
||||
}
|
||||
else
|
||||
integral(img, innSum, innSqSum);
|
||||
normfactor.ptr<float>(0)[idx] = calcNormFactor( innSum, innSqSum );
|
||||
}
|
||||
|
||||
void CvHaarEvaluator::writeFeatures( FileStorage &fs, const Mat& featureMap ) const
|
||||
{
|
||||
_writeFeatures( features, fs, featureMap );
|
||||
}
|
||||
|
||||
void CvHaarEvaluator::writeFeature(FileStorage &fs, int fi) const
|
||||
{
|
||||
CV_DbgAssert( fi < (int)features.size() );
|
||||
features[fi].write(fs);
|
||||
}
|
||||
|
||||
void CvHaarEvaluator::generateFeatures()
|
||||
{
|
||||
int mode = ((const CvHaarFeatureParams*)((CvFeatureParams*)featureParams))->mode;
|
||||
int offset = winSize.width + 1;
|
||||
for( int x = 0; x < winSize.width; x++ )
|
||||
{
|
||||
for( int y = 0; y < winSize.height; y++ )
|
||||
{
|
||||
for( int dx = 1; dx <= winSize.width; dx++ )
|
||||
{
|
||||
for( int dy = 1; dy <= winSize.height; dy++ )
|
||||
{
|
||||
// haar_x2
|
||||
if ( (x+dx*2 <= winSize.width) && (y+dy <= winSize.height) )
|
||||
{
|
||||
features.push_back( Feature( offset, false,
|
||||
x, y, dx*2, dy, -1,
|
||||
x+dx, y, dx , dy, +2 ) );
|
||||
}
|
||||
// haar_y2
|
||||
if ( (x+dx <= winSize.width) && (y+dy*2 <= winSize.height) )
|
||||
{
|
||||
features.push_back( Feature( offset, false,
|
||||
x, y, dx, dy*2, -1,
|
||||
x, y+dy, dx, dy, +2 ) );
|
||||
}
|
||||
// haar_x3
|
||||
if ( (x+dx*3 <= winSize.width) && (y+dy <= winSize.height) )
|
||||
{
|
||||
features.push_back( Feature( offset, false,
|
||||
x, y, dx*3, dy, -1,
|
||||
x+dx, y, dx , dy, +2 ) );
|
||||
}
|
||||
// haar_y3
|
||||
if ( (x+dx <= winSize.width) && (y+dy*3 <= winSize.height) )
|
||||
{
|
||||
features.push_back( Feature( offset, false,
|
||||
x, y, dx, dy*3, -1,
|
||||
x, y+dy, dx, dy, +2 ) );
|
||||
}
|
||||
if( mode != CvHaarFeatureParams::BASIC )
|
||||
{
|
||||
// haar_x4
|
||||
if ( (x+dx*4 <= winSize.width) && (y+dy <= winSize.height) )
|
||||
{
|
||||
features.push_back( Feature( offset, false,
|
||||
x, y, dx*4, dy, -1,
|
||||
x+dx, y, dx*2, dy, +2 ) );
|
||||
}
|
||||
// haar_y4
|
||||
if ( (x+dx <= winSize.width ) && (y+dy*4 <= winSize.height) )
|
||||
{
|
||||
features.push_back( Feature( offset, false,
|
||||
x, y, dx, dy*4, -1,
|
||||
x, y+dy, dx, dy*2, +2 ) );
|
||||
}
|
||||
}
|
||||
// x2_y2
|
||||
if ( (x+dx*2 <= winSize.width) && (y+dy*2 <= winSize.height) )
|
||||
{
|
||||
features.push_back( Feature( offset, false,
|
||||
x, y, dx*2, dy*2, -1,
|
||||
x, y, dx, dy, +2,
|
||||
x+dx, y+dy, dx, dy, +2 ) );
|
||||
}
|
||||
if (mode != CvHaarFeatureParams::BASIC)
|
||||
{
|
||||
if ( (x+dx*3 <= winSize.width) && (y+dy*3 <= winSize.height) )
|
||||
{
|
||||
features.push_back( Feature( offset, false,
|
||||
x , y , dx*3, dy*3, -1,
|
||||
x+dx, y+dy, dx , dy , +9) );
|
||||
}
|
||||
}
|
||||
if (mode == CvHaarFeatureParams::ALL)
|
||||
{
|
||||
// tilted haar_x2
|
||||
if ( (x+2*dx <= winSize.width) && (y+2*dx+dy <= winSize.height) && (x-dy>= 0) )
|
||||
{
|
||||
features.push_back( Feature( offset, true,
|
||||
x, y, dx*2, dy, -1,
|
||||
x, y, dx, dy, +2 ) );
|
||||
}
|
||||
// tilted haar_y2
|
||||
if ( (x+dx <= winSize.width) && (y+dx+2*dy <= winSize.height) && (x-2*dy>= 0) )
|
||||
{
|
||||
features.push_back( Feature( offset, true,
|
||||
x, y, dx, 2*dy, -1,
|
||||
x, y, dx, dy, +2 ) );
|
||||
}
|
||||
// tilted haar_x3
|
||||
if ( (x+3*dx <= winSize.width) && (y+3*dx+dy <= winSize.height) && (x-dy>= 0) )
|
||||
{
|
||||
features.push_back( Feature( offset, true,
|
||||
x, y, dx*3, dy, -1,
|
||||
x+dx, y+dx, dx, dy, +3 ) );
|
||||
}
|
||||
// tilted haar_y3
|
||||
if ( (x+dx <= winSize.width) && (y+dx+3*dy <= winSize.height) && (x-3*dy>= 0) )
|
||||
{
|
||||
features.push_back( Feature( offset, true,
|
||||
x, y, dx, 3*dy, -1,
|
||||
x-dy, y+dy, dx, dy, +3 ) );
|
||||
}
|
||||
// tilted haar_x4
|
||||
if ( (x+4*dx <= winSize.width) && (y+4*dx+dy <= winSize.height) && (x-dy>= 0) )
|
||||
{
|
||||
features.push_back( Feature( offset, true,
|
||||
x, y, dx*4, dy, -1,
|
||||
x+dx, y+dx, dx*2, dy, +2 ) );
|
||||
}
|
||||
// tilted haar_y4
|
||||
if ( (x+dx <= winSize.width) && (y+dx+4*dy <= winSize.height) && (x-4*dy>= 0) )
|
||||
{
|
||||
features.push_back( Feature( offset, true,
|
||||
x, y, dx, 4*dy, -1,
|
||||
x-dy, y+dy, dx, 2*dy, +2 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
numFeatures = (int)features.size();
|
||||
}
|
||||
|
||||
CvHaarEvaluator::Feature::Feature()
|
||||
{
|
||||
tilted = false;
|
||||
rect[0].r = rect[1].r = rect[2].r = Rect(0,0,0,0);
|
||||
rect[0].weight = rect[1].weight = rect[2].weight = 0;
|
||||
}
|
||||
|
||||
CvHaarEvaluator::Feature::Feature( int offset, bool _tilted,
|
||||
int x0, int y0, int w0, int h0, float wt0,
|
||||
int x1, int y1, int w1, int h1, float wt1,
|
||||
int x2, int y2, int w2, int h2, float wt2 )
|
||||
{
|
||||
tilted = _tilted;
|
||||
|
||||
rect[0].r.x = x0;
|
||||
rect[0].r.y = y0;
|
||||
rect[0].r.width = w0;
|
||||
rect[0].r.height = h0;
|
||||
rect[0].weight = wt0;
|
||||
|
||||
rect[1].r.x = x1;
|
||||
rect[1].r.y = y1;
|
||||
rect[1].r.width = w1;
|
||||
rect[1].r.height = h1;
|
||||
rect[1].weight = wt1;
|
||||
|
||||
rect[2].r.x = x2;
|
||||
rect[2].r.y = y2;
|
||||
rect[2].r.width = w2;
|
||||
rect[2].r.height = h2;
|
||||
rect[2].weight = wt2;
|
||||
|
||||
if( !tilted )
|
||||
{
|
||||
for( int j = 0; j < CV_HAAR_FEATURE_MAX; j++ )
|
||||
{
|
||||
if( rect[j].weight == 0.0F )
|
||||
break;
|
||||
CV_SUM_OFFSETS( fastRect[j].p0, fastRect[j].p1, fastRect[j].p2, fastRect[j].p3, rect[j].r, offset )
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( int j = 0; j < CV_HAAR_FEATURE_MAX; j++ )
|
||||
{
|
||||
if( rect[j].weight == 0.0F )
|
||||
break;
|
||||
CV_TILTED_OFFSETS( fastRect[j].p0, fastRect[j].p1, fastRect[j].p2, fastRect[j].p3, rect[j].r, offset )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CvHaarEvaluator::Feature::write( FileStorage &fs ) const
|
||||
{
|
||||
fs << CC_RECTS << "[";
|
||||
for( int ri = 0; ri < CV_HAAR_FEATURE_MAX && rect[ri].r.width != 0; ++ri )
|
||||
{
|
||||
fs << "[:" << rect[ri].r.x << rect[ri].r.y <<
|
||||
rect[ri].r.width << rect[ri].r.height << rect[ri].weight << "]";
|
||||
}
|
||||
fs << "]" << CC_TILTED << tilted;
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
#ifndef _OPENCV_HAARFEATURES_H_
|
||||
#define _OPENCV_HAARFEATURES_H_
|
||||
|
||||
#include "traincascade_features.h"
|
||||
|
||||
#define CV_HAAR_FEATURE_MAX 3
|
||||
|
||||
#define HFP_NAME "haarFeatureParams"
|
||||
class CvHaarFeatureParams : public CvFeatureParams
|
||||
{
|
||||
public:
|
||||
enum { BASIC = 0, CORE = 1, ALL = 2 };
|
||||
/* 0 - BASIC = Viola
|
||||
* 1 - CORE = All upright
|
||||
* 2 - ALL = All features */
|
||||
|
||||
CvHaarFeatureParams();
|
||||
CvHaarFeatureParams( int _mode );
|
||||
|
||||
virtual void init( const CvFeatureParams& fp );
|
||||
virtual void write( cv::FileStorage &fs ) const;
|
||||
virtual bool read( const cv::FileNode &node );
|
||||
|
||||
virtual void printDefaults() const;
|
||||
virtual void printAttrs() const;
|
||||
virtual bool scanAttr( const std::string prm, const std::string val);
|
||||
|
||||
int mode;
|
||||
};
|
||||
|
||||
class CvHaarEvaluator : public CvFeatureEvaluator
|
||||
{
|
||||
public:
|
||||
virtual void init(const CvFeatureParams *_featureParams,
|
||||
int _maxSampleCount, cv::Size _winSize );
|
||||
virtual void setImage(const cv::Mat& img, uchar clsLabel, int idx);
|
||||
virtual float operator()(int featureIdx, int sampleIdx) const;
|
||||
virtual void writeFeatures( cv::FileStorage &fs, const cv::Mat& featureMap ) const;
|
||||
void writeFeature( cv::FileStorage &fs, int fi ) const; // for old file fornat
|
||||
protected:
|
||||
virtual void generateFeatures();
|
||||
|
||||
class Feature
|
||||
{
|
||||
public:
|
||||
Feature();
|
||||
Feature( int offset, bool _tilted,
|
||||
int x0, int y0, int w0, int h0, float wt0,
|
||||
int x1, int y1, int w1, int h1, float wt1,
|
||||
int x2 = 0, int y2 = 0, int w2 = 0, int h2 = 0, float wt2 = 0.0F );
|
||||
float calc( const cv::Mat &sum, const cv::Mat &tilted, size_t y) const;
|
||||
void write( cv::FileStorage &fs ) const;
|
||||
|
||||
bool tilted;
|
||||
struct
|
||||
{
|
||||
cv::Rect r;
|
||||
float weight;
|
||||
} rect[CV_HAAR_FEATURE_MAX];
|
||||
|
||||
struct
|
||||
{
|
||||
int p0, p1, p2, p3;
|
||||
} fastRect[CV_HAAR_FEATURE_MAX];
|
||||
};
|
||||
|
||||
std::vector<Feature> features;
|
||||
cv::Mat sum; /* sum images (each row represents image) */
|
||||
cv::Mat tilted; /* tilted sum images (each row represents image) */
|
||||
cv::Mat normfactor; /* normalization factor */
|
||||
};
|
||||
|
||||
inline float CvHaarEvaluator::operator()(int featureIdx, int sampleIdx) const
|
||||
{
|
||||
float nf = normfactor.at<float>(0, sampleIdx);
|
||||
return !nf ? 0.0f : (features[featureIdx].calc( sum, tilted, sampleIdx)/nf);
|
||||
}
|
||||
|
||||
inline float CvHaarEvaluator::Feature::calc( const cv::Mat &_sum, const cv::Mat &_tilted, size_t y) const
|
||||
{
|
||||
const int* img = tilted ? _tilted.ptr<int>((int)y) : _sum.ptr<int>((int)y);
|
||||
float ret = rect[0].weight * (img[fastRect[0].p0] - img[fastRect[0].p1] - img[fastRect[0].p2] + img[fastRect[0].p3] ) +
|
||||
rect[1].weight * (img[fastRect[1].p0] - img[fastRect[1].p1] - img[fastRect[1].p2] + img[fastRect[1].p3] );
|
||||
if( rect[2].weight != 0.0f )
|
||||
ret += rect[2].weight * (img[fastRect[2].p0] - img[fastRect[2].p1] - img[fastRect[2].p2] + img[fastRect[2].p3] );
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,186 @@
|
|||
#include "opencv2/core.hpp"
|
||||
#include "opencv2/core/core_c.h"
|
||||
#include "opencv2/imgproc.hpp"
|
||||
#include "opencv2/imgcodecs.hpp"
|
||||
|
||||
#include "imagestorage.h"
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
bool CvCascadeImageReader::create( const string _posFilename, const string _negFilename, Size _winSize )
|
||||
{
|
||||
return posReader.create(_posFilename) && negReader.create(_negFilename, _winSize);
|
||||
}
|
||||
|
||||
CvCascadeImageReader::NegReader::NegReader()
|
||||
{
|
||||
src.create( 0, 0 , CV_8UC1 );
|
||||
img.create( 0, 0, CV_8UC1 );
|
||||
point = offset = Point( 0, 0 );
|
||||
scale = 1.0F;
|
||||
scaleFactor = 1.4142135623730950488016887242097F;
|
||||
stepFactor = 0.5F;
|
||||
}
|
||||
|
||||
bool CvCascadeImageReader::NegReader::create( const string _filename, Size _winSize )
|
||||
{
|
||||
string str;
|
||||
std::ifstream file(_filename.c_str());
|
||||
if ( !file.is_open() )
|
||||
return false;
|
||||
|
||||
while( !file.eof() )
|
||||
{
|
||||
std::getline(file, str);
|
||||
str.erase(str.find_last_not_of(" \n\r\t")+1);
|
||||
if (str.empty()) break;
|
||||
if (str.at(0) == '#' ) continue; /* comment */
|
||||
imgFilenames.push_back(str);
|
||||
}
|
||||
file.close();
|
||||
|
||||
winSize = _winSize;
|
||||
last = round = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CvCascadeImageReader::NegReader::nextImg()
|
||||
{
|
||||
Point _offset = Point(0,0);
|
||||
size_t count = imgFilenames.size();
|
||||
for( size_t i = 0; i < count; i++ )
|
||||
{
|
||||
src = imread( imgFilenames[last++], 0 );
|
||||
if( src.empty() ){
|
||||
last %= count;
|
||||
continue;
|
||||
}
|
||||
round += last / count;
|
||||
round = round % (winSize.width * winSize.height);
|
||||
last %= count;
|
||||
|
||||
_offset.x = std::min( (int)round % winSize.width, src.cols - winSize.width );
|
||||
_offset.y = std::min( (int)round / winSize.width, src.rows - winSize.height );
|
||||
if( !src.empty() && src.type() == CV_8UC1
|
||||
&& _offset.x >= 0 && _offset.y >= 0 )
|
||||
break;
|
||||
}
|
||||
|
||||
if( src.empty() )
|
||||
return false; // no appropriate image
|
||||
point = offset = _offset;
|
||||
scale = max( ((float)winSize.width + point.x) / ((float)src.cols),
|
||||
((float)winSize.height + point.y) / ((float)src.rows) );
|
||||
|
||||
Size sz( (int)(scale*src.cols + 0.5F), (int)(scale*src.rows + 0.5F) );
|
||||
resize( src, img, sz, 0, 0, INTER_LINEAR_EXACT );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CvCascadeImageReader::NegReader::get( Mat& _img )
|
||||
{
|
||||
CV_Assert( !_img.empty() );
|
||||
CV_Assert( _img.type() == CV_8UC1 );
|
||||
CV_Assert( _img.cols == winSize.width );
|
||||
CV_Assert( _img.rows == winSize.height );
|
||||
|
||||
if( img.empty() )
|
||||
if ( !nextImg() )
|
||||
return false;
|
||||
|
||||
Mat mat( winSize.height, winSize.width, CV_8UC1,
|
||||
(void*)(img.ptr(point.y) + point.x * img.elemSize()), img.step );
|
||||
mat.copyTo(_img);
|
||||
|
||||
if( (int)( point.x + (1.0F + stepFactor ) * winSize.width ) < img.cols )
|
||||
point.x += (int)(stepFactor * winSize.width);
|
||||
else
|
||||
{
|
||||
point.x = offset.x;
|
||||
if( (int)( point.y + (1.0F + stepFactor ) * winSize.height ) < img.rows )
|
||||
point.y += (int)(stepFactor * winSize.height);
|
||||
else
|
||||
{
|
||||
point.y = offset.y;
|
||||
scale *= scaleFactor;
|
||||
if( scale <= 1.0F )
|
||||
resize( src, img, Size( (int)(scale*src.cols), (int)(scale*src.rows) ), 0, 0, INTER_LINEAR_EXACT );
|
||||
else
|
||||
{
|
||||
if ( !nextImg() )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
CvCascadeImageReader::PosReader::PosReader()
|
||||
{
|
||||
file = 0;
|
||||
vec = 0;
|
||||
}
|
||||
|
||||
bool CvCascadeImageReader::PosReader::create( const string _filename )
|
||||
{
|
||||
if ( file )
|
||||
fclose( file );
|
||||
file = fopen( _filename.c_str(), "rb" );
|
||||
|
||||
if( !file )
|
||||
return false;
|
||||
short tmp = 0;
|
||||
if( fread( &count, sizeof( count ), 1, file ) != 1 ||
|
||||
fread( &vecSize, sizeof( vecSize ), 1, file ) != 1 ||
|
||||
fread( &tmp, sizeof( tmp ), 1, file ) != 1 ||
|
||||
fread( &tmp, sizeof( tmp ), 1, file ) != 1 )
|
||||
CV_Error_( CV_StsParseError, ("wrong file format for %s\n", _filename.c_str()) );
|
||||
base = sizeof( count ) + sizeof( vecSize ) + 2*sizeof( tmp );
|
||||
if( feof( file ) )
|
||||
return false;
|
||||
last = 0;
|
||||
vec = (short*) cvAlloc( sizeof( *vec ) * vecSize );
|
||||
CV_Assert( vec );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CvCascadeImageReader::PosReader::get( Mat &_img )
|
||||
{
|
||||
CV_Assert( _img.rows * _img.cols == vecSize );
|
||||
uchar tmp = 0;
|
||||
size_t elements_read = fread( &tmp, sizeof( tmp ), 1, file );
|
||||
if( elements_read != 1 )
|
||||
CV_Error( CV_StsBadArg, "Can not get new positive sample. The most possible reason is "
|
||||
"insufficient count of samples in given vec-file.\n");
|
||||
elements_read = fread( vec, sizeof( vec[0] ), vecSize, file );
|
||||
if( elements_read != (size_t)(vecSize) )
|
||||
CV_Error( CV_StsBadArg, "Can not get new positive sample. Seems that vec-file has incorrect structure.\n");
|
||||
|
||||
if( feof( file ) || last++ >= count )
|
||||
CV_Error( CV_StsBadArg, "Can not get new positive sample. vec-file is over.\n");
|
||||
|
||||
for( int r = 0; r < _img.rows; r++ )
|
||||
{
|
||||
for( int c = 0; c < _img.cols; c++ )
|
||||
_img.ptr(r)[c] = (uchar)vec[r * _img.cols + c];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CvCascadeImageReader::PosReader::restart()
|
||||
{
|
||||
CV_Assert( file );
|
||||
last = 0;
|
||||
fseek( file, base, SEEK_SET );
|
||||
}
|
||||
|
||||
CvCascadeImageReader::PosReader::~PosReader()
|
||||
{
|
||||
if (file)
|
||||
fclose( file );
|
||||
cvFree( &vec );
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
#ifndef _OPENCV_IMAGESTORAGE_H_
|
||||
#define _OPENCV_IMAGESTORAGE_H_
|
||||
|
||||
|
||||
class CvCascadeImageReader
|
||||
{
|
||||
public:
|
||||
bool create( const std::string _posFilename, const std::string _negFilename, cv::Size _winSize );
|
||||
void restart() { posReader.restart(); }
|
||||
bool getNeg(cv::Mat &_img) { return negReader.get( _img ); }
|
||||
bool getPos(cv::Mat &_img) { return posReader.get( _img ); }
|
||||
|
||||
private:
|
||||
class PosReader
|
||||
{
|
||||
public:
|
||||
PosReader();
|
||||
virtual ~PosReader();
|
||||
bool create( const std::string _filename );
|
||||
bool get( cv::Mat &_img );
|
||||
void restart();
|
||||
|
||||
short* vec;
|
||||
FILE* file;
|
||||
int count;
|
||||
int vecSize;
|
||||
int last;
|
||||
int base;
|
||||
} posReader;
|
||||
|
||||
class NegReader
|
||||
{
|
||||
public:
|
||||
NegReader();
|
||||
bool create( const std::string _filename, cv::Size _winSize );
|
||||
bool get( cv::Mat& _img );
|
||||
bool nextImg();
|
||||
|
||||
cv::Mat src, img;
|
||||
std::vector<std::string> imgFilenames;
|
||||
cv::Point offset, point;
|
||||
float scale;
|
||||
float scaleFactor;
|
||||
float stepFactor;
|
||||
size_t last, round;
|
||||
cv::Size winSize;
|
||||
} negReader;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,67 @@
|
|||
#include "opencv2/core.hpp"
|
||||
#include "opencv2/imgproc.hpp"
|
||||
|
||||
#include "lbpfeatures.h"
|
||||
#include "cascadeclassifier.h"
|
||||
|
||||
using namespace cv;
|
||||
|
||||
CvLBPFeatureParams::CvLBPFeatureParams()
|
||||
{
|
||||
maxCatCount = 256;
|
||||
name = LBPF_NAME;
|
||||
}
|
||||
|
||||
void CvLBPEvaluator::init(const CvFeatureParams *_featureParams, int _maxSampleCount, Size _winSize)
|
||||
{
|
||||
CV_Assert( _maxSampleCount > 0);
|
||||
sum.create((int)_maxSampleCount, (_winSize.width + 1) * (_winSize.height + 1), CV_32SC1);
|
||||
CvFeatureEvaluator::init( _featureParams, _maxSampleCount, _winSize );
|
||||
}
|
||||
|
||||
void CvLBPEvaluator::setImage(const Mat &img, uchar clsLabel, int idx)
|
||||
{
|
||||
CV_DbgAssert( !sum.empty() );
|
||||
CvFeatureEvaluator::setImage( img, clsLabel, idx );
|
||||
Mat innSum(winSize.height + 1, winSize.width + 1, sum.type(), sum.ptr<int>((int)idx));
|
||||
integral( img, innSum );
|
||||
}
|
||||
|
||||
void CvLBPEvaluator::writeFeatures( FileStorage &fs, const Mat& featureMap ) const
|
||||
{
|
||||
_writeFeatures( features, fs, featureMap );
|
||||
}
|
||||
|
||||
void CvLBPEvaluator::generateFeatures()
|
||||
{
|
||||
int offset = winSize.width + 1;
|
||||
for( int x = 0; x < winSize.width; x++ )
|
||||
for( int y = 0; y < winSize.height; y++ )
|
||||
for( int w = 1; w <= winSize.width / 3; w++ )
|
||||
for( int h = 1; h <= winSize.height / 3; h++ )
|
||||
if ( (x+3*w <= winSize.width) && (y+3*h <= winSize.height) )
|
||||
features.push_back( Feature(offset, x, y, w, h ) );
|
||||
numFeatures = (int)features.size();
|
||||
}
|
||||
|
||||
CvLBPEvaluator::Feature::Feature()
|
||||
{
|
||||
rect = cvRect(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
CvLBPEvaluator::Feature::Feature( int offset, int x, int y, int _blockWidth, int _blockHeight )
|
||||
{
|
||||
Rect tr = rect = cvRect(x, y, _blockWidth, _blockHeight);
|
||||
CV_SUM_OFFSETS( p[0], p[1], p[4], p[5], tr, offset )
|
||||
tr.x += 2*rect.width;
|
||||
CV_SUM_OFFSETS( p[2], p[3], p[6], p[7], tr, offset )
|
||||
tr.y +=2*rect.height;
|
||||
CV_SUM_OFFSETS( p[10], p[11], p[14], p[15], tr, offset )
|
||||
tr.x -= 2*rect.width;
|
||||
CV_SUM_OFFSETS( p[8], p[9], p[12], p[13], tr, offset )
|
||||
}
|
||||
|
||||
void CvLBPEvaluator::Feature::write(FileStorage &fs) const
|
||||
{
|
||||
fs << CC_RECT << "[:" << rect.x << rect.y << rect.width << rect.height << "]";
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
#ifndef _OPENCV_LBPFEATURES_H_
|
||||
#define _OPENCV_LBPFEATURES_H_
|
||||
|
||||
#include "traincascade_features.h"
|
||||
|
||||
#define LBPF_NAME "lbpFeatureParams"
|
||||
struct CvLBPFeatureParams : CvFeatureParams
|
||||
{
|
||||
CvLBPFeatureParams();
|
||||
|
||||
};
|
||||
|
||||
class CvLBPEvaluator : public CvFeatureEvaluator
|
||||
{
|
||||
public:
|
||||
virtual ~CvLBPEvaluator() {}
|
||||
virtual void init(const CvFeatureParams *_featureParams,
|
||||
int _maxSampleCount, cv::Size _winSize );
|
||||
virtual void setImage(const cv::Mat& img, uchar clsLabel, int idx);
|
||||
virtual float operator()(int featureIdx, int sampleIdx) const
|
||||
{ return (float)features[featureIdx].calc( sum, sampleIdx); }
|
||||
virtual void writeFeatures( cv::FileStorage &fs, const cv::Mat& featureMap ) const;
|
||||
protected:
|
||||
virtual void generateFeatures();
|
||||
|
||||
class Feature
|
||||
{
|
||||
public:
|
||||
Feature();
|
||||
Feature( int offset, int x, int y, int _block_w, int _block_h );
|
||||
uchar calc( const cv::Mat& _sum, size_t y ) const;
|
||||
void write( cv::FileStorage &fs ) const;
|
||||
|
||||
cv::Rect rect;
|
||||
int p[16];
|
||||
};
|
||||
std::vector<Feature> features;
|
||||
|
||||
cv::Mat sum;
|
||||
};
|
||||
|
||||
inline uchar CvLBPEvaluator::Feature::calc(const cv::Mat &_sum, size_t y) const
|
||||
{
|
||||
const int* psum = _sum.ptr<int>((int)y);
|
||||
int cval = psum[p[5]] - psum[p[6]] - psum[p[9]] + psum[p[10]];
|
||||
|
||||
return (uchar)((psum[p[0]] - psum[p[1]] - psum[p[4]] + psum[p[5]] >= cval ? 128 : 0) | // 0
|
||||
(psum[p[1]] - psum[p[2]] - psum[p[5]] + psum[p[6]] >= cval ? 64 : 0) | // 1
|
||||
(psum[p[2]] - psum[p[3]] - psum[p[6]] + psum[p[7]] >= cval ? 32 : 0) | // 2
|
||||
(psum[p[6]] - psum[p[7]] - psum[p[10]] + psum[p[11]] >= cval ? 16 : 0) | // 5
|
||||
(psum[p[10]] - psum[p[11]] - psum[p[14]] + psum[p[15]] >= cval ? 8 : 0) | // 8
|
||||
(psum[p[9]] - psum[p[10]] - psum[p[13]] + psum[p[14]] >= cval ? 4 : 0) | // 7
|
||||
(psum[p[8]] - psum[p[9]] - psum[p[12]] + psum[p[13]] >= cval ? 2 : 0) | // 6
|
||||
(psum[p[4]] - psum[p[5]] - psum[p[8]] + psum[p[9]] >= cval ? 1 : 0)); // 3
|
||||
}
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,792 @@
|
|||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of Intel Corporation may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "old_ml_precomp.hpp"
|
||||
#include <ctype.h>
|
||||
|
||||
#define MISS_VAL FLT_MAX
|
||||
#define CV_VAR_MISS 0
|
||||
|
||||
CvTrainTestSplit::CvTrainTestSplit()
|
||||
{
|
||||
train_sample_part_mode = CV_COUNT;
|
||||
train_sample_part.count = -1;
|
||||
mix = false;
|
||||
}
|
||||
|
||||
CvTrainTestSplit::CvTrainTestSplit( int _train_sample_count, bool _mix )
|
||||
{
|
||||
train_sample_part_mode = CV_COUNT;
|
||||
train_sample_part.count = _train_sample_count;
|
||||
mix = _mix;
|
||||
}
|
||||
|
||||
CvTrainTestSplit::CvTrainTestSplit( float _train_sample_portion, bool _mix )
|
||||
{
|
||||
train_sample_part_mode = CV_PORTION;
|
||||
train_sample_part.portion = _train_sample_portion;
|
||||
mix = _mix;
|
||||
}
|
||||
|
||||
////////////////
|
||||
|
||||
CvMLData::CvMLData()
|
||||
{
|
||||
values = missing = var_types = var_idx_mask = response_out = var_idx_out = var_types_out = 0;
|
||||
train_sample_idx = test_sample_idx = 0;
|
||||
header_lines_number = 0;
|
||||
sample_idx = 0;
|
||||
response_idx = -1;
|
||||
|
||||
train_sample_count = -1;
|
||||
|
||||
delimiter = ',';
|
||||
miss_ch = '?';
|
||||
//flt_separator = '.';
|
||||
|
||||
rng = &cv::theRNG();
|
||||
}
|
||||
|
||||
CvMLData::~CvMLData()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
void CvMLData::free_train_test_idx()
|
||||
{
|
||||
cvReleaseMat( &train_sample_idx );
|
||||
cvReleaseMat( &test_sample_idx );
|
||||
sample_idx = 0;
|
||||
}
|
||||
|
||||
void CvMLData::clear()
|
||||
{
|
||||
class_map.clear();
|
||||
|
||||
cvReleaseMat( &values );
|
||||
cvReleaseMat( &missing );
|
||||
cvReleaseMat( &var_types );
|
||||
cvReleaseMat( &var_idx_mask );
|
||||
|
||||
cvReleaseMat( &response_out );
|
||||
cvReleaseMat( &var_idx_out );
|
||||
cvReleaseMat( &var_types_out );
|
||||
|
||||
free_train_test_idx();
|
||||
|
||||
total_class_count = 0;
|
||||
|
||||
response_idx = -1;
|
||||
|
||||
train_sample_count = -1;
|
||||
}
|
||||
|
||||
|
||||
void CvMLData::set_header_lines_number( int idx )
|
||||
{
|
||||
header_lines_number = std::max(0, idx);
|
||||
}
|
||||
|
||||
int CvMLData::get_header_lines_number() const
|
||||
{
|
||||
return header_lines_number;
|
||||
}
|
||||
|
||||
static char *fgets_chomp(char *str, int n, FILE *stream)
|
||||
{
|
||||
char *head = fgets(str, n, stream);
|
||||
if( head )
|
||||
{
|
||||
for(char *tail = head + strlen(head) - 1; tail >= head; --tail)
|
||||
{
|
||||
if( *tail != '\r' && *tail != '\n' )
|
||||
break;
|
||||
*tail = '\0';
|
||||
}
|
||||
}
|
||||
return head;
|
||||
}
|
||||
|
||||
|
||||
int CvMLData::read_csv(const char* filename)
|
||||
{
|
||||
const int M = 1000000;
|
||||
const char str_delimiter[3] = { ' ', delimiter, '\0' };
|
||||
FILE* file = 0;
|
||||
CvMemStorage* storage;
|
||||
CvSeq* seq;
|
||||
char *ptr;
|
||||
float* el_ptr;
|
||||
CvSeqReader reader;
|
||||
int cols_count = 0;
|
||||
uchar *var_types_ptr = 0;
|
||||
|
||||
clear();
|
||||
|
||||
file = fopen( filename, "rt" );
|
||||
|
||||
if( !file )
|
||||
return -1;
|
||||
|
||||
std::vector<char> _buf(M);
|
||||
char* buf = &_buf[0];
|
||||
|
||||
// skip header lines
|
||||
for( int i = 0; i < header_lines_number; i++ )
|
||||
{
|
||||
if( fgets( buf, M, file ) == 0 )
|
||||
{
|
||||
fclose(file);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// read the first data line and determine the number of variables
|
||||
if( !fgets_chomp( buf, M, file ))
|
||||
{
|
||||
fclose(file);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ptr = buf;
|
||||
while( *ptr == ' ' )
|
||||
ptr++;
|
||||
for( ; *ptr != '\0'; )
|
||||
{
|
||||
if(*ptr == delimiter || *ptr == ' ')
|
||||
{
|
||||
cols_count++;
|
||||
ptr++;
|
||||
while( *ptr == ' ' ) ptr++;
|
||||
}
|
||||
else
|
||||
ptr++;
|
||||
}
|
||||
|
||||
cols_count++;
|
||||
|
||||
if ( cols_count == 0)
|
||||
{
|
||||
fclose(file);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// create temporary memory storage to store the whole database
|
||||
el_ptr = new float[cols_count];
|
||||
storage = cvCreateMemStorage();
|
||||
seq = cvCreateSeq( 0, sizeof(*seq), cols_count*sizeof(float), storage );
|
||||
|
||||
var_types = cvCreateMat( 1, cols_count, CV_8U );
|
||||
cvZero( var_types );
|
||||
var_types_ptr = var_types->data.ptr;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
char *token = NULL;
|
||||
int type;
|
||||
token = strtok(buf, str_delimiter);
|
||||
if (!token)
|
||||
break;
|
||||
for (int i = 0; i < cols_count-1; i++)
|
||||
{
|
||||
str_to_flt_elem( token, el_ptr[i], type);
|
||||
var_types_ptr[i] |= type;
|
||||
token = strtok(NULL, str_delimiter);
|
||||
if (!token)
|
||||
{
|
||||
fclose(file);
|
||||
delete [] el_ptr;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
str_to_flt_elem( token, el_ptr[cols_count-1], type);
|
||||
var_types_ptr[cols_count-1] |= type;
|
||||
cvSeqPush( seq, el_ptr );
|
||||
if( !fgets_chomp( buf, M, file ) )
|
||||
break;
|
||||
}
|
||||
fclose(file);
|
||||
|
||||
values = cvCreateMat( seq->total, cols_count, CV_32FC1 );
|
||||
missing = cvCreateMat( seq->total, cols_count, CV_8U );
|
||||
var_idx_mask = cvCreateMat( 1, values->cols, CV_8UC1 );
|
||||
cvSet( var_idx_mask, cvRealScalar(1) );
|
||||
train_sample_count = seq->total;
|
||||
|
||||
cvStartReadSeq( seq, &reader );
|
||||
for(int i = 0; i < seq->total; i++ )
|
||||
{
|
||||
const float* sdata = (float*)reader.ptr;
|
||||
float* ddata = values->data.fl + cols_count*i;
|
||||
uchar* dm = missing->data.ptr + cols_count*i;
|
||||
|
||||
for( int j = 0; j < cols_count; j++ )
|
||||
{
|
||||
ddata[j] = sdata[j];
|
||||
dm[j] = ( fabs( MISS_VAL - sdata[j] ) <= FLT_EPSILON );
|
||||
}
|
||||
CV_NEXT_SEQ_ELEM( seq->elem_size, reader );
|
||||
}
|
||||
|
||||
if ( cvNorm( missing, 0, CV_L1 ) <= FLT_EPSILON )
|
||||
cvReleaseMat( &missing );
|
||||
|
||||
cvReleaseMemStorage( &storage );
|
||||
delete []el_ptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const CvMat* CvMLData::get_values() const
|
||||
{
|
||||
return values;
|
||||
}
|
||||
|
||||
const CvMat* CvMLData::get_missing() const
|
||||
{
|
||||
CV_FUNCNAME( "CvMLData::get_missing" );
|
||||
__BEGIN__;
|
||||
|
||||
if ( !values )
|
||||
CV_ERROR( CV_StsInternal, "data is empty" );
|
||||
|
||||
__END__;
|
||||
|
||||
return missing;
|
||||
}
|
||||
|
||||
const std::map<cv::String, int>& CvMLData::get_class_labels_map() const
|
||||
{
|
||||
return class_map;
|
||||
}
|
||||
|
||||
void CvMLData::str_to_flt_elem( const char* token, float& flt_elem, int& type)
|
||||
{
|
||||
|
||||
char* stopstring = NULL;
|
||||
flt_elem = (float)strtod( token, &stopstring );
|
||||
assert( stopstring );
|
||||
type = CV_VAR_ORDERED;
|
||||
if ( *stopstring == miss_ch && strlen(stopstring) == 1 ) // missed value
|
||||
{
|
||||
flt_elem = MISS_VAL;
|
||||
type = CV_VAR_MISS;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( (*stopstring != 0) && (*stopstring != '\n') && (strcmp(stopstring, "\r\n") != 0) ) // class label
|
||||
{
|
||||
int idx = class_map[token];
|
||||
if ( idx == 0)
|
||||
{
|
||||
total_class_count++;
|
||||
idx = total_class_count;
|
||||
class_map[token] = idx;
|
||||
}
|
||||
flt_elem = (float)idx;
|
||||
type = CV_VAR_CATEGORICAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CvMLData::set_delimiter(char ch)
|
||||
{
|
||||
CV_FUNCNAME( "CvMLData::set_delimited" );
|
||||
__BEGIN__;
|
||||
|
||||
if (ch == miss_ch /*|| ch == flt_separator*/)
|
||||
CV_ERROR(CV_StsBadArg, "delimited, miss_character and flt_separator must be different");
|
||||
|
||||
delimiter = ch;
|
||||
|
||||
__END__;
|
||||
}
|
||||
|
||||
char CvMLData::get_delimiter() const
|
||||
{
|
||||
return delimiter;
|
||||
}
|
||||
|
||||
void CvMLData::set_miss_ch(char ch)
|
||||
{
|
||||
CV_FUNCNAME( "CvMLData::set_miss_ch" );
|
||||
__BEGIN__;
|
||||
|
||||
if (ch == delimiter/* || ch == flt_separator*/)
|
||||
CV_ERROR(CV_StsBadArg, "delimited, miss_character and flt_separator must be different");
|
||||
|
||||
miss_ch = ch;
|
||||
|
||||
__END__;
|
||||
}
|
||||
|
||||
char CvMLData::get_miss_ch() const
|
||||
{
|
||||
return miss_ch;
|
||||
}
|
||||
|
||||
void CvMLData::set_response_idx( int idx )
|
||||
{
|
||||
CV_FUNCNAME( "CvMLData::set_response_idx" );
|
||||
__BEGIN__;
|
||||
|
||||
if ( !values )
|
||||
CV_ERROR( CV_StsInternal, "data is empty" );
|
||||
|
||||
if ( idx >= values->cols)
|
||||
CV_ERROR( CV_StsBadArg, "idx value is not correct" );
|
||||
|
||||
if ( response_idx >= 0 )
|
||||
chahge_var_idx( response_idx, true );
|
||||
if ( idx >= 0 )
|
||||
chahge_var_idx( idx, false );
|
||||
response_idx = idx;
|
||||
|
||||
__END__;
|
||||
}
|
||||
|
||||
int CvMLData::get_response_idx() const
|
||||
{
|
||||
CV_FUNCNAME( "CvMLData::get_response_idx" );
|
||||
__BEGIN__;
|
||||
|
||||
if ( !values )
|
||||
CV_ERROR( CV_StsInternal, "data is empty" );
|
||||
__END__;
|
||||
return response_idx;
|
||||
}
|
||||
|
||||
void CvMLData::change_var_type( int var_idx, int type )
|
||||
{
|
||||
CV_FUNCNAME( "CvMLData::change_var_type" );
|
||||
__BEGIN__;
|
||||
|
||||
int var_count = 0;
|
||||
|
||||
if ( !values )
|
||||
CV_ERROR( CV_StsInternal, "data is empty" );
|
||||
|
||||
var_count = values->cols;
|
||||
|
||||
if ( var_idx < 0 || var_idx >= var_count)
|
||||
CV_ERROR( CV_StsBadArg, "var_idx is not correct" );
|
||||
|
||||
if ( type != CV_VAR_ORDERED && type != CV_VAR_CATEGORICAL)
|
||||
CV_ERROR( CV_StsBadArg, "type is not correct" );
|
||||
|
||||
assert( var_types );
|
||||
if ( var_types->data.ptr[var_idx] == CV_VAR_CATEGORICAL && type == CV_VAR_ORDERED)
|
||||
CV_ERROR( CV_StsBadArg, "it`s impossible to assign CV_VAR_ORDERED type to categorical variable" );
|
||||
var_types->data.ptr[var_idx] = (uchar)type;
|
||||
|
||||
__END__;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void CvMLData::set_var_types( const char* str )
|
||||
{
|
||||
CV_FUNCNAME( "CvMLData::set_var_types" );
|
||||
__BEGIN__;
|
||||
|
||||
const char* ord = 0, *cat = 0;
|
||||
int var_count = 0, set_var_type_count = 0;
|
||||
if ( !values )
|
||||
CV_ERROR( CV_StsInternal, "data is empty" );
|
||||
|
||||
var_count = values->cols;
|
||||
|
||||
assert( var_types );
|
||||
|
||||
ord = strstr( str, "ord" );
|
||||
cat = strstr( str, "cat" );
|
||||
if ( !ord && !cat )
|
||||
CV_ERROR( CV_StsBadArg, "types string is not correct" );
|
||||
|
||||
if ( !ord && strlen(cat) == 3 ) // str == "cat"
|
||||
{
|
||||
cvSet( var_types, cvScalarAll(CV_VAR_CATEGORICAL) );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !cat && strlen(ord) == 3 ) // str == "ord"
|
||||
{
|
||||
cvSet( var_types, cvScalarAll(CV_VAR_ORDERED) );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ord ) // parse ord str
|
||||
{
|
||||
char* stopstring = NULL;
|
||||
if ( ord[3] != '[')
|
||||
CV_ERROR( CV_StsBadArg, "types string is not correct" );
|
||||
|
||||
ord += 4; // pass "ord["
|
||||
do
|
||||
{
|
||||
int b1 = (int)strtod( ord, &stopstring );
|
||||
if ( *stopstring == 0 || (*stopstring != ',' && *stopstring != ']' && *stopstring != '-') )
|
||||
CV_ERROR( CV_StsBadArg, "types string is not correct" );
|
||||
ord = stopstring + 1;
|
||||
if ( (stopstring[0] == ',') || (stopstring[0] == ']'))
|
||||
{
|
||||
if ( var_types->data.ptr[b1] == CV_VAR_CATEGORICAL)
|
||||
CV_ERROR( CV_StsBadArg, "it`s impossible to assign CV_VAR_ORDERED type to categorical variable" );
|
||||
var_types->data.ptr[b1] = CV_VAR_ORDERED;
|
||||
set_var_type_count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( stopstring[0] == '-')
|
||||
{
|
||||
int b2 = (int)strtod( ord, &stopstring);
|
||||
if ( (*stopstring == 0) || (*stopstring != ',' && *stopstring != ']') )
|
||||
CV_ERROR( CV_StsBadArg, "types string is not correct" );
|
||||
ord = stopstring + 1;
|
||||
for (int i = b1; i <= b2; i++)
|
||||
{
|
||||
if ( var_types->data.ptr[i] == CV_VAR_CATEGORICAL)
|
||||
CV_ERROR( CV_StsBadArg, "it`s impossible to assign CV_VAR_ORDERED type to categorical variable" );
|
||||
var_types->data.ptr[i] = CV_VAR_ORDERED;
|
||||
}
|
||||
set_var_type_count += b2 - b1 + 1;
|
||||
}
|
||||
else
|
||||
CV_ERROR( CV_StsBadArg, "types string is not correct" );
|
||||
|
||||
}
|
||||
}
|
||||
while (*stopstring != ']');
|
||||
|
||||
if ( stopstring[1] != '\0' && stopstring[1] != ',')
|
||||
CV_ERROR( CV_StsBadArg, "types string is not correct" );
|
||||
}
|
||||
|
||||
if ( cat ) // parse cat str
|
||||
{
|
||||
char* stopstring = NULL;
|
||||
if ( cat[3] != '[')
|
||||
CV_ERROR( CV_StsBadArg, "types string is not correct" );
|
||||
|
||||
cat += 4; // pass "cat["
|
||||
do
|
||||
{
|
||||
int b1 = (int)strtod( cat, &stopstring );
|
||||
if ( *stopstring == 0 || (*stopstring != ',' && *stopstring != ']' && *stopstring != '-') )
|
||||
CV_ERROR( CV_StsBadArg, "types string is not correct" );
|
||||
cat = stopstring + 1;
|
||||
if ( (stopstring[0] == ',') || (stopstring[0] == ']'))
|
||||
{
|
||||
var_types->data.ptr[b1] = CV_VAR_CATEGORICAL;
|
||||
set_var_type_count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( stopstring[0] == '-')
|
||||
{
|
||||
int b2 = (int)strtod( cat, &stopstring);
|
||||
if ( (*stopstring == 0) || (*stopstring != ',' && *stopstring != ']') )
|
||||
CV_ERROR( CV_StsBadArg, "types string is not correct" );
|
||||
cat = stopstring + 1;
|
||||
for (int i = b1; i <= b2; i++)
|
||||
var_types->data.ptr[i] = CV_VAR_CATEGORICAL;
|
||||
set_var_type_count += b2 - b1 + 1;
|
||||
}
|
||||
else
|
||||
CV_ERROR( CV_StsBadArg, "types string is not correct" );
|
||||
|
||||
}
|
||||
}
|
||||
while (*stopstring != ']');
|
||||
|
||||
if ( stopstring[1] != '\0' && stopstring[1] != ',')
|
||||
CV_ERROR( CV_StsBadArg, "types string is not correct" );
|
||||
}
|
||||
|
||||
if (set_var_type_count != var_count)
|
||||
CV_ERROR( CV_StsBadArg, "types string is not correct" );
|
||||
|
||||
__END__;
|
||||
}
|
||||
|
||||
const CvMat* CvMLData::get_var_types()
|
||||
{
|
||||
CV_FUNCNAME( "CvMLData::get_var_types" );
|
||||
__BEGIN__;
|
||||
|
||||
uchar *var_types_out_ptr = 0;
|
||||
int avcount, vt_size;
|
||||
if ( !values )
|
||||
CV_ERROR( CV_StsInternal, "data is empty" );
|
||||
|
||||
assert( var_idx_mask );
|
||||
|
||||
avcount = cvFloor( cvNorm( var_idx_mask, 0, CV_L1 ) );
|
||||
vt_size = avcount + (response_idx >= 0);
|
||||
|
||||
if ( avcount == values->cols || (avcount == values->cols-1 && response_idx == values->cols-1) )
|
||||
return var_types;
|
||||
|
||||
if ( !var_types_out || ( var_types_out && var_types_out->cols != vt_size ) )
|
||||
{
|
||||
cvReleaseMat( &var_types_out );
|
||||
var_types_out = cvCreateMat( 1, vt_size, CV_8UC1 );
|
||||
}
|
||||
|
||||
var_types_out_ptr = var_types_out->data.ptr;
|
||||
for( int i = 0; i < var_types->cols; i++)
|
||||
{
|
||||
if (i == response_idx || !var_idx_mask->data.ptr[i]) continue;
|
||||
*var_types_out_ptr = var_types->data.ptr[i];
|
||||
var_types_out_ptr++;
|
||||
}
|
||||
if ( response_idx >= 0 )
|
||||
*var_types_out_ptr = var_types->data.ptr[response_idx];
|
||||
|
||||
__END__;
|
||||
|
||||
return var_types_out;
|
||||
}
|
||||
|
||||
int CvMLData::get_var_type( int var_idx ) const
|
||||
{
|
||||
return var_types->data.ptr[var_idx];
|
||||
}
|
||||
|
||||
const CvMat* CvMLData::get_responses()
|
||||
{
|
||||
CV_FUNCNAME( "CvMLData::get_responses_ptr" );
|
||||
__BEGIN__;
|
||||
|
||||
int var_count = 0;
|
||||
|
||||
if ( !values )
|
||||
CV_ERROR( CV_StsInternal, "data is empty" );
|
||||
var_count = values->cols;
|
||||
|
||||
if ( response_idx < 0 || response_idx >= var_count )
|
||||
return 0;
|
||||
if ( !response_out )
|
||||
response_out = cvCreateMatHeader( values->rows, 1, CV_32FC1 );
|
||||
else
|
||||
cvInitMatHeader( response_out, values->rows, 1, CV_32FC1);
|
||||
cvGetCol( values, response_out, response_idx );
|
||||
|
||||
__END__;
|
||||
|
||||
return response_out;
|
||||
}
|
||||
|
||||
void CvMLData::set_train_test_split( const CvTrainTestSplit * spl)
|
||||
{
|
||||
CV_FUNCNAME( "CvMLData::set_division" );
|
||||
__BEGIN__;
|
||||
|
||||
int sample_count = 0;
|
||||
|
||||
if ( !values )
|
||||
CV_ERROR( CV_StsInternal, "data is empty" );
|
||||
|
||||
sample_count = values->rows;
|
||||
|
||||
float train_sample_portion;
|
||||
|
||||
if (spl->train_sample_part_mode == CV_COUNT)
|
||||
{
|
||||
train_sample_count = spl->train_sample_part.count;
|
||||
if (train_sample_count > sample_count)
|
||||
CV_ERROR( CV_StsBadArg, "train samples count is not correct" );
|
||||
train_sample_count = train_sample_count<=0 ? sample_count : train_sample_count;
|
||||
}
|
||||
else // dtype.train_sample_part_mode == CV_PORTION
|
||||
{
|
||||
train_sample_portion = spl->train_sample_part.portion;
|
||||
if ( train_sample_portion > 1)
|
||||
CV_ERROR( CV_StsBadArg, "train samples count is not correct" );
|
||||
train_sample_portion = train_sample_portion <= FLT_EPSILON ||
|
||||
1 - train_sample_portion <= FLT_EPSILON ? 1 : train_sample_portion;
|
||||
train_sample_count = std::max(1, cvFloor( train_sample_portion * sample_count ));
|
||||
}
|
||||
|
||||
if ( train_sample_count == sample_count )
|
||||
{
|
||||
free_train_test_idx();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( train_sample_idx && train_sample_idx->cols != train_sample_count )
|
||||
free_train_test_idx();
|
||||
|
||||
if ( !sample_idx)
|
||||
{
|
||||
int test_sample_count = sample_count- train_sample_count;
|
||||
sample_idx = (int*)cvAlloc( sample_count * sizeof(sample_idx[0]) );
|
||||
for (int i = 0; i < sample_count; i++ )
|
||||
sample_idx[i] = i;
|
||||
train_sample_idx = cvCreateMatHeader( 1, train_sample_count, CV_32SC1 );
|
||||
*train_sample_idx = cvMat( 1, train_sample_count, CV_32SC1, &sample_idx[0] );
|
||||
|
||||
CV_Assert(test_sample_count > 0);
|
||||
test_sample_idx = cvCreateMatHeader( 1, test_sample_count, CV_32SC1 );
|
||||
*test_sample_idx = cvMat( 1, test_sample_count, CV_32SC1, &sample_idx[train_sample_count] );
|
||||
}
|
||||
|
||||
mix = spl->mix;
|
||||
if ( mix )
|
||||
mix_train_and_test_idx();
|
||||
|
||||
__END__;
|
||||
}
|
||||
|
||||
const CvMat* CvMLData::get_train_sample_idx() const
|
||||
{
|
||||
CV_FUNCNAME( "CvMLData::get_train_sample_idx" );
|
||||
__BEGIN__;
|
||||
|
||||
if ( !values )
|
||||
CV_ERROR( CV_StsInternal, "data is empty" );
|
||||
__END__;
|
||||
|
||||
return train_sample_idx;
|
||||
}
|
||||
|
||||
const CvMat* CvMLData::get_test_sample_idx() const
|
||||
{
|
||||
CV_FUNCNAME( "CvMLData::get_test_sample_idx" );
|
||||
__BEGIN__;
|
||||
|
||||
if ( !values )
|
||||
CV_ERROR( CV_StsInternal, "data is empty" );
|
||||
__END__;
|
||||
|
||||
return test_sample_idx;
|
||||
}
|
||||
|
||||
void CvMLData::mix_train_and_test_idx()
|
||||
{
|
||||
CV_FUNCNAME( "CvMLData::mix_train_and_test_idx" );
|
||||
__BEGIN__;
|
||||
|
||||
if ( !values )
|
||||
CV_ERROR( CV_StsInternal, "data is empty" );
|
||||
__END__;
|
||||
|
||||
if ( !sample_idx)
|
||||
return;
|
||||
|
||||
if ( train_sample_count > 0 && train_sample_count < values->rows )
|
||||
{
|
||||
int n = values->rows;
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
int a = (*rng)(n);
|
||||
int b = (*rng)(n);
|
||||
int t;
|
||||
CV_SWAP( sample_idx[a], sample_idx[b], t );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const CvMat* CvMLData::get_var_idx()
|
||||
{
|
||||
CV_FUNCNAME( "CvMLData::get_var_idx" );
|
||||
__BEGIN__;
|
||||
|
||||
int avcount = 0;
|
||||
|
||||
if ( !values )
|
||||
CV_ERROR( CV_StsInternal, "data is empty" );
|
||||
|
||||
assert( var_idx_mask );
|
||||
|
||||
avcount = cvFloor( cvNorm( var_idx_mask, 0, CV_L1 ) );
|
||||
int* vidx;
|
||||
|
||||
if ( avcount == values->cols )
|
||||
return 0;
|
||||
|
||||
if ( !var_idx_out || ( var_idx_out && var_idx_out->cols != avcount ) )
|
||||
{
|
||||
cvReleaseMat( &var_idx_out );
|
||||
var_idx_out = cvCreateMat( 1, avcount, CV_32SC1);
|
||||
if ( response_idx >=0 )
|
||||
var_idx_mask->data.ptr[response_idx] = 0;
|
||||
}
|
||||
|
||||
vidx = var_idx_out->data.i;
|
||||
|
||||
for(int i = 0; i < var_idx_mask->cols; i++)
|
||||
if ( var_idx_mask->data.ptr[i] )
|
||||
{
|
||||
*vidx = i;
|
||||
vidx++;
|
||||
}
|
||||
|
||||
__END__;
|
||||
|
||||
return var_idx_out;
|
||||
}
|
||||
|
||||
void CvMLData::chahge_var_idx( int vi, bool state )
|
||||
{
|
||||
change_var_idx( vi, state );
|
||||
}
|
||||
|
||||
void CvMLData::change_var_idx( int vi, bool state )
|
||||
{
|
||||
CV_FUNCNAME( "CvMLData::change_var_idx" );
|
||||
__BEGIN__;
|
||||
|
||||
int var_count = 0;
|
||||
|
||||
if ( !values )
|
||||
CV_ERROR( CV_StsInternal, "data is empty" );
|
||||
|
||||
var_count = values->cols;
|
||||
|
||||
if ( vi < 0 || vi >= var_count)
|
||||
CV_ERROR( CV_StsBadArg, "variable index is not correct" );
|
||||
|
||||
assert( var_idx_mask );
|
||||
var_idx_mask->data.ptr[vi] = state;
|
||||
|
||||
__END__;
|
||||
}
|
||||
|
||||
/* End of file. */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,376 @@
|
|||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// Intel License Agreement
|
||||
//
|
||||
// Copyright (C) 2000, Intel Corporation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of Intel Corporation may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#ifndef OPENCV_PRECOMP_H
|
||||
#define OPENCV_PRECOMP_H
|
||||
|
||||
#include "opencv2/core.hpp"
|
||||
#include "old_ml.hpp"
|
||||
#include "opencv2/core/core_c.h"
|
||||
#include "opencv2/core/utility.hpp"
|
||||
|
||||
#include "opencv2/core/private.hpp"
|
||||
|
||||
#include <assert.h>
|
||||
#include <float.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#define ML_IMPL CV_IMPL
|
||||
#define __BEGIN__ __CV_BEGIN__
|
||||
#define __END__ __CV_END__
|
||||
#define EXIT __CV_EXIT__
|
||||
|
||||
#define CV_MAT_ELEM_FLAG( mat, type, comp, vect, tflag ) \
|
||||
(( tflag == CV_ROW_SAMPLE ) \
|
||||
? (CV_MAT_ELEM( mat, type, comp, vect )) \
|
||||
: (CV_MAT_ELEM( mat, type, vect, comp )))
|
||||
|
||||
/* Convert matrix to vector */
|
||||
#define ICV_MAT2VEC( mat, vdata, vstep, num ) \
|
||||
if( MIN( (mat).rows, (mat).cols ) != 1 ) \
|
||||
CV_ERROR( CV_StsBadArg, "" ); \
|
||||
(vdata) = ((mat).data.ptr); \
|
||||
if( (mat).rows == 1 ) \
|
||||
{ \
|
||||
(vstep) = CV_ELEM_SIZE( (mat).type ); \
|
||||
(num) = (mat).cols; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
(vstep) = (mat).step; \
|
||||
(num) = (mat).rows; \
|
||||
}
|
||||
|
||||
/* get raw data */
|
||||
#define ICV_RAWDATA( mat, flags, rdata, sstep, cstep, m, n ) \
|
||||
(rdata) = (mat).data.ptr; \
|
||||
if( CV_IS_ROW_SAMPLE( flags ) ) \
|
||||
{ \
|
||||
(sstep) = (mat).step; \
|
||||
(cstep) = CV_ELEM_SIZE( (mat).type ); \
|
||||
(m) = (mat).rows; \
|
||||
(n) = (mat).cols; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
(cstep) = (mat).step; \
|
||||
(sstep) = CV_ELEM_SIZE( (mat).type ); \
|
||||
(n) = (mat).rows; \
|
||||
(m) = (mat).cols; \
|
||||
}
|
||||
|
||||
#define ICV_IS_MAT_OF_TYPE( mat, mat_type) \
|
||||
(CV_IS_MAT( mat ) && CV_MAT_TYPE( mat->type ) == (mat_type) && \
|
||||
(mat)->cols > 0 && (mat)->rows > 0)
|
||||
|
||||
/*
|
||||
uchar* data; int sstep, cstep; - trainData->data
|
||||
uchar* classes; int clstep; int ncl;- trainClasses
|
||||
uchar* tmask; int tmstep; int ntm; - typeMask
|
||||
uchar* missed;int msstep, mcstep; -missedMeasurements...
|
||||
int mm, mn; == m,n == size,dim
|
||||
uchar* sidx;int sistep; - sampleIdx
|
||||
uchar* cidx;int cistep; - compIdx
|
||||
int k, l; == n,m == dim,size (length of cidx, sidx)
|
||||
int m, n; == size,dim
|
||||
*/
|
||||
#define ICV_DECLARE_TRAIN_ARGS() \
|
||||
uchar* data; \
|
||||
int sstep, cstep; \
|
||||
uchar* classes; \
|
||||
int clstep; \
|
||||
int ncl; \
|
||||
uchar* tmask; \
|
||||
int tmstep; \
|
||||
int ntm; \
|
||||
uchar* missed; \
|
||||
int msstep, mcstep; \
|
||||
int mm, mn; \
|
||||
uchar* sidx; \
|
||||
int sistep; \
|
||||
uchar* cidx; \
|
||||
int cistep; \
|
||||
int k, l; \
|
||||
int m, n; \
|
||||
\
|
||||
data = classes = tmask = missed = sidx = cidx = NULL; \
|
||||
sstep = cstep = clstep = ncl = tmstep = ntm = msstep = mcstep = mm = mn = 0; \
|
||||
sistep = cistep = k = l = m = n = 0;
|
||||
|
||||
#define ICV_TRAIN_DATA_REQUIRED( param, flags ) \
|
||||
if( !ICV_IS_MAT_OF_TYPE( (param), CV_32FC1 ) ) \
|
||||
{ \
|
||||
CV_ERROR( CV_StsBadArg, "Invalid " #param " parameter" ); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
ICV_RAWDATA( *(param), (flags), data, sstep, cstep, m, n ); \
|
||||
k = n; \
|
||||
l = m; \
|
||||
}
|
||||
|
||||
#define ICV_TRAIN_CLASSES_REQUIRED( param ) \
|
||||
if( !ICV_IS_MAT_OF_TYPE( (param), CV_32FC1 ) ) \
|
||||
{ \
|
||||
CV_ERROR( CV_StsBadArg, "Invalid " #param " parameter" ); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
ICV_MAT2VEC( *(param), classes, clstep, ncl ); \
|
||||
if( m != ncl ) \
|
||||
{ \
|
||||
CV_ERROR( CV_StsBadArg, "Unmatched sizes" ); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define ICV_ARG_NULL( param ) \
|
||||
if( (param) != NULL ) \
|
||||
{ \
|
||||
CV_ERROR( CV_StsBadArg, #param " parameter must be NULL" ); \
|
||||
}
|
||||
|
||||
#define ICV_MISSED_MEASUREMENTS_OPTIONAL( param, flags ) \
|
||||
if( param ) \
|
||||
{ \
|
||||
if( !ICV_IS_MAT_OF_TYPE( param, CV_8UC1 ) ) \
|
||||
{ \
|
||||
CV_ERROR( CV_StsBadArg, "Invalid " #param " parameter" ); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
ICV_RAWDATA( *(param), (flags), missed, msstep, mcstep, mm, mn ); \
|
||||
if( mm != m || mn != n ) \
|
||||
{ \
|
||||
CV_ERROR( CV_StsBadArg, "Unmatched sizes" ); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define ICV_COMP_IDX_OPTIONAL( param ) \
|
||||
if( param ) \
|
||||
{ \
|
||||
if( !ICV_IS_MAT_OF_TYPE( param, CV_32SC1 ) ) \
|
||||
{ \
|
||||
CV_ERROR( CV_StsBadArg, "Invalid " #param " parameter" ); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
ICV_MAT2VEC( *(param), cidx, cistep, k ); \
|
||||
if( k > n ) \
|
||||
CV_ERROR( CV_StsBadArg, "Invalid " #param " parameter" ); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define ICV_SAMPLE_IDX_OPTIONAL( param ) \
|
||||
if( param ) \
|
||||
{ \
|
||||
if( !ICV_IS_MAT_OF_TYPE( param, CV_32SC1 ) ) \
|
||||
{ \
|
||||
CV_ERROR( CV_StsBadArg, "Invalid " #param " parameter" ); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
ICV_MAT2VEC( *sampleIdx, sidx, sistep, l ); \
|
||||
if( l > m ) \
|
||||
CV_ERROR( CV_StsBadArg, "Invalid " #param " parameter" ); \
|
||||
} \
|
||||
}
|
||||
|
||||
/****************************************************************************************/
|
||||
#define ICV_CONVERT_FLOAT_ARRAY_TO_MATRICE( array, matrice ) \
|
||||
{ \
|
||||
CvMat a, b; \
|
||||
int dims = (matrice)->cols; \
|
||||
int nsamples = (matrice)->rows; \
|
||||
int type = CV_MAT_TYPE((matrice)->type); \
|
||||
int i, offset = dims; \
|
||||
\
|
||||
CV_ASSERT( type == CV_32FC1 || type == CV_64FC1 ); \
|
||||
offset *= ((type == CV_32FC1) ? sizeof(float) : sizeof(double));\
|
||||
\
|
||||
b = cvMat( 1, dims, CV_32FC1 ); \
|
||||
cvGetRow( matrice, &a, 0 ); \
|
||||
for( i = 0; i < nsamples; i++, a.data.ptr += offset ) \
|
||||
{ \
|
||||
b.data.fl = (float*)array[i]; \
|
||||
CV_CALL( cvConvert( &b, &a ) ); \
|
||||
} \
|
||||
}
|
||||
|
||||
/****************************************************************************************\
|
||||
* Auxiliary functions declarations *
|
||||
\****************************************************************************************/
|
||||
|
||||
/* Generates a set of classes centers in quantity <num_of_clusters> that are generated as
|
||||
uniform random vectors in parallelepiped, where <data> is concentrated. Vectors in
|
||||
<data> should have horizontal orientation. If <centers> != NULL, the function doesn't
|
||||
allocate any memory and stores generated centers in <centers>, returns <centers>.
|
||||
If <centers> == NULL, the function allocates memory and creates the matrice. Centers
|
||||
are supposed to be oriented horizontally. */
|
||||
CvMat* icvGenerateRandomClusterCenters( int seed,
|
||||
const CvMat* data,
|
||||
int num_of_clusters,
|
||||
CvMat* centers CV_DEFAULT(0));
|
||||
|
||||
/* Fills the <labels> using <probs> by choosing the maximal probability. Outliers are
|
||||
fixed by <oulier_tresh> and have cluster label (-1). Function also controls that there
|
||||
weren't "empty" clusters by filling empty clusters with the maximal probability vector.
|
||||
If probs_sums != NULL, fills it with the sums of probabilities for each sample (it is
|
||||
useful for normalizing probabilities' matrice of FCM) */
|
||||
void icvFindClusterLabels( const CvMat* probs, float outlier_thresh, float r,
|
||||
const CvMat* labels );
|
||||
|
||||
typedef struct CvSparseVecElem32f
|
||||
{
|
||||
int idx;
|
||||
float val;
|
||||
}
|
||||
CvSparseVecElem32f;
|
||||
|
||||
/* Prepare training data and related parameters */
|
||||
#define CV_TRAIN_STATMODEL_DEFRAGMENT_TRAIN_DATA 1
|
||||
#define CV_TRAIN_STATMODEL_SAMPLES_AS_ROWS 2
|
||||
#define CV_TRAIN_STATMODEL_SAMPLES_AS_COLUMNS 4
|
||||
#define CV_TRAIN_STATMODEL_CATEGORICAL_RESPONSE 8
|
||||
#define CV_TRAIN_STATMODEL_ORDERED_RESPONSE 16
|
||||
#define CV_TRAIN_STATMODEL_RESPONSES_ON_OUTPUT 32
|
||||
#define CV_TRAIN_STATMODEL_ALWAYS_COPY_TRAIN_DATA 64
|
||||
#define CV_TRAIN_STATMODEL_SPARSE_AS_SPARSE 128
|
||||
|
||||
int
|
||||
cvPrepareTrainData( const char* /*funcname*/,
|
||||
const CvMat* train_data, int tflag,
|
||||
const CvMat* responses, int response_type,
|
||||
const CvMat* var_idx,
|
||||
const CvMat* sample_idx,
|
||||
bool always_copy_data,
|
||||
const float*** out_train_samples,
|
||||
int* _sample_count,
|
||||
int* _var_count,
|
||||
int* _var_all,
|
||||
CvMat** out_responses,
|
||||
CvMat** out_response_map,
|
||||
CvMat** out_var_idx,
|
||||
CvMat** out_sample_idx=0 );
|
||||
|
||||
void
|
||||
cvSortSamplesByClasses( const float** samples, const CvMat* classes,
|
||||
int* class_ranges, const uchar** mask CV_DEFAULT(0) );
|
||||
|
||||
void
|
||||
cvCombineResponseMaps (CvMat* _responses,
|
||||
const CvMat* old_response_map,
|
||||
CvMat* new_response_map,
|
||||
CvMat** out_response_map);
|
||||
|
||||
void
|
||||
cvPreparePredictData( const CvArr* sample, int dims_all, const CvMat* comp_idx,
|
||||
int class_count, const CvMat* prob, float** row_sample,
|
||||
int as_sparse CV_DEFAULT(0) );
|
||||
|
||||
/* copies clustering [or batch "predict"] results
|
||||
(labels and/or centers and/or probs) back to the output arrays */
|
||||
void
|
||||
cvWritebackLabels( const CvMat* labels, CvMat* dst_labels,
|
||||
const CvMat* centers, CvMat* dst_centers,
|
||||
const CvMat* probs, CvMat* dst_probs,
|
||||
const CvMat* sample_idx, int samples_all,
|
||||
const CvMat* comp_idx, int dims_all );
|
||||
#define cvWritebackResponses cvWritebackLabels
|
||||
|
||||
#define XML_FIELD_NAME "_name"
|
||||
CvFileNode* icvFileNodeGetChild(CvFileNode* father, const char* name);
|
||||
CvFileNode* icvFileNodeGetChildArrayElem(CvFileNode* father, const char* name,int index);
|
||||
CvFileNode* icvFileNodeGetNext(CvFileNode* n, const char* name);
|
||||
|
||||
|
||||
void cvCheckTrainData( const CvMat* train_data, int tflag,
|
||||
const CvMat* missing_mask,
|
||||
int* var_all, int* sample_all );
|
||||
|
||||
CvMat* cvPreprocessIndexArray( const CvMat* idx_arr, int data_arr_size, bool check_for_duplicates=false );
|
||||
|
||||
CvMat* cvPreprocessVarType( const CvMat* type_mask, const CvMat* var_idx,
|
||||
int var_all, int* response_type );
|
||||
|
||||
CvMat* cvPreprocessOrderedResponses( const CvMat* responses,
|
||||
const CvMat* sample_idx, int sample_all );
|
||||
|
||||
CvMat* cvPreprocessCategoricalResponses( const CvMat* responses,
|
||||
const CvMat* sample_idx, int sample_all,
|
||||
CvMat** out_response_map, CvMat** class_counts=0 );
|
||||
|
||||
const float** cvGetTrainSamples( const CvMat* train_data, int tflag,
|
||||
const CvMat* var_idx, const CvMat* sample_idx,
|
||||
int* _var_count, int* _sample_count,
|
||||
bool always_copy_data=false );
|
||||
|
||||
namespace cv
|
||||
{
|
||||
struct DTreeBestSplitFinder
|
||||
{
|
||||
DTreeBestSplitFinder(){ splitSize = 0, tree = 0; node = 0; }
|
||||
DTreeBestSplitFinder( CvDTree* _tree, CvDTreeNode* _node);
|
||||
DTreeBestSplitFinder( const DTreeBestSplitFinder& finder, Split );
|
||||
virtual ~DTreeBestSplitFinder() {}
|
||||
virtual void operator()(const BlockedRange& range);
|
||||
void join( DTreeBestSplitFinder& rhs );
|
||||
Ptr<CvDTreeSplit> bestSplit;
|
||||
Ptr<CvDTreeSplit> split;
|
||||
int splitSize;
|
||||
CvDTree* tree;
|
||||
CvDTreeNode* node;
|
||||
};
|
||||
|
||||
struct ForestTreeBestSplitFinder : DTreeBestSplitFinder
|
||||
{
|
||||
ForestTreeBestSplitFinder() : DTreeBestSplitFinder() {}
|
||||
ForestTreeBestSplitFinder( CvForestTree* _tree, CvDTreeNode* _node );
|
||||
ForestTreeBestSplitFinder( const ForestTreeBestSplitFinder& finder, Split );
|
||||
virtual void operator()(const BlockedRange& range);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* __ML_H__ */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,129 @@
|
|||
#include "opencv2/core.hpp"
|
||||
#include "cascadeclassifier.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
/*
|
||||
traincascade.cpp is the source file of the program used for cascade training.
|
||||
User has to provide training input in form of positive and negative training images,
|
||||
and other data related to training in form of command line argument.
|
||||
*/
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
CvCascadeClassifier classifier;
|
||||
string cascadeDirName, vecName, bgName;
|
||||
int numPos = 2000;
|
||||
int numNeg = 1000;
|
||||
int numStages = 20;
|
||||
int numThreads = getNumThreads();
|
||||
int precalcValBufSize = 1024,
|
||||
precalcIdxBufSize = 1024;
|
||||
bool baseFormatSave = false;
|
||||
double acceptanceRatioBreakValue = -1.0;
|
||||
|
||||
CvCascadeParams cascadeParams;
|
||||
CvCascadeBoostParams stageParams;
|
||||
Ptr<CvFeatureParams> featureParams[] = { makePtr<CvHaarFeatureParams>(),
|
||||
makePtr<CvLBPFeatureParams>(),
|
||||
makePtr<CvHOGFeatureParams>()
|
||||
};
|
||||
int fc = sizeof(featureParams)/sizeof(featureParams[0]);
|
||||
if( argc == 1 )
|
||||
{
|
||||
cout << "Usage: " << argv[0] << endl;
|
||||
cout << " -data <cascade_dir_name>" << endl;
|
||||
cout << " -vec <vec_file_name>" << endl;
|
||||
cout << " -bg <background_file_name>" << endl;
|
||||
cout << " [-numPos <number_of_positive_samples = " << numPos << ">]" << endl;
|
||||
cout << " [-numNeg <number_of_negative_samples = " << numNeg << ">]" << endl;
|
||||
cout << " [-numStages <number_of_stages = " << numStages << ">]" << endl;
|
||||
cout << " [-precalcValBufSize <precalculated_vals_buffer_size_in_Mb = " << precalcValBufSize << ">]" << endl;
|
||||
cout << " [-precalcIdxBufSize <precalculated_idxs_buffer_size_in_Mb = " << precalcIdxBufSize << ">]" << endl;
|
||||
cout << " [-baseFormatSave]" << endl;
|
||||
cout << " [-numThreads <max_number_of_threads = " << numThreads << ">]" << endl;
|
||||
cout << " [-acceptanceRatioBreakValue <value> = " << acceptanceRatioBreakValue << ">]" << endl;
|
||||
cascadeParams.printDefaults();
|
||||
stageParams.printDefaults();
|
||||
for( int fi = 0; fi < fc; fi++ )
|
||||
featureParams[fi]->printDefaults();
|
||||
return 0;
|
||||
}
|
||||
|
||||
for( int i = 1; i < argc; i++ )
|
||||
{
|
||||
bool set = false;
|
||||
if( !strcmp( argv[i], "-data" ) )
|
||||
{
|
||||
cascadeDirName = argv[++i];
|
||||
}
|
||||
else if( !strcmp( argv[i], "-vec" ) )
|
||||
{
|
||||
vecName = argv[++i];
|
||||
}
|
||||
else if( !strcmp( argv[i], "-bg" ) )
|
||||
{
|
||||
bgName = argv[++i];
|
||||
}
|
||||
else if( !strcmp( argv[i], "-numPos" ) )
|
||||
{
|
||||
numPos = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-numNeg" ) )
|
||||
{
|
||||
numNeg = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-numStages" ) )
|
||||
{
|
||||
numStages = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-precalcValBufSize" ) )
|
||||
{
|
||||
precalcValBufSize = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-precalcIdxBufSize" ) )
|
||||
{
|
||||
precalcIdxBufSize = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-baseFormatSave" ) )
|
||||
{
|
||||
baseFormatSave = true;
|
||||
}
|
||||
else if( !strcmp( argv[i], "-numThreads" ) )
|
||||
{
|
||||
numThreads = atoi(argv[++i]);
|
||||
}
|
||||
else if( !strcmp( argv[i], "-acceptanceRatioBreakValue" ) )
|
||||
{
|
||||
acceptanceRatioBreakValue = atof(argv[++i]);
|
||||
}
|
||||
else if ( cascadeParams.scanAttr( argv[i], argv[i+1] ) ) { i++; }
|
||||
else if ( stageParams.scanAttr( argv[i], argv[i+1] ) ) { i++; }
|
||||
else if ( !set )
|
||||
{
|
||||
for( int fi = 0; fi < fc; fi++ )
|
||||
{
|
||||
set = featureParams[fi]->scanAttr(argv[i], argv[i+1]);
|
||||
if ( !set )
|
||||
{
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setNumThreads( numThreads );
|
||||
classifier.train( cascadeDirName,
|
||||
vecName,
|
||||
bgName,
|
||||
numPos, numNeg,
|
||||
precalcValBufSize, precalcIdxBufSize,
|
||||
numStages,
|
||||
cascadeParams,
|
||||
*featureParams[cascadeParams.featureType],
|
||||
stageParams,
|
||||
baseFormatSave,
|
||||
acceptanceRatioBreakValue );
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
#ifndef _OPENCV_FEATURES_H_
|
||||
#define _OPENCV_FEATURES_H_
|
||||
|
||||
#include "imagestorage.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define FEATURES "features"
|
||||
|
||||
#define CV_SUM_OFFSETS( p0, p1, p2, p3, rect, step ) \
|
||||
/* (x, y) */ \
|
||||
(p0) = (rect).x + (step) * (rect).y; \
|
||||
/* (x + w, y) */ \
|
||||
(p1) = (rect).x + (rect).width + (step) * (rect).y; \
|
||||
/* (x + w, y) */ \
|
||||
(p2) = (rect).x + (step) * ((rect).y + (rect).height); \
|
||||
/* (x + w, y + h) */ \
|
||||
(p3) = (rect).x + (rect).width + (step) * ((rect).y + (rect).height);
|
||||
|
||||
#define CV_TILTED_OFFSETS( p0, p1, p2, p3, rect, step ) \
|
||||
/* (x, y) */ \
|
||||
(p0) = (rect).x + (step) * (rect).y; \
|
||||
/* (x - h, y + h) */ \
|
||||
(p1) = (rect).x - (rect).height + (step) * ((rect).y + (rect).height);\
|
||||
/* (x + w, y + w) */ \
|
||||
(p2) = (rect).x + (rect).width + (step) * ((rect).y + (rect).width); \
|
||||
/* (x + w - h, y + w + h) */ \
|
||||
(p3) = (rect).x + (rect).width - (rect).height \
|
||||
+ (step) * ((rect).y + (rect).width + (rect).height);
|
||||
|
||||
float calcNormFactor( const cv::Mat& sum, const cv::Mat& sqSum );
|
||||
|
||||
template<class Feature>
|
||||
void _writeFeatures( const std::vector<Feature> features, cv::FileStorage &fs, const cv::Mat& featureMap )
|
||||
{
|
||||
fs << FEATURES << "[";
|
||||
const cv::Mat_<int>& featureMap_ = (const cv::Mat_<int>&)featureMap;
|
||||
for ( int fi = 0; fi < featureMap.cols; fi++ )
|
||||
if ( featureMap_(0, fi) >= 0 )
|
||||
{
|
||||
fs << "{";
|
||||
features[fi].write( fs );
|
||||
fs << "}";
|
||||
}
|
||||
fs << "]";
|
||||
}
|
||||
|
||||
class CvParams
|
||||
{
|
||||
public:
|
||||
CvParams();
|
||||
virtual ~CvParams() {}
|
||||
// from|to file
|
||||
virtual void write( cv::FileStorage &fs ) const = 0;
|
||||
virtual bool read( const cv::FileNode &node ) = 0;
|
||||
// from|to screen
|
||||
virtual void printDefaults() const;
|
||||
virtual void printAttrs() const;
|
||||
virtual bool scanAttr( const std::string prmName, const std::string val );
|
||||
std::string name;
|
||||
};
|
||||
|
||||
class CvFeatureParams : public CvParams
|
||||
{
|
||||
public:
|
||||
enum { HAAR = 0, LBP = 1, HOG = 2 };
|
||||
CvFeatureParams();
|
||||
virtual void init( const CvFeatureParams& fp );
|
||||
virtual void write( cv::FileStorage &fs ) const;
|
||||
virtual bool read( const cv::FileNode &node );
|
||||
static cv::Ptr<CvFeatureParams> create( int featureType );
|
||||
int maxCatCount; // 0 in case of numerical features
|
||||
int featSize; // 1 in case of simple features (HAAR, LBP) and N_BINS(9)*N_CELLS(4) in case of Dalal's HOG features
|
||||
};
|
||||
|
||||
class CvFeatureEvaluator
|
||||
{
|
||||
public:
|
||||
virtual ~CvFeatureEvaluator() {}
|
||||
virtual void init(const CvFeatureParams *_featureParams,
|
||||
int _maxSampleCount, cv::Size _winSize );
|
||||
virtual void setImage(const cv::Mat& img, uchar clsLabel, int idx);
|
||||
virtual void writeFeatures( cv::FileStorage &fs, const cv::Mat& featureMap ) const = 0;
|
||||
virtual float operator()(int featureIdx, int sampleIdx) const = 0;
|
||||
static cv::Ptr<CvFeatureEvaluator> create(int type);
|
||||
|
||||
int getNumFeatures() const { return numFeatures; }
|
||||
int getMaxCatCount() const { return featureParams->maxCatCount; }
|
||||
int getFeatureSize() const { return featureParams->featSize; }
|
||||
const cv::Mat& getCls() const { return cls; }
|
||||
float getCls(int si) const { return cls.at<float>(si, 0); }
|
||||
protected:
|
||||
virtual void generateFeatures() = 0;
|
||||
|
||||
int npos, nneg;
|
||||
int numFeatures;
|
||||
cv::Size winSize;
|
||||
CvFeatureParams *featureParams;
|
||||
cv::Mat cls;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,5 @@
|
|||
ocv_add_application(opencv_version MODULES opencv_core SRCS opencv_version.cpp)
|
||||
if(WIN32)
|
||||
ocv_add_application(opencv_version_win32 MODULES opencv_core SRCS opencv_version.cpp)
|
||||
target_compile_definitions(opencv_version_win32 PRIVATE "OPENCV_WIN32_API=1")
|
||||
endif()
|
|
@ -0,0 +1,84 @@
|
|||
// This file is part of OpenCV project.
|
||||
// It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
// of this distribution and at http://opencv.org/license.html.
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <opencv2/core.hpp>
|
||||
#include <opencv2/core/utils/trace.hpp>
|
||||
|
||||
#include <opencv2/core/opencl/opencl_info.hpp>
|
||||
|
||||
#ifdef OPENCV_WIN32_API
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
static void dumpHWFeatures(bool showAll = false)
|
||||
{
|
||||
std::cout << "OpenCV's HW features list:" << std::endl;
|
||||
int count = 0;
|
||||
for (int i = 0; i < CV_HARDWARE_MAX_FEATURE; i++)
|
||||
{
|
||||
cv::String name = cv::getHardwareFeatureName(i);
|
||||
if (name.empty())
|
||||
continue;
|
||||
bool enabled = cv::checkHardwareSupport(i);
|
||||
if (enabled)
|
||||
count++;
|
||||
if (enabled || showAll)
|
||||
{
|
||||
printf(" ID=%3d (%s) -> %s\n", i, name.c_str(), enabled ? "ON" : "N/A");
|
||||
}
|
||||
}
|
||||
std::cout << "Total available: " << count << std::endl;
|
||||
}
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
CV_TRACE_FUNCTION();
|
||||
CV_TRACE_ARG(argc);
|
||||
CV_TRACE_ARG_VALUE(argv0, "argv0", argv[0]);
|
||||
CV_TRACE_ARG_VALUE(argv1, "argv1", argv[1]);
|
||||
|
||||
#ifndef OPENCV_WIN32_API
|
||||
cv::CommandLineParser parser(argc, argv,
|
||||
"{ help h usage ? | | show this help message }"
|
||||
"{ verbose v | | show build configuration log }"
|
||||
"{ opencl | | show information about OpenCL (available platforms/devices, default selected device) }"
|
||||
"{ hw | | show detected HW features (see cv::checkHardwareSupport() function). Use --hw=0 to show available features only }"
|
||||
);
|
||||
|
||||
if (parser.has("help"))
|
||||
{
|
||||
parser.printMessage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (parser.has("verbose"))
|
||||
{
|
||||
std::cout << cv::getBuildInformation().c_str() << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << CV_VERSION << std::endl;
|
||||
}
|
||||
|
||||
if (parser.has("opencl"))
|
||||
{
|
||||
cv::dumpOpenCLInformation();
|
||||
}
|
||||
|
||||
if (parser.has("hw"))
|
||||
{
|
||||
dumpHWFeatures(parser.get<bool>("hw"));
|
||||
}
|
||||
#else
|
||||
std::cout << cv::getBuildInformation().c_str() << std::endl;
|
||||
cv::dumpOpenCLInformation();
|
||||
dumpHWFeatures();
|
||||
MessageBoxA(NULL, "Check console window output", "OpenCV(" CV_VERSION ")", MB_ICONINFORMATION | MB_OK);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
ocv_add_application(opencv_visualisation
|
||||
MODULES opencv_core opencv_highgui opencv_imgproc opencv_videoio opencv_imgcodecs
|
||||
SRCS opencv_visualisation.cpp)
|
|
@ -0,0 +1,364 @@
|
|||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// By downloading, copying, installing or using the software you agree to this license.
|
||||
// If you do not agree to this license, do not download, install,
|
||||
// copy or use the software.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
|
||||
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * Redistribution's in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// This software is provided by the copyright holders and contributors "as is" and
|
||||
// any express or implied warranties, including, but not limited to, the implied
|
||||
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
// indirect, incidental, special, exemplary, or consequential damages
|
||||
// (including, but not limited to, procurement of substitute goods or services;
|
||||
// loss of use, data, or profits; or business interruption) however caused
|
||||
// and on any theory of liability, whether in contract, strict liability,
|
||||
// or tort (including negligence or otherwise) arising in any way out of
|
||||
// the use of this software, even if advised of the possibility of such damage.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*****************************************************************************************************
|
||||
|
||||
Software for visualising cascade classifier models trained by OpenCV and to get a better
|
||||
understanding of the used features.
|
||||
|
||||
USAGE:
|
||||
./opencv_visualisation --model=<model.xml> --image=<ref.png> --data=<video output folder>
|
||||
|
||||
Created by: Puttemans Steven - April 2016
|
||||
*****************************************************************************************************/
|
||||
|
||||
#include <opencv2/core.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
#include <opencv2/imgcodecs.hpp>
|
||||
#include <opencv2/videoio.hpp>
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace cv;
|
||||
|
||||
struct rect_data{
|
||||
int x;
|
||||
int y;
|
||||
int w;
|
||||
int h;
|
||||
float weight;
|
||||
};
|
||||
|
||||
static void printLimits(){
|
||||
cerr << "Limits of the current interface:" << endl;
|
||||
cerr << " - Only handles cascade classifier models, trained with the opencv_traincascade tool, containing stumps as decision trees [default settings]." << endl;
|
||||
cerr << " - The image provided needs to be a sample window with the original model dimensions, passed to the --image parameter." << endl;
|
||||
cerr << " - ONLY handles HAAR and LBP features." << endl;
|
||||
}
|
||||
|
||||
int main( int argc, const char** argv )
|
||||
{
|
||||
CommandLineParser parser(argc, argv,
|
||||
"{ help h usage ? | | show this message }"
|
||||
"{ image i | | (required) path to reference image }"
|
||||
"{ model m | | (required) path to cascade xml file }"
|
||||
"{ data d | | (optional) path to video output folder }"
|
||||
);
|
||||
// Read in the input arguments
|
||||
if (parser.has("help")){
|
||||
parser.printMessage();
|
||||
printLimits();
|
||||
return 0;
|
||||
}
|
||||
string model(parser.get<string>("model"));
|
||||
string output_folder(parser.get<string>("data"));
|
||||
string image_ref = (parser.get<string>("image"));
|
||||
if (model.empty() || image_ref.empty()){
|
||||
parser.printMessage();
|
||||
printLimits();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Value for timing
|
||||
// You can increase this to have a better visualisation during the generation
|
||||
int timing = 1;
|
||||
|
||||
// Value for cols of storing elements
|
||||
int cols_prefered = 5;
|
||||
|
||||
// Open the XML model
|
||||
FileStorage fs;
|
||||
bool model_ok = fs.open(model, FileStorage::READ);
|
||||
if (!model_ok){
|
||||
cerr << "the cascade file '" << model << "' could not be loaded." << endl;
|
||||
return -1;
|
||||
}
|
||||
// Get a the required information
|
||||
// First decide which feature type we are using
|
||||
FileNode cascade = fs["cascade"];
|
||||
string feature_type = cascade["featureType"];
|
||||
bool haar = false, lbp = false;
|
||||
if (feature_type.compare("HAAR") == 0){
|
||||
haar = true;
|
||||
}
|
||||
if (feature_type.compare("LBP") == 0){
|
||||
lbp = true;
|
||||
}
|
||||
if ( feature_type.compare("HAAR") != 0 && feature_type.compare("LBP")){
|
||||
cerr << "The model is not an HAAR or LBP feature based model!" << endl;
|
||||
cerr << "Please select a model that can be visualized by the software." << endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// We make a visualisation mask - which increases the window to make it at least a bit more visible
|
||||
int resize_factor = 10;
|
||||
int resize_storage_factor = 10;
|
||||
Mat reference_image = imread(image_ref, IMREAD_GRAYSCALE );
|
||||
if (reference_image.empty()){
|
||||
cerr << "the reference image '" << image_ref << "'' could not be loaded." << endl;
|
||||
return -1;
|
||||
}
|
||||
Mat visualization;
|
||||
resize(reference_image, visualization, Size(reference_image.cols * resize_factor, reference_image.rows * resize_factor), 0, 0, INTER_LINEAR_EXACT);
|
||||
|
||||
// First recover for each stage the number of weak features and their index
|
||||
// Important since it is NOT sequential when using LBP features
|
||||
vector< vector<int> > stage_features;
|
||||
FileNode stages = cascade["stages"];
|
||||
FileNodeIterator it_stages = stages.begin(), it_stages_end = stages.end();
|
||||
int idx = 0;
|
||||
for( ; it_stages != it_stages_end; it_stages++, idx++ ){
|
||||
vector<int> current_feature_indexes;
|
||||
FileNode weak_classifiers = (*it_stages)["weakClassifiers"];
|
||||
FileNodeIterator it_weak = weak_classifiers.begin(), it_weak_end = weak_classifiers.end();
|
||||
vector<int> values;
|
||||
for(int idy = 0; it_weak != it_weak_end; it_weak++, idy++ ){
|
||||
(*it_weak)["internalNodes"] >> values;
|
||||
current_feature_indexes.push_back( (int)values[2] );
|
||||
}
|
||||
stage_features.push_back(current_feature_indexes);
|
||||
}
|
||||
|
||||
// If the output option has been chosen than we will store a combined image plane for
|
||||
// each stage, containing all weak classifiers for that stage.
|
||||
bool draw_planes = false;
|
||||
stringstream output_video;
|
||||
output_video << output_folder << "model_visualization.avi";
|
||||
VideoWriter result_video;
|
||||
if( output_folder.compare("") != 0 ){
|
||||
draw_planes = true;
|
||||
result_video.open(output_video.str(), VideoWriter::fourcc('X','V','I','D'), 15, Size(reference_image.cols * resize_factor, reference_image.rows * resize_factor), false);
|
||||
}
|
||||
|
||||
if(haar){
|
||||
// Grab the corresponding features dimensions and weights
|
||||
FileNode features = cascade["features"];
|
||||
vector< vector< rect_data > > feature_data;
|
||||
FileNodeIterator it_features = features.begin(), it_features_end = features.end();
|
||||
for(int idf = 0; it_features != it_features_end; it_features++, idf++ ){
|
||||
vector< rect_data > current_feature_rectangles;
|
||||
FileNode rectangles = (*it_features)["rects"];
|
||||
int nrects = (int)rectangles.size();
|
||||
for(int k = 0; k < nrects; k++){
|
||||
rect_data current_data;
|
||||
FileNode single_rect = rectangles[k];
|
||||
current_data.x = (int)single_rect[0];
|
||||
current_data.y = (int)single_rect[1];
|
||||
current_data.w = (int)single_rect[2];
|
||||
current_data.h = (int)single_rect[3];
|
||||
current_data.weight = (float)single_rect[4];
|
||||
current_feature_rectangles.push_back(current_data);
|
||||
}
|
||||
feature_data.push_back(current_feature_rectangles);
|
||||
}
|
||||
|
||||
// Loop over each possible feature on its index, visualise on the mask and wait a bit,
|
||||
// then continue to the next feature.
|
||||
// If visualisations should be stored then do the in between calculations
|
||||
Mat image_plane;
|
||||
Mat metadata = Mat::zeros(150, 1000, CV_8UC1);
|
||||
vector< rect_data > current_rects;
|
||||
for(int sid = 0; sid < (int)stage_features.size(); sid ++){
|
||||
if(draw_planes){
|
||||
int features_nmbr = (int)stage_features[sid].size();
|
||||
int cols = cols_prefered;
|
||||
int rows = features_nmbr / cols;
|
||||
if( (features_nmbr % cols) > 0){
|
||||
rows++;
|
||||
}
|
||||
image_plane = Mat::zeros(reference_image.rows * resize_storage_factor * rows, reference_image.cols * resize_storage_factor * cols, CV_8UC1);
|
||||
}
|
||||
for(int fid = 0; fid < (int)stage_features[sid].size(); fid++){
|
||||
stringstream meta1, meta2;
|
||||
meta1 << "Stage " << sid << " / Feature " << fid;
|
||||
meta2 << "Rectangles: ";
|
||||
Mat temp_window = visualization.clone();
|
||||
Mat temp_metadata = metadata.clone();
|
||||
int current_feature_index = stage_features[sid][fid];
|
||||
current_rects = feature_data[current_feature_index];
|
||||
Mat single_feature = reference_image.clone();
|
||||
resize(single_feature, single_feature, Size(), resize_storage_factor, resize_storage_factor, INTER_LINEAR_EXACT);
|
||||
for(int i = 0; i < (int)current_rects.size(); i++){
|
||||
rect_data local = current_rects[i];
|
||||
if(draw_planes){
|
||||
if(local.weight >= 0){
|
||||
rectangle(single_feature, Rect(local.x * resize_storage_factor, local.y * resize_storage_factor, local.w * resize_storage_factor, local.h * resize_storage_factor), Scalar(0), FILLED);
|
||||
}else{
|
||||
rectangle(single_feature, Rect(local.x * resize_storage_factor, local.y * resize_storage_factor, local.w * resize_storage_factor, local.h * resize_storage_factor), Scalar(255), FILLED);
|
||||
}
|
||||
}
|
||||
Rect part(local.x * resize_factor, local.y * resize_factor, local.w * resize_factor, local.h * resize_factor);
|
||||
meta2 << part << " (w " << local.weight << ") ";
|
||||
if(local.weight >= 0){
|
||||
rectangle(temp_window, part, Scalar(0), FILLED);
|
||||
}else{
|
||||
rectangle(temp_window, part, Scalar(255), FILLED);
|
||||
}
|
||||
}
|
||||
imshow("features", temp_window);
|
||||
putText(temp_window, meta1.str(), Point(15,15), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(255));
|
||||
result_video.write(temp_window);
|
||||
// Copy the feature image if needed
|
||||
if(draw_planes){
|
||||
single_feature.copyTo(image_plane(Rect(0 + (fid%cols_prefered)*single_feature.cols, 0 + (fid/cols_prefered) * single_feature.rows, single_feature.cols, single_feature.rows)));
|
||||
}
|
||||
putText(temp_metadata, meta1.str(), Point(15,15), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(255));
|
||||
putText(temp_metadata, meta2.str(), Point(15,40), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(255));
|
||||
imshow("metadata", temp_metadata);
|
||||
waitKey(timing);
|
||||
}
|
||||
//Store the stage image if needed
|
||||
if(draw_planes){
|
||||
stringstream save_location;
|
||||
save_location << output_folder << "stage_" << sid << ".png";
|
||||
imwrite(save_location.str(), image_plane);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(lbp){
|
||||
// Grab the corresponding features dimensions and weights
|
||||
FileNode features = cascade["features"];
|
||||
vector<Rect> feature_data;
|
||||
FileNodeIterator it_features = features.begin(), it_features_end = features.end();
|
||||
for(int idf = 0; it_features != it_features_end; it_features++, idf++ ){
|
||||
FileNode rectangle = (*it_features)["rect"];
|
||||
Rect current_feature ((int)rectangle[0], (int)rectangle[1], (int)rectangle[2], (int)rectangle[3]);
|
||||
feature_data.push_back(current_feature);
|
||||
}
|
||||
|
||||
// Loop over each possible feature on its index, visualise on the mask and wait a bit,
|
||||
// then continue to the next feature.
|
||||
Mat image_plane;
|
||||
Mat metadata = Mat::zeros(150, 1000, CV_8UC1);
|
||||
for(int sid = 0; sid < (int)stage_features.size(); sid ++){
|
||||
if(draw_planes){
|
||||
int features_nmbr = (int)stage_features[sid].size();
|
||||
int cols = cols_prefered;
|
||||
int rows = features_nmbr / cols;
|
||||
if( (features_nmbr % cols) > 0){
|
||||
rows++;
|
||||
}
|
||||
image_plane = Mat::zeros(reference_image.rows * resize_storage_factor * rows, reference_image.cols * resize_storage_factor * cols, CV_8UC1);
|
||||
}
|
||||
for(int fid = 0; fid < (int)stage_features[sid].size(); fid++){
|
||||
stringstream meta1, meta2;
|
||||
meta1 << "Stage " << sid << " / Feature " << fid;
|
||||
meta2 << "Rectangle: ";
|
||||
Mat temp_window = visualization.clone();
|
||||
Mat temp_metadata = metadata.clone();
|
||||
int current_feature_index = stage_features[sid][fid];
|
||||
Rect current_rect = feature_data[current_feature_index];
|
||||
Mat single_feature = reference_image.clone();
|
||||
resize(single_feature, single_feature, Size(), resize_storage_factor, resize_storage_factor, INTER_LINEAR_EXACT);
|
||||
|
||||
// VISUALISATION
|
||||
// The rectangle is the top left one of a 3x3 block LBP constructor
|
||||
Rect resized(current_rect.x * resize_factor, current_rect.y * resize_factor, current_rect.width * resize_factor, current_rect.height * resize_factor);
|
||||
meta2 << resized;
|
||||
// Top left
|
||||
rectangle(temp_window, resized, Scalar(255), 1);
|
||||
// Top middle
|
||||
rectangle(temp_window, Rect(resized.x + resized.width, resized.y, resized.width, resized.height), Scalar(255), 1);
|
||||
// Top right
|
||||
rectangle(temp_window, Rect(resized.x + 2*resized.width, resized.y, resized.width, resized.height), Scalar(255), 1);
|
||||
// Middle left
|
||||
rectangle(temp_window, Rect(resized.x, resized.y + resized.height, resized.width, resized.height), Scalar(255), 1);
|
||||
// Middle middle
|
||||
rectangle(temp_window, Rect(resized.x + resized.width, resized.y + resized.height, resized.width, resized.height), Scalar(255), FILLED);
|
||||
// Middle right
|
||||
rectangle(temp_window, Rect(resized.x + 2*resized.width, resized.y + resized.height, resized.width, resized.height), Scalar(255), 1);
|
||||
// Bottom left
|
||||
rectangle(temp_window, Rect(resized.x, resized.y + 2*resized.height, resized.width, resized.height), Scalar(255), 1);
|
||||
// Bottom middle
|
||||
rectangle(temp_window, Rect(resized.x + resized.width, resized.y + 2*resized.height, resized.width, resized.height), Scalar(255), 1);
|
||||
// Bottom right
|
||||
rectangle(temp_window, Rect(resized.x + 2*resized.width, resized.y + 2*resized.height, resized.width, resized.height), Scalar(255), 1);
|
||||
|
||||
if(draw_planes){
|
||||
Rect resized_inner(current_rect.x * resize_storage_factor, current_rect.y * resize_storage_factor, current_rect.width * resize_storage_factor, current_rect.height * resize_storage_factor);
|
||||
// Top left
|
||||
rectangle(single_feature, resized_inner, Scalar(255), 1);
|
||||
// Top middle
|
||||
rectangle(single_feature, Rect(resized_inner.x + resized_inner.width, resized_inner.y, resized_inner.width, resized_inner.height), Scalar(255), 1);
|
||||
// Top right
|
||||
rectangle(single_feature, Rect(resized_inner.x + 2*resized_inner.width, resized_inner.y, resized_inner.width, resized_inner.height), Scalar(255), 1);
|
||||
// Middle left
|
||||
rectangle(single_feature, Rect(resized_inner.x, resized_inner.y + resized_inner.height, resized_inner.width, resized_inner.height), Scalar(255), 1);
|
||||
// Middle middle
|
||||
rectangle(single_feature, Rect(resized_inner.x + resized_inner.width, resized_inner.y + resized_inner.height, resized_inner.width, resized_inner.height), Scalar(255), FILLED);
|
||||
// Middle right
|
||||
rectangle(single_feature, Rect(resized_inner.x + 2*resized_inner.width, resized_inner.y + resized_inner.height, resized_inner.width, resized_inner.height), Scalar(255), 1);
|
||||
// Bottom left
|
||||
rectangle(single_feature, Rect(resized_inner.x, resized_inner.y + 2*resized_inner.height, resized_inner.width, resized_inner.height), Scalar(255), 1);
|
||||
// Bottom middle
|
||||
rectangle(single_feature, Rect(resized_inner.x + resized_inner.width, resized_inner.y + 2*resized_inner.height, resized_inner.width, resized_inner.height), Scalar(255), 1);
|
||||
// Bottom right
|
||||
rectangle(single_feature, Rect(resized_inner.x + 2*resized_inner.width, resized_inner.y + 2*resized_inner.height, resized_inner.width, resized_inner.height), Scalar(255), 1);
|
||||
|
||||
single_feature.copyTo(image_plane(Rect(0 + (fid%cols_prefered)*single_feature.cols, 0 + (fid/cols_prefered) * single_feature.rows, single_feature.cols, single_feature.rows)));
|
||||
}
|
||||
|
||||
putText(temp_metadata, meta1.str(), Point(15,15), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(255));
|
||||
putText(temp_metadata, meta2.str(), Point(15,40), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(255));
|
||||
imshow("metadata", temp_metadata);
|
||||
imshow("features", temp_window);
|
||||
putText(temp_window, meta1.str(), Point(15,15), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(255));
|
||||
result_video.write(temp_window);
|
||||
|
||||
waitKey(timing);
|
||||
}
|
||||
|
||||
//Store the stage image if needed
|
||||
if(draw_planes){
|
||||
stringstream save_location;
|
||||
save_location << output_folder << "stage_" << sid << ".png";
|
||||
imwrite(save_location.str(), image_plane);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,92 @@
|
|||
# James Bigler, NVIDIA Corp (nvidia.com - jbigler)
|
||||
# Abe Stephens, SCI Institute -- http://www.sci.utah.edu/~abe/FindCuda.html
|
||||
#
|
||||
# Copyright (c) 2008 - 2009 NVIDIA Corporation. All rights reserved.
|
||||
#
|
||||
# Copyright (c) 2007-2009
|
||||
# Scientific Computing and Imaging Institute, University of Utah
|
||||
#
|
||||
# This code is licensed under the MIT License. See the FindCUDA.cmake script
|
||||
# for the text of the license.
|
||||
|
||||
# The MIT License
|
||||
#
|
||||
# License for the specific language governing rights and limitations under
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
#######################################################################
|
||||
# This converts a file written in makefile syntax into one that can be included
|
||||
# by CMake.
|
||||
|
||||
file(READ ${input_file} depend_text)
|
||||
|
||||
if (NOT "${depend_text}" STREQUAL "")
|
||||
|
||||
# message("FOUND DEPENDS")
|
||||
|
||||
string(REPLACE "\\ " " " depend_text ${depend_text})
|
||||
|
||||
# This works for the nvcc -M generated dependency files.
|
||||
string(REGEX REPLACE "^.* : " "" depend_text ${depend_text})
|
||||
string(REGEX REPLACE "[ \\\\]*\n" ";" depend_text ${depend_text})
|
||||
|
||||
set(dependency_list "")
|
||||
|
||||
foreach(file ${depend_text})
|
||||
|
||||
string(REGEX REPLACE "^ +" "" file ${file})
|
||||
|
||||
# OK, now if we had a UNC path, nvcc has a tendency to only output the first '/'
|
||||
# instead of '//'. Here we will test to see if the file exists, if it doesn't then
|
||||
# try to prepend another '/' to the path and test again. If it still fails remove the
|
||||
# path.
|
||||
|
||||
if(NOT EXISTS "${file}")
|
||||
if (EXISTS "/${file}")
|
||||
set(file "/${file}")
|
||||
else()
|
||||
message(WARNING " Removing non-existent dependency file: ${file}")
|
||||
set(file "")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT IS_DIRECTORY "${file}")
|
||||
# If softlinks start to matter, we should change this to REALPATH. For now we need
|
||||
# to flatten paths, because nvcc can generate stuff like /bin/../include instead of
|
||||
# just /include.
|
||||
get_filename_component(file_absolute "${file}" ABSOLUTE)
|
||||
list(APPEND dependency_list "${file_absolute}")
|
||||
endif()
|
||||
|
||||
endforeach()
|
||||
|
||||
else()
|
||||
# message("FOUND NO DEPENDS")
|
||||
endif()
|
||||
|
||||
# Remove the duplicate entries and sort them.
|
||||
list(REMOVE_DUPLICATES dependency_list)
|
||||
list(SORT dependency_list)
|
||||
|
||||
foreach(file ${dependency_list})
|
||||
set(cuda_nvcc_depend "${cuda_nvcc_depend} \"${file}\"\n")
|
||||
endforeach()
|
||||
|
||||
file(WRITE ${output_file} "# Generated by: make2cmake.cmake\nSET(CUDA_NVCC_DEPEND\n ${cuda_nvcc_depend})\n\n")
|
|
@ -0,0 +1,109 @@
|
|||
# James Bigler, NVIDIA Corp (nvidia.com - jbigler)
|
||||
# Abe Stephens, SCI Institute -- http://www.sci.utah.edu/~abe/FindCuda.html
|
||||
#
|
||||
# Copyright (c) 2008 - 2009 NVIDIA Corporation. All rights reserved.
|
||||
#
|
||||
# Copyright (c) 2007-2009
|
||||
# Scientific Computing and Imaging Institute, University of Utah
|
||||
#
|
||||
# This code is licensed under the MIT License. See the FindCUDA.cmake script
|
||||
# for the text of the license.
|
||||
|
||||
# The MIT License
|
||||
#
|
||||
# License for the specific language governing rights and limitations under
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
#######################################################################
|
||||
# Parses a .cubin file produced by nvcc and reports statistics about the file.
|
||||
|
||||
|
||||
file(READ ${input_file} file_text)
|
||||
|
||||
if (NOT "${file_text}" STREQUAL "")
|
||||
|
||||
string(REPLACE ";" "\\;" file_text ${file_text})
|
||||
string(REPLACE "\ncode" ";code" file_text ${file_text})
|
||||
|
||||
list(LENGTH file_text len)
|
||||
|
||||
foreach(line ${file_text})
|
||||
|
||||
# Only look at "code { }" blocks.
|
||||
if(line MATCHES "^code")
|
||||
|
||||
# Break into individual lines.
|
||||
string(REGEX REPLACE "\n" ";" line ${line})
|
||||
|
||||
foreach(entry ${line})
|
||||
|
||||
# Extract kernel names.
|
||||
if (${entry} MATCHES "[^g]name = ([^ ]+)")
|
||||
set(entry "${CMAKE_MATCH_1}")
|
||||
|
||||
# Check to see if the kernel name starts with "_"
|
||||
set(skip FALSE)
|
||||
# if (${entry} MATCHES "^_")
|
||||
# Skip the rest of this block.
|
||||
# message("Skipping ${entry}")
|
||||
# set(skip TRUE)
|
||||
# else ()
|
||||
message("Kernel: ${entry}")
|
||||
# endif ()
|
||||
|
||||
endif()
|
||||
|
||||
# Skip the rest of the block if necessary
|
||||
if(NOT skip)
|
||||
|
||||
# Registers
|
||||
if (${entry} MATCHES "reg([ ]+)=([ ]+)([^ ]+)")
|
||||
set(entry "${CMAKE_MATCH_3}")
|
||||
message("Registers: ${entry}")
|
||||
endif()
|
||||
|
||||
# Local memory
|
||||
if (${entry} MATCHES "lmem([ ]+)=([ ]+)([^ ]+)")
|
||||
set(entry "${CMAKE_MATCH_3}")
|
||||
message("Local: ${entry}")
|
||||
endif()
|
||||
|
||||
# Shared memory
|
||||
if (${entry} MATCHES "smem([ ]+)=([ ]+)([^ ]+)")
|
||||
set(entry "${CMAKE_MATCH_3}")
|
||||
message("Shared: ${entry}")
|
||||
endif()
|
||||
|
||||
if (${entry} MATCHES "^}")
|
||||
message("")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
|
||||
endforeach()
|
||||
|
||||
endif()
|
||||
|
||||
endforeach()
|
||||
|
||||
else()
|
||||
# message("FOUND NO DEPENDS")
|
||||
endif()
|
|
@ -0,0 +1,288 @@
|
|||
# James Bigler, NVIDIA Corp (nvidia.com - jbigler)
|
||||
#
|
||||
# Copyright (c) 2008 - 2009 NVIDIA Corporation. All rights reserved.
|
||||
#
|
||||
# This code is licensed under the MIT License. See the FindCUDA.cmake script
|
||||
# for the text of the license.
|
||||
|
||||
# The MIT License
|
||||
#
|
||||
# License for the specific language governing rights and limitations under
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
# to deal in the Software without restriction, including without limitation
|
||||
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
# and/or sell copies of the Software, and to permit persons to whom the
|
||||
# Software is furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
##########################################################################
|
||||
# This file runs the nvcc commands to produce the desired output file along with
|
||||
# the dependency file needed by CMake to compute dependencies. In addition the
|
||||
# file checks the output of each command and if the command fails it deletes the
|
||||
# output files.
|
||||
|
||||
# Input variables
|
||||
#
|
||||
# verbose:BOOL=<> OFF: Be as quiet as possible (default)
|
||||
# ON : Describe each step
|
||||
#
|
||||
# build_configuration:STRING=<> Typically one of Debug, MinSizeRel, Release, or
|
||||
# RelWithDebInfo, but it should match one of the
|
||||
# entries in CUDA_HOST_FLAGS. This is the build
|
||||
# configuration used when compiling the code. If
|
||||
# blank or unspecified Debug is assumed as this is
|
||||
# what CMake does.
|
||||
#
|
||||
# generated_file:STRING=<> File to generate. This argument must be passed in.
|
||||
#
|
||||
# generated_cubin_file:STRING=<> File to generate. This argument must be passed
|
||||
# in if build_cubin is true.
|
||||
|
||||
if(NOT generated_file)
|
||||
message(FATAL_ERROR "You must specify generated_file on the command line")
|
||||
endif()
|
||||
|
||||
# Set these up as variables to make reading the generated file easier
|
||||
set(CMAKE_COMMAND "@CMAKE_COMMAND@") # path
|
||||
set(source_file "@source_file@") # path
|
||||
set(NVCC_generated_dependency_file "@NVCC_generated_dependency_file@") # path
|
||||
set(cmake_dependency_file "@cmake_dependency_file@") # path
|
||||
set(CUDA_make2cmake "@CUDA_make2cmake@") # path
|
||||
set(CUDA_parse_cubin "@CUDA_parse_cubin@") # path
|
||||
set(build_cubin @build_cubin@) # bool
|
||||
set(CUDA_HOST_COMPILER "@CUDA_HOST_COMPILER@") # path
|
||||
# We won't actually use these variables for now, but we need to set this, in
|
||||
# order to force this file to be run again if it changes.
|
||||
set(generated_file_path "@generated_file_path@") # path
|
||||
set(generated_file_internal "@generated_file@") # path
|
||||
set(generated_cubin_file_internal "@generated_cubin_file@") # path
|
||||
|
||||
set(CUDA_NVCC_EXECUTABLE "@CUDA_NVCC_EXECUTABLE@") # path
|
||||
set(CUDA_NVCC_FLAGS @CUDA_NVCC_FLAGS@ ;; @CUDA_WRAP_OPTION_NVCC_FLAGS@) # list
|
||||
@CUDA_NVCC_FLAGS_CONFIG@
|
||||
set(nvcc_flags "@nvcc_flags@") # list
|
||||
set(CUDA_NVCC_INCLUDE_ARGS "@CUDA_NVCC_INCLUDE_ARGS@") # list (needs to be in quotes to handle spaces properly).
|
||||
set(format_flag "@format_flag@") # string
|
||||
|
||||
if(build_cubin AND NOT generated_cubin_file)
|
||||
message(FATAL_ERROR "You must specify generated_cubin_file on the command line")
|
||||
endif()
|
||||
|
||||
# This is the list of host compilation flags. It C or CXX should already have
|
||||
# been chosen by FindCUDA.cmake.
|
||||
@CUDA_HOST_FLAGS@
|
||||
|
||||
# Take the compiler flags and package them up to be sent to the compiler via -Xcompiler
|
||||
set(nvcc_host_compiler_flags "")
|
||||
# If we weren't given a build_configuration, use Debug.
|
||||
if(NOT build_configuration)
|
||||
set(build_configuration Debug)
|
||||
endif()
|
||||
string(TOUPPER "${build_configuration}" build_configuration)
|
||||
#message("CUDA_NVCC_HOST_COMPILER_FLAGS = ${CUDA_NVCC_HOST_COMPILER_FLAGS}")
|
||||
foreach(flag ${CMAKE_HOST_FLAGS} ${CMAKE_HOST_FLAGS_${build_configuration}})
|
||||
# Extra quotes are added around each flag to help nvcc parse out flags with spaces.
|
||||
set(nvcc_host_compiler_flags "${nvcc_host_compiler_flags},\"${flag}\"")
|
||||
endforeach()
|
||||
if (nvcc_host_compiler_flags)
|
||||
set(nvcc_host_compiler_flags "-Xcompiler" ${nvcc_host_compiler_flags})
|
||||
endif()
|
||||
#message("nvcc_host_compiler_flags = \"${nvcc_host_compiler_flags}\"")
|
||||
# Add the build specific configuration flags
|
||||
list(APPEND CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS_${build_configuration}})
|
||||
|
||||
# Any -ccbin existing in CUDA_NVCC_FLAGS gets highest priority
|
||||
list( FIND CUDA_NVCC_FLAGS "-ccbin" ccbin_found0 )
|
||||
list( FIND CUDA_NVCC_FLAGS "--compiler-bindir" ccbin_found1 )
|
||||
if( ccbin_found0 LESS 0 AND ccbin_found1 LESS 0 AND CUDA_HOST_COMPILER )
|
||||
if (CUDA_HOST_COMPILER STREQUAL "@_CUDA_MSVC_HOST_COMPILER@" AND DEFINED CCBIN)
|
||||
set(CCBIN -ccbin "${CCBIN}")
|
||||
else()
|
||||
set(CCBIN -ccbin "${CUDA_HOST_COMPILER}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# cuda_execute_process - Executes a command with optional command echo and status message.
|
||||
#
|
||||
# status - Status message to print if verbose is true
|
||||
# command - COMMAND argument from the usual execute_process argument structure
|
||||
# ARGN - Remaining arguments are the command with arguments
|
||||
#
|
||||
# CUDA_result - return value from running the command
|
||||
#
|
||||
# Make this a macro instead of a function, so that things like RESULT_VARIABLE
|
||||
# and other return variables are present after executing the process.
|
||||
macro(cuda_execute_process status command)
|
||||
set(_command ${command})
|
||||
if(NOT "x${_command}" STREQUAL "xCOMMAND")
|
||||
message(FATAL_ERROR "Malformed call to cuda_execute_process. Missing COMMAND as second argument. (command = ${command})")
|
||||
endif()
|
||||
if(verbose)
|
||||
execute_process(COMMAND "${CMAKE_COMMAND}" -E echo -- ${status})
|
||||
# Now we need to build up our command string. We are accounting for quotes
|
||||
# and spaces, anything else is left up to the user to fix if they want to
|
||||
# copy and paste a runnable command line.
|
||||
set(cuda_execute_process_string)
|
||||
foreach(arg ${ARGN})
|
||||
# If there are quotes, escape them, so they come through.
|
||||
string(REPLACE "\"" "\\\"" arg ${arg})
|
||||
# Args with spaces need quotes around them to get them to be parsed as a single argument.
|
||||
if(arg MATCHES " ")
|
||||
list(APPEND cuda_execute_process_string "\"${arg}\"")
|
||||
else()
|
||||
list(APPEND cuda_execute_process_string ${arg})
|
||||
endif()
|
||||
endforeach()
|
||||
# Echo the command
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E echo ${cuda_execute_process_string})
|
||||
endif()
|
||||
# Run the command
|
||||
execute_process(COMMAND ${ARGN} RESULT_VARIABLE CUDA_result )
|
||||
endmacro()
|
||||
|
||||
# Delete the target file
|
||||
cuda_execute_process(
|
||||
"Removing ${generated_file}"
|
||||
COMMAND "${CMAKE_COMMAND}" -E remove "${generated_file}"
|
||||
)
|
||||
|
||||
# For CUDA 2.3 and below, -G -M doesn't work, so remove the -G flag
|
||||
# for dependency generation and hope for the best.
|
||||
set(depends_CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS}")
|
||||
set(CUDA_VERSION @CUDA_VERSION@)
|
||||
if(CUDA_VERSION VERSION_LESS "3.0")
|
||||
cmake_policy(PUSH)
|
||||
# CMake policy 0007 NEW states that empty list elements are not
|
||||
# ignored. I'm just setting it to avoid the warning that's printed.
|
||||
cmake_policy(SET CMP0007 NEW)
|
||||
# Note that this will remove all occurrences of -G.
|
||||
list(REMOVE_ITEM depends_CUDA_NVCC_FLAGS "-G")
|
||||
cmake_policy(POP)
|
||||
endif()
|
||||
|
||||
# nvcc doesn't define __CUDACC__ for some reason when generating dependency files. This
|
||||
# can cause incorrect dependencies when #including files based on this macro which is
|
||||
# defined in the generating passes of nvcc invocation. We will go ahead and manually
|
||||
# define this for now until a future version fixes this bug.
|
||||
set(CUDACC_DEFINE -D__CUDACC__)
|
||||
|
||||
# Generate the dependency file
|
||||
cuda_execute_process(
|
||||
"Generating dependency file: ${NVCC_generated_dependency_file}"
|
||||
COMMAND "${CUDA_NVCC_EXECUTABLE}"
|
||||
-M
|
||||
${CUDACC_DEFINE}
|
||||
"${source_file}"
|
||||
-o "${NVCC_generated_dependency_file}"
|
||||
${CCBIN}
|
||||
${nvcc_flags}
|
||||
${nvcc_host_compiler_flags}
|
||||
${depends_CUDA_NVCC_FLAGS}
|
||||
-DNVCC
|
||||
${CUDA_NVCC_INCLUDE_ARGS}
|
||||
)
|
||||
|
||||
if(CUDA_result)
|
||||
message(FATAL_ERROR "Error generating ${generated_file}")
|
||||
endif()
|
||||
|
||||
# Generate the cmake readable dependency file to a temp file. Don't put the
|
||||
# quotes just around the filenames for the input_file and output_file variables.
|
||||
# CMake will pass the quotes through and not be able to find the file.
|
||||
cuda_execute_process(
|
||||
"Generating temporary cmake readable file: ${cmake_dependency_file}.tmp"
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
-D "input_file:FILEPATH=${NVCC_generated_dependency_file}"
|
||||
-D "output_file:FILEPATH=${cmake_dependency_file}.tmp"
|
||||
-P "${CUDA_make2cmake}"
|
||||
)
|
||||
|
||||
if(CUDA_result)
|
||||
message(FATAL_ERROR "Error generating ${generated_file}")
|
||||
endif()
|
||||
|
||||
# Copy the file if it is different
|
||||
cuda_execute_process(
|
||||
"Copy if different ${cmake_dependency_file}.tmp to ${cmake_dependency_file}"
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${cmake_dependency_file}.tmp" "${cmake_dependency_file}"
|
||||
)
|
||||
|
||||
if(CUDA_result)
|
||||
message(FATAL_ERROR "Error generating ${generated_file}")
|
||||
endif()
|
||||
|
||||
# Delete the temporary file
|
||||
cuda_execute_process(
|
||||
"Removing ${cmake_dependency_file}.tmp and ${NVCC_generated_dependency_file}"
|
||||
COMMAND "${CMAKE_COMMAND}" -E remove "${cmake_dependency_file}.tmp" "${NVCC_generated_dependency_file}"
|
||||
)
|
||||
|
||||
if(CUDA_result)
|
||||
message(FATAL_ERROR "Error generating ${generated_file}")
|
||||
endif()
|
||||
|
||||
# Generate the code
|
||||
cuda_execute_process(
|
||||
"Generating ${generated_file}"
|
||||
COMMAND "${CUDA_NVCC_EXECUTABLE}"
|
||||
"${source_file}"
|
||||
${format_flag} -o "${generated_file}"
|
||||
${CCBIN}
|
||||
${nvcc_flags}
|
||||
${nvcc_host_compiler_flags}
|
||||
${CUDA_NVCC_FLAGS}
|
||||
-DNVCC
|
||||
${CUDA_NVCC_INCLUDE_ARGS}
|
||||
)
|
||||
|
||||
if(CUDA_result)
|
||||
# Since nvcc can sometimes leave half done files make sure that we delete the output file.
|
||||
cuda_execute_process(
|
||||
"Removing ${generated_file}"
|
||||
COMMAND "${CMAKE_COMMAND}" -E remove "${generated_file}"
|
||||
)
|
||||
message(FATAL_ERROR "Error generating file ${generated_file}")
|
||||
else()
|
||||
if(verbose)
|
||||
message("Generated ${generated_file} successfully.")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Cubin resource report commands.
|
||||
if( build_cubin )
|
||||
# Run with -cubin to produce resource usage report.
|
||||
cuda_execute_process(
|
||||
"Generating ${generated_cubin_file}"
|
||||
COMMAND "${CUDA_NVCC_EXECUTABLE}"
|
||||
"${source_file}"
|
||||
${CUDA_NVCC_FLAGS}
|
||||
${nvcc_flags}
|
||||
${CCBIN}
|
||||
${nvcc_host_compiler_flags}
|
||||
-DNVCC
|
||||
-cubin
|
||||
-o "${generated_cubin_file}"
|
||||
${CUDA_NVCC_INCLUDE_ARGS}
|
||||
)
|
||||
|
||||
# Execute the parser script.
|
||||
cuda_execute_process(
|
||||
"Executing the parser script"
|
||||
COMMAND "${CMAKE_COMMAND}"
|
||||
-D "input_file:STRING=${generated_cubin_file}"
|
||||
-P "${CUDA_parse_cubin}"
|
||||
)
|
||||
|
||||
endif()
|
|
@ -0,0 +1,105 @@
|
|||
# template taken from https://cmake.org/cmake/help/v3.14/manual/cmake-developer.7.html
|
||||
|
||||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||
|
||||
#[=======================================================================[.rst:
|
||||
FindCUDNN
|
||||
---------
|
||||
|
||||
Finds the cuDNN library.
|
||||
|
||||
Requires:
|
||||
^^^^^^^^^
|
||||
|
||||
find_cuda_helper_libs from FindCUDA.cmake
|
||||
i.e. CUDA module should be found using FindCUDA.cmake before attempting to find cuDNN
|
||||
|
||||
Result Variables
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
This will define the following variables:
|
||||
|
||||
``CUDNN_FOUND``
|
||||
``CUDNN_INCLUDE_DIRS`` location of cudnn.h
|
||||
``CUDNN_LIBRARIES`` location of cudnn library
|
||||
|
||||
Cache Variables
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
The following cache variables will be set if cuDNN was found. They may also be set on failure.
|
||||
|
||||
``CUDNN_LIBRARY``
|
||||
``CUDNN_INCLUDE_DIR``
|
||||
``CUDNN_VERSION``
|
||||
|
||||
``CUDNN_VERSION_MAJOR`` INTERNAL
|
||||
``CUDNN_VERSION_MINOR`` INTERNAL
|
||||
``CUDNN_VERSION_PATCH`` INTERNAL
|
||||
|
||||
#]=======================================================================]
|
||||
|
||||
# find the library
|
||||
if(CUDA_FOUND)
|
||||
find_cuda_helper_libs(cudnn)
|
||||
set(CUDNN_LIBRARY ${CUDA_cudnn_LIBRARY} CACHE FILEPATH "location of the cuDNN library")
|
||||
unset(CUDA_cudnn_LIBRARY CACHE)
|
||||
endif()
|
||||
|
||||
# find the include
|
||||
if(CUDNN_LIBRARY)
|
||||
find_path(CUDNN_INCLUDE_DIR
|
||||
cudnn.h
|
||||
PATHS ${CUDA_TOOLKIT_INCLUDE}
|
||||
DOC "location of cudnn.h"
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
if(NOT CUDNN_INCLUDE_DIR)
|
||||
find_path(CUDNN_INCLUDE_DIR
|
||||
cudnn.h
|
||||
DOC "location of cudnn.h"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# extract version from the include
|
||||
if(CUDNN_INCLUDE_DIR)
|
||||
file(READ "${CUDNN_INCLUDE_DIR}/cudnn.h" CUDNN_H_CONTENTS)
|
||||
|
||||
string(REGEX MATCH "define CUDNN_MAJOR ([0-9]+)" _ "${CUDNN_H_CONTENTS}")
|
||||
set(CUDNN_MAJOR_VERSION ${CMAKE_MATCH_1} CACHE INTERNAL "")
|
||||
string(REGEX MATCH "define CUDNN_MINOR ([0-9]+)" _ "${CUDNN_H_CONTENTS}")
|
||||
set(CUDNN_MINOR_VERSION ${CMAKE_MATCH_1} CACHE INTERNAL "")
|
||||
string(REGEX MATCH "define CUDNN_PATCHLEVEL ([0-9]+)" _ "${CUDNN_H_CONTENTS}")
|
||||
set(CUDNN_PATCH_VERSION ${CMAKE_MATCH_1} CACHE INTERNAL "")
|
||||
|
||||
set(CUDNN_VERSION
|
||||
"${CUDNN_MAJOR_VERSION}.${CUDNN_MINOR_VERSION}.${CUDNN_PATCH_VERSION}"
|
||||
CACHE
|
||||
STRING
|
||||
"cuDNN version"
|
||||
)
|
||||
|
||||
unset(CUDNN_H_CONTENTS)
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(CUDNN
|
||||
FOUND_VAR CUDNN_FOUND
|
||||
REQUIRED_VARS
|
||||
CUDNN_LIBRARY
|
||||
CUDNN_INCLUDE_DIR
|
||||
VERSION_VAR CUDNN_VERSION
|
||||
)
|
||||
|
||||
if(CUDNN_FOUND)
|
||||
set(CUDNN_LIBRARIES ${CUDNN_LIBRARY})
|
||||
set(CUDNN_INCLUDE_DIRS ${CUDNN_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
mark_as_advanced(
|
||||
CUDNN_LIBRARY
|
||||
CUDNN_INCLUDE_DIR
|
||||
CUDNN_VERSION
|
||||
)
|
|
@ -0,0 +1,27 @@
|
|||
# - Find Flake8
|
||||
# Find the Flake8 executable and extract the version number
|
||||
#
|
||||
# OUTPUT Variables
|
||||
#
|
||||
# FLAKE8_FOUND
|
||||
# True if the flake8 package was found
|
||||
# FLAKE8_EXECUTABLE
|
||||
# The flake8 executable location
|
||||
# FLAKE8_VERSION
|
||||
# A string denoting the version of flake8 that has been found
|
||||
|
||||
find_host_program(FLAKE8_EXECUTABLE flake8 PATHS /usr/bin)
|
||||
|
||||
if(FLAKE8_EXECUTABLE)
|
||||
execute_process(COMMAND ${FLAKE8_EXECUTABLE} --version OUTPUT_VARIABLE FLAKE8_VERSION_RAW ERROR_QUIET)
|
||||
if(FLAKE8_VERSION_RAW MATCHES "^([0-9\\.]+[0-9])")
|
||||
set(FLAKE8_VERSION "${CMAKE_MATCH_1}")
|
||||
else()
|
||||
set(FLAKE8_VERSION "unknown")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Flake8 DEFAULT_MSG FLAKE8_EXECUTABLE)
|
||||
|
||||
mark_as_advanced(FLAKE8_EXECUTABLE FLAKE8_VERSION)
|
|
@ -0,0 +1,46 @@
|
|||
ocv_clear_vars(HAVE_OPENVX)
|
||||
|
||||
set(OPENVX_ROOT "" CACHE PATH "OpenVX install directory")
|
||||
set(OPENVX_LIB_CANDIDATES "openvx;vxu" CACHE STRING "OpenVX library candidates list")
|
||||
|
||||
function(find_openvx_libs _found)
|
||||
foreach(one ${OPENVX_LIB_CANDIDATES})
|
||||
find_library(OPENVX_${one}_LIBRARY ${one} PATHS "${OPENVX_ROOT}/lib" "${OPENVX_ROOT}/bin")
|
||||
if(OPENVX_${one}_LIBRARY)
|
||||
list(APPEND _list ${OPENVX_${one}_LIBRARY})
|
||||
endif()
|
||||
endforeach()
|
||||
set(${_found} ${_list} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
if(OPENVX_ROOT)
|
||||
find_path(OPENVX_INCLUDE_DIR "VX/vx.h" PATHS "${OPENVX_ROOT}/include" DOC "OpenVX include path")
|
||||
if(NOT DEFINED OPENVX_LIBRARIES)
|
||||
find_openvx_libs(found)
|
||||
if(found)
|
||||
set(OPENVX_LIBRARIES "${found}" CACHE STRING "OpenVX libraries")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(OPENVX_INCLUDE_DIR AND OPENVX_LIBRARIES)
|
||||
set(HAVE_OPENVX TRUE)
|
||||
|
||||
try_compile(OPENVX_RENAMED_REF
|
||||
"${OpenCV_BINARY_DIR}"
|
||||
"${OpenCV_SOURCE_DIR}/cmake/checks/openvx_refenum_test.cpp"
|
||||
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${OPENVX_INCLUDE_DIR}"
|
||||
LINK_LIBRARIES ${OPENVX_LIBRARIES}
|
||||
OUTPUT_VARIABLE OUTPUT
|
||||
)
|
||||
if(OPENVX_RENAMED_REF)
|
||||
add_definitions(-DIVX_RENAMED_REFS=1)
|
||||
message(STATUS "OpenVX: Checking reference attribute name convention... New")
|
||||
else()
|
||||
message(STATUS "OpenVX: Checking reference attribute name convention... Old")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT HAVE_OPENVX)
|
||||
ocv_clear_vars(HAVE_OPENVX OPENVX_LIBRARIES OPENVX_INCLUDE_DIR)
|
||||
endif()
|
|
@ -0,0 +1,27 @@
|
|||
# - Find Pylint
|
||||
# Find the Pylint executable and extract the version number
|
||||
#
|
||||
# OUTPUT Variables
|
||||
#
|
||||
# PYLINT_FOUND
|
||||
# True if the pylint package was found
|
||||
# PYLINT_EXECUTABLE
|
||||
# The pylint executable location
|
||||
# PYLINT_VERSION
|
||||
# A string denoting the version of pylint that has been found
|
||||
|
||||
find_host_program(PYLINT_EXECUTABLE pylint PATHS /usr/bin)
|
||||
|
||||
if(PYLINT_EXECUTABLE)
|
||||
execute_process(COMMAND ${PYLINT_EXECUTABLE} --version OUTPUT_VARIABLE PYLINT_VERSION_RAW ERROR_QUIET)
|
||||
if(PYLINT_VERSION_RAW MATCHES "pylint([^,]*) ([0-9\\.]+[0-9])")
|
||||
set(PYLINT_VERSION "${CMAKE_MATCH_2}")
|
||||
else()
|
||||
set(PYLINT_VERSION "unknown")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Pylint DEFAULT_MSG PYLINT_EXECUTABLE)
|
||||
|
||||
mark_as_advanced(PYLINT_EXECUTABLE PYLINT_VERSION)
|
|
@ -0,0 +1,27 @@
|
|||
# Find Vulkan
|
||||
#
|
||||
# Vulkan_INCLUDE_DIRS
|
||||
# Vulkan_LIBRARIES
|
||||
# Vulkan_FOUND
|
||||
if (WIN32)
|
||||
find_path(Vulkan_INCLUDE_DIRS NAMES vulkan/vulkan.h HINTS
|
||||
"$ENV{VULKAN_SDK}/Include"
|
||||
"$ENV{VK_SDK_PATH}/Include")
|
||||
if (CMAKE_CL_64)
|
||||
find_library(Vulkan_LIBRARIES NAMES vulkan-1 HINTS
|
||||
"$ENV{VULKAN_SDK}/Bin"
|
||||
"$ENV{VK_SDK_PATH}/Bin")
|
||||
else()
|
||||
find_library(Vulkan_LIBRARIES NAMES vulkan-1 HINTS
|
||||
"$ENV{VULKAN_SDK}/Bin32"
|
||||
"$ENV{VK_SDK_PATH}/Bin32")
|
||||
endif()
|
||||
else()
|
||||
find_path(Vulkan_INCLUDE_DIRS NAMES vulkan/vulkan.h HINTS
|
||||
"$ENV{VULKAN_SDK}/include")
|
||||
find_library(Vulkan_LIBRARIES NAMES vulkan HINTS
|
||||
"$ENV{VULKAN_SDK}/lib")
|
||||
endif()
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Vulkan DEFAULT_MSG Vulkan_LIBRARIES Vulkan_INCLUDE_DIRS)
|
||||
mark_as_advanced(Vulkan_INCLUDE_DIRS Vulkan_LIBRARIES)
|
|
@ -0,0 +1,75 @@
|
|||
# Use statically or dynamically linked CRT?
|
||||
|
||||
if(NOT MSVC)
|
||||
message(FATAL_ERROR "CRT options are available only for MSVC")
|
||||
endif()
|
||||
|
||||
# Removing LNK4075 warnings for debug WinRT builds
|
||||
# "LNK4075: ignoring '/INCREMENTAL' due to '/OPT:ICF' specification"
|
||||
# "LNK4075: ignoring '/INCREMENTAL' due to '/OPT:REF' specification"
|
||||
if(MSVC AND WINRT)
|
||||
# Optional verification checks since we don't know existing contents of variables below
|
||||
string(REPLACE "/OPT:ICF " "/OPT:NOICF " CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG}")
|
||||
string(REPLACE "/OPT:REF " "/OPT:NOREF " CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG}")
|
||||
string(REPLACE "/INCREMENTAL:YES " "/INCREMENTAL:NO " CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG}")
|
||||
string(REPLACE "/INCREMENTAL " "/INCREMENTAL:NO " CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG}")
|
||||
|
||||
string(REPLACE "/OPT:ICF " "/OPT:NOICF " CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS_DEBUG}")
|
||||
string(REPLACE "/OPT:REF " "/OPT:NOREF" CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS_DEBUG}")
|
||||
string(REPLACE "/INCREMENTAL:YES " "/INCREMENTAL:NO " CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS_DEBUG}")
|
||||
string(REPLACE "/INCREMENTAL " "/INCREMENTAL:NO " CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS_DEBUG}")
|
||||
|
||||
string(REPLACE "/OPT:ICF " "/OPT:NOICF " CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}")
|
||||
string(REPLACE "/OPT:REF " "/OPT:NOREF " CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}")
|
||||
string(REPLACE "/INCREMENTAL:YES " "/INCREMENTAL:NO " CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}")
|
||||
string(REPLACE "/INCREMENTAL " "/INCREMENTAL:NO " CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}")
|
||||
|
||||
# Mandatory
|
||||
set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS_DEBUG} /INCREMENTAL:NO /OPT:NOREF /OPT:NOICF")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /INCREMENTAL:NO /OPT:NOREF /OPT:NOICF")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} /INCREMENTAL:NO /OPT:NOREF /OPT:NOICF")
|
||||
endif()
|
||||
|
||||
# Ignore warning: This object file does not define any previously undefined public symbols, ...
|
||||
set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /IGNORE:4221")
|
||||
|
||||
if(NOT BUILD_SHARED_LIBS AND BUILD_WITH_STATIC_CRT)
|
||||
foreach(flag_var
|
||||
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
|
||||
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
|
||||
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
|
||||
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
|
||||
if(${flag_var} MATCHES "/MD")
|
||||
string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
|
||||
endif()
|
||||
if(${flag_var} MATCHES "/MDd")
|
||||
string(REGEX REPLACE "/MDd" "/MTd" ${flag_var} "${${flag_var}}")
|
||||
endif()
|
||||
endforeach(flag_var)
|
||||
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /NODEFAULTLIB:atlthunk.lib")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:libcpmt.lib /NODEFAULTLIB:msvcrt.lib")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /NODEFAULTLIB:libcmtd.lib /NODEFAULTLIB:libcpmtd.lib /NODEFAULTLIB:msvcrtd.lib")
|
||||
else()
|
||||
foreach(flag_var
|
||||
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
|
||||
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
|
||||
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
|
||||
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
|
||||
if(${flag_var} MATCHES "/MT")
|
||||
string(REGEX REPLACE "/MT" "/MD" ${flag_var} "${${flag_var}}")
|
||||
endif()
|
||||
if(${flag_var} MATCHES "/MTd")
|
||||
string(REGEX REPLACE "/MTd" "/MDd" ${flag_var} "${${flag_var}}")
|
||||
endif()
|
||||
endforeach(flag_var)
|
||||
endif()
|
||||
|
||||
if(CMAKE_VERSION VERSION_GREATER "2.8.6")
|
||||
include(ProcessorCount)
|
||||
ProcessorCount(N)
|
||||
if(NOT N EQUAL 0)
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /MP${N} ")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP${N} ")
|
||||
endif()
|
||||
endif()
|
|
@ -0,0 +1,97 @@
|
|||
# Enable build defense flags.
|
||||
# Performance may be affected.
|
||||
# More information:
|
||||
# - https://www.owasp.org/index.php/C-Based_Toolchain_Hardening
|
||||
# - https://wiki.debian.org/Hardening
|
||||
# - https://wiki.gentoo.org/wiki/Hardened/Toolchain
|
||||
# - https://docs.microsoft.com/en-us/cpp/build/reference/sdl-enable-additional-security-checks
|
||||
# - https://developer.apple.com/library/archive/documentation/Security/Conceptual/SecureCodingGuide/Articles/BufferOverflows.html
|
||||
|
||||
set(OPENCV_LINKER_DEFENSES_FLAGS_COMMON "")
|
||||
|
||||
macro(ocv_add_defense_compiler_flag option)
|
||||
ocv_check_flag_support(CXX "${option}" _varname "${ARGN}")
|
||||
if(${_varname})
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${option}")
|
||||
endif()
|
||||
|
||||
ocv_check_flag_support(C "${option}" _varname "${ARGN}")
|
||||
if(${_varname})
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${option}")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(ocv_add_defense_compiler_flag_release option)
|
||||
ocv_check_flag_support(CXX "${option}" _varname "${ARGN}")
|
||||
if(${_varname})
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${option}")
|
||||
endif()
|
||||
|
||||
ocv_check_flag_support(C "${option}" _varname "${ARGN}")
|
||||
if(${_varname})
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${option}")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# Define flags
|
||||
|
||||
if(MSVC)
|
||||
ocv_add_defense_compiler_flag("/GS")
|
||||
ocv_add_defense_compiler_flag("/sdl")
|
||||
ocv_add_defense_compiler_flag("/guard:cf")
|
||||
ocv_add_defense_compiler_flag("/w34018 /w34146 /w34244 /w34267 /w34302 /w34308 /w34509 /w34532 /w34533 /w34700 /w34789 /w34995 /w34996")
|
||||
set(OPENCV_LINKER_DEFENSES_FLAGS_COMMON "${OPENCV_LINKER_DEFENSES_FLAGS_COMMON} /guard:cf /dynamicbase" )
|
||||
if(NOT X86_64)
|
||||
set(OPENCV_LINKER_DEFENSES_FLAGS_COMMON "${OPENCV_LINKER_DEFENSES_FLAGS_COMMON} /safeseh")
|
||||
endif()
|
||||
elseif(CV_CLANG)
|
||||
ocv_add_defense_compiler_flag("-fstack-protector-strong")
|
||||
ocv_add_defense_compiler_flag_release("-D_FORTIFY_SOURCE=2")
|
||||
if (NOT APPLE)
|
||||
set(OPENCV_LINKER_DEFENSES_FLAGS_COMMON "${OPENCV_LINKER_DEFENSES_FLAGS_COMMON} -z noexecstack -z relro -z now" )
|
||||
endif()
|
||||
elseif(CV_GCC)
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.9")
|
||||
ocv_add_defense_compiler_flag("-fstack-protector")
|
||||
else()
|
||||
ocv_add_defense_compiler_flag("-fstack-protector-strong")
|
||||
endif()
|
||||
|
||||
# These flags is added by general options: -Wformat -Wformat-security
|
||||
if(NOT CMAKE_CXX_FLAGS MATCHES "-Wformat" OR NOT CMAKE_CXX_FLAGS MATCHES "format-security")
|
||||
message(FATAL_ERROR "Defense flags: uncompatible options")
|
||||
endif()
|
||||
|
||||
if(ANDROID)
|
||||
ocv_add_defense_compiler_flag_release("-D_FORTIFY_SOURCE=2")
|
||||
if(NOT CMAKE_CXX_FLAGS_RELEASE MATCHES "-D_FORTIFY_SOURCE=2") # TODO Check this
|
||||
ocv_add_defense_compiler_flag_release("-D_FORTIFY_SOURCE=1")
|
||||
endif()
|
||||
else()
|
||||
ocv_add_defense_compiler_flag_release("-D_FORTIFY_SOURCE=2")
|
||||
endif()
|
||||
|
||||
set(OPENCV_LINKER_DEFENSES_FLAGS_COMMON "${OPENCV_LINKER_DEFENSES_FLAGS_COMMON} -z noexecstack -z relro -z now" )
|
||||
else()
|
||||
# not supported
|
||||
endif()
|
||||
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
|
||||
if(CV_GCC OR CV_CLANG)
|
||||
if(NOT CMAKE_CXX_FLAGS MATCHES "-fPIC")
|
||||
ocv_add_defense_compiler_flag("-fPIC")
|
||||
endif()
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fPIE -pie")
|
||||
endif()
|
||||
|
||||
set( CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${OPENCV_LINKER_DEFENSES_FLAGS_COMMON}" )
|
||||
set( CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${OPENCV_LINKER_DEFENSES_FLAGS_COMMON}" )
|
||||
set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OPENCV_LINKER_DEFENSES_FLAGS_COMMON}" )
|
||||
|
||||
if(CV_GCC OR CV_CLANG)
|
||||
foreach(flags
|
||||
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG
|
||||
CMAKE_C_FLAGS CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_DEBUG)
|
||||
string(REPLACE "-O3" "-O2" ${flags} "${${flags}}")
|
||||
endforeach()
|
||||
endif()
|
|
@ -0,0 +1,922 @@
|
|||
# x86/x86-64 arch:
|
||||
# SSE / SSE2 (always available on 64-bit CPUs)
|
||||
# SSE3 / SSSE3
|
||||
# SSE4_1 / SSE4_2 / POPCNT
|
||||
# AVX / AVX2 / AVX_512F
|
||||
# FMA3
|
||||
#
|
||||
# AVX512 details: https://en.wikipedia.org/wiki/AVX-512#CPUs_with_AVX-512
|
||||
#
|
||||
# CPU features groups:
|
||||
# AVX512_COMMON (Common instructions AVX-512F/CD for all CPUs that support AVX-512)
|
||||
# AVX512_KNL (Knights Landing with AVX-512F/CD/ER/PF)
|
||||
# AVX512_KNM (Knights Mill with AVX-512F/CD/ER/PF/4FMAPS/4VNNIW/VPOPCNTDQ)
|
||||
# AVX512_SKX (Skylake-X with AVX-512F/CD/BW/DQ/VL)
|
||||
# AVX512_CNL (Cannon Lake with AVX-512F/CD/BW/DQ/VL/IFMA/VBMI)
|
||||
# AVX512_CLX (Cascade Lake with AVX-512F/CD/BW/DQ/VL/VNNI)
|
||||
# AVX512_ICL (Ice Lake with AVX-512F/CD/BW/DQ/VL/IFMA/VBMI/VNNI/VBMI2/BITALG/VPOPCNTDQ/VPCLMULQDQ*/GFNI*/VAES*)
|
||||
|
||||
# ppc64le arch:
|
||||
# VSX (always available on Power8)
|
||||
# VSX3 (always available on Power9)
|
||||
|
||||
# CPU_{opt}_SUPPORTED=ON/OFF - compiler support (possibly with additional flag)
|
||||
# CPU_{opt}_IMPLIES=<list>
|
||||
# CPU_{opt}_FORCE=<list> - subset of "implies" list
|
||||
# CPU_{opt}_GROUP=<list> - similar to "implies" list, but additionally merges compiler flags
|
||||
# CPU_{opt}_FLAGS_ON=""
|
||||
# CPU_{opt}_FEATURE_ALIAS - mapping to CV_CPU_* HWFeature enum
|
||||
|
||||
# Input variables:
|
||||
# CPU_BASELINE=<list> - preferred list of baseline optimizations
|
||||
# CPU_DISPATCH=<list> - preferred list of dispatched optimizations
|
||||
|
||||
# Advanced input variables:
|
||||
# CPU_BASELINE_REQUIRE=<list> - list of required baseline optimizations
|
||||
# CPU_DISPATCH_REQUIRE=<list> - list of required dispatched optimizations
|
||||
# CPU_BASELINE_DISABLE=<list> - list of disabled baseline optimizations
|
||||
|
||||
# Output variables:
|
||||
# CPU_BASELINE_FINAL=<list> - final list of enabled compiler optimizations
|
||||
# CPU_DISPATCH_FINAL=<list> - final list of dispatched optimizations
|
||||
#
|
||||
# CPU_DISPATCH_FLAGS_${opt} - flags for source files compiled separately (<name>.avx2.cpp)
|
||||
#
|
||||
# CPU_{opt}_ENABLED_DEFAULT=ON/OFF - has compiler support without additional flag (CPU_BASELINE_DETECT=ON only)
|
||||
|
||||
set(CPU_ALL_OPTIMIZATIONS "SSE;SSE2;SSE3;SSSE3;SSE4_1;SSE4_2;POPCNT;AVX;FP16;AVX2;FMA3;AVX_512F")
|
||||
list(APPEND CPU_ALL_OPTIMIZATIONS "AVX512_COMMON;AVX512_KNL;AVX512_KNM;AVX512_SKX;AVX512_CNL;AVX512_CLX;AVX512_ICL")
|
||||
list(APPEND CPU_ALL_OPTIMIZATIONS NEON VFPV3 FP16)
|
||||
list(APPEND CPU_ALL_OPTIMIZATIONS MSA)
|
||||
list(APPEND CPU_ALL_OPTIMIZATIONS VSX VSX3)
|
||||
list(REMOVE_DUPLICATES CPU_ALL_OPTIMIZATIONS)
|
||||
|
||||
ocv_update(CPU_VFPV3_FEATURE_ALIAS "")
|
||||
|
||||
|
||||
set(HELP_CPU_BASELINE "Specify list of enabled baseline CPU optimizations")
|
||||
set(HELP_CPU_BASELINE_REQUIRE "Specify list of required baseline CPU optimizations")
|
||||
set(HELP_CPU_BASELINE_DISABLE "Specify list of forbidden baseline CPU optimizations")
|
||||
set(HELP_CPU_DISPATCH "Specify list of dispatched CPU optimizations")
|
||||
set(HELP_CPU_DISPATCH_REQUIRE "Specify list of required dispatched CPU optimizations")
|
||||
|
||||
foreach(var CPU_BASELINE CPU_BASELINE_REQUIRE CPU_BASELINE_DISABLE CPU_DISPATCH CPU_DISPATCH_REQUIRE)
|
||||
if(DEFINED ${var})
|
||||
string(REPLACE "," ";" _list "${${var}}")
|
||||
set(${var} "${_list}" CACHE STRING "${HELP_${var}}" FORCE)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# process legacy flags
|
||||
macro(ocv_optimization_process_obsolete_option legacy_flag OPT legacy_warn)
|
||||
if(DEFINED "${legacy_flag}")
|
||||
if("${legacy_warn}")
|
||||
message(STATUS "WARNING: Option ${legacy_flag}='${${legacy_flag}}' is deprecated and should not be used anymore")
|
||||
message(STATUS " Behaviour of this option is not backward compatible")
|
||||
message(STATUS " Refer to 'CPU_BASELINE'/'CPU_DISPATCH' CMake options documentation")
|
||||
endif()
|
||||
if("${${legacy_flag}}")
|
||||
if(NOT ";${CPU_BASELINE_REQUIRE};" MATCHES ";${OPT};")
|
||||
set(CPU_BASELINE_REQUIRE "${CPU_BASELINE_REQUIRE};${OPT}" CACHE STRING "${HELP_CPU_BASELINE_REQUIRE}" FORCE)
|
||||
endif()
|
||||
else()
|
||||
if(NOT ";${CPU_BASELINE_DISABLE};" MATCHES ";${OPT};")
|
||||
set(CPU_BASELINE_DISABLE "${CPU_BASELINE_DISABLE};${OPT}" CACHE STRING "${HELP_CPU_BASELINE_DISABLE}" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
ocv_optimization_process_obsolete_option(ENABLE_SSE SSE ON)
|
||||
ocv_optimization_process_obsolete_option(ENABLE_SSE2 SSE2 ON)
|
||||
ocv_optimization_process_obsolete_option(ENABLE_SSE3 SSE3 ON)
|
||||
ocv_optimization_process_obsolete_option(ENABLE_SSSE3 SSSE3 ON)
|
||||
ocv_optimization_process_obsolete_option(ENABLE_SSE41 SSE4_1 ON)
|
||||
ocv_optimization_process_obsolete_option(ENABLE_SSE42 SSE4_2 ON)
|
||||
ocv_optimization_process_obsolete_option(ENABLE_POPCNT POPCNT ON)
|
||||
ocv_optimization_process_obsolete_option(ENABLE_AVX AVX ON)
|
||||
ocv_optimization_process_obsolete_option(ENABLE_AVX2 AVX2 ON)
|
||||
ocv_optimization_process_obsolete_option(ENABLE_FMA3 FMA3 ON)
|
||||
|
||||
ocv_optimization_process_obsolete_option(ENABLE_VFPV3 VFPV3 OFF)
|
||||
ocv_optimization_process_obsolete_option(ENABLE_NEON NEON OFF)
|
||||
|
||||
ocv_optimization_process_obsolete_option(ENABLE_VSX VSX ON)
|
||||
|
||||
macro(ocv_is_optimization_in_list resultvar check_opt)
|
||||
set(__checked "")
|
||||
set(__queue ${ARGN})
|
||||
set(${resultvar} 0)
|
||||
while(__queue AND NOT ${resultvar})
|
||||
list(REMOVE_DUPLICATES __queue)
|
||||
set(__queue_current ${__queue})
|
||||
set(__queue "")
|
||||
foreach(OPT ${__queue_current})
|
||||
if("x${OPT}" STREQUAL "x${check_opt}")
|
||||
set(${resultvar} 1)
|
||||
break()
|
||||
elseif(NOT ";${__checked};" MATCHES ";${OPT};")
|
||||
list(APPEND __queue ${CPU_${OPT}_IMPLIES})
|
||||
endif()
|
||||
list(APPEND __checked ${OPT})
|
||||
endforeach()
|
||||
endwhile()
|
||||
endmacro()
|
||||
|
||||
macro(ocv_is_optimization_in_force_list resultvar check_opt)
|
||||
set(__checked "")
|
||||
set(__queue ${ARGN})
|
||||
set(${resultvar} 0)
|
||||
while(__queue AND NOT ${resultvar})
|
||||
list(REMOVE_DUPLICATES __queue)
|
||||
set(__queue_current ${__queue})
|
||||
set(__queue "")
|
||||
foreach(OPT ${__queue_current})
|
||||
if(OPT STREQUAL "${check_opt}")
|
||||
set(${resultvar} 1)
|
||||
break()
|
||||
elseif(NOT ";${__checked};" MATCHES ";${OPT};")
|
||||
list(APPEND __queue ${CPU_${OPT}_FORCE})
|
||||
endif()
|
||||
list(APPEND __checked ${OPT})
|
||||
endforeach()
|
||||
endwhile()
|
||||
endmacro()
|
||||
|
||||
macro(ocv_append_optimization_flag var OPT)
|
||||
if(CPU_${OPT}_FLAGS_CONFLICT)
|
||||
string(REGEX REPLACE " ${CPU_${OPT}_FLAGS_CONFLICT}" "" ${var} " ${${var}} ")
|
||||
string(REGEX REPLACE "^ +" "" ${var} "${${var}}")
|
||||
endif()
|
||||
set(${var} "${${var}} ${CPU_${OPT}_FLAGS_ON}")
|
||||
endmacro()
|
||||
|
||||
# Support GCC -march=native or Intel Compiler -xHost flags
|
||||
if(";${CPU_BASELINE};" MATCHES ";NATIVE;" OR ";${CPU_BASELINE};" MATCHES ";HOST;")
|
||||
set(CPU_BASELINE_DETECT ON)
|
||||
set(_add_native_flag ON)
|
||||
elseif(";${CPU_BASELINE};" MATCHES ";DETECT;")
|
||||
set(CPU_BASELINE_DETECT ON)
|
||||
elseif(" ${CMAKE_CXX_FLAGS} " MATCHES " -march=native | -xHost | /QxHost ")
|
||||
if(DEFINED CPU_BASELINE)
|
||||
message(STATUS "CPU: Detected '-march=native' or '-xHost' compiler flag. Force CPU_BASELINE=DETECT.")
|
||||
endif()
|
||||
set(CPU_BASELINE "DETECT" CACHE STRING "${HELP_CPU_BASELINE}")
|
||||
set(CPU_BASELINE_DETECT ON)
|
||||
endif()
|
||||
|
||||
if(X86 OR X86_64)
|
||||
ocv_update(CPU_KNOWN_OPTIMIZATIONS "SSE;SSE2;SSE3;SSSE3;SSE4_1;POPCNT;SSE4_2;FP16;FMA3;AVX;AVX2;AVX_512F;AVX512_COMMON;AVX512_KNL;AVX512_KNM;AVX512_SKX;AVX512_CNL;AVX512_CLX;AVX512_ICL")
|
||||
|
||||
ocv_update(CPU_AVX512_COMMON_GROUP "AVX_512F;AVX_512CD")
|
||||
ocv_update(CPU_AVX512_KNL_GROUP "AVX512_COMMON;AVX512_KNL_EXTRA")
|
||||
ocv_update(CPU_AVX512_KNM_GROUP "AVX512_KNL;AVX512_KNM_EXTRA;AVX_512VPOPCNTDQ")
|
||||
ocv_update(CPU_AVX512_SKX_GROUP "AVX512_COMMON;AVX_512VL;AVX_512BW;AVX_512DQ")
|
||||
ocv_update(CPU_AVX512_CNL_GROUP "AVX512_SKX;AVX_512IFMA;AVX_512VBMI")
|
||||
ocv_update(CPU_AVX512_CLX_GROUP "AVX512_SKX;AVX_512VNNI")
|
||||
ocv_update(CPU_AVX512_ICL_GROUP "AVX512_SKX;AVX_512IFMA;AVX_512VBMI;AVX_512VNNI;AVX_512VBMI2;AVX_512BITALG;AVX_512VPOPCNTDQ") # ? VPCLMULQDQ, GFNI, VAES
|
||||
|
||||
ocv_update(CPU_SSE_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_sse.cpp")
|
||||
ocv_update(CPU_SSE2_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_sse2.cpp")
|
||||
ocv_update(CPU_SSE3_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_sse3.cpp")
|
||||
ocv_update(CPU_SSSE3_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_ssse3.cpp")
|
||||
ocv_update(CPU_SSE4_1_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_sse41.cpp")
|
||||
ocv_update(CPU_SSE4_2_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_sse42.cpp")
|
||||
ocv_update(CPU_POPCNT_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_popcnt.cpp")
|
||||
ocv_update(CPU_AVX_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_avx.cpp")
|
||||
ocv_update(CPU_AVX2_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_avx2.cpp")
|
||||
ocv_update(CPU_FP16_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_fp16.cpp")
|
||||
ocv_update(CPU_AVX_512F_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_avx512.cpp")
|
||||
ocv_update(CPU_AVX512_COMMON_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_avx512common.cpp")
|
||||
ocv_update(CPU_AVX512_KNL_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_avx512knl.cpp")
|
||||
ocv_update(CPU_AVX512_KNM_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_avx512knm.cpp")
|
||||
ocv_update(CPU_AVX512_SKX_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_avx512skx.cpp")
|
||||
ocv_update(CPU_AVX512_CNL_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_avx512cnl.cpp")
|
||||
ocv_update(CPU_AVX512_CLX_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_avx512clx.cpp")
|
||||
ocv_update(CPU_AVX512_ICL_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_avx512icl.cpp")
|
||||
|
||||
if(NOT OPENCV_CPU_OPT_IMPLIES_IGNORE)
|
||||
ocv_update(CPU_AVX512_ICL_IMPLIES "AVX512_SKX")
|
||||
ocv_update(CPU_AVX512_CLX_IMPLIES "AVX512_SKX")
|
||||
ocv_update(CPU_AVX512_CNL_IMPLIES "AVX512_SKX")
|
||||
ocv_update(CPU_AVX512_SKX_IMPLIES "AVX512_COMMON")
|
||||
ocv_update(CPU_AVX512_KNM_IMPLIES "AVX512_KNL")
|
||||
ocv_update(CPU_AVX512_KNL_IMPLIES "AVX512_COMMON")
|
||||
ocv_update(CPU_AVX512_COMMON_IMPLIES "AVX_512F")
|
||||
ocv_update(CPU_AVX_512F_IMPLIES "AVX2")
|
||||
ocv_update(CPU_AVX_512F_FORCE "") # Don't force other optimizations
|
||||
ocv_update(CPU_AVX2_IMPLIES "AVX;FMA3;FP16")
|
||||
ocv_update(CPU_FMA3_IMPLIES "AVX2")
|
||||
ocv_update(CPU_FMA3_FORCE "") # Don't force other optimizations
|
||||
ocv_update(CPU_FP16_IMPLIES "AVX")
|
||||
ocv_update(CPU_FP16_FORCE "") # Don't force other optimizations
|
||||
ocv_update(CPU_AVX_IMPLIES "SSE4_2")
|
||||
ocv_update(CPU_SSE4_2_IMPLIES "SSE4_1;POPCNT")
|
||||
ocv_update(CPU_POPCNT_IMPLIES "SSE4_1")
|
||||
ocv_update(CPU_POPCNT_FORCE "") # Don't force other optimizations
|
||||
ocv_update(CPU_SSE4_1_IMPLIES "SSE3;SSSE3")
|
||||
ocv_update(CPU_SSSE3_IMPLIES "SSE3")
|
||||
ocv_update(CPU_SSE3_IMPLIES "SSE2")
|
||||
ocv_update(CPU_SSE2_IMPLIES "SSE")
|
||||
endif()
|
||||
|
||||
if(CV_ICC)
|
||||
macro(ocv_intel_compiler_optimization_option name unix_flags msvc_flags)
|
||||
ocv_update(CPU_${name}_FLAGS_NAME "${name}")
|
||||
if(MSVC)
|
||||
set(enable_flags "${msvc_flags}")
|
||||
set(flags_conflict "/arch:[^ ]*|/Qx:[^ ]+")
|
||||
else()
|
||||
set(enable_flags "${unix_flags}")
|
||||
set(flags_conflict "-msse[^ ]*|-mssse3|-mavx[^ ]*|-march[^ ]*|-x[^ ]+")
|
||||
endif()
|
||||
ocv_update(CPU_${name}_FLAGS_ON "${enable_flags}")
|
||||
if(flags_conflict)
|
||||
ocv_update(CPU_${name}_FLAGS_CONFLICT "${flags_conflict}")
|
||||
endif()
|
||||
endmacro()
|
||||
ocv_intel_compiler_optimization_option(AVX2 "-march=core-avx2" "/arch:CORE-AVX2")
|
||||
ocv_intel_compiler_optimization_option(FP16 "-mavx" "/arch:AVX")
|
||||
ocv_intel_compiler_optimization_option(AVX "-mavx" "/arch:AVX")
|
||||
ocv_intel_compiler_optimization_option(FMA3 "" "")
|
||||
ocv_intel_compiler_optimization_option(POPCNT "" "")
|
||||
ocv_intel_compiler_optimization_option(SSE4_2 "-msse4.2" "/arch:SSE4.2")
|
||||
ocv_intel_compiler_optimization_option(SSE4_1 "-msse4.1" "/arch:SSE4.1")
|
||||
ocv_intel_compiler_optimization_option(SSE3 "-msse3" "/arch:SSE3")
|
||||
ocv_intel_compiler_optimization_option(SSSE3 "-mssse3" "/arch:SSSE3")
|
||||
ocv_intel_compiler_optimization_option(SSE2 "-msse2" "/arch:SSE2")
|
||||
if(NOT X86_64) # x64 compiler doesn't support /arch:sse
|
||||
ocv_intel_compiler_optimization_option(SSE "-msse" "/arch:SSE")
|
||||
endif()
|
||||
ocv_intel_compiler_optimization_option(AVX_512F "-xCOMMON-AVX512" "/Qx:COMMON-AVX512")
|
||||
ocv_intel_compiler_optimization_option(AVX512_COMMON "-xCOMMON-AVX512" "/Qx:COMMON-AVX512")
|
||||
ocv_intel_compiler_optimization_option(AVX512_KNL "-xKNL" "/Qx:KNL")
|
||||
ocv_intel_compiler_optimization_option(AVX512_KNM "-xKNM" "/Qx:KNM")
|
||||
ocv_intel_compiler_optimization_option(AVX512_SKX "-xSKYLAKE-AVX512" "/Qx:SKYLAKE-AVX512")
|
||||
ocv_intel_compiler_optimization_option(AVX512_CNL "-xCANNONLAKE" "/Qx:CANNONLAKE")
|
||||
ocv_intel_compiler_optimization_option(AVX512_CLX "-xCASCADELAKE" "/Qx:CASCADELAKE")
|
||||
ocv_intel_compiler_optimization_option(AVX512_ICL "-xICELAKE-CLIENT" "/Qx:ICELAKE-CLIENT")
|
||||
elseif(CV_GCC OR CV_CLANG)
|
||||
ocv_update(CPU_AVX2_FLAGS_ON "-mavx2")
|
||||
ocv_update(CPU_FP16_FLAGS_ON "-mf16c")
|
||||
ocv_update(CPU_AVX_FLAGS_ON "-mavx")
|
||||
ocv_update(CPU_FMA3_FLAGS_ON "-mfma")
|
||||
ocv_update(CPU_POPCNT_FLAGS_ON "-mpopcnt")
|
||||
ocv_update(CPU_SSE4_2_FLAGS_ON "-msse4.2")
|
||||
ocv_update(CPU_SSE4_1_FLAGS_ON "-msse4.1")
|
||||
ocv_update(CPU_SSE3_FLAGS_ON "-msse3")
|
||||
ocv_update(CPU_SSSE3_FLAGS_ON "-mssse3")
|
||||
ocv_update(CPU_SSE2_FLAGS_ON "-msse2")
|
||||
ocv_update(CPU_SSE_FLAGS_ON "-msse")
|
||||
if(NOT (CV_GCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "5.0")) # GCC >= 5.0
|
||||
ocv_update(CPU_AVX_512F_FLAGS_ON "-mavx512f")
|
||||
ocv_update(CPU_AVX_512CD_FLAGS_ON "-mavx512cd")
|
||||
ocv_update(CPU_AVX512_KNL_EXTRA_FLAGS_ON "-mavx512er -mavx512pf")
|
||||
ocv_update(CPU_AVX512_KNM_EXTRA_FLAGS_ON "-mavx5124fmaps -mavx5124vnniw")
|
||||
ocv_update(CPU_AVX_512BW_FLAGS_ON "-mavx512bw")
|
||||
ocv_update(CPU_AVX_512DQ_FLAGS_ON "-mavx512dq")
|
||||
ocv_update(CPU_AVX_512VL_FLAGS_ON "-mavx512vl")
|
||||
ocv_update(CPU_AVX_512IFMA_FLAGS_ON "-mavx512ifma")
|
||||
ocv_update(CPU_AVX_512VBMI_FLAGS_ON "-mavx512vbmi")
|
||||
ocv_update(CPU_AVX_512VNNI_FLAGS_ON "-mavx512vnni")
|
||||
ocv_update(CPU_AVX_512VBMI2_FLAGS_ON "-mavx512vbmi2")
|
||||
ocv_update(CPU_AVX_512BITALG_FLAGS_ON "-mavx512bitalg")
|
||||
ocv_update(CPU_AVX_512VPOPCNTDQ_FLAGS_ON "-mavx512vpopcntdq")
|
||||
else()
|
||||
ocv_update(CPU_AVX_512F_SUPPORTED OFF)
|
||||
endif()
|
||||
elseif(MSVC)
|
||||
ocv_update(CPU_AVX2_FLAGS_ON "/arch:AVX2")
|
||||
ocv_update(CPU_AVX_FLAGS_ON "/arch:AVX")
|
||||
ocv_update(CPU_FP16_FLAGS_ON "/arch:AVX")
|
||||
if(NOT X86_64)
|
||||
# 64-bit MSVC compiler uses SSE/SSE2 by default
|
||||
ocv_update(CPU_SSE_FLAGS_ON "/arch:SSE")
|
||||
ocv_update(CPU_SSE_SUPPORTED ON)
|
||||
ocv_update(CPU_SSE2_FLAGS_ON "/arch:SSE2")
|
||||
ocv_update(CPU_SSE2_SUPPORTED ON)
|
||||
else()
|
||||
ocv_update(CPU_SSE_SUPPORTED ON)
|
||||
ocv_update(CPU_SSE2_SUPPORTED ON)
|
||||
ocv_update(CPU_AVX_512F_FLAGS_ON "/arch:AVX512")
|
||||
endif()
|
||||
# Other instruction sets are supported by default since MSVC 2008 at least
|
||||
else()
|
||||
message(WARNING "TODO: Unsupported compiler")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CPU_DISPATCH)
|
||||
if(X86_64)
|
||||
set(CPU_DISPATCH "SSE4_1;SSE4_2;AVX;FP16;AVX2;AVX512_SKX" CACHE STRING "${HELP_CPU_DISPATCH}")
|
||||
else()
|
||||
set(CPU_DISPATCH "SSE4_1;SSE4_2;AVX;FP16" CACHE STRING "${HELP_CPU_DISPATCH}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CPU_BASELINE)
|
||||
if(APPLE)
|
||||
# MacOS X has limited set of possible supported H/W, so compiler is configured well
|
||||
set(CPU_BASELINE "DETECT" CACHE STRING "${HELP_CPU_BASELINE}")
|
||||
elseif(X86_64)
|
||||
set(CPU_BASELINE "SSE3" CACHE STRING "${HELP_CPU_BASELINE}")
|
||||
else()
|
||||
set(CPU_BASELINE "SSE2" CACHE STRING "${HELP_CPU_BASELINE}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
elseif(ARM OR AARCH64)
|
||||
ocv_update(CPU_NEON_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_neon.cpp")
|
||||
ocv_update(CPU_FP16_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_fp16.cpp")
|
||||
if(NOT AARCH64)
|
||||
ocv_update(CPU_KNOWN_OPTIMIZATIONS "VFPV3;NEON;FP16")
|
||||
if(NOT MSVC)
|
||||
ocv_update(CPU_VFPV3_FLAGS_ON "-mfpu=vfpv3")
|
||||
ocv_update(CPU_NEON_FLAGS_ON "-mfpu=neon")
|
||||
ocv_update(CPU_NEON_FLAGS_CONFLICT "-mfpu=[^ ]*")
|
||||
ocv_update(CPU_FP16_FLAGS_ON "-mfpu=neon-fp16 -mfp16-format=ieee")
|
||||
ocv_update(CPU_FP16_FLAGS_CONFLICT "-mfpu=[^ ]*")
|
||||
endif()
|
||||
ocv_update(CPU_FP16_IMPLIES "NEON")
|
||||
else()
|
||||
ocv_update(CPU_KNOWN_OPTIMIZATIONS "NEON;FP16")
|
||||
ocv_update(CPU_NEON_FLAGS_ON "")
|
||||
ocv_update(CPU_FP16_IMPLIES "NEON")
|
||||
set(CPU_BASELINE "NEON;FP16" CACHE STRING "${HELP_CPU_BASELINE}")
|
||||
endif()
|
||||
elseif(MIPS)
|
||||
ocv_update(CPU_MSA_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_msa.cpp")
|
||||
ocv_update(CPU_KNOWN_OPTIMIZATIONS "MSA")
|
||||
ocv_update(CPU_MSA_FLAGS_ON "-mmsa")
|
||||
set(CPU_BASELINE "DETECT" CACHE STRING "${HELP_CPU_BASELINE}")
|
||||
elseif(PPC64LE)
|
||||
ocv_update(CPU_KNOWN_OPTIMIZATIONS "VSX;VSX3")
|
||||
ocv_update(CPU_VSX_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_vsx.cpp")
|
||||
ocv_update(CPU_VSX3_TEST_FILE "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_vsx3.cpp")
|
||||
|
||||
if(NOT OPENCV_CPU_OPT_IMPLIES_IGNORE)
|
||||
ocv_update(CPU_VSX3_IMPLIES "VSX")
|
||||
endif()
|
||||
|
||||
if(CV_CLANG AND (NOT ${CMAKE_CXX_COMPILER} MATCHES "xlc"))
|
||||
ocv_update(CPU_VSX_FLAGS_ON "-mvsx -maltivec")
|
||||
ocv_update(CPU_VSX3_FLAGS_ON "-mpower9-vector")
|
||||
else()
|
||||
ocv_update(CPU_VSX_FLAGS_ON "-mcpu=power8")
|
||||
ocv_update(CPU_VSX3_FLAGS_ON "-mcpu=power9 -mtune=power9")
|
||||
endif()
|
||||
|
||||
set(CPU_DISPATCH "VSX3" CACHE STRING "${HELP_CPU_DISPATCH}")
|
||||
set(CPU_BASELINE "VSX" CACHE STRING "${HELP_CPU_BASELINE}")
|
||||
endif()
|
||||
|
||||
# Helper values for cmake-gui
|
||||
set(CPU_BASELINE "DETECT" CACHE STRING "${HELP_CPU_BASELINE}")
|
||||
set(CPU_DISPATCH "" CACHE STRING "${HELP_CPU_DISPATCH}")
|
||||
set_property(CACHE CPU_BASELINE PROPERTY STRINGS "" ${CPU_KNOWN_OPTIMIZATIONS})
|
||||
set_property(CACHE CPU_DISPATCH PROPERTY STRINGS "" ${CPU_KNOWN_OPTIMIZATIONS})
|
||||
|
||||
# Update CPU_BASELINE_DETECT flag
|
||||
if(";${CPU_BASELINE};" MATCHES ";DETECT;")
|
||||
set(CPU_BASELINE_DETECT ON)
|
||||
endif()
|
||||
|
||||
set(CPU_BASELINE_FLAGS "")
|
||||
|
||||
set(CPU_BASELINE_FINAL "")
|
||||
set(CPU_DISPATCH_FINAL "")
|
||||
|
||||
if(CV_DISABLE_OPTIMIZATION)
|
||||
set(CPU_DISPATCH "")
|
||||
set(CPU_DISPATCH_REQUIRE "")
|
||||
endif()
|
||||
|
||||
if("x${CPU_DISPATCH}" STREQUAL "xALL")
|
||||
set(CPU_DISPATCH "${CPU_KNOWN_OPTIMIZATIONS}")
|
||||
endif()
|
||||
|
||||
macro(ocv_check_compiler_optimization OPT)
|
||||
if(NOT DEFINED CPU_${OPT}_SUPPORTED)
|
||||
if((DEFINED CPU_${OPT}_FLAGS_ON AND NOT "x${CPU_${OPT}_FLAGS_ON}" STREQUAL "x") OR CPU_${OPT}_TEST_FILE)
|
||||
set(_varname "")
|
||||
if(CPU_${OPT}_TEST_FILE)
|
||||
set(__available 0)
|
||||
if(CPU_BASELINE_DETECT)
|
||||
set(_varname "HAVE_CPU_${OPT}_SUPPORT")
|
||||
ocv_check_compiler_flag(CXX "${CPU_BASELINE_FLAGS}" "${_varname}" "${CPU_${OPT}_TEST_FILE}")
|
||||
if(${_varname})
|
||||
list(APPEND CPU_BASELINE_FINAL ${OPT})
|
||||
set(CPU_${OPT}_ENABLED_DEFAULT ON)
|
||||
set(__available 1)
|
||||
endif()
|
||||
endif()
|
||||
if(NOT __available)
|
||||
if(NOT "x${CPU_${OPT}_FLAGS_NAME}" STREQUAL "x")
|
||||
set(_varname "HAVE_CPU_${CPU_${OPT}_FLAGS_NAME}")
|
||||
set(_compile_flags "${CPU_BASELINE_FLAGS}")
|
||||
ocv_append_optimization_flag(_compile_flags ${OPT})
|
||||
ocv_check_compiler_flag(CXX "${_compile_flags}" "${_varname}" "${CPU_${OPT}_TEST_FILE}")
|
||||
elseif(NOT "x${CPU_${OPT}_FLAGS_ON}" STREQUAL "x")
|
||||
ocv_check_flag_support(CXX "${CPU_${OPT}_FLAGS_ON}" _varname "" "${CPU_${OPT}_TEST_FILE}")
|
||||
else()
|
||||
set(_varname "HAVE_CPU_${OPT}_SUPPORT")
|
||||
set(_compile_flags "${CPU_BASELINE_FLAGS}")
|
||||
ocv_append_optimization_flag(_compile_flags ${OPT})
|
||||
ocv_check_compiler_flag(CXX "${_compile_flags}" "${_varname}" "${CPU_${OPT}_TEST_FILE}")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
ocv_check_flag_support(CXX "${CPU_${OPT}_FLAGS_ON}" _varname "")
|
||||
endif()
|
||||
if(_varname AND ${_varname})
|
||||
set(CPU_${OPT}_SUPPORTED ON)
|
||||
elseif(NOT CPU_${OPT}_SUPPORTED)
|
||||
message(STATUS "${OPT} is not supported by C++ compiler")
|
||||
endif()
|
||||
else()
|
||||
set(CPU_${OPT}_SUPPORTED ON)
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
foreach(OPT ${CPU_KNOWN_OPTIMIZATIONS})
|
||||
set(CPU_${OPT}_USAGE_COUNT 0 CACHE INTERNAL "")
|
||||
if("${CPU_${OPT}_FLAGS_ON}" STREQUAL "disabled")
|
||||
set(CPU_${OPT}_SUPPORTED OFF)
|
||||
elseif(DEFINED CPU_${OPT}_GROUP)
|
||||
if(NOT DEFINED CPU_${OPT}_IMPLIES)
|
||||
set(CPU_${OPT}_IMPLIES "${CPU_${OPT}_GROUP}")
|
||||
endif()
|
||||
set(__disabled 0)
|
||||
set(__flags "")
|
||||
foreach(OPT2 ${CPU_${OPT}_GROUP})
|
||||
if("${CPU_${OPT2}_FLAGS_ON}" STREQUAL "disabled" OR (DEFINED CPU_${OPT2}_SUPPORTED AND NOT CPU_${OPT}_SUPPORTED))
|
||||
set(__disabled 1)
|
||||
endif()
|
||||
set(__flags "${__flags} ${CPU_${OPT2}_FLAGS_ON}")
|
||||
string(STRIP "${__flags}" __flags)
|
||||
endforeach()
|
||||
if(__disabled)
|
||||
set(CPU_${OPT}_SUPPORTED OFF)
|
||||
else()
|
||||
if(NOT DEFINED CPU_${OPT}_FLAGS_ON)
|
||||
set(CPU_${OPT}_FLAGS_ON "${__flags}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
if(NOT DEFINED CPU_${OPT}_FORCE)
|
||||
set(CPU_${OPT}_FORCE "${CPU_${OPT}_IMPLIES}")
|
||||
endif()
|
||||
#message("${OPT}: CPU_${OPT}_FLAGS_ON=${CPU_${OPT}_FLAGS_ON}")
|
||||
endforeach()
|
||||
|
||||
if(_add_native_flag)
|
||||
set(_varname "HAVE_CPU_NATIVE_SUPPORT")
|
||||
ocv_check_compiler_flag(CXX "-march=native" "${_varname}" "")
|
||||
if(${_varname})
|
||||
set(CPU_BASELINE_FLAGS "${CPU_BASELINE_FLAGS} -march=native")
|
||||
else()
|
||||
set(_varname "HAVE_CPU_HOST_SUPPORT")
|
||||
if(MSVC)
|
||||
set(_flag "/QxHost")
|
||||
else()
|
||||
set(_flag "-xHost")
|
||||
endif()
|
||||
ocv_check_compiler_flag(CXX "${_flag}" "${_varname}" "")
|
||||
if(${_varname})
|
||||
set(CPU_BASELINE_FLAGS "${CPU_BASELINE_FLAGS} ${_flag}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
foreach(OPT ${CPU_KNOWN_OPTIMIZATIONS})
|
||||
set(__is_disabled 0)
|
||||
foreach(OPT2 ${CPU_BASELINE_DISABLE})
|
||||
ocv_is_optimization_in_list(__is_disabled ${OPT2} ${OPT})
|
||||
if(__is_disabled)
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
if(__is_disabled)
|
||||
set(__is_from_baseline 0)
|
||||
else()
|
||||
if(CPU_${OPT}_SUPPORTED AND CPU_BASELINE_DETECT)
|
||||
list(APPEND CPU_BASELINE_FINAL ${OPT})
|
||||
endif()
|
||||
ocv_is_optimization_in_list(__is_from_baseline ${OPT} ${CPU_BASELINE_REQUIRE})
|
||||
if(NOT __is_from_baseline)
|
||||
ocv_is_optimization_in_list(__is_from_baseline ${OPT} ${CPU_BASELINE})
|
||||
endif()
|
||||
endif()
|
||||
ocv_is_optimization_in_list(__is_from_dispatch ${OPT} ${CPU_DISPATCH_REQUIRE})
|
||||
if(NOT __is_from_dispatch)
|
||||
ocv_is_optimization_in_list(__is_from_dispatch ${OPT} ${CPU_DISPATCH})
|
||||
endif()
|
||||
if(__is_from_dispatch OR __is_from_baseline OR CPU_BASELINE_DETECT)
|
||||
ocv_check_compiler_optimization(${OPT})
|
||||
endif()
|
||||
if(CPU_BASELINE_DETECT AND NOT __is_from_baseline AND NOT __is_disabled)
|
||||
ocv_is_optimization_in_list(__is_from_baseline ${OPT} ${CPU_BASELINE_FINAL})
|
||||
endif()
|
||||
if(CPU_${OPT}_SUPPORTED)
|
||||
if(";${CPU_DISPATCH};" MATCHES ";${OPT};" AND NOT __is_from_baseline)
|
||||
list(APPEND CPU_DISPATCH_FINAL ${OPT})
|
||||
elseif(__is_from_baseline)
|
||||
if(NOT ";${CPU_BASELINE_FINAL};" MATCHES ";${OPT};")
|
||||
list(APPEND CPU_BASELINE_FINAL ${OPT})
|
||||
endif()
|
||||
if(NOT CPU_${OPT}_ENABLED_DEFAULT) # Don't change compiler flags in 'detection' mode
|
||||
ocv_append_optimization_flag(CPU_BASELINE_FLAGS ${OPT})
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
foreach(OPT ${CPU_BASELINE_REQUIRE})
|
||||
if(NOT ";${CPU_BASELINE_FINAL};" MATCHES ";${OPT};")
|
||||
message(SEND_ERROR "Required baseline optimization is not supported: ${OPT} (CPU_BASELINE_REQUIRE=${CPU_BASELINE_REQUIRE})")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
foreach(OPT ${CPU_BASELINE})
|
||||
if(OPT STREQUAL "DETECT" OR OPT STREQUAL "HOST" OR OPT STREQUAL "NATIVE")
|
||||
# nothing
|
||||
elseif(NOT ";${CPU_BASELINE_FINAL};" MATCHES ";${OPT};")
|
||||
message(STATUS "Optimization ${OPT} is not available, skipped")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
foreach(OPT ${CPU_DISPATCH_REQUIRE})
|
||||
if(";${CPU_DISPATCH_FINAL};" MATCHES ";${OPT};")
|
||||
# OK
|
||||
elseif(";${CPU_BASELINE_FINAL};" MATCHES ";${OPT};")
|
||||
message(SEND_ERROR "Dispatched optimization ${OPT} is in baseline list (CPU_DISPATCH_REQUIRE=${CPU_DISPATCH_REQUIRE})")
|
||||
else()
|
||||
message(SEND_ERROR "Required dispatch optimization is not supported: ${OPT} (CPU_DISPATCH_REQUIRE=${CPU_DISPATCH_REQUIRE})")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
foreach(OPT ${CPU_DISPATCH})
|
||||
if(";${CPU_DISPATCH_FINAL};" MATCHES ";${OPT};")
|
||||
# OK
|
||||
elseif(";${CPU_BASELINE_FINAL};" MATCHES ";${OPT};")
|
||||
# OK
|
||||
else()
|
||||
message(STATUS "Dispatch optimization ${OPT} is not available, skipped")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
#message(STATUS "CPU_BASELINE_FINAL=${CPU_BASELINE_FINAL}")
|
||||
#message(STATUS "CPU_DISPATCH_FINAL=${CPU_DISPATCH_FINAL}")
|
||||
|
||||
#if(CPU_DISPATCH_FINAL AND NOT PYTHON_DEFAULT_EXECUTABLE)
|
||||
# message(FATAL_ERROR "Python is required for CPU dispatched optimization support")
|
||||
#endif()
|
||||
|
||||
macro(ocv_compiler_optimization_options)
|
||||
set(__flags "${OPENCV_EXTRA_CXX_FLAGS} ${CPU_BASELINE_FLAGS}")
|
||||
if(NOT __flags STREQUAL CACHED_CPU_BASELINE_FLAGS)
|
||||
set(CACHED_CPU_BASELINE_FLAGS "${__flags}" CACHE INTERNAL "" FORCE)
|
||||
ocv_clear_vars(HAVE_CPU_BASELINE_FLAGS)
|
||||
endif()
|
||||
ocv_check_compiler_flag(CXX "${__flags}" HAVE_CPU_BASELINE_FLAGS)
|
||||
if(NOT HAVE_CPU_BASELINE_FLAGS)
|
||||
message(FATAL_ERROR "Compiler doesn't support baseline optimization flags: ${CPU_BASELINE_FLAGS}")
|
||||
endif()
|
||||
add_extra_compiler_option_force("${CPU_BASELINE_FLAGS}")
|
||||
|
||||
foreach(OPT ${CPU_DISPATCH_FINAL})
|
||||
set(__dispatch_flags "")
|
||||
set(__dispatch_definitions "")
|
||||
set(__dispatch_opts "")
|
||||
set(__dispatch_opts_force "")
|
||||
foreach(OPT2 ${CPU_KNOWN_OPTIMIZATIONS})
|
||||
if(NOT CPU_${OPT2}_SUPPORTED)
|
||||
#continue()
|
||||
else()
|
||||
ocv_is_optimization_in_list(__is_from_baseline ${OPT2} ${CPU_BASELINE_FINAL})
|
||||
if(NOT __is_from_baseline)
|
||||
ocv_is_optimization_in_list(__is_active ${OPT2} ${OPT})
|
||||
if(__is_active)
|
||||
ocv_append_optimization_flag(__dispatch_flags ${OPT2})
|
||||
list(APPEND __dispatch_definitions "CV_CPU_COMPILE_${OPT2}=1")
|
||||
list(APPEND __dispatch_opts "${OPT2}")
|
||||
endif()
|
||||
ocv_is_optimization_in_force_list(__is_force ${OPT2} ${OPT})
|
||||
if(__is_force)
|
||||
list(APPEND __dispatch_opts_force "${OPT2}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
set(__flags "${OPENCV_EXTRA_CXX_FLAGS} ${__dispatch_flags}")
|
||||
if(NOT __flags STREQUAL CACHED_CPU_DISPATCH_${OPT}_FLAGS)
|
||||
set(CACHED_CPU_DISPATCH_${OPT}_FLAGS "${__flags}" CACHE INTERNAL "" FORCE)
|
||||
ocv_clear_vars(HAVE_CPU_DISPATCH_FLAGS_${OPT})
|
||||
endif()
|
||||
ocv_check_compiler_flag(CXX "${__flags}" HAVE_CPU_DISPATCH_FLAGS_${OPT})
|
||||
if(NOT HAVE_CPU_DISPATCH_FLAGS_${OPT})
|
||||
message(FATAL_ERROR "Compiler doesn't support optimization flags for ${OPT} dispatch mode: ${__dispatch_flags}")
|
||||
endif()
|
||||
set(CPU_DISPATCH_FLAGS_${OPT} "${__dispatch_flags}")
|
||||
set(CPU_DISPATCH_DEFINITIONS_${OPT} "${__dispatch_definitions}")
|
||||
set(CPU_DISPATCH_${OPT}_INCLUDED "${__dispatch_opts}")
|
||||
set(CPU_DISPATCH_${OPT}_FORCED "${__dispatch_opts_force}")
|
||||
endforeach()
|
||||
|
||||
if(ENABLE_POWERPC)
|
||||
add_extra_compiler_option("-mcpu=G3 -mtune=G5")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(ocv_compiler_optimization_options_finalize)
|
||||
if((CV_GCC OR CV_CLANG) AND (X86 OR X86_64))
|
||||
if(NOT APPLE AND CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
if(OPENCV_EXTRA_CXX_FLAGS MATCHES "-m(sse2|avx)")
|
||||
add_extra_compiler_option(-mfpmath=sse) # !! important - be on the same wave with x64 compilers
|
||||
else()
|
||||
add_extra_compiler_option(-mfpmath=387)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
# Generate Intrinsic Functions
|
||||
set(OPENCV_EXTRA_FLAGS "${OPENCV_EXTRA_FLAGS} /Oi")
|
||||
endif(MSVC)
|
||||
endmacro()
|
||||
|
||||
macro(ocv_compiler_optimization_process_sources SOURCES_VAR_NAME LIBS_VAR_NAME TARGET_BASE_NAME)
|
||||
set(__result "")
|
||||
set(__result_libs "")
|
||||
foreach(OPT ${CPU_DISPATCH_FINAL})
|
||||
set(__result_${OPT} "")
|
||||
endforeach()
|
||||
foreach(fname ${${SOURCES_VAR_NAME}})
|
||||
string(TOLOWER "${fname}" fname_LOWER)
|
||||
get_filename_component(fname_LOWER "${fname_LOWER}" NAME)
|
||||
if(fname_LOWER MATCHES ".+\\.([^\\.]*)\\.cpp$")
|
||||
string(TOUPPER "${CMAKE_MATCH_1}" OPT_)
|
||||
if(OPT_ MATCHES "(CUDA.*|DISPATCH.*|OCL)") # don't touch files like filename.cuda.cpp
|
||||
list(APPEND __result "${fname}")
|
||||
#continue()
|
||||
elseif(CV_DISABLE_OPTIMIZATION OR NOT CV_ENABLE_INTRINSICS)
|
||||
ocv_get_smart_file_name(fname_ "${fname}")
|
||||
message(STATUS "Excluding from source files list (optimization is disabled): ${fname_}")
|
||||
#continue()
|
||||
else()
|
||||
get_source_file_property(__definitions "${fname}" COMPILE_DEFINITIONS)
|
||||
if(__definitions)
|
||||
list(APPEND __definitions "CV_CPU_DISPATCH_MODE=${OPT_}")
|
||||
else()
|
||||
set(__definitions "CV_CPU_DISPATCH_MODE=${OPT_}")
|
||||
endif()
|
||||
set_source_files_properties("${fname}" PROPERTIES COMPILE_DEFINITIONS "${__definitions}")
|
||||
|
||||
set(__opt_found 0)
|
||||
foreach(OPT ${CPU_BASELINE_FINAL})
|
||||
string(TOLOWER "${OPT}" OPT_LOWER)
|
||||
if(fname_LOWER MATCHES "\\.${OPT_LOWER}\\.cpp$")
|
||||
#message("${fname} BASELINE-${OPT}")
|
||||
set(__opt_found 1)
|
||||
list(APPEND __result "${fname}")
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
foreach(OPT ${CPU_DISPATCH_FINAL})
|
||||
foreach(OPT2 ${CPU_DISPATCH_${OPT}_FORCED})
|
||||
string(TOLOWER "${OPT2}" OPT2_LOWER)
|
||||
if(fname_LOWER MATCHES "\\.${OPT2_LOWER}\\.cpp$")
|
||||
list(APPEND __result_${OPT} "${fname}")
|
||||
math(EXPR CPU_${OPT}_USAGE_COUNT "${CPU_${OPT}_USAGE_COUNT}+1")
|
||||
set(CPU_${OPT}_USAGE_COUNT "${CPU_${OPT}_USAGE_COUNT}" CACHE INTERNAL "" FORCE)
|
||||
#message("(${CPU_${OPT}_USAGE_COUNT})${fname} ${OPT}")
|
||||
#message(" ${CPU_DISPATCH_${OPT}_INCLUDED}")
|
||||
#message(" ${CPU_DISPATCH_DEFINITIONS_${OPT}}")
|
||||
#message(" ${CPU_DISPATCH_FLAGS_${OPT}}")
|
||||
set(__opt_found 1)
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
if(__opt_found)
|
||||
set(__opt_found 1)
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
if(NOT __opt_found)
|
||||
ocv_get_smart_file_name(fname_ "${fname}")
|
||||
message(STATUS "Excluding from source files list: ${fname_}")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
list(APPEND __result "${fname}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
foreach(OPT ${CPU_DISPATCH_FINAL})
|
||||
if(__result_${OPT})
|
||||
#message("${OPT}: ${__result_${OPT}}")
|
||||
if(CMAKE_GENERATOR MATCHES "^Visual"
|
||||
OR OPENCV_CMAKE_CPU_OPTIMIZATIONS_FORCE_TARGETS
|
||||
)
|
||||
# MSVS generator is not able to properly order compilation flags:
|
||||
# extra flags are added before common flags, so switching between optimizations doesn't work correctly
|
||||
# Also CMAKE_CXX_FLAGS doesn't work (it is directory-based, so add_subdirectory is required)
|
||||
add_library(${TARGET_BASE_NAME}_${OPT} OBJECT ${__result_${OPT}})
|
||||
ocv_append_dependant_targets(${TARGET_BASE_NAME} ${TARGET_BASE_NAME}_${OPT})
|
||||
set_target_properties(${TARGET_BASE_NAME}_${OPT} PROPERTIES COMPILE_DEFINITIONS "${CPU_DISPATCH_DEFINITIONS_${OPT}}")
|
||||
set_target_properties(${TARGET_BASE_NAME}_${OPT} PROPERTIES COMPILE_FLAGS "${CPU_DISPATCH_FLAGS_${OPT}}")
|
||||
target_include_directories(${TARGET_BASE_NAME}_${OPT} PRIVATE $<TARGET_PROPERTY:${TARGET_BASE_NAME},INCLUDE_DIRECTORIES>)
|
||||
#list(APPEND __result_libs ${TARGET_BASE_NAME}_${OPT})
|
||||
list(APPEND __result "$<TARGET_OBJECTS:${TARGET_BASE_NAME}_${OPT}>")
|
||||
if(ENABLE_SOLUTION_FOLDERS)
|
||||
set_target_properties(${TARGET_BASE_NAME}_${OPT} PROPERTIES FOLDER "dispatched")
|
||||
endif()
|
||||
else()
|
||||
foreach(fname ${__result_${OPT}})
|
||||
get_source_file_property(__definitions "${fname}" COMPILE_DEFINITIONS)
|
||||
if(__definitions)
|
||||
list(APPEND __definitions "${CPU_DISPATCH_DEFINITIONS_${OPT}}")
|
||||
else()
|
||||
set(__definitions "${CPU_DISPATCH_DEFINITIONS_${OPT}}")
|
||||
endif()
|
||||
set_source_files_properties("${fname}" PROPERTIES COMPILE_DEFINITIONS "${__definitions}")
|
||||
set_source_files_properties("${fname}" PROPERTIES COMPILE_FLAGS "${CPU_DISPATCH_FLAGS_${OPT}}")
|
||||
endforeach()
|
||||
list(APPEND __result ${__result_${OPT}})
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
set(${SOURCES_VAR_NAME} "${__result}")
|
||||
list(APPEND ${LIBS_VAR_NAME} ${__result_libs})
|
||||
endmacro()
|
||||
|
||||
macro(ocv_compiler_optimization_fill_cpu_config)
|
||||
set(OPENCV_CPU_BASELINE_DEFINITIONS_CONFIGMAKE "")
|
||||
foreach(OPT ${CPU_BASELINE_FINAL})
|
||||
set(OPENCV_CPU_BASELINE_DEFINITIONS_CONFIGMAKE "${OPENCV_CPU_BASELINE_DEFINITIONS_CONFIGMAKE}
|
||||
#define CV_CPU_COMPILE_${OPT} 1
|
||||
#define CV_CPU_BASELINE_COMPILE_${OPT} 1
|
||||
")
|
||||
endforeach()
|
||||
|
||||
set(OPENCV_CPU_BASELINE_DEFINITIONS_CONFIGMAKE "${OPENCV_CPU_BASELINE_DEFINITIONS_CONFIGMAKE}
|
||||
#define CV_CPU_BASELINE_FEATURES 0 \\")
|
||||
foreach(OPT ${CPU_BASELINE_FINAL})
|
||||
if(NOT DEFINED CPU_${OPT}_FEATURE_ALIAS OR NOT "x${CPU_${OPT}_FEATURE_ALIAS}" STREQUAL "x")
|
||||
set(OPENCV_CPU_BASELINE_DEFINITIONS_CONFIGMAKE "${OPENCV_CPU_BASELINE_DEFINITIONS_CONFIGMAKE}
|
||||
, CV_CPU_${OPT} \\")
|
||||
endif()
|
||||
endforeach()
|
||||
set(OPENCV_CPU_BASELINE_DEFINITIONS_CONFIGMAKE "${OPENCV_CPU_BASELINE_DEFINITIONS_CONFIGMAKE}\n")
|
||||
|
||||
set(__dispatch_modes "")
|
||||
foreach(OPT ${CPU_DISPATCH_FINAL})
|
||||
list(APPEND __dispatch_modes ${CPU_DISPATCH_${OPT}_FORCE} ${OPT})
|
||||
endforeach()
|
||||
list(REMOVE_DUPLICATES __dispatch_modes)
|
||||
foreach(OPT ${__dispatch_modes})
|
||||
set(OPENCV_CPU_DISPATCH_DEFINITIONS_CONFIGMAKE "${OPENCV_CPU_DISPATCH_DEFINITIONS_CONFIGMAKE}
|
||||
#define CV_CPU_DISPATCH_COMPILE_${OPT} 1")
|
||||
endforeach()
|
||||
|
||||
set(OPENCV_CPU_DISPATCH_DEFINITIONS_CONFIGMAKE "${OPENCV_CPU_DISPATCH_DEFINITIONS_CONFIGMAKE}
|
||||
\n\n#define CV_CPU_DISPATCH_FEATURES 0 \\")
|
||||
foreach(OPT ${__dispatch_modes})
|
||||
if(NOT DEFINED CPU_${OPT}_FEATURE_ALIAS OR NOT "x${CPU_${OPT}_FEATURE_ALIAS}" STREQUAL "x")
|
||||
set(OPENCV_CPU_DISPATCH_DEFINITIONS_CONFIGMAKE "${OPENCV_CPU_DISPATCH_DEFINITIONS_CONFIGMAKE}
|
||||
, CV_CPU_${OPT} \\")
|
||||
endif()
|
||||
endforeach()
|
||||
set(OPENCV_CPU_DISPATCH_DEFINITIONS_CONFIGMAKE "${OPENCV_CPU_DISPATCH_DEFINITIONS_CONFIGMAKE}\n")
|
||||
|
||||
set(OPENCV_CPU_CONTROL_DEFINITIONS_CONFIGMAKE "// AUTOGENERATED, DO NOT EDIT\n")
|
||||
foreach(OPT ${CPU_ALL_OPTIMIZATIONS})
|
||||
if(NOT DEFINED CPU_${OPT}_FEATURE_ALIAS OR NOT "x${CPU_${OPT}_FEATURE_ALIAS}" STREQUAL "x")
|
||||
set(OPENCV_CPU_CONTROL_DEFINITIONS_CONFIGMAKE "${OPENCV_CPU_CONTROL_DEFINITIONS_CONFIGMAKE}
|
||||
#if !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_COMPILE_${OPT}
|
||||
# define CV_TRY_${OPT} 1
|
||||
# define CV_CPU_FORCE_${OPT} 1
|
||||
# define CV_CPU_HAS_SUPPORT_${OPT} 1
|
||||
# define CV_CPU_CALL_${OPT}(fn, args) return (cpu_baseline::fn args)
|
||||
# define CV_CPU_CALL_${OPT}_(fn, args) return (opt_${OPT}::fn args)
|
||||
#elif !defined CV_DISABLE_OPTIMIZATION && defined CV_ENABLE_INTRINSICS && defined CV_CPU_DISPATCH_COMPILE_${OPT}
|
||||
# define CV_TRY_${OPT} 1
|
||||
# define CV_CPU_FORCE_${OPT} 0
|
||||
# define CV_CPU_HAS_SUPPORT_${OPT} (cv::checkHardwareSupport(CV_CPU_${OPT}))
|
||||
# define CV_CPU_CALL_${OPT}(fn, args) if (CV_CPU_HAS_SUPPORT_${OPT}) return (opt_${OPT}::fn args)
|
||||
# define CV_CPU_CALL_${OPT}_(fn, args) if (CV_CPU_HAS_SUPPORT_${OPT}) return (opt_${OPT}::fn args)
|
||||
#else
|
||||
# define CV_TRY_${OPT} 0
|
||||
# define CV_CPU_FORCE_${OPT} 0
|
||||
# define CV_CPU_HAS_SUPPORT_${OPT} 0
|
||||
# define CV_CPU_CALL_${OPT}(fn, args)
|
||||
# define CV_CPU_CALL_${OPT}_(fn, args)
|
||||
#endif
|
||||
#define __CV_CPU_DISPATCH_CHAIN_${OPT}(fn, args, mode, ...) CV_CPU_CALL_${OPT}(fn, args); __CV_EXPAND(__CV_CPU_DISPATCH_CHAIN_ ## mode(fn, args, __VA_ARGS__))
|
||||
")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
set(OPENCV_CPU_CONTROL_DEFINITIONS_CONFIGMAKE "${OPENCV_CPU_CONTROL_DEFINITIONS_CONFIGMAKE}
|
||||
#define CV_CPU_CALL_BASELINE(fn, args) return (cpu_baseline::fn args)
|
||||
#define __CV_CPU_DISPATCH_CHAIN_BASELINE(fn, args, mode, ...) CV_CPU_CALL_BASELINE(fn, args) /* last in sequence */
|
||||
")
|
||||
|
||||
|
||||
set(__file "${OpenCV_SOURCE_DIR}/modules/core/include/opencv2/core/cv_cpu_helper.h")
|
||||
if(EXISTS "${__file}")
|
||||
file(READ "${__file}" __content)
|
||||
endif()
|
||||
if(__content STREQUAL OPENCV_CPU_CONTROL_DEFINITIONS_CONFIGMAKE)
|
||||
#message(STATUS "${__file} contains same content")
|
||||
else()
|
||||
file(WRITE "${__file}" "${OPENCV_CPU_CONTROL_DEFINITIONS_CONFIGMAKE}")
|
||||
message(WARNING "${__file} is updated")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(__ocv_add_dispatched_file filename target_src_var src_directory dst_directory precomp_hpp optimizations_var)
|
||||
if(NOT OPENCV_INITIAL_PASS)
|
||||
set(__codestr "
|
||||
#include \"${src_directory}/${precomp_hpp}\"
|
||||
#include \"${src_directory}/${filename}.simd.hpp\"
|
||||
")
|
||||
|
||||
set(__declarations_str "#define CV_CPU_SIMD_FILENAME \"${src_directory}/${filename}.simd.hpp\"")
|
||||
set(__dispatch_modes "BASELINE")
|
||||
|
||||
set(__optimizations "${${optimizations_var}}")
|
||||
if(CV_DISABLE_OPTIMIZATION OR NOT CV_ENABLE_INTRINSICS)
|
||||
set(__optimizations "")
|
||||
endif()
|
||||
|
||||
foreach(OPT ${__optimizations})
|
||||
string(TOLOWER "${OPT}" OPT_LOWER)
|
||||
set(__file "${CMAKE_CURRENT_BINARY_DIR}/${dst_directory}${filename}.${OPT_LOWER}.cpp")
|
||||
if(EXISTS "${__file}")
|
||||
file(READ "${__file}" __content)
|
||||
else()
|
||||
set(__content "")
|
||||
endif()
|
||||
if(__content STREQUAL __codestr)
|
||||
#message(STATUS "${__file} contains up-to-date content")
|
||||
else()
|
||||
file(WRITE "${__file}" "${__codestr}")
|
||||
endif()
|
||||
|
||||
if(";${CPU_DISPATCH_FINAL};" MATCHES "${OPT}" OR __CPU_DISPATCH_INCLUDE_ALL)
|
||||
if(EXISTS "${src_directory}/${filename}.${OPT_LOWER}.cpp")
|
||||
message(STATUS "Using overridden ${OPT} source: ${src_directory}/${filename}.${OPT_LOWER}.cpp")
|
||||
else()
|
||||
list(APPEND ${target_src_var} "${__file}")
|
||||
endif()
|
||||
|
||||
set(__declarations_str "${__declarations_str}
|
||||
#define CV_CPU_DISPATCH_MODE ${OPT}
|
||||
#include \"opencv2/core/private/cv_cpu_include_simd_declarations.hpp\"
|
||||
")
|
||||
set(__dispatch_modes "${OPT}, ${__dispatch_modes}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
set(__declarations_str "${__declarations_str}
|
||||
#define CV_CPU_DISPATCH_MODES_ALL ${__dispatch_modes}
|
||||
|
||||
#undef CV_CPU_SIMD_FILENAME
|
||||
")
|
||||
|
||||
set(__file "${CMAKE_CURRENT_BINARY_DIR}/${dst_directory}${filename}.simd_declarations.hpp")
|
||||
if(EXISTS "${__file}")
|
||||
file(READ "${__file}" __content)
|
||||
endif()
|
||||
if(__content STREQUAL __declarations_str)
|
||||
#message(STATUS "${__file} contains up-to-date content")
|
||||
else()
|
||||
file(WRITE "${__file}" "${__declarations_str}")
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(ocv_add_dispatched_file filename)
|
||||
set(__optimizations "${ARGN}")
|
||||
if(" ${ARGV1}" STREQUAL " TEST")
|
||||
list(REMOVE_AT __optimizations 0)
|
||||
__ocv_add_dispatched_file("${filename}" "OPENCV_MODULE_${the_module}_TEST_SOURCES_DISPATCHED" "${CMAKE_CURRENT_LIST_DIR}/test" "test/" "test_precomp.hpp" __optimizations)
|
||||
else()
|
||||
__ocv_add_dispatched_file("${filename}" "OPENCV_MODULE_${the_module}_SOURCES_DISPATCHED" "${CMAKE_CURRENT_LIST_DIR}/src" "" "precomp.hpp" __optimizations)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
||||
# Workaround to support code which always require all code paths
|
||||
macro(ocv_add_dispatched_file_force_all)
|
||||
set(__CPU_DISPATCH_INCLUDE_ALL 1)
|
||||
ocv_add_dispatched_file(${ARGN})
|
||||
unset(__CPU_DISPATCH_INCLUDE_ALL)
|
||||
endmacro()
|
||||
|
||||
|
||||
if(CV_DISABLE_OPTIMIZATION OR CV_ICC)
|
||||
ocv_update(CV_ENABLE_UNROLLED 0)
|
||||
else()
|
||||
ocv_update(CV_ENABLE_UNROLLED 1)
|
||||
endif()
|
|
@ -0,0 +1,431 @@
|
|||
if("${CMAKE_CXX_COMPILER};${CMAKE_C_COMPILER};${CMAKE_CXX_COMPILER_LAUNCHER}" MATCHES "ccache")
|
||||
set(CMAKE_COMPILER_IS_CCACHE 1) # TODO: FIXIT Avoid setting of CMAKE_ variables
|
||||
set(OPENCV_COMPILER_IS_CCACHE 1)
|
||||
endif()
|
||||
function(access_CMAKE_COMPILER_IS_CCACHE)
|
||||
if(NOT OPENCV_SUPPRESS_DEPRECATIONS)
|
||||
message(WARNING "DEPRECATED: CMAKE_COMPILER_IS_CCACHE is replaced to OPENCV_COMPILER_IS_CCACHE.")
|
||||
endif()
|
||||
endfunction()
|
||||
variable_watch(CMAKE_COMPILER_IS_CCACHE access_CMAKE_COMPILER_IS_CCACHE)
|
||||
if(ENABLE_CCACHE AND NOT OPENCV_COMPILER_IS_CCACHE AND NOT CMAKE_GENERATOR MATCHES "Xcode")
|
||||
# This works fine with Unix Makefiles and Ninja generators
|
||||
find_host_program(CCACHE_PROGRAM ccache)
|
||||
if(CCACHE_PROGRAM)
|
||||
message(STATUS "Looking for ccache - found (${CCACHE_PROGRAM})")
|
||||
get_property(__OLD_RULE_LAUNCH_COMPILE GLOBAL PROPERTY RULE_LAUNCH_COMPILE)
|
||||
if(__OLD_RULE_LAUNCH_COMPILE)
|
||||
message(STATUS "Can't replace CMake compiler launcher")
|
||||
else()
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
|
||||
# NOTE: Actually this check doesn't work as expected.
|
||||
# "RULE_LAUNCH_COMPILE" is ignored by CMake during try_compile() step.
|
||||
# ocv_check_compiler_flag(CXX "" IS_CCACHE_WORKS)
|
||||
set(IS_CCACHE_WORKS 1)
|
||||
if(IS_CCACHE_WORKS)
|
||||
set(OPENCV_COMPILER_IS_CCACHE 1)
|
||||
else()
|
||||
message(STATUS "Unable to compile program with enabled ccache, reverting...")
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${__OLD_RULE_LAUNCH_COMPILE}")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "Looking for ccache - not found")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if((CV_CLANG AND NOT CMAKE_GENERATOR MATCHES "Xcode") # PCH has no support for Clang
|
||||
OR OPENCV_COMPILER_IS_CCACHE
|
||||
)
|
||||
set(ENABLE_PRECOMPILED_HEADERS OFF CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
|
||||
macro(add_extra_compiler_option option)
|
||||
ocv_check_flag_support(CXX "${option}" _varname "${OPENCV_EXTRA_CXX_FLAGS} ${ARGN}")
|
||||
if(${_varname})
|
||||
set(OPENCV_EXTRA_CXX_FLAGS "${OPENCV_EXTRA_CXX_FLAGS} ${option}")
|
||||
endif()
|
||||
|
||||
ocv_check_flag_support(C "${option}" _varname "${OPENCV_EXTRA_C_FLAGS} ${ARGN}")
|
||||
if(${_varname})
|
||||
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} ${option}")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(add_extra_compiler_option_force option)
|
||||
set(OPENCV_EXTRA_CXX_FLAGS "${OPENCV_EXTRA_CXX_FLAGS} ${option}")
|
||||
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} ${option}")
|
||||
endmacro()
|
||||
|
||||
|
||||
# Gets environment variable and puts its value to the corresponding preprocessor definition
|
||||
# Useful for WINRT that has no access to environment variables
|
||||
macro(add_env_definitions option)
|
||||
set(value $ENV{${option}})
|
||||
if("${value}" STREQUAL "")
|
||||
message(WARNING "${option} environment variable is empty. Please set it to appropriate location to get correct results")
|
||||
else()
|
||||
string(REPLACE "\\" "\\\\" value ${value})
|
||||
endif()
|
||||
add_definitions("-D${option}=\"${value}\"")
|
||||
endmacro()
|
||||
|
||||
if(NOT MSVC)
|
||||
# OpenCV fails some tests when 'char' is 'unsigned' by default
|
||||
add_extra_compiler_option(-fsigned-char)
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
if(NOT " ${CMAKE_CXX_FLAGS} ${OPENCV_EXTRA_FLAGS} ${OPENCV_EXTRA_CXX_FLAGS}" MATCHES " /fp:")
|
||||
if(ENABLE_FAST_MATH)
|
||||
add_extra_compiler_option("/fp:fast")
|
||||
else()
|
||||
add_extra_compiler_option("/fp:precise")
|
||||
endif()
|
||||
endif()
|
||||
elseif(CV_ICC)
|
||||
if(NOT " ${CMAKE_CXX_FLAGS} ${OPENCV_EXTRA_FLAGS} ${OPENCV_EXTRA_CXX_FLAGS}" MATCHES " /fp:"
|
||||
AND NOT " ${CMAKE_CXX_FLAGS} ${OPENCV_EXTRA_FLAGS} ${OPENCV_EXTRA_CXX_FLAGS}" MATCHES " -fp-model"
|
||||
)
|
||||
if(NOT ENABLE_FAST_MATH)
|
||||
add_extra_compiler_option("-fp-model precise")
|
||||
endif()
|
||||
endif()
|
||||
elseif(CV_GCC OR CV_CLANG)
|
||||
if(ENABLE_FAST_MATH)
|
||||
add_extra_compiler_option(-ffast-math)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CV_GCC OR CV_CLANG)
|
||||
# High level of warnings.
|
||||
add_extra_compiler_option(-W)
|
||||
if (NOT MSVC)
|
||||
# clang-cl interprets -Wall as MSVC would: -Weverything, which is more than
|
||||
# we want.
|
||||
add_extra_compiler_option(-Wall)
|
||||
endif()
|
||||
add_extra_compiler_option(-Werror=return-type)
|
||||
add_extra_compiler_option(-Werror=non-virtual-dtor)
|
||||
add_extra_compiler_option(-Werror=address)
|
||||
add_extra_compiler_option(-Werror=sequence-point)
|
||||
add_extra_compiler_option(-Wformat)
|
||||
add_extra_compiler_option(-Werror=format-security -Wformat)
|
||||
add_extra_compiler_option(-Wmissing-declarations)
|
||||
add_extra_compiler_option(-Wmissing-prototypes)
|
||||
add_extra_compiler_option(-Wstrict-prototypes)
|
||||
add_extra_compiler_option(-Wundef)
|
||||
add_extra_compiler_option(-Winit-self)
|
||||
add_extra_compiler_option(-Wpointer-arith)
|
||||
if(NOT (CV_GCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "5.0"))
|
||||
add_extra_compiler_option(-Wshadow) # old GCC emits warnings for variables + methods combination
|
||||
endif()
|
||||
add_extra_compiler_option(-Wsign-promo)
|
||||
add_extra_compiler_option(-Wuninitialized)
|
||||
add_extra_compiler_option(-Winit-self)
|
||||
if(CV_GCC AND (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 6.0) AND (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0))
|
||||
add_extra_compiler_option(-Wno-psabi)
|
||||
endif()
|
||||
if(HAVE_CXX11)
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT ENABLE_PRECOMPILED_HEADERS)
|
||||
add_extra_compiler_option(-Wsuggest-override)
|
||||
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
add_extra_compiler_option(-Winconsistent-missing-override)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ENABLE_NOISY_WARNINGS)
|
||||
add_extra_compiler_option(-Wcast-align)
|
||||
add_extra_compiler_option(-Wstrict-aliasing=2)
|
||||
else()
|
||||
add_extra_compiler_option(-Wno-delete-non-virtual-dtor)
|
||||
add_extra_compiler_option(-Wno-unnamed-type-template-args)
|
||||
add_extra_compiler_option(-Wno-comment)
|
||||
if(NOT OPENCV_SKIP_IMPLICIT_FALLTHROUGH
|
||||
AND NOT " ${CMAKE_CXX_FLAGS} ${OPENCV_EXTRA_FLAGS} ${OPENCV_EXTRA_CXX_FLAGS}" MATCHES "implicit-fallthrough"
|
||||
AND (CV_GCC AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0.0)
|
||||
)
|
||||
add_extra_compiler_option(-Wimplicit-fallthrough=3)
|
||||
endif()
|
||||
if(CV_GCC AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7.0)
|
||||
add_extra_compiler_option(-Wno-strict-overflow) # Issue appears when compiling surf.cpp from opencv_contrib/modules/xfeatures2d
|
||||
endif()
|
||||
if(CV_GCC AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
|
||||
add_extra_compiler_option(-Wno-missing-field-initializers) # GCC 4.x emits warnings about {}, fixed in GCC 5+
|
||||
endif()
|
||||
endif()
|
||||
add_extra_compiler_option(-fdiagnostics-show-option)
|
||||
|
||||
# The -Wno-long-long is required in 64bit systems when including system headers.
|
||||
if(X86_64)
|
||||
add_extra_compiler_option(-Wno-long-long)
|
||||
endif()
|
||||
|
||||
# We need pthread's
|
||||
if(UNIX AND NOT ANDROID AND NOT (APPLE AND CV_CLANG)) # TODO
|
||||
add_extra_compiler_option(-pthread)
|
||||
endif()
|
||||
|
||||
if(CV_CLANG)
|
||||
add_extra_compiler_option(-Qunused-arguments)
|
||||
endif()
|
||||
|
||||
if(OPENCV_WARNINGS_ARE_ERRORS)
|
||||
add_extra_compiler_option(-Werror)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
add_extra_compiler_option(-Wno-semicolon-before-method-body)
|
||||
endif()
|
||||
|
||||
# Other optimizations
|
||||
if(ENABLE_OMIT_FRAME_POINTER)
|
||||
add_extra_compiler_option(-fomit-frame-pointer)
|
||||
elseif(DEFINED ENABLE_OMIT_FRAME_POINTER)
|
||||
add_extra_compiler_option(-fno-omit-frame-pointer)
|
||||
endif()
|
||||
|
||||
# Profiling?
|
||||
if(ENABLE_PROFILING)
|
||||
add_extra_compiler_option("-pg -g")
|
||||
# turn off incompatible options
|
||||
foreach(flags CMAKE_CXX_FLAGS CMAKE_C_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG CMAKE_C_FLAGS_DEBUG
|
||||
OPENCV_EXTRA_FLAGS_RELEASE OPENCV_EXTRA_FLAGS_DEBUG OPENCV_EXTRA_C_FLAGS OPENCV_EXTRA_CXX_FLAGS)
|
||||
string(REPLACE "-fomit-frame-pointer" "" ${flags} "${${flags}}")
|
||||
string(REPLACE "-ffunction-sections" "" ${flags} "${${flags}}")
|
||||
string(REPLACE "-fdata-sections" "" ${flags} "${${flags}}")
|
||||
endforeach()
|
||||
else()
|
||||
if(MSVC)
|
||||
# TODO: Clang/C2 is not supported
|
||||
elseif(((IOS OR ANDROID) AND NOT BUILD_SHARED_LIBS) AND NOT OPENCV_FORCE_FUNCTIONS_SECTIONS)
|
||||
# don't create separate sections for functions/data, reduce package size
|
||||
else()
|
||||
# Remove unreferenced functions: function level linking
|
||||
add_extra_compiler_option(-ffunction-sections)
|
||||
add_extra_compiler_option(-fdata-sections)
|
||||
if(NOT OPENCV_SKIP_GC_SECTIONS)
|
||||
if(APPLE)
|
||||
set(OPENCV_EXTRA_EXE_LINKER_FLAGS "${OPENCV_EXTRA_EXE_LINKER_FLAGS} -Wl,-dead_strip")
|
||||
set(OPENCV_EXTRA_SHARED_LINKER_FLAGS "${OPENCV_EXTRA_SHARED_LINKER_FLAGS} -Wl,-dead_strip")
|
||||
else()
|
||||
set(OPENCV_EXTRA_EXE_LINKER_FLAGS "${OPENCV_EXTRA_EXE_LINKER_FLAGS} -Wl,--gc-sections")
|
||||
set(OPENCV_EXTRA_SHARED_LINKER_FLAGS "${OPENCV_EXTRA_SHARED_LINKER_FLAGS} -Wl,--gc-sections")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ENABLE_COVERAGE)
|
||||
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} --coverage")
|
||||
set(OPENCV_EXTRA_CXX_FLAGS "${OPENCV_EXTRA_CXX_FLAGS} --coverage")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage")
|
||||
endif()
|
||||
|
||||
if(ENABLE_INSTRUMENTATION)
|
||||
if(NOT HAVE_CXX11)
|
||||
message(WARNING "ENABLE_INSTRUMENTATION requires C++11 support")
|
||||
endif()
|
||||
set(WITH_VTK OFF) # There are issues with VTK 6.0
|
||||
endif()
|
||||
|
||||
if(ENABLE_LTO)
|
||||
add_extra_compiler_option(-flto)
|
||||
endif()
|
||||
if(ENABLE_THIN_LTO)
|
||||
add_extra_compiler_option(-flto=thin)
|
||||
endif()
|
||||
|
||||
set(OPENCV_EXTRA_FLAGS_RELEASE "${OPENCV_EXTRA_FLAGS_RELEASE} -DNDEBUG")
|
||||
if(NOT " ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_DEBUG} ${OPENCV_EXTRA_FLAGS_DEBUG} " MATCHES "-O")
|
||||
set(OPENCV_EXTRA_FLAGS_DEBUG "${OPENCV_EXTRA_FLAGS_DEBUG} -O0")
|
||||
endif()
|
||||
set(OPENCV_EXTRA_FLAGS_DEBUG "${OPENCV_EXTRA_FLAGS_DEBUG} -DDEBUG -D_DEBUG")
|
||||
|
||||
if(BUILD_WITH_DEBUG_INFO)
|
||||
# https://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html
|
||||
# '-g' is equal to '-g2', '-g1' produces minimal information, enough for making backtraces
|
||||
ocv_update(OPENCV_DEBUG_OPTION "-g1")
|
||||
if(NOT " ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE} ${OPENCV_EXTRA_CXX_FLAGS} ${OPENCV_EXTRA_FLAGS_RELEASE}" MATCHES " -g")
|
||||
set(OPENCV_EXTRA_FLAGS_RELEASE "${OPENCV_EXTRA_FLAGS_RELEASE} ${OPENCV_DEBUG_OPTION}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
#TODO Code refactoring is required to resolve security warnings
|
||||
#if(NOT ENABLE_BUILD_HARDENING)
|
||||
set(OPENCV_EXTRA_FLAGS "${OPENCV_EXTRA_FLAGS} /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS")
|
||||
#endif()
|
||||
|
||||
if(BUILD_WITH_DEBUG_INFO)
|
||||
set(OPENCV_EXTRA_FLAGS_RELEASE "${OPENCV_EXTRA_FLAGS_RELEASE} /Zi")
|
||||
set(OPENCV_EXTRA_EXE_LINKER_FLAGS_RELEASE "${OPENCV_EXTRA_EXE_LINKER_FLAGS_RELEASE} /debug")
|
||||
set(OPENCV_EXTRA_SHARED_LINKER_FLAGS_RELEASE "${OPENCV_EXTRA_SHARED_LINKER_FLAGS_RELEASE} /debug")
|
||||
endif()
|
||||
|
||||
# Remove unreferenced functions: function level linking
|
||||
set(OPENCV_EXTRA_FLAGS "${OPENCV_EXTRA_FLAGS} /Gy")
|
||||
if(NOT MSVC_VERSION LESS 1400)
|
||||
set(OPENCV_EXTRA_FLAGS "${OPENCV_EXTRA_FLAGS} /bigobj")
|
||||
endif()
|
||||
|
||||
if(OPENCV_WARNINGS_ARE_ERRORS)
|
||||
set(OPENCV_EXTRA_FLAGS "${OPENCV_EXTRA_FLAGS} /WX")
|
||||
endif()
|
||||
|
||||
if(ENABLE_LTO)
|
||||
set(OPENCV_EXTRA_FLAGS_RELEASE "${OPENCV_EXTRA_FLAGS_RELEASE} /GL")
|
||||
set(OPENCV_EXTRA_EXE_LINKER_FLAGS_RELEASE "${OPENCV_EXTRA_EXE_LINKER_FLAGS_RELEASE} /LTCG")
|
||||
endif()
|
||||
|
||||
if(NOT MSVC_VERSION LESS 1800 AND NOT CMAKE_GENERATOR MATCHES "Visual Studio")
|
||||
set(OPENCV_EXTRA_C_FLAGS "${OPENCV_EXTRA_C_FLAGS} /FS")
|
||||
set(OPENCV_EXTRA_CXX_FLAGS "${OPENCV_EXTRA_CXX_FLAGS} /FS")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include(cmake/OpenCVCompilerOptimizations.cmake)
|
||||
if(COMMAND ocv_compiler_optimization_options)
|
||||
ocv_compiler_optimization_options()
|
||||
endif()
|
||||
if(COMMAND ocv_compiler_optimization_options_finalize)
|
||||
ocv_compiler_optimization_options_finalize()
|
||||
endif()
|
||||
|
||||
# set default visibility to hidden
|
||||
if((CV_GCC OR CV_CLANG)
|
||||
AND NOT MSVC
|
||||
AND NOT OPENCV_SKIP_VISIBILITY_HIDDEN
|
||||
AND NOT " ${CMAKE_CXX_FLAGS} ${OPENCV_EXTRA_FLAGS} ${OPENCV_EXTRA_CXX_FLAGS}" MATCHES " -fvisibility")
|
||||
add_extra_compiler_option(-fvisibility=hidden)
|
||||
add_extra_compiler_option(-fvisibility-inlines-hidden)
|
||||
endif()
|
||||
|
||||
# workaround gcc bug for aligned ld/st
|
||||
# https://github.com/opencv/opencv/issues/13211
|
||||
if((PPC64LE AND NOT CMAKE_CROSSCOMPILING) OR OPENCV_FORCE_COMPILER_CHECK_VSX_ALIGNED)
|
||||
ocv_check_runtime_flag("${CPU_BASELINE_FLAGS}" OPENCV_CHECK_VSX_ALIGNED "${OpenCV_SOURCE_DIR}/cmake/checks/runtime/cpu_vsx_aligned.cpp")
|
||||
if(NOT OPENCV_CHECK_VSX_ALIGNED)
|
||||
add_extra_compiler_option_force(-DCV_COMPILER_VSX_BROKEN_ALIGNED)
|
||||
endif()
|
||||
endif()
|
||||
# validate inline asm with fixes register number and constraints wa, wd, wf
|
||||
if(PPC64LE)
|
||||
ocv_check_compiler_flag(CXX "${CPU_BASELINE_FLAGS}" OPENCV_CHECK_VSX_ASM "${OpenCV_SOURCE_DIR}/cmake/checks/cpu_vsx_asm.cpp")
|
||||
if(NOT OPENCV_CHECK_VSX_ASM)
|
||||
add_extra_compiler_option_force(-DCV_COMPILER_VSX_BROKEN_ASM)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# combine all "extra" options
|
||||
if(NOT OPENCV_SKIP_EXTRA_COMPILER_FLAGS)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OPENCV_EXTRA_FLAGS} ${OPENCV_EXTRA_C_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OPENCV_EXTRA_FLAGS} ${OPENCV_EXTRA_CXX_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${OPENCV_EXTRA_FLAGS_RELEASE}")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${OPENCV_EXTRA_FLAGS_RELEASE}")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${OPENCV_EXTRA_FLAGS_DEBUG}")
|
||||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${OPENCV_EXTRA_FLAGS_DEBUG}")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OPENCV_EXTRA_EXE_LINKER_FLAGS}")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${OPENCV_EXTRA_EXE_LINKER_FLAGS_RELEASE}")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${OPENCV_EXTRA_EXE_LINKER_FLAGS_DEBUG}")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${OPENCV_EXTRA_SHARED_LINKER_FLAGS}")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} ${OPENCV_EXTRA_SHARED_LINKER_FLAGS_RELEASE}")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} ${OPENCV_EXTRA_SHARED_LINKER_FLAGS_DEBUG}")
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
if(NOT ENABLE_NOISY_WARNINGS)
|
||||
if(MSVC_VERSION EQUAL 1400)
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4510 /wd4610 /wd4312 /wd4201 /wd4244 /wd4328 /wd4267)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
foreach(flags CMAKE_C_FLAGS CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG)
|
||||
string(REPLACE "/Zm1000" "" ${flags} "${${flags}}")
|
||||
endforeach()
|
||||
|
||||
# Enable 'extern "C"' and asynchronous (division by zero, access violation) exceptions
|
||||
if(NOT OPENCV_SKIP_MSVC_EXCEPTIONS_FLAG)
|
||||
foreach(flags CMAKE_C_FLAGS CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG)
|
||||
string(REGEX REPLACE " /EH[^ ]* " " " ${flags} " ${${flags}}")
|
||||
endforeach()
|
||||
if(NOT " ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE} ${CMAKE_CXX_FLAGS_DEBUG}" MATCHES " /EH")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHa")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT ENABLE_NOISY_WARNINGS)
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4127) # conditional expression is constant
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4251) # class 'std::XXX' needs to have dll-interface to be used by clients of YYY
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4324) # 'struct_name' : structure was padded due to __declspec(align())
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4275) # non dll-interface class 'std::exception' used as base for dll-interface class 'cv::Exception'
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4512) # Assignment operator could not be generated
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4589) # Constructor of abstract class 'cv::ORB' ignores initializer for virtual base class 'cv::Algorithm'
|
||||
endif()
|
||||
|
||||
if(CV_ICC AND NOT ENABLE_NOISY_WARNINGS)
|
||||
foreach(flags CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG CMAKE_C_FLAGS CMAKE_C_FLAGS_RELEASE CMAKE_C_FLAGS_DEBUG)
|
||||
string(REGEX REPLACE "( |^)/W[0-9]+( |$)" "\\1\\2" ${flags} "${${flags}}")
|
||||
endforeach()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Qwd673") # PCH warning
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(APPLE AND NOT CMAKE_CROSSCOMPILING AND NOT DEFINED ENV{LDFLAGS} AND EXISTS "/usr/local/lib")
|
||||
link_directories("/usr/local/lib")
|
||||
endif()
|
||||
|
||||
if(ENABLE_BUILD_HARDENING)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/OpenCVCompilerDefenses.cmake)
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
include(cmake/OpenCVCRTLinkage.cmake)
|
||||
add_definitions(-D_VARIADIC_MAX=10)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
get_directory_property(__DIRECTORY_COMPILE_DEFINITIONS COMPILE_DEFINITIONS)
|
||||
if((NOT " ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE} ${OPENCV_EXTRA_CXX_FLAGS} ${OPENCV_EXTRA_FLAGS_RELEASE} ${__DIRECTORY_COMPILE_DEFINITIONS}" MATCHES "_WIN32_WINNT"
|
||||
AND NOT OPENCV_CMAKE_SKIP_MACRO_WIN32_WINNT)
|
||||
OR OPENCV_CMAKE_FORCE_MACRO_WIN32_WINNT
|
||||
)
|
||||
# https://docs.microsoft.com/en-us/cpp/porting/modifying-winver-and-win32-winnt
|
||||
# Target Windows 7 API
|
||||
set(OPENCV_CMAKE_MACRO_WIN32_WINNT "0x0601" CACHE STRING "Value of _WIN32_WINNT macro")
|
||||
add_definitions(-D_WIN32_WINNT=${OPENCV_CMAKE_MACRO_WIN32_WINNT})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Enable compiler options for OpenCV modules/apps/samples only (ignore 3rdparty)
|
||||
macro(ocv_add_modules_compiler_options)
|
||||
if(MSVC AND NOT OPENCV_SKIP_MSVC_W4_OPTION)
|
||||
foreach(flags CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG)
|
||||
string(REPLACE "/W3" "/W4" ${flags} "${${flags}}")
|
||||
endforeach()
|
||||
endif()
|
||||
if(OPENCV_ENABLE_MEMORY_SANITIZER)
|
||||
add_definitions(-DOPENCV_ENABLE_MEMORY_SANITIZER=1)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# adjust -Wl,-rpath-link
|
||||
if(CMAKE_SKIP_RPATH)
|
||||
if((NOT CMAKE_CROSSCOMPILING OR OPENCV_ENABLE_LINKER_RPATH_LINK_ORIGIN) AND NOT OPENCV_SKIP_LINKER_RPATH_LINK_ORIGIN)
|
||||
if(DEFINED CMAKE_SHARED_LIBRARY_RPATH_ORIGIN_TOKEN)
|
||||
list(APPEND CMAKE_PLATFORM_RUNTIME_PATH "${CMAKE_SHARED_LIBRARY_RPATH_ORIGIN_TOKEN}")
|
||||
else()
|
||||
list(APPEND CMAKE_PLATFORM_RUNTIME_PATH "\$ORIGIN")
|
||||
endif()
|
||||
elseif(NOT OPENCV_SKIP_LINKER_RPATH_LINK_BINARY_LIB)
|
||||
list(APPEND CMAKE_PLATFORM_RUNTIME_PATH "${LIBRARY_OUTPUT_PATH}")
|
||||
endif()
|
||||
endif()
|
||||
if(OPENCV_EXTRA_RPATH_LINK_PATH)
|
||||
string(REPLACE ":" ";" OPENCV_EXTRA_RPATH_LINK_PATH_ "${OPENCV_EXTRA_RPATH_LINK_PATH}")
|
||||
list(APPEND CMAKE_PLATFORM_RUNTIME_PATH ${OPENCV_EXTRA_RPATH_LINK_PATH_})
|
||||
if(NOT CMAKE_EXECUTABLE_RPATH_LINK_CXX_FLAG)
|
||||
message(WARNING "OPENCV_EXTRA_RPATH_LINK_PATH may not work properly because CMAKE_EXECUTABLE_RPATH_LINK_CXX_FLAG is not defined (not supported)")
|
||||
endif()
|
||||
endif()
|
|
@ -0,0 +1,34 @@
|
|||
set(OPENCV_JAVA_SOURCE_VERSION "" CACHE STRING "Java source version (javac Ant target)")
|
||||
set(OPENCV_JAVA_TARGET_VERSION "" CACHE STRING "Java target version (javac Ant target)")
|
||||
|
||||
file(TO_CMAKE_PATH "$ENV{ANT_DIR}" ANT_DIR_ENV_PATH)
|
||||
file(TO_CMAKE_PATH "$ENV{ProgramFiles}" ProgramFiles_ENV_PATH)
|
||||
|
||||
if(CMAKE_HOST_WIN32)
|
||||
set(ANT_NAME ant.bat)
|
||||
else()
|
||||
set(ANT_NAME ant)
|
||||
endif()
|
||||
|
||||
find_host_program(ANT_EXECUTABLE NAMES ${ANT_NAME}
|
||||
PATHS "${ANT_DIR_ENV_PATH}/bin" "${ProgramFiles_ENV_PATH}/apache-ant/bin"
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
find_host_program(ANT_EXECUTABLE NAMES ${ANT_NAME})
|
||||
|
||||
if(ANT_EXECUTABLE)
|
||||
execute_process(COMMAND ${ANT_EXECUTABLE} -version
|
||||
RESULT_VARIABLE ANT_ERROR_LEVEL
|
||||
OUTPUT_VARIABLE ANT_VERSION_FULL
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if (ANT_ERROR_LEVEL)
|
||||
unset(ANT_EXECUTABLE)
|
||||
unset(ANT_EXECUTABLE CACHE)
|
||||
else()
|
||||
string(REGEX MATCH "[0-9]+.[0-9]+.[0-9]+" ANT_VERSION "${ANT_VERSION_FULL}")
|
||||
set(ANT_VERSION "${ANT_VERSION}" CACHE INTERNAL "Detected ant version")
|
||||
|
||||
message(STATUS "Found apache ant: ${ANT_EXECUTABLE} (${ANT_VERSION})")
|
||||
endif()
|
||||
endif()
|
|
@ -0,0 +1,388 @@
|
|||
if(WIN32 AND NOT MSVC)
|
||||
message(STATUS "CUDA compilation is disabled (due to only Visual Studio compiler supported on your platform).")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(NOT UNIX AND CV_CLANG)
|
||||
message(STATUS "CUDA compilation is disabled (due to Clang unsupported on your platform).")
|
||||
return()
|
||||
endif()
|
||||
|
||||
|
||||
if(((NOT CMAKE_VERSION VERSION_LESS "3.9.0") # requires https://gitlab.kitware.com/cmake/cmake/merge_requests/663
|
||||
OR OPENCV_CUDA_FORCE_EXTERNAL_CMAKE_MODULE)
|
||||
AND NOT OPENCV_CUDA_FORCE_BUILTIN_CMAKE_MODULE)
|
||||
ocv_update(CUDA_LINK_LIBRARIES_KEYWORD "PRIVATE")
|
||||
find_host_package(CUDA "${MIN_VER_CUDA}" QUIET)
|
||||
else()
|
||||
# Use OpenCV's patched "FindCUDA" module
|
||||
set(CMAKE_MODULE_PATH "${OpenCV_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
|
||||
|
||||
if(ANDROID)
|
||||
set(CUDA_TARGET_OS_VARIANT "Android")
|
||||
endif()
|
||||
find_host_package(CUDA "${MIN_VER_CUDA}" QUIET)
|
||||
|
||||
list(REMOVE_AT CMAKE_MODULE_PATH 0)
|
||||
endif()
|
||||
|
||||
if(CUDA_FOUND)
|
||||
set(HAVE_CUDA 1)
|
||||
|
||||
if(WITH_CUFFT)
|
||||
set(HAVE_CUFFT 1)
|
||||
endif()
|
||||
|
||||
if(WITH_CUBLAS)
|
||||
set(HAVE_CUBLAS 1)
|
||||
endif()
|
||||
|
||||
if(WITH_CUDNN)
|
||||
set(CMAKE_MODULE_PATH "${OpenCV_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
|
||||
find_host_package(CUDNN "${MIN_VER_CUDNN}")
|
||||
list(REMOVE_AT CMAKE_MODULE_PATH 0)
|
||||
|
||||
if(CUDNN_FOUND)
|
||||
set(HAVE_CUDNN 1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_NVCUVID)
|
||||
find_cuda_helper_libs(nvcuvid)
|
||||
if(WIN32)
|
||||
find_cuda_helper_libs(nvcuvenc)
|
||||
endif()
|
||||
if(CUDA_nvcuvid_LIBRARY)
|
||||
set(HAVE_NVCUVID 1)
|
||||
endif()
|
||||
if(CUDA_nvcuvenc_LIBRARY)
|
||||
set(HAVE_NVCUVENC 1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
message(STATUS "CUDA detected: " ${CUDA_VERSION})
|
||||
|
||||
set(_generations "Fermi" "Kepler" "Maxwell" "Pascal" "Volta" "Turing")
|
||||
if(NOT CMAKE_CROSSCOMPILING)
|
||||
list(APPEND _generations "Auto")
|
||||
endif()
|
||||
set(CUDA_GENERATION "" CACHE STRING "Build CUDA device code only for specific GPU architecture. Leave empty to build for all architectures.")
|
||||
if( CMAKE_VERSION VERSION_GREATER "2.8" )
|
||||
set_property( CACHE CUDA_GENERATION PROPERTY STRINGS "" ${_generations} )
|
||||
endif()
|
||||
|
||||
if(CUDA_GENERATION)
|
||||
if(NOT ";${_generations};" MATCHES ";${CUDA_GENERATION};")
|
||||
string(REPLACE ";" ", " _generations "${_generations}")
|
||||
message(FATAL_ERROR "ERROR: ${_generations} Generations are suppered.")
|
||||
endif()
|
||||
unset(CUDA_ARCH_BIN CACHE)
|
||||
unset(CUDA_ARCH_PTX CACHE)
|
||||
endif()
|
||||
|
||||
SET(DETECT_ARCHS_COMMAND "${CUDA_NVCC_EXECUTABLE}" ${CUDA_NVCC_FLAGS} "${OpenCV_SOURCE_DIR}/cmake/checks/OpenCVDetectCudaArch.cu" "--run")
|
||||
if(WIN32 AND CMAKE_LINKER) #Workaround for VS cl.exe not being in the env. path
|
||||
get_filename_component(host_compiler_bindir ${CMAKE_LINKER} DIRECTORY)
|
||||
SET(DETECT_ARCHS_COMMAND ${DETECT_ARCHS_COMMAND} "-ccbin" "${host_compiler_bindir}")
|
||||
endif()
|
||||
|
||||
set(__cuda_arch_ptx "")
|
||||
if(CUDA_GENERATION STREQUAL "Fermi")
|
||||
set(__cuda_arch_bin "2.0")
|
||||
elseif(CUDA_GENERATION STREQUAL "Kepler")
|
||||
set(__cuda_arch_bin "3.0 3.5 3.7")
|
||||
elseif(CUDA_GENERATION STREQUAL "Maxwell")
|
||||
set(__cuda_arch_bin "5.0 5.2")
|
||||
elseif(CUDA_GENERATION STREQUAL "Pascal")
|
||||
set(__cuda_arch_bin "6.0 6.1")
|
||||
elseif(CUDA_GENERATION STREQUAL "Volta")
|
||||
set(__cuda_arch_bin "7.0")
|
||||
elseif(CUDA_GENERATION STREQUAL "Turing")
|
||||
set(__cuda_arch_bin "7.5")
|
||||
elseif(CUDA_GENERATION STREQUAL "Auto")
|
||||
execute_process( COMMAND ${DETECT_ARCHS_COMMAND}
|
||||
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/"
|
||||
RESULT_VARIABLE _nvcc_res OUTPUT_VARIABLE _nvcc_out
|
||||
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
string(REGEX REPLACE ".*\n" "" _nvcc_out "${_nvcc_out}") #Strip leading warning messages, if any
|
||||
if(NOT _nvcc_res EQUAL 0)
|
||||
message(STATUS "Automatic detection of CUDA generation failed. Going to build for all known architectures.")
|
||||
else()
|
||||
set(__cuda_arch_bin "${_nvcc_out}")
|
||||
string(REPLACE "2.1" "2.1(2.0)" __cuda_arch_bin "${__cuda_arch_bin}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED __cuda_arch_bin)
|
||||
if(ARM)
|
||||
set(__cuda_arch_bin "3.2")
|
||||
set(__cuda_arch_ptx "")
|
||||
elseif(AARCH64)
|
||||
execute_process( COMMAND ${DETECT_ARCHS_COMMAND}
|
||||
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/"
|
||||
RESULT_VARIABLE _nvcc_res OUTPUT_VARIABLE _nvcc_out
|
||||
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
string(REGEX REPLACE ".*\n" "" _nvcc_out "${_nvcc_out}") #Strip leading warning messages, if any
|
||||
if(NOT _nvcc_res EQUAL 0)
|
||||
message(STATUS "Automatic detection of CUDA generation failed. Going to build for all known architectures.")
|
||||
set(__cuda_arch_bin "5.3 6.2 7.2")
|
||||
else()
|
||||
set(__cuda_arch_bin "${_nvcc_out}")
|
||||
string(REPLACE "2.1" "2.1(2.0)" __cuda_arch_bin "${__cuda_arch_bin}")
|
||||
endif()
|
||||
set(__cuda_arch_ptx "")
|
||||
else()
|
||||
if(CUDA_VERSION VERSION_LESS "9.0")
|
||||
set(__cuda_arch_bin "2.0 3.0 3.5 3.7 5.0 5.2 6.0 6.1")
|
||||
elseif(CUDA_VERSION VERSION_LESS "10.0")
|
||||
set(__cuda_arch_bin "3.0 3.5 3.7 5.0 5.2 6.0 6.1 7.0")
|
||||
else()
|
||||
set(__cuda_arch_bin "3.0 3.5 3.7 5.0 5.2 6.0 6.1 7.0 7.5")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(CUDA_ARCH_BIN ${__cuda_arch_bin} CACHE STRING "Specify 'real' GPU architectures to build binaries for, BIN(PTX) format is supported")
|
||||
set(CUDA_ARCH_PTX ${__cuda_arch_ptx} CACHE STRING "Specify 'virtual' PTX architectures to build PTX intermediate code for")
|
||||
|
||||
string(REGEX REPLACE "\\." "" ARCH_BIN_NO_POINTS "${CUDA_ARCH_BIN}")
|
||||
string(REGEX REPLACE "\\." "" ARCH_PTX_NO_POINTS "${CUDA_ARCH_PTX}")
|
||||
|
||||
# Ckeck if user specified 1.0 compute capability: we don't support it
|
||||
string(REGEX MATCH "1.0" HAS_ARCH_10 "${CUDA_ARCH_BIN} ${CUDA_ARCH_PTX}")
|
||||
set(CUDA_ARCH_BIN_OR_PTX_10 0)
|
||||
if(NOT ${HAS_ARCH_10} STREQUAL "")
|
||||
set(CUDA_ARCH_BIN_OR_PTX_10 1)
|
||||
endif()
|
||||
|
||||
# NVCC flags to be set
|
||||
set(NVCC_FLAGS_EXTRA "")
|
||||
|
||||
# These vars will be passed into the templates
|
||||
set(OPENCV_CUDA_ARCH_BIN "")
|
||||
set(OPENCV_CUDA_ARCH_PTX "")
|
||||
set(OPENCV_CUDA_ARCH_FEATURES "")
|
||||
|
||||
# Tell NVCC to add binaries for the specified GPUs
|
||||
string(REGEX MATCHALL "[0-9()]+" ARCH_LIST "${ARCH_BIN_NO_POINTS}")
|
||||
foreach(ARCH IN LISTS ARCH_LIST)
|
||||
if(ARCH MATCHES "([0-9]+)\\(([0-9]+)\\)")
|
||||
# User explicitly specified PTX for the concrete BIN
|
||||
set(NVCC_FLAGS_EXTRA ${NVCC_FLAGS_EXTRA} -gencode arch=compute_${CMAKE_MATCH_2},code=sm_${CMAKE_MATCH_1})
|
||||
set(OPENCV_CUDA_ARCH_BIN "${OPENCV_CUDA_ARCH_BIN} ${CMAKE_MATCH_1}")
|
||||
set(OPENCV_CUDA_ARCH_FEATURES "${OPENCV_CUDA_ARCH_FEATURES} ${CMAKE_MATCH_2}")
|
||||
else()
|
||||
# User didn't explicitly specify PTX for the concrete BIN, we assume PTX=BIN
|
||||
set(NVCC_FLAGS_EXTRA ${NVCC_FLAGS_EXTRA} -gencode arch=compute_${ARCH},code=sm_${ARCH})
|
||||
set(OPENCV_CUDA_ARCH_BIN "${OPENCV_CUDA_ARCH_BIN} ${ARCH}")
|
||||
set(OPENCV_CUDA_ARCH_FEATURES "${OPENCV_CUDA_ARCH_FEATURES} ${ARCH}")
|
||||
endif()
|
||||
endforeach()
|
||||
set(NVCC_FLAGS_EXTRA ${NVCC_FLAGS_EXTRA} -D_FORCE_INLINES)
|
||||
|
||||
# Tell NVCC to add PTX intermediate code for the specified architectures
|
||||
string(REGEX MATCHALL "[0-9]+" ARCH_LIST "${ARCH_PTX_NO_POINTS}")
|
||||
foreach(ARCH IN LISTS ARCH_LIST)
|
||||
set(NVCC_FLAGS_EXTRA ${NVCC_FLAGS_EXTRA} -gencode arch=compute_${ARCH},code=compute_${ARCH})
|
||||
set(OPENCV_CUDA_ARCH_PTX "${OPENCV_CUDA_ARCH_PTX} ${ARCH}")
|
||||
set(OPENCV_CUDA_ARCH_FEATURES "${OPENCV_CUDA_ARCH_FEATURES} ${ARCH}")
|
||||
endforeach()
|
||||
|
||||
# These vars will be processed in other scripts
|
||||
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} ${NVCC_FLAGS_EXTRA})
|
||||
set(OpenCV_CUDA_CC "${NVCC_FLAGS_EXTRA}")
|
||||
|
||||
if(ANDROID)
|
||||
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} "-Xptxas;-dlcm=ca")
|
||||
endif()
|
||||
|
||||
message(STATUS "CUDA NVCC target flags: ${CUDA_NVCC_FLAGS}")
|
||||
|
||||
OCV_OPTION(CUDA_FAST_MATH "Enable --use_fast_math for CUDA compiler " OFF)
|
||||
|
||||
if(CUDA_FAST_MATH)
|
||||
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} --use_fast_math)
|
||||
endif()
|
||||
|
||||
mark_as_advanced(CUDA_BUILD_CUBIN CUDA_BUILD_EMULATION CUDA_VERBOSE_BUILD CUDA_SDK_ROOT_DIR)
|
||||
|
||||
macro(ocv_cuda_filter_options)
|
||||
foreach(var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG)
|
||||
set(${var}_backup_in_cuda_compile_ "${${var}}")
|
||||
|
||||
if (CV_CLANG)
|
||||
# we remove -Winconsistent-missing-override and -Qunused-arguments
|
||||
# just in case we are compiling CUDA with gcc but OpenCV with clang
|
||||
string(REPLACE "-Winconsistent-missing-override" "" ${var} "${${var}}")
|
||||
string(REPLACE "-Qunused-arguments" "" ${var} "${${var}}")
|
||||
endif()
|
||||
|
||||
# we remove /EHa as it generates warnings under windows
|
||||
string(REPLACE "/EHa" "" ${var} "${${var}}")
|
||||
|
||||
# we remove -ggdb3 flag as it leads to preprocessor errors when compiling CUDA files (CUDA 4.1)
|
||||
string(REPLACE "-ggdb3" "" ${var} "${${var}}")
|
||||
|
||||
# we remove -Wsign-promo as it generates warnings under linux
|
||||
string(REPLACE "-Wsign-promo" "" ${var} "${${var}}")
|
||||
|
||||
# we remove -Wno-sign-promo as it generates warnings under linux
|
||||
string(REPLACE "-Wno-sign-promo" "" ${var} "${${var}}")
|
||||
|
||||
# we remove -Wno-delete-non-virtual-dtor because it's used for C++ compiler
|
||||
# but NVCC uses C compiler by default
|
||||
string(REPLACE "-Wno-delete-non-virtual-dtor" "" ${var} "${${var}}")
|
||||
|
||||
# we remove -frtti because it's used for C++ compiler
|
||||
# but NVCC uses C compiler by default
|
||||
string(REPLACE "-frtti" "" ${var} "${${var}}")
|
||||
|
||||
string(REPLACE "-fvisibility-inlines-hidden" "" ${var} "${${var}}")
|
||||
|
||||
# cc1: warning: command line option '-Wsuggest-override' is valid for C++/ObjC++ but not for C
|
||||
string(REPLACE "-Wsuggest-override" "" ${var} "${${var}}")
|
||||
|
||||
# issue: #11552 (from OpenCVCompilerOptions.cmake)
|
||||
string(REGEX REPLACE "-Wimplicit-fallthrough(=[0-9]+)? " "" ${var} "${${var}}")
|
||||
|
||||
# removal of custom specified options
|
||||
if(OPENCV_CUDA_NVCC_FILTEROUT_OPTIONS)
|
||||
foreach(__flag ${OPENCV_CUDA_NVCC_FILTEROUT_OPTIONS})
|
||||
string(REPLACE "${__flag}" "" ${var} "${${var}}")
|
||||
endforeach()
|
||||
endif()
|
||||
endforeach()
|
||||
endmacro()
|
||||
|
||||
macro(ocv_cuda_compile VAR)
|
||||
ocv_cuda_filter_options()
|
||||
|
||||
if(BUILD_SHARED_LIBS)
|
||||
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xcompiler -DCVAPI_EXPORTS)
|
||||
endif()
|
||||
|
||||
if(UNIX OR APPLE)
|
||||
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xcompiler -fPIC --std=c++11)
|
||||
endif()
|
||||
if(APPLE)
|
||||
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xcompiler -fno-finite-math-only)
|
||||
endif()
|
||||
|
||||
if(CMAKE_CROSSCOMPILING AND (ARM OR AARCH64))
|
||||
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xlinker --unresolved-symbols=ignore-in-shared-libs)
|
||||
endif()
|
||||
|
||||
# disabled because of multiple warnings during building nvcc auto generated files
|
||||
if(CV_GCC AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "4.6.0")
|
||||
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wunused-but-set-variable)
|
||||
endif()
|
||||
|
||||
CUDA_COMPILE(${VAR} ${ARGN})
|
||||
|
||||
foreach(var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG)
|
||||
set(${var} "${${var}_backup_in_cuda_compile_}")
|
||||
unset(${var}_backup_in_cuda_compile_)
|
||||
endforeach()
|
||||
endmacro()
|
||||
else()
|
||||
unset(CUDA_ARCH_BIN CACHE)
|
||||
unset(CUDA_ARCH_PTX CACHE)
|
||||
endif()
|
||||
|
||||
if(HAVE_CUDA)
|
||||
set(CUDA_LIBS_PATH "")
|
||||
foreach(p ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY})
|
||||
get_filename_component(_tmp ${p} PATH)
|
||||
list(APPEND CUDA_LIBS_PATH ${_tmp})
|
||||
endforeach()
|
||||
|
||||
if(HAVE_CUBLAS)
|
||||
foreach(p ${CUDA_cublas_LIBRARY})
|
||||
get_filename_component(_tmp ${p} PATH)
|
||||
list(APPEND CUDA_LIBS_PATH ${_tmp})
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
if(HAVE_CUDNN)
|
||||
foreach(p ${CUDNN_LIBRARIES})
|
||||
get_filename_component(_tmp ${p} PATH)
|
||||
list(APPEND CUDA_LIBS_PATH ${_tmp})
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
if(HAVE_CUFFT)
|
||||
foreach(p ${CUDA_cufft_LIBRARY})
|
||||
get_filename_component(_tmp ${p} PATH)
|
||||
list(APPEND CUDA_LIBS_PATH ${_tmp})
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
list(REMOVE_DUPLICATES CUDA_LIBS_PATH)
|
||||
link_directories(${CUDA_LIBS_PATH})
|
||||
|
||||
set(CUDA_LIBRARIES_ABS ${CUDA_LIBRARIES})
|
||||
ocv_convert_to_lib_name(CUDA_LIBRARIES ${CUDA_LIBRARIES})
|
||||
set(CUDA_npp_LIBRARY_ABS ${CUDA_npp_LIBRARY})
|
||||
ocv_convert_to_lib_name(CUDA_npp_LIBRARY ${CUDA_npp_LIBRARY})
|
||||
if(HAVE_CUBLAS)
|
||||
set(CUDA_cublas_LIBRARY_ABS ${CUDA_cublas_LIBRARY})
|
||||
ocv_convert_to_lib_name(CUDA_cublas_LIBRARY ${CUDA_cublas_LIBRARY})
|
||||
endif()
|
||||
if(HAVE_CUDNN)
|
||||
set(CUDNN_LIBRARIES_ABS ${CUDNN_LIBRARIES})
|
||||
ocv_convert_to_lib_name(CUDNN_LIBRARIES ${CUDNN_LIBRARIES})
|
||||
endif()
|
||||
if(HAVE_CUFFT)
|
||||
set(CUDA_cufft_LIBRARY_ABS ${CUDA_cufft_LIBRARY})
|
||||
ocv_convert_to_lib_name(CUDA_cufft_LIBRARY ${CUDA_cufft_LIBRARY})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Add CUDA libraries (needed for apps/tools, samples)
|
||||
# ----------------------------------------------------------------------------
|
||||
if(HAVE_CUDA)
|
||||
# details: https://github.com/NVIDIA/nvidia-docker/issues/775
|
||||
if(" ${CUDA_CUDA_LIBRARY}" MATCHES "/stubs/libcuda.so" AND NOT OPENCV_SKIP_CUDA_STUB_WORKAROUND)
|
||||
set(CUDA_STUB_ENABLED_LINK_WORKAROUND 1)
|
||||
if(EXISTS "${CUDA_CUDA_LIBRARY}" AND NOT OPENCV_SKIP_CUDA_STUB_WORKAROUND_RPATH_LINK)
|
||||
set(CUDA_STUB_TARGET_PATH "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/")
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${CUDA_CUDA_LIBRARY}" "${CUDA_STUB_TARGET_PATH}/libcuda.so.1"
|
||||
RESULT_VARIABLE CUDA_STUB_SYMLINK_RESULT)
|
||||
if(NOT CUDA_STUB_SYMLINK_RESULT EQUAL 0)
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CUDA_CUDA_LIBRARY}" "${CUDA_STUB_TARGET_PATH}/libcuda.so.1"
|
||||
RESULT_VARIABLE CUDA_STUB_COPY_RESULT)
|
||||
if(NOT CUDA_STUB_COPY_RESULT EQUAL 0)
|
||||
set(CUDA_STUB_ENABLED_LINK_WORKAROUND 0)
|
||||
endif()
|
||||
endif()
|
||||
if(CUDA_STUB_ENABLED_LINK_WORKAROUND)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath-link,\"${CUDA_STUB_TARGET_PATH}\"")
|
||||
endif()
|
||||
else()
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--allow-shlib-undefined")
|
||||
endif()
|
||||
if(NOT CUDA_STUB_ENABLED_LINK_WORKAROUND)
|
||||
message(WARNING "CUDA: workaround for stubs/libcuda.so.1 is not applied")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
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})
|
||||
endif()
|
||||
if(HAVE_CUDNN)
|
||||
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDNN_LIBRARIES})
|
||||
endif()
|
||||
if(HAVE_CUFFT)
|
||||
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDA_cufft_LIBRARY})
|
||||
endif()
|
||||
foreach(p ${CUDA_LIBS_PATH})
|
||||
if(MSVC AND CMAKE_GENERATOR MATCHES "Ninja|JOM")
|
||||
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CMAKE_LIBRARY_PATH_FLAG}"${p}")
|
||||
else()
|
||||
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CMAKE_LIBRARY_PATH_FLAG}${p})
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
|
@ -0,0 +1,232 @@
|
|||
# Compilers:
|
||||
# - CV_GCC - GNU compiler (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
# - CV_CLANG - Clang-compatible compiler (CMAKE_CXX_COMPILER_ID MATCHES "Clang" - Clang or AppleClang, see CMP0025)
|
||||
# - CV_ICC - Intel compiler
|
||||
# - MSVC - Microsoft Visual Compiler (CMake variable)
|
||||
# - MINGW / CYGWIN / CMAKE_COMPILER_IS_MINGW / CMAKE_COMPILER_IS_CYGWIN (CMake original variables)
|
||||
#
|
||||
# CPU Platforms:
|
||||
# - X86 / X86_64
|
||||
# - ARM - ARM CPU, not defined for AArch64
|
||||
# - AARCH64 - ARMv8+ (64-bit)
|
||||
# - PPC64 / PPC64LE - PowerPC
|
||||
# - MIPS
|
||||
#
|
||||
# OS:
|
||||
# - WIN32 - Windows | MINGW
|
||||
# - UNIX - Linux | MacOSX | ANDROID
|
||||
# - ANDROID
|
||||
# - IOS
|
||||
# - APPLE - MacOSX | iOS
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
ocv_declare_removed_variables(MINGW64 MSVC64)
|
||||
# do not use (CMake variables): CMAKE_CL_64
|
||||
|
||||
if(NOT DEFINED CV_GCC AND CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
set(CV_GCC 1)
|
||||
endif()
|
||||
if(NOT DEFINED CV_CLANG AND CMAKE_CXX_COMPILER_ID MATCHES "Clang") # Clang or AppleClang (see CMP0025)
|
||||
set(CV_CLANG 1)
|
||||
set(CMAKE_COMPILER_IS_CLANGCXX 1) # TODO next release: remove this
|
||||
set(CMAKE_COMPILER_IS_CLANGCC 1) # TODO next release: remove this
|
||||
endif()
|
||||
|
||||
function(access_CMAKE_COMPILER_IS_CLANGCXX)
|
||||
if(NOT OPENCV_SUPPRESS_DEPRECATIONS)
|
||||
message(WARNING "DEPRECATED: CMAKE_COMPILER_IS_CLANGCXX support is deprecated in OpenCV.
|
||||
Consider using:
|
||||
- CV_GCC # GCC
|
||||
- CV_CLANG # Clang or AppleClang (see CMP0025)
|
||||
")
|
||||
endif()
|
||||
endfunction()
|
||||
variable_watch(CMAKE_COMPILER_IS_CLANGCXX access_CMAKE_COMPILER_IS_CLANGCXX)
|
||||
variable_watch(CMAKE_COMPILER_IS_CLANGCC access_CMAKE_COMPILER_IS_CLANGCXX)
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Detect Intel ICC compiler
|
||||
# ----------------------------------------------------------------------------
|
||||
if(UNIX)
|
||||
if(__ICL)
|
||||
set(CV_ICC __ICL)
|
||||
elseif(__ICC)
|
||||
set(CV_ICC __ICC)
|
||||
elseif(__ECL)
|
||||
set(CV_ICC __ECL)
|
||||
elseif(__ECC)
|
||||
set(CV_ICC __ECC)
|
||||
elseif(__INTEL_COMPILER)
|
||||
set(CV_ICC __INTEL_COMPILER)
|
||||
elseif(CMAKE_C_COMPILER MATCHES "icc")
|
||||
set(CV_ICC icc_matches_c_compiler)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(MSVC AND CMAKE_C_COMPILER MATCHES "icc|icl")
|
||||
set(CV_ICC __INTEL_COMPILER_FOR_WINDOWS)
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED CMAKE_CXX_COMPILER_VERSION
|
||||
AND NOT OPENCV_SUPPRESS_MESSAGE_MISSING_COMPILER_VERSION)
|
||||
message(WARNING "OpenCV: Compiler version is not available: CMAKE_CXX_COMPILER_VERSION is not set")
|
||||
endif()
|
||||
if((NOT DEFINED CMAKE_SYSTEM_PROCESSOR OR CMAKE_SYSTEM_PROCESSOR STREQUAL "")
|
||||
AND NOT OPENCV_SUPPRESS_MESSAGE_MISSING_CMAKE_SYSTEM_PROCESSOR)
|
||||
message(WARNING "OpenCV: CMAKE_SYSTEM_PROCESSOR is not defined. Perhaps CMake toolchain is broken")
|
||||
endif()
|
||||
if(NOT DEFINED CMAKE_SIZEOF_VOID_P
|
||||
AND NOT OPENCV_SUPPRESS_MESSAGE_MISSING_CMAKE_SIZEOF_VOID_P)
|
||||
message(WARNING "OpenCV: CMAKE_SIZEOF_VOID_P is not defined. Perhaps CMake toolchain is broken")
|
||||
endif()
|
||||
|
||||
message(STATUS "Detected processor: ${CMAKE_SYSTEM_PROCESSOR}")
|
||||
if(OPENCV_SKIP_SYSTEM_PROCESSOR_DETECTION)
|
||||
# custom setup: required variables are passed through cache / CMake's command-line
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64.*|x86_64.*|AMD64.*")
|
||||
set(X86_64 1)
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "i686.*|i386.*|x86.*")
|
||||
set(X86 1)
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64.*|AARCH64.*|arm64.*|ARM64.*)")
|
||||
set(AARCH64 1)
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm.*|ARM.*)")
|
||||
set(ARM 1)
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64le")
|
||||
set(PPC64LE 1)
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64")
|
||||
set(PPC64 1)
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(mips.*|MIPS.*)")
|
||||
set(MIPS 1)
|
||||
else()
|
||||
if(NOT OPENCV_SUPPRESS_MESSAGE_UNRECOGNIZED_SYSTEM_PROCESSOR)
|
||||
message(WARNING "OpenCV: unrecognized target processor configuration")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Workaround for 32-bit operating systems on x86_64
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 4 AND X86_64
|
||||
AND NOT FORCE_X86_64 # deprecated (2019-12)
|
||||
AND NOT OPENCV_FORCE_X86_64
|
||||
)
|
||||
message(STATUS "sizeof(void) = 4 on 64 bit processor. Assume 32-bit compilation mode")
|
||||
if(X86_64)
|
||||
unset(X86_64)
|
||||
set(X86 1)
|
||||
endif()
|
||||
endif()
|
||||
# Workaround for 32-bit operating systems on aarch64 processor
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 4 AND AARCH64
|
||||
AND NOT OPENCV_FORCE_AARCH64
|
||||
)
|
||||
message(STATUS "sizeof(void) = 4 on 64 bit processor. Assume 32-bit compilation mode")
|
||||
if(AARCH64)
|
||||
unset(AARCH64)
|
||||
set(ARM 1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
# Similar code exists in OpenCVConfig.cmake
|
||||
if(NOT DEFINED OpenCV_STATIC)
|
||||
# look for global setting
|
||||
if(NOT DEFINED BUILD_SHARED_LIBS OR BUILD_SHARED_LIBS)
|
||||
set(OpenCV_STATIC OFF)
|
||||
else()
|
||||
set(OpenCV_STATIC ON)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(DEFINED OpenCV_ARCH AND DEFINED OpenCV_RUNTIME)
|
||||
# custom overridden values
|
||||
elseif(MSVC)
|
||||
# see Modules/CMakeGenericSystem.cmake
|
||||
if("${CMAKE_GENERATOR}" MATCHES "(Win64|IA64)")
|
||||
set(OpenCV_ARCH "x64")
|
||||
elseif("${CMAKE_GENERATOR_PLATFORM}" MATCHES "ARM64")
|
||||
set(OpenCV_ARCH "ARM64")
|
||||
elseif("${CMAKE_GENERATOR}" MATCHES "ARM")
|
||||
set(OpenCV_ARCH "ARM")
|
||||
elseif("${CMAKE_SIZEOF_VOID_P}" STREQUAL "8")
|
||||
set(OpenCV_ARCH "x64")
|
||||
else()
|
||||
set(OpenCV_ARCH x86)
|
||||
endif()
|
||||
|
||||
if(MSVC_VERSION EQUAL 1400)
|
||||
set(OpenCV_RUNTIME vc8)
|
||||
elseif(MSVC_VERSION EQUAL 1500)
|
||||
set(OpenCV_RUNTIME vc9)
|
||||
elseif(MSVC_VERSION EQUAL 1600)
|
||||
set(OpenCV_RUNTIME vc10)
|
||||
elseif(MSVC_VERSION EQUAL 1700)
|
||||
set(OpenCV_RUNTIME vc11)
|
||||
elseif(MSVC_VERSION EQUAL 1800)
|
||||
set(OpenCV_RUNTIME vc12)
|
||||
elseif(MSVC_VERSION EQUAL 1900)
|
||||
set(OpenCV_RUNTIME vc14)
|
||||
elseif(MSVC_VERSION MATCHES "^191[0-9]$")
|
||||
set(OpenCV_RUNTIME vc15)
|
||||
elseif(MSVC_VERSION MATCHES "^192[0-9]$")
|
||||
set(OpenCV_RUNTIME vc16)
|
||||
else()
|
||||
message(WARNING "OpenCV does not recognize MSVC_VERSION \"${MSVC_VERSION}\". Cannot set OpenCV_RUNTIME")
|
||||
endif()
|
||||
elseif(MINGW)
|
||||
set(OpenCV_RUNTIME mingw)
|
||||
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64.*|x86_64.*|AMD64.*")
|
||||
set(OpenCV_ARCH x64)
|
||||
else()
|
||||
set(OpenCV_ARCH x86)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Fix handling of duplicated files in the same static library:
|
||||
# https://public.kitware.com/Bug/view.php?id=14874
|
||||
if(CMAKE_VERSION VERSION_LESS "3.1")
|
||||
foreach(var CMAKE_C_ARCHIVE_APPEND CMAKE_CXX_ARCHIVE_APPEND)
|
||||
if(${var} MATCHES "^<CMAKE_AR> r")
|
||||
string(REPLACE "<CMAKE_AR> r" "<CMAKE_AR> q" ${var} "${${var}}")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF) # use -std=c++11 instead of -std=gnu++11
|
||||
if(CMAKE_CXX11_COMPILE_FEATURES)
|
||||
set(HAVE_CXX11 ON)
|
||||
endif()
|
||||
if(NOT HAVE_CXX11)
|
||||
ocv_check_compiler_flag(CXX "" HAVE_CXX11 "${OpenCV_SOURCE_DIR}/cmake/checks/cxx11.cpp")
|
||||
if(NOT HAVE_CXX11)
|
||||
ocv_check_compiler_flag(CXX "-std=c++11" HAVE_STD_CXX11 "${OpenCV_SOURCE_DIR}/cmake/checks/cxx11.cpp")
|
||||
if(HAVE_STD_CXX11)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
set(HAVE_CXX11 ON)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT HAVE_CXX11)
|
||||
message(FATAL_ERROR "OpenCV 4.x requires C++11")
|
||||
endif()
|
||||
|
||||
if((HAVE_CXX11
|
||||
AND NOT MSVC
|
||||
AND NOT (X86 OR X86_64)
|
||||
AND NOT OPENCV_SKIP_LIBATOMIC_COMPILER_CHECK)
|
||||
OR OPENCV_FORCE_LIBATOMIC_COMPILER_CHECK
|
||||
)
|
||||
ocv_check_compiler_flag(CXX "" HAVE_CXX_ATOMICS_WITHOUT_LIB "${OpenCV_SOURCE_DIR}/cmake/checks/atomic_check.cpp")
|
||||
if(NOT HAVE_CXX_ATOMICS_WITHOUT_LIB)
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES atomic)
|
||||
ocv_check_compiler_flag(CXX "" HAVE_CXX_ATOMICS_WITH_LIB "${OpenCV_SOURCE_DIR}/cmake/checks/atomic_check.cpp")
|
||||
if(HAVE_CXX_ATOMICS_WITH_LIB)
|
||||
list(APPEND OPENCV_LINKER_LIBS atomic)
|
||||
else()
|
||||
message(FATAL_ERROR "C++11 compiler must support std::atomic")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
|
@ -0,0 +1,30 @@
|
|||
if(WIN32)
|
||||
try_compile(__VALID_DIRECTX
|
||||
"${OpenCV_BINARY_DIR}"
|
||||
"${OpenCV_SOURCE_DIR}/cmake/checks/directx.cpp"
|
||||
OUTPUT_VARIABLE TRY_OUT
|
||||
)
|
||||
if(NOT __VALID_DIRECTX)
|
||||
return()
|
||||
endif()
|
||||
try_compile(__VALID_DIRECTX_NV12
|
||||
"${OpenCV_BINARY_DIR}"
|
||||
"${OpenCV_SOURCE_DIR}/cmake/checks/directx.cpp"
|
||||
COMPILE_DEFINITIONS "-DCHECK_NV12"
|
||||
OUTPUT_VARIABLE TRY_OUT
|
||||
)
|
||||
if(__VALID_DIRECTX_NV12)
|
||||
set(HAVE_DIRECTX_NV12 ON)
|
||||
else()
|
||||
message(STATUS "No support for DirectX NV12 format (install Windows 8 SDK)")
|
||||
endif()
|
||||
set(HAVE_DIRECTX ON)
|
||||
set(HAVE_D3D11 ON)
|
||||
set(HAVE_D3D10 ON)
|
||||
set(HAVE_D3D9 ON)
|
||||
|
||||
if(HAVE_OPENCL AND WITH_OPENCL_D3D11_NV AND EXISTS "${OPENCL_INCLUDE_DIR}/CL/cl_d3d11_ext.h")
|
||||
set(HAVE_OPENCL_D3D11_NV ON)
|
||||
endif()
|
||||
|
||||
endif()
|
|
@ -0,0 +1,45 @@
|
|||
cmake_minimum_required(VERSION 3.1)
|
||||
|
||||
if(" ${HALIDE_ROOT_DIR}" STREQUAL " ")
|
||||
unset(HALIDE_ROOT_DIR CACHE)
|
||||
endif()
|
||||
ocv_check_environment_variables(HALIDE_ROOT_DIR)
|
||||
set(HALIDE_ROOT_DIR "${HALIDE_ROOT_DIR}" CACHE PATH "Halide root directory")
|
||||
|
||||
if(NOT HAVE_HALIDE)
|
||||
find_package(Halide QUIET) # Try CMake-based config files
|
||||
if(Halide_FOUND)
|
||||
set(HALIDE_INCLUDE_DIRS "${Halide_INCLUDE_DIRS}" CACHE PATH "Halide include directories" FORCE)
|
||||
set(HALIDE_LIBRARIES "${Halide_LIBRARIES}" CACHE PATH "Halide libraries" FORCE)
|
||||
set(HAVE_HALIDE TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT HAVE_HALIDE AND HALIDE_ROOT_DIR)
|
||||
# Try manual search
|
||||
find_library(HALIDE_LIBRARY
|
||||
NAMES Halide
|
||||
HINTS ${HALIDE_ROOT_DIR}/lib # Unix
|
||||
HINTS ${HALIDE_ROOT_DIR}/lib/Release # Win32
|
||||
)
|
||||
find_path(HALIDE_INCLUDE_DIR
|
||||
NAMES Halide.h HalideRuntime.h
|
||||
HINTS ${HALIDE_ROOT_DIR}/include
|
||||
)
|
||||
if(HALIDE_LIBRARY AND HALIDE_INCLUDE_DIR)
|
||||
# TODO try_compile
|
||||
set(HALIDE_INCLUDE_DIRS "${HALIDE_INCLUDE_DIR}" CACHE PATH "Halide include directories" FORCE)
|
||||
set(HALIDE_LIBRARIES "${HALIDE_LIBRARY}" CACHE PATH "Halide libraries" FORCE)
|
||||
set(HAVE_HALIDE TRUE)
|
||||
endif()
|
||||
if(NOT HAVE_HALIDE)
|
||||
ocv_clear_vars(HALIDE_LIBRARIES HALIDE_INCLUDE_DIRS CACHE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(HAVE_HALIDE)
|
||||
include_directories(${HALIDE_INCLUDE_DIRS})
|
||||
list(APPEND OPENCV_LINKER_LIBS ${HALIDE_LIBRARIES})
|
||||
else()
|
||||
ocv_clear_vars(HALIDE_INCLUDE_DIRS HALIDE_LIBRARIES)
|
||||
endif()
|
|
@ -0,0 +1,115 @@
|
|||
# The script detects Intel(R) Inference Engine installation
|
||||
#
|
||||
# Cache variables:
|
||||
# INF_ENGINE_RELEASE - a number reflecting IE source interface (linked with OpenVINO release)
|
||||
#
|
||||
# Detect parameters:
|
||||
# 1. Native cmake IE package:
|
||||
# - environment variable InferenceEngine_DIR is set to location of cmake module
|
||||
# 2. Custom location:
|
||||
# - INF_ENGINE_INCLUDE_DIRS - headers search location
|
||||
# - INF_ENGINE_LIB_DIRS - library search location
|
||||
# 3. OpenVINO location:
|
||||
# - environment variable INTEL_OPENVINO_DIR is set to location of OpenVINO installation dir
|
||||
# - INF_ENGINE_PLATFORM - part of name of library directory representing its platform
|
||||
#
|
||||
# Result:
|
||||
# INF_ENGINE_TARGET - set to name of imported library target representing InferenceEngine
|
||||
#
|
||||
|
||||
function(add_custom_ie_build _inc _lib _lib_rel _lib_dbg _msg)
|
||||
if(NOT _inc OR NOT (_lib OR _lib_rel OR _lib_dbg))
|
||||
return()
|
||||
endif()
|
||||
add_library(inference_engine UNKNOWN IMPORTED)
|
||||
set_target_properties(inference_engine PROPERTIES
|
||||
IMPORTED_LOCATION "${_lib}"
|
||||
IMPORTED_IMPLIB_RELEASE "${_lib_rel}"
|
||||
IMPORTED_IMPLIB_DEBUG "${_lib_dbg}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${_inc}"
|
||||
)
|
||||
|
||||
find_library(ie_builder_custom_lib "inference_engine_nn_builder" PATHS "${INF_ENGINE_LIB_DIRS}" NO_DEFAULT_PATH)
|
||||
if(EXISTS "${ie_builder_custom_lib}")
|
||||
add_library(inference_engine_nn_builder UNKNOWN IMPORTED)
|
||||
set_target_properties(inference_engine_nn_builder PROPERTIES
|
||||
IMPORTED_LOCATION "${ie_builder_custom_lib}"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(NOT INF_ENGINE_RELEASE VERSION_GREATER "2018050000")
|
||||
find_library(INF_ENGINE_OMP_LIBRARY iomp5 PATHS "${INF_ENGINE_OMP_DIR}" NO_DEFAULT_PATH)
|
||||
if(NOT INF_ENGINE_OMP_LIBRARY)
|
||||
message(WARNING "OpenMP for IE have not been found. Set INF_ENGINE_OMP_DIR variable if you experience build errors.")
|
||||
else()
|
||||
set_target_properties(inference_engine PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES "${INF_ENGINE_OMP_LIBRARY}")
|
||||
endif()
|
||||
endif()
|
||||
set(INF_ENGINE_VERSION "Unknown" CACHE STRING "")
|
||||
set(INF_ENGINE_TARGET inference_engine)
|
||||
if(TARGET inference_engine_nn_builder)
|
||||
list(APPEND INF_ENGINE_TARGET inference_engine_nn_builder)
|
||||
set(_msg "${_msg}, with IE NN Builder API")
|
||||
endif()
|
||||
set(INF_ENGINE_TARGET "${INF_ENGINE_TARGET}" PARENT_SCOPE)
|
||||
message(STATUS "Detected InferenceEngine: ${_msg}")
|
||||
endfunction()
|
||||
|
||||
# ======================
|
||||
|
||||
find_package(InferenceEngine QUIET)
|
||||
if(InferenceEngine_FOUND)
|
||||
set(INF_ENGINE_TARGET ${InferenceEngine_LIBRARIES})
|
||||
set(INF_ENGINE_VERSION "${InferenceEngine_VERSION}" CACHE STRING "")
|
||||
message(STATUS "Detected InferenceEngine: cmake package (${InferenceEngine_VERSION})")
|
||||
endif()
|
||||
|
||||
if(NOT INF_ENGINE_TARGET AND INF_ENGINE_LIB_DIRS AND INF_ENGINE_INCLUDE_DIRS)
|
||||
find_path(ie_custom_inc "inference_engine.hpp" PATHS "${INF_ENGINE_INCLUDE_DIRS}" NO_DEFAULT_PATH)
|
||||
find_library(ie_custom_lib "inference_engine" PATHS "${INF_ENGINE_LIB_DIRS}" NO_DEFAULT_PATH)
|
||||
find_library(ie_custom_lib_rel "inference_engine" PATHS "${INF_ENGINE_LIB_DIRS}/Release" NO_DEFAULT_PATH)
|
||||
find_library(ie_custom_lib_dbg "inference_engine" PATHS "${INF_ENGINE_LIB_DIRS}/Debug" NO_DEFAULT_PATH)
|
||||
add_custom_ie_build("${ie_custom_inc}" "${ie_custom_lib}" "${ie_custom_lib_rel}" "${ie_custom_lib_dbg}" "INF_ENGINE_{INCLUDE,LIB}_DIRS")
|
||||
endif()
|
||||
|
||||
set(_loc "$ENV{INTEL_OPENVINO_DIR}")
|
||||
if(NOT _loc AND DEFINED ENV{INTEL_CVSDK_DIR})
|
||||
set(_loc "$ENV{INTEL_CVSDK_DIR}") # OpenVINO 2018.x
|
||||
endif()
|
||||
if(NOT INF_ENGINE_TARGET AND _loc)
|
||||
if(NOT INF_ENGINE_RELEASE VERSION_GREATER "2018050000")
|
||||
set(INF_ENGINE_PLATFORM_DEFAULT "ubuntu_16.04")
|
||||
else()
|
||||
set(INF_ENGINE_PLATFORM_DEFAULT "")
|
||||
endif()
|
||||
set(INF_ENGINE_PLATFORM "${INF_ENGINE_PLATFORM_DEFAULT}" CACHE STRING "InferenceEngine platform (library dir)")
|
||||
find_path(ie_custom_env_inc "inference_engine.hpp" PATHS "${_loc}/deployment_tools/inference_engine/include" NO_DEFAULT_PATH)
|
||||
find_library(ie_custom_env_lib "inference_engine" PATHS "${_loc}/deployment_tools/inference_engine/lib/${INF_ENGINE_PLATFORM}/intel64" NO_DEFAULT_PATH)
|
||||
find_library(ie_custom_env_lib_rel "inference_engine" PATHS "${_loc}/deployment_tools/inference_engine/lib/intel64/Release" NO_DEFAULT_PATH)
|
||||
find_library(ie_custom_env_lib_dbg "inference_engine" PATHS "${_loc}/deployment_tools/inference_engine/lib/intel64/Debug" NO_DEFAULT_PATH)
|
||||
add_custom_ie_build("${ie_custom_env_inc}" "${ie_custom_env_lib}" "${ie_custom_env_lib_rel}" "${ie_custom_env_lib_dbg}" "OpenVINO (${_loc})")
|
||||
endif()
|
||||
|
||||
# Add more features to the target
|
||||
|
||||
if(INF_ENGINE_TARGET)
|
||||
if(NOT INF_ENGINE_RELEASE)
|
||||
message(WARNING "InferenceEngine version have not been set, 2019R3 will be used by default. Set INF_ENGINE_RELEASE variable if you experience build errors.")
|
||||
endif()
|
||||
set(INF_ENGINE_RELEASE "2019030000" CACHE STRING "Force IE version, should be in form YYYYAABBCC (e.g. 2018R2.0.2 -> 2018020002)")
|
||||
set_target_properties(${INF_ENGINE_TARGET} PROPERTIES
|
||||
INTERFACE_COMPILE_DEFINITIONS "HAVE_INF_ENGINE=1;INF_ENGINE_RELEASE=${INF_ENGINE_RELEASE}"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WITH_NGRAPH)
|
||||
find_package(ngraph QUIET)
|
||||
if(ngraph_FOUND)
|
||||
ocv_assert(TARGET ngraph::ngraph)
|
||||
if(INF_ENGINE_RELEASE VERSION_LESS "2019039999")
|
||||
message(WARNING "nGraph is not tested with current InferenceEngine version: INF_ENGINE_RELEASE=${INF_ENGINE_RELEASE}")
|
||||
endif()
|
||||
message(STATUS "Detected ngraph: cmake package (${ngraph_VERSION})")
|
||||
set(HAVE_NGRAPH ON)
|
||||
endif()
|
||||
endif()
|
|
@ -0,0 +1,84 @@
|
|||
set(OPENCL_FOUND ON CACHE BOOL "OpenCL library is found")
|
||||
if(APPLE)
|
||||
set(OPENCL_LIBRARY "-framework OpenCL" CACHE STRING "OpenCL library")
|
||||
set(OPENCL_INCLUDE_DIR "" CACHE PATH "OpenCL include directory")
|
||||
else()
|
||||
set(OPENCL_LIBRARY "" CACHE STRING "OpenCL library")
|
||||
set(OPENCL_INCLUDE_DIR "${OpenCV_SOURCE_DIR}/3rdparty/include/opencl/1.2" CACHE PATH "OpenCL include directory")
|
||||
ocv_install_3rdparty_licenses(opencl-headers "${OpenCV_SOURCE_DIR}/3rdparty/include/opencl/LICENSE.txt")
|
||||
endif()
|
||||
mark_as_advanced(OPENCL_INCLUDE_DIR OPENCL_LIBRARY)
|
||||
|
||||
if(OPENCL_FOUND)
|
||||
|
||||
if(OPENCL_LIBRARY)
|
||||
set(HAVE_OPENCL_STATIC ON)
|
||||
set(OPENCL_LIBRARIES "${OPENCL_LIBRARY}")
|
||||
else()
|
||||
set(HAVE_OPENCL_STATIC OFF)
|
||||
endif()
|
||||
|
||||
if(NOT HAVE_OPENCL_STATIC)
|
||||
try_compile(__VALID_OPENCL
|
||||
"${OpenCV_BINARY_DIR}"
|
||||
"${OpenCV_SOURCE_DIR}/cmake/checks/opencl.cpp"
|
||||
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${OPENCL_INCLUDE_DIR}"
|
||||
OUTPUT_VARIABLE TRY_OUT
|
||||
)
|
||||
if(NOT TRY_OUT MATCHES "OpenCL is valid")
|
||||
message(WARNING "Can't use OpenCL")
|
||||
return()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(HAVE_OPENCL 1)
|
||||
|
||||
if(WITH_OPENCL_SVM)
|
||||
set(HAVE_OPENCL_SVM 1)
|
||||
endif()
|
||||
|
||||
set(OPENCL_INCLUDE_DIRS ${OPENCL_INCLUDE_DIR})
|
||||
|
||||
if(WITH_OPENCLAMDFFT)
|
||||
find_path(CLAMDFFT_ROOT_DIR
|
||||
NAMES include/clAmdFft.h
|
||||
PATHS ENV CLAMDFFT_PATH ENV ProgramFiles
|
||||
PATH_SUFFIXES clAmdFft AMD/clAmdFft
|
||||
DOC "AMD FFT root directory"
|
||||
NO_DEFAULT_PATH)
|
||||
|
||||
find_path(CLAMDFFT_INCLUDE_DIR
|
||||
NAMES clAmdFft.h
|
||||
HINTS ${CLAMDFFT_ROOT_DIR}
|
||||
PATH_SUFFIXES include
|
||||
DOC "clAmdFft include directory")
|
||||
|
||||
if(CLAMDFFT_INCLUDE_DIR)
|
||||
set(HAVE_CLAMDFFT 1)
|
||||
list(APPEND OPENCL_INCLUDE_DIRS "${CLAMDFFT_INCLUDE_DIR}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_OPENCLAMDBLAS)
|
||||
find_path(CLAMDBLAS_ROOT_DIR
|
||||
NAMES include/clAmdBlas.h
|
||||
PATHS ENV CLAMDBLAS_PATH ENV ProgramFiles
|
||||
PATH_SUFFIXES clAmdBlas AMD/clAmdBlas
|
||||
DOC "AMD FFT root directory"
|
||||
NO_DEFAULT_PATH)
|
||||
|
||||
find_path(CLAMDBLAS_INCLUDE_DIR
|
||||
NAMES clAmdBlas.h
|
||||
HINTS ${CLAMDBLAS_ROOT_DIR}
|
||||
PATH_SUFFIXES include
|
||||
DOC "clAmdFft include directory")
|
||||
|
||||
if(CLAMDBLAS_INCLUDE_DIR)
|
||||
set(HAVE_CLAMDBLAS 1)
|
||||
list(APPEND OPENCL_INCLUDE_DIRS "${CLAMDBLAS_INCLUDE_DIR}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# check WITH_OPENCL_D3D11_NV is located in OpenCVDetectDirectX.cmake file
|
||||
|
||||
endif()
|
|
@ -0,0 +1,299 @@
|
|||
# Find specified Python version
|
||||
# Arguments:
|
||||
# preferred_version (value): Version to check for first
|
||||
# min_version (value): Minimum supported version
|
||||
# library_env (value): Name of Python library ENV variable to check
|
||||
# include_dir_env (value): Name of Python include directory ENV variable to check
|
||||
# found (variable): Set if interpreter found
|
||||
# executable (variable): Output of executable found
|
||||
# version_string (variable): Output of found version
|
||||
# version_major (variable): Output of found major version
|
||||
# version_minor (variable): Output of found minor version
|
||||
# libs_found (variable): Set if libs found
|
||||
# libs_version_string (variable): Output of found libs version
|
||||
# libraries (variable): Output of found Python libraries
|
||||
# library (variable): Output of found Python library
|
||||
# debug_libraries (variable): Output of found Python debug libraries
|
||||
# debug_library (variable): Output of found Python debug library
|
||||
# include_path (variable): Output of found Python include path
|
||||
# include_dir (variable): Output of found Python include dir
|
||||
# include_dir2 (variable): Output of found Python include dir2
|
||||
# packages_path (variable): Output of found Python packages path
|
||||
# numpy_include_dirs (variable): Output of found Python Numpy include dirs
|
||||
# numpy_version (variable): Output of found Python Numpy version
|
||||
function(find_python preferred_version min_version library_env include_dir_env
|
||||
found executable version_string version_major version_minor
|
||||
libs_found libs_version_string libraries library debug_libraries
|
||||
debug_library include_path include_dir include_dir2 packages_path
|
||||
numpy_include_dirs numpy_version)
|
||||
if(NOT ${found})
|
||||
if(" ${executable}" STREQUAL " PYTHON_EXECUTABLE")
|
||||
set(__update_python_vars 0)
|
||||
else()
|
||||
set(__update_python_vars 1)
|
||||
endif()
|
||||
|
||||
ocv_check_environment_variables(${executable})
|
||||
if(${executable})
|
||||
set(PYTHON_EXECUTABLE "${${executable}}")
|
||||
endif()
|
||||
|
||||
if(WIN32 AND NOT ${executable} AND OPENCV_PYTHON_PREFER_WIN32_REGISTRY) # deprecated
|
||||
# search for executable with the same bitness as resulting binaries
|
||||
# standard FindPythonInterp always prefers executable from system path
|
||||
# this is really important because we are using the interpreter for numpy search and for choosing the install location
|
||||
foreach(_CURRENT_VERSION ${Python_ADDITIONAL_VERSIONS} "${preferred_version}" "${min_version}")
|
||||
find_host_program(PYTHON_EXECUTABLE
|
||||
NAMES python${_CURRENT_VERSION} python
|
||||
PATHS
|
||||
[HKEY_LOCAL_MACHINE\\\\SOFTWARE\\\\Python\\\\PythonCore\\\\${_CURRENT_VERSION}\\\\InstallPath]
|
||||
[HKEY_CURRENT_USER\\\\SOFTWARE\\\\Python\\\\PythonCore\\\\${_CURRENT_VERSION}\\\\InstallPath]
|
||||
NO_SYSTEM_ENVIRONMENT_PATH
|
||||
)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
if(preferred_version)
|
||||
set(__python_package_version "${preferred_version} EXACT")
|
||||
find_host_package(PythonInterp "${preferred_version}" EXACT)
|
||||
if(NOT PYTHONINTERP_FOUND)
|
||||
message(STATUS "Python is not found: ${preferred_version} EXACT")
|
||||
endif()
|
||||
elseif(min_version)
|
||||
set(__python_package_version "${min_version}")
|
||||
find_host_package(PythonInterp "${min_version}")
|
||||
else()
|
||||
set(__python_package_version "")
|
||||
find_host_package(PythonInterp)
|
||||
endif()
|
||||
|
||||
string(REGEX MATCH "^[0-9]+" _python_version_major "${min_version}")
|
||||
|
||||
if(PYTHONINTERP_FOUND)
|
||||
# Check if python major version is correct
|
||||
if(" ${_python_version_major}" STREQUAL " ")
|
||||
set(_python_version_major "${PYTHON_VERSION_MAJOR}")
|
||||
endif()
|
||||
if(NOT "${_python_version_major}" STREQUAL "${PYTHON_VERSION_MAJOR}"
|
||||
AND NOT DEFINED ${executable}
|
||||
)
|
||||
if(NOT OPENCV_SKIP_PYTHON_WARNING)
|
||||
message(WARNING "CMake's 'find_host_package(PythonInterp ${__python_package_version})' founds wrong Python version:\n"
|
||||
"PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}\n"
|
||||
"PYTHON_VERSION_STRING=${PYTHON_VERSION_STRING}\n"
|
||||
"Consider specify '${executable}' variable via CMake command line or environment variables\n")
|
||||
endif()
|
||||
ocv_clear_vars(PYTHONINTERP_FOUND PYTHON_EXECUTABLE PYTHON_VERSION_STRING PYTHON_VERSION_MAJOR PYTHON_VERSION_MINOR PYTHON_VERSION_PATCH)
|
||||
if(NOT CMAKE_VERSION VERSION_LESS "3.12")
|
||||
if(_python_version_major STREQUAL "2")
|
||||
set(__PYTHON_PREFIX Python2)
|
||||
else()
|
||||
set(__PYTHON_PREFIX Python3)
|
||||
endif()
|
||||
find_host_package(${__PYTHON_PREFIX} "${preferred_version}" COMPONENTS Interpreter)
|
||||
if(${__PYTHON_PREFIX}_EXECUTABLE)
|
||||
set(PYTHON_EXECUTABLE "${${__PYTHON_PREFIX}_EXECUTABLE}")
|
||||
find_host_package(PythonInterp "${preferred_version}") # Populate other variables
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "Consider using CMake 3.12+ for better Python support")
|
||||
endif()
|
||||
endif()
|
||||
if(PYTHONINTERP_FOUND AND "${_python_version_major}" STREQUAL "${PYTHON_VERSION_MAJOR}")
|
||||
# Copy outputs
|
||||
set(_found ${PYTHONINTERP_FOUND})
|
||||
set(_executable ${PYTHON_EXECUTABLE})
|
||||
set(_version_string ${PYTHON_VERSION_STRING})
|
||||
set(_version_major ${PYTHON_VERSION_MAJOR})
|
||||
set(_version_minor ${PYTHON_VERSION_MINOR})
|
||||
set(_version_patch ${PYTHON_VERSION_PATCH})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(__update_python_vars)
|
||||
# Clear find_host_package side effects
|
||||
unset(PYTHONINTERP_FOUND)
|
||||
unset(PYTHON_EXECUTABLE CACHE)
|
||||
unset(PYTHON_VERSION_STRING)
|
||||
unset(PYTHON_VERSION_MAJOR)
|
||||
unset(PYTHON_VERSION_MINOR)
|
||||
unset(PYTHON_VERSION_PATCH)
|
||||
endif()
|
||||
|
||||
if(_found)
|
||||
set(_version_major_minor "${_version_major}.${_version_minor}")
|
||||
|
||||
if(NOT ANDROID AND NOT APPLE_FRAMEWORK)
|
||||
ocv_check_environment_variables(${library_env} ${include_dir_env})
|
||||
if(NOT ${${library_env}} STREQUAL "")
|
||||
set(PYTHON_LIBRARY "${${library_env}}")
|
||||
endif()
|
||||
if(NOT ${${include_dir_env}} STREQUAL "")
|
||||
set(PYTHON_INCLUDE_DIR "${${include_dir_env}}")
|
||||
endif()
|
||||
|
||||
# not using _version_string here, because it might not conform to the CMake version format
|
||||
if(CMAKE_CROSSCOMPILING)
|
||||
# builder version can differ from target, matching base version (e.g. 2.7)
|
||||
find_package(PythonLibs "${_version_major_minor}")
|
||||
else()
|
||||
find_package(PythonLibs "${_version_major_minor}.${_version_patch}" EXACT)
|
||||
endif()
|
||||
|
||||
if(PYTHONLIBS_FOUND)
|
||||
# Copy outputs
|
||||
set(_libs_found ${PYTHONLIBS_FOUND})
|
||||
set(_libraries ${PYTHON_LIBRARIES})
|
||||
set(_include_path ${PYTHON_INCLUDE_PATH})
|
||||
set(_include_dirs ${PYTHON_INCLUDE_DIRS})
|
||||
set(_debug_libraries ${PYTHON_DEBUG_LIBRARIES})
|
||||
set(_libs_version_string ${PYTHONLIBS_VERSION_STRING})
|
||||
set(_debug_library ${PYTHON_DEBUG_LIBRARY})
|
||||
set(_library ${PYTHON_LIBRARY})
|
||||
set(_library_debug ${PYTHON_LIBRARY_DEBUG})
|
||||
set(_library_release ${PYTHON_LIBRARY_RELEASE})
|
||||
set(_include_dir ${PYTHON_INCLUDE_DIR})
|
||||
set(_include_dir2 ${PYTHON_INCLUDE_DIR2})
|
||||
endif()
|
||||
if(__update_python_vars)
|
||||
# Clear find_package side effects
|
||||
unset(PYTHONLIBS_FOUND)
|
||||
unset(PYTHON_LIBRARIES)
|
||||
unset(PYTHON_INCLUDE_PATH)
|
||||
unset(PYTHON_INCLUDE_DIRS)
|
||||
unset(PYTHON_DEBUG_LIBRARIES)
|
||||
unset(PYTHONLIBS_VERSION_STRING)
|
||||
unset(PYTHON_DEBUG_LIBRARY CACHE)
|
||||
unset(PYTHON_LIBRARY)
|
||||
unset(PYTHON_LIBRARY_DEBUG)
|
||||
unset(PYTHON_LIBRARY_RELEASE)
|
||||
unset(PYTHON_LIBRARY CACHE)
|
||||
unset(PYTHON_LIBRARY_DEBUG CACHE)
|
||||
unset(PYTHON_LIBRARY_RELEASE CACHE)
|
||||
unset(PYTHON_INCLUDE_DIR CACHE)
|
||||
unset(PYTHON_INCLUDE_DIR2 CACHE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT ANDROID AND NOT IOS)
|
||||
if(CMAKE_HOST_UNIX)
|
||||
execute_process(COMMAND ${_executable} -c "from distutils.sysconfig import *; print(get_python_lib())"
|
||||
RESULT_VARIABLE _cvpy_process
|
||||
OUTPUT_VARIABLE _std_packages_path
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if("${_std_packages_path}" MATCHES "site-packages")
|
||||
set(_packages_path "python${_version_major_minor}/site-packages")
|
||||
else() #debian based assumed, install to the dist-packages.
|
||||
set(_packages_path "python${_version_major_minor}/dist-packages")
|
||||
endif()
|
||||
set(_packages_path "lib/${_packages_path}")
|
||||
elseif(CMAKE_HOST_WIN32)
|
||||
get_filename_component(_path "${_executable}" PATH)
|
||||
file(TO_CMAKE_PATH "${_path}" _path)
|
||||
if(NOT EXISTS "${_path}/Lib/site-packages")
|
||||
unset(_path)
|
||||
get_filename_component(_path "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_version_major_minor}\\InstallPath]" ABSOLUTE)
|
||||
if(NOT _path)
|
||||
get_filename_component(_path "[HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${_version_major_minor}\\InstallPath]" ABSOLUTE)
|
||||
endif()
|
||||
file(TO_CMAKE_PATH "${_path}" _path)
|
||||
endif()
|
||||
set(_packages_path "${_path}/Lib/site-packages")
|
||||
unset(_path)
|
||||
endif()
|
||||
|
||||
set(_numpy_include_dirs "${${numpy_include_dirs}}")
|
||||
|
||||
if(NOT _numpy_include_dirs)
|
||||
if(CMAKE_CROSSCOMPILING)
|
||||
message(STATUS "Cannot probe for Python/Numpy support (because we are cross-compiling OpenCV)")
|
||||
message(STATUS "If you want to enable Python/Numpy support, set the following variables:")
|
||||
message(STATUS " PYTHON2_INCLUDE_PATH")
|
||||
message(STATUS " PYTHON2_LIBRARIES (optional on Unix-like systems)")
|
||||
message(STATUS " PYTHON2_NUMPY_INCLUDE_DIRS")
|
||||
message(STATUS " PYTHON3_INCLUDE_PATH")
|
||||
message(STATUS " PYTHON3_LIBRARIES (optional on Unix-like systems)")
|
||||
message(STATUS " PYTHON3_NUMPY_INCLUDE_DIRS")
|
||||
else()
|
||||
# Attempt to discover the NumPy include directory. If this succeeds, then build python API with NumPy
|
||||
execute_process(COMMAND "${_executable}" -c "import os; os.environ['DISTUTILS_USE_SDK']='1'; import numpy.distutils; print(os.pathsep.join(numpy.distutils.misc_util.get_numpy_include_dirs()))"
|
||||
RESULT_VARIABLE _numpy_process
|
||||
OUTPUT_VARIABLE _numpy_include_dirs
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
if(NOT _numpy_process EQUAL 0)
|
||||
unset(_numpy_include_dirs)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(_numpy_include_dirs)
|
||||
file(TO_CMAKE_PATH "${_numpy_include_dirs}" _numpy_include_dirs)
|
||||
if(CMAKE_CROSSCOMPILING)
|
||||
if(NOT _numpy_version)
|
||||
set(_numpy_version "undefined - cannot be probed because of the cross-compilation")
|
||||
endif()
|
||||
else()
|
||||
execute_process(COMMAND "${_executable}" -c "import numpy; print(numpy.version.version)"
|
||||
RESULT_VARIABLE _numpy_process
|
||||
OUTPUT_VARIABLE _numpy_version
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
endif()
|
||||
endif()
|
||||
endif(NOT ANDROID AND NOT IOS)
|
||||
endif()
|
||||
|
||||
# Export return values
|
||||
set(${found} "${_found}" CACHE INTERNAL "")
|
||||
set(${executable} "${_executable}" CACHE FILEPATH "Path to Python interpreter")
|
||||
set(${version_string} "${_version_string}" CACHE INTERNAL "")
|
||||
set(${version_major} "${_version_major}" CACHE INTERNAL "")
|
||||
set(${version_minor} "${_version_minor}" CACHE INTERNAL "")
|
||||
set(${libs_found} "${_libs_found}" CACHE INTERNAL "")
|
||||
set(${libs_version_string} "${_libs_version_string}" CACHE INTERNAL "")
|
||||
set(${libraries} "${_libraries}" CACHE INTERNAL "Python libraries")
|
||||
set(${library} "${_library}" CACHE FILEPATH "Path to Python library")
|
||||
set(${debug_libraries} "${_debug_libraries}" CACHE INTERNAL "")
|
||||
set(${debug_library} "${_debug_library}" CACHE FILEPATH "Path to Python debug")
|
||||
set(${include_path} "${_include_path}" CACHE INTERNAL "")
|
||||
set(${include_dir} "${_include_dir}" CACHE PATH "Python include dir")
|
||||
set(${include_dir2} "${_include_dir2}" CACHE PATH "Python include dir 2")
|
||||
set(${packages_path} "${_packages_path}" CACHE PATH "Where to install the python packages.")
|
||||
set(${numpy_include_dirs} ${_numpy_include_dirs} CACHE PATH "Path to numpy headers")
|
||||
set(${numpy_version} "${_numpy_version}" CACHE INTERNAL "")
|
||||
endif()
|
||||
endfunction(find_python)
|
||||
|
||||
if(OPENCV_PYTHON_SKIP_DETECTION)
|
||||
return()
|
||||
endif()
|
||||
|
||||
find_python("" "${MIN_VER_PYTHON2}" PYTHON2_LIBRARY PYTHON2_INCLUDE_DIR
|
||||
PYTHON2INTERP_FOUND PYTHON2_EXECUTABLE PYTHON2_VERSION_STRING
|
||||
PYTHON2_VERSION_MAJOR PYTHON2_VERSION_MINOR PYTHON2LIBS_FOUND
|
||||
PYTHON2LIBS_VERSION_STRING PYTHON2_LIBRARIES PYTHON2_LIBRARY
|
||||
PYTHON2_DEBUG_LIBRARIES PYTHON2_LIBRARY_DEBUG PYTHON2_INCLUDE_PATH
|
||||
PYTHON2_INCLUDE_DIR PYTHON2_INCLUDE_DIR2 PYTHON2_PACKAGES_PATH
|
||||
PYTHON2_NUMPY_INCLUDE_DIRS PYTHON2_NUMPY_VERSION)
|
||||
|
||||
option(OPENCV_PYTHON3_VERSION "Python3 version" "")
|
||||
find_python("${OPENCV_PYTHON3_VERSION}" "${MIN_VER_PYTHON3}" PYTHON3_LIBRARY PYTHON3_INCLUDE_DIR
|
||||
PYTHON3INTERP_FOUND PYTHON3_EXECUTABLE PYTHON3_VERSION_STRING
|
||||
PYTHON3_VERSION_MAJOR PYTHON3_VERSION_MINOR PYTHON3LIBS_FOUND
|
||||
PYTHON3LIBS_VERSION_STRING PYTHON3_LIBRARIES PYTHON3_LIBRARY
|
||||
PYTHON3_DEBUG_LIBRARIES PYTHON3_LIBRARY_DEBUG PYTHON3_INCLUDE_PATH
|
||||
PYTHON3_INCLUDE_DIR PYTHON3_INCLUDE_DIR2 PYTHON3_PACKAGES_PATH
|
||||
PYTHON3_NUMPY_INCLUDE_DIRS PYTHON3_NUMPY_VERSION)
|
||||
|
||||
|
||||
if(PYTHON_DEFAULT_EXECUTABLE)
|
||||
set(PYTHON_DEFAULT_AVAILABLE "TRUE")
|
||||
elseif(PYTHON2_EXECUTABLE AND PYTHON2INTERP_FOUND)
|
||||
# Use Python 2 as default Python interpreter
|
||||
set(PYTHON_DEFAULT_AVAILABLE "TRUE")
|
||||
set(PYTHON_DEFAULT_EXECUTABLE "${PYTHON2_EXECUTABLE}")
|
||||
elseif(PYTHON3_EXECUTABLE AND PYTHON3INTERP_FOUND)
|
||||
# Use Python 3 as fallback Python interpreter (if there is no Python 2)
|
||||
set(PYTHON_DEFAULT_AVAILABLE "TRUE")
|
||||
set(PYTHON_DEFAULT_EXECUTABLE "${PYTHON3_EXECUTABLE}")
|
||||
endif()
|
|
@ -0,0 +1,115 @@
|
|||
# Search TBB library (4.1 - 4.4, 2017)
|
||||
#
|
||||
# Own TBB (3rdparty/tbb):
|
||||
# - set cmake option BUILD_TBB to ON
|
||||
#
|
||||
# External TBB (from system):
|
||||
# - Fedora: install 'tbb-devel' package
|
||||
# - Ubuntu: install 'libtbb-dev' package
|
||||
#
|
||||
# External TBB (from official site):
|
||||
# - Linux/OSX:
|
||||
# - in tbbvars.sh replace 'SUBSTITUTE_INSTALL_DIR_HERE' with absolute path to TBB dir
|
||||
# - in terminal run 'source tbbvars.sh intel64 linux' ('source tbbvars.sh' in OSX)
|
||||
# - Windows:
|
||||
# - in terminal run 'tbbvars.bat intel64 vs2015'
|
||||
#
|
||||
# Return:
|
||||
# - HAVE_TBB set to TRUE
|
||||
# - "tbb" target exists and added to OPENCV_LINKER_LIBS
|
||||
|
||||
function(ocv_tbb_cmake_guess _found)
|
||||
find_package(TBB QUIET COMPONENTS tbb PATHS "$ENV{TBBROOT}/cmake")
|
||||
if(TBB_FOUND)
|
||||
if(NOT TARGET TBB::tbb)
|
||||
message(WARNING "No TBB::tbb target found!")
|
||||
return()
|
||||
endif()
|
||||
get_target_property(_lib TBB::tbb IMPORTED_LOCATION_RELEASE)
|
||||
message(STATUS "Found TBB (cmake): ${_lib}")
|
||||
get_target_property(_inc TBB::tbb INTERFACE_INCLUDE_DIRECTORIES)
|
||||
ocv_tbb_read_version("${_inc}")
|
||||
add_library(tbb INTERFACE IMPORTED)
|
||||
set_target_properties(tbb PROPERTIES
|
||||
INTERFACE_LINK_LIBRARIES TBB::tbb
|
||||
)
|
||||
set(${_found} TRUE PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(ocv_tbb_env_verify)
|
||||
if (NOT "$ENV{TBBROOT}" STREQUAL "")
|
||||
# check that library and include dir are inside TBBROOT location
|
||||
get_filename_component(_root "$ENV{TBBROOT}" ABSOLUTE)
|
||||
get_filename_component(_lib "${TBB_ENV_LIB}" ABSOLUTE)
|
||||
get_filename_component(_inc "${TBB_ENV_INCLUDE}" ABSOLUTE)
|
||||
string(FIND "${_lib}" "${_root}" _lib_pos)
|
||||
string(FIND "${_inc}" "${_root}" _inc_pos)
|
||||
if (NOT (_lib_pos EQUAL 0 AND _inc_pos EQUAL 0))
|
||||
message(SEND_ERROR
|
||||
"Possible issue with TBB detection - TBBROOT is set, "
|
||||
"but library/include path is not inside it:\n "
|
||||
"TBBROOT: $ENV{TBBROOT}\n "
|
||||
"(absolute): ${_root}\n "
|
||||
"INCLUDE: ${_inc}\n "
|
||||
"LIBRARY: ${_lib}\n")
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(ocv_tbb_env_guess _found)
|
||||
find_path(TBB_ENV_INCLUDE NAMES "tbb/tbb.h" PATHS ENV CPATH NO_DEFAULT_PATH)
|
||||
find_path(TBB_ENV_INCLUDE NAMES "tbb/tbb.h")
|
||||
find_library(TBB_ENV_LIB NAMES "tbb" PATHS ENV LIBRARY_PATH NO_DEFAULT_PATH)
|
||||
find_library(TBB_ENV_LIB NAMES "tbb")
|
||||
find_library(TBB_ENV_LIB_DEBUG NAMES "tbb_debug" PATHS ENV LIBRARY_PATH NO_DEFAULT_PATH)
|
||||
find_library(TBB_ENV_LIB_DEBUG NAMES "tbb_debug")
|
||||
if (TBB_ENV_INCLUDE AND (TBB_ENV_LIB OR TBB_ENV_LIB_DEBUG))
|
||||
ocv_tbb_env_verify()
|
||||
ocv_tbb_read_version("${TBB_ENV_INCLUDE}")
|
||||
add_library(tbb UNKNOWN IMPORTED)
|
||||
set_target_properties(tbb PROPERTIES
|
||||
IMPORTED_LOCATION "${TBB_ENV_LIB}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${TBB_ENV_INCLUDE}"
|
||||
)
|
||||
if (TBB_ENV_LIB_DEBUG)
|
||||
set_target_properties(tbb PROPERTIES
|
||||
IMPORTED_LOCATION_DEBUG "${TBB_ENV_LIB_DEBUG}"
|
||||
)
|
||||
endif()
|
||||
# workaround: system TBB library is used for linking instead of provided
|
||||
if(CV_GCC)
|
||||
get_filename_component(_dir "${TBB_ENV_LIB}" DIRECTORY)
|
||||
set_target_properties(tbb PROPERTIES INTERFACE_LINK_LIBRARIES "-L${_dir}")
|
||||
endif()
|
||||
message(STATUS "Found TBB (env): ${TBB_ENV_LIB}")
|
||||
set(${_found} TRUE PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(ocv_tbb_read_version _path)
|
||||
find_file(TBB_VER_FILE tbb/tbb_stddef.h "${_path}" NO_DEFAULT_PATH CMAKE_FIND_ROOT_PATH_BOTH)
|
||||
ocv_parse_header("${TBB_VER_FILE}" TBB_VERSION_LINES TBB_VERSION_MAJOR TBB_VERSION_MINOR TBB_INTERFACE_VERSION CACHE)
|
||||
endfunction()
|
||||
|
||||
#=====================================================================
|
||||
|
||||
if(BUILD_TBB)
|
||||
add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/tbb")
|
||||
if(NOT TARGET tbb)
|
||||
return()
|
||||
endif()
|
||||
set(HAVE_TBB TRUE)
|
||||
endif()
|
||||
|
||||
if(NOT HAVE_TBB)
|
||||
ocv_tbb_cmake_guess(HAVE_TBB)
|
||||
endif()
|
||||
|
||||
if(NOT HAVE_TBB)
|
||||
ocv_tbb_env_guess(HAVE_TBB)
|
||||
endif()
|
||||
|
||||
if(TBB_INTERFACE_VERSION LESS 6000) # drop support of versions < 4.0
|
||||
set(HAVE_TBB FALSE)
|
||||
endif()
|
|
@ -0,0 +1,13 @@
|
|||
if(WITH_ITT)
|
||||
if(BUILD_ITT)
|
||||
add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/ittnotify")
|
||||
set(ITT_INCLUDE_DIR "${OpenCV_SOURCE_DIR}/3rdparty/ittnotify/include")
|
||||
set(ITT_INCLUDE_DIRS "${ITT_INCLUDE_DIR}")
|
||||
set(ITT_LIBRARIES "ittnotify")
|
||||
set(HAVE_ITT 1)
|
||||
else()
|
||||
#TODO
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(OPENCV_TRACE 1)
|
|
@ -0,0 +1,69 @@
|
|||
# VTK 6.x components
|
||||
find_package(VTK QUIET COMPONENTS vtkInteractionStyle vtkRenderingLOD vtkIOPLY vtkFiltersTexture vtkRenderingFreeType vtkIOExport NO_MODULE)
|
||||
IF(VTK_FOUND)
|
||||
IF(VTK_RENDERING_BACKEND) #in vtk 7, the rendering backend is exported as a var.
|
||||
find_package(VTK QUIET COMPONENTS vtkRendering${VTK_RENDERING_BACKEND} vtkInteractionStyle vtkRenderingLOD vtkIOPLY vtkFiltersTexture vtkRenderingFreeType vtkIOExport vtkIOGeometry NO_MODULE)
|
||||
ELSE(VTK_RENDERING_BACKEND)
|
||||
find_package(VTK QUIET COMPONENTS vtkRenderingOpenGL vtkInteractionStyle vtkRenderingLOD vtkIOPLY vtkFiltersTexture vtkRenderingFreeType vtkIOExport NO_MODULE)
|
||||
ENDIF(VTK_RENDERING_BACKEND)
|
||||
ENDIF(VTK_FOUND)
|
||||
|
||||
# VTK 5.x components
|
||||
if(NOT VTK_FOUND)
|
||||
find_package(VTK QUIET COMPONENTS vtkCommon NO_MODULE)
|
||||
endif()
|
||||
|
||||
if(NOT VTK_FOUND)
|
||||
set(HAVE_VTK OFF)
|
||||
message(STATUS "VTK is not found. Please set -DVTK_DIR in CMake to VTK build directory, or to VTK install subdirectory with VTKConfig.cmake file")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Don't support earlier VTKs
|
||||
if(VTK_VERSION VERSION_LESS "5.8.0")
|
||||
message(STATUS "VTK support is disabled. VTK ver. 5.8.0 is minimum required, but found VTK ver. ${VTK_VERSION}")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Different Qt versions can't be linked together
|
||||
if(HAVE_QT5 AND VTK_VERSION VERSION_LESS "6.0.0")
|
||||
if(VTK_USE_QT)
|
||||
message(STATUS "VTK support is disabled. Incompatible combination: OpenCV + Qt5 and VTK ver.${VTK_VERSION} + Qt4")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Different Qt versions can't be linked together. VTK 6.0.0 doesn't provide a way to get Qt version it was linked with
|
||||
if(HAVE_QT5 AND VTK_VERSION VERSION_EQUAL "6.0.0" AND NOT DEFINED FORCE_VTK)
|
||||
message(STATUS "VTK support is disabled. Possible incompatible combination: OpenCV+Qt5, and VTK ver.${VTK_VERSION} with Qt4")
|
||||
message(STATUS "If it is known that VTK was compiled without Qt4, please define '-DFORCE_VTK=TRUE' flag in CMake")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Different Qt versions can't be linked together
|
||||
if(HAVE_QT AND VTK_VERSION VERSION_GREATER "6.0.0" AND NOT ${VTK_QT_VERSION} STREQUAL "")
|
||||
if(HAVE_QT5 AND ${VTK_QT_VERSION} EQUAL "4")
|
||||
message(STATUS "VTK support is disabled. Incompatible combination: OpenCV + Qt5 and VTK ver.${VTK_VERSION} + Qt4")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(NOT HAVE_QT5 AND ${VTK_QT_VERSION} EQUAL "5")
|
||||
message(STATUS "VTK support is disabled. Incompatible combination: OpenCV + Qt4 and VTK ver.${VTK_VERSION} + Qt5")
|
||||
return()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
try_compile(VTK_COMPILE_STATUS
|
||||
"${OpenCV_BINARY_DIR}"
|
||||
"${OpenCV_SOURCE_DIR}/cmake/checks/vtk_test.cpp"
|
||||
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${VTK_INCLUDE_DIRS}"
|
||||
LINK_LIBRARIES ${VTK_LIBRARIES}
|
||||
OUTPUT_VARIABLE OUTPUT
|
||||
)
|
||||
|
||||
if(NOT ${VTK_COMPILE_STATUS})
|
||||
message(STATUS "VTK support is disabled. Compilation of the sample code has failed.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(HAVE_VTK ON)
|
||||
message(STATUS "Found VTK ${VTK_VERSION} (${VTK_USE_FILE})")
|
|
@ -0,0 +1,20 @@
|
|||
set(VULKAN_INCLUDE_DIRS "${OpenCV_SOURCE_DIR}/3rdparty/include" CACHE PATH "Vulkan include directory")
|
||||
set(VULKAN_LIBRARIES "")
|
||||
|
||||
try_compile(VALID_VULKAN
|
||||
"${OpenCV_BINARY_DIR}"
|
||||
"${OpenCV_SOURCE_DIR}/cmake/checks/vulkan.cpp"
|
||||
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${VULKAN_INCLUDE_DIRS}"
|
||||
OUTPUT_VARIABLE TRY_OUT
|
||||
)
|
||||
if(NOT ${VALID_VULKAN})
|
||||
message(WARNING "Can't use Vulkan")
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(HAVE_VULKAN 1)
|
||||
|
||||
if(HAVE_VULKAN)
|
||||
add_definitions(-DVK_NO_PROTOTYPES)
|
||||
include_directories(${VULKAN_INCLUDE_DIRS})
|
||||
endif()
|
|
@ -0,0 +1,254 @@
|
|||
#
|
||||
# Download and optionally unpack a file
|
||||
#
|
||||
# ocv_download(FILENAME p HASH h URL u1 [u2 ...] DESTINATION_DIR d [ID id] [STATUS s] [UNPACK] [RELATIVE_URL])
|
||||
# FILENAME - filename
|
||||
# HASH - MD5 hash
|
||||
# URL - full download url (first nonempty value will be chosen)
|
||||
# DESTINATION_DIR - file will be copied to this directory
|
||||
# ID - identifier for project/group of downloaded files
|
||||
# STATUS - passed variable will be updated in parent scope,
|
||||
# function will not fail the build in case of download problem if this option is provided,
|
||||
# but will fail in case when other operations (copy, remove, etc.) failed
|
||||
# UNPACK - downloaded file will be unpacked to DESTINATION_DIR
|
||||
# RELATIVE_URL - if set, then URL is treated as a base, and FILENAME will be appended to it
|
||||
# Note: uses OPENCV_DOWNLOAD_PATH folder as cache, default is <opencv>/.cache
|
||||
|
||||
set(HELP_OPENCV_DOWNLOAD_PATH "Cache directory for downloaded files")
|
||||
if(DEFINED ENV{OPENCV_DOWNLOAD_PATH})
|
||||
set(OPENCV_DOWNLOAD_PATH "$ENV{OPENCV_DOWNLOAD_PATH}" CACHE PATH "${HELP_OPENCV_DOWNLOAD_PATH}")
|
||||
endif()
|
||||
set(OPENCV_DOWNLOAD_PATH "${OpenCV_SOURCE_DIR}/.cache" CACHE PATH "${HELP_OPENCV_DOWNLOAD_PATH}")
|
||||
set(OPENCV_DOWNLOAD_LOG "${OpenCV_BINARY_DIR}/CMakeDownloadLog.txt")
|
||||
set(OPENCV_DOWNLOAD_WITH_CURL "${OpenCV_BINARY_DIR}/download_with_curl.sh")
|
||||
set(OPENCV_DOWNLOAD_WITH_WGET "${OpenCV_BINARY_DIR}/download_with_wget.sh")
|
||||
set(OPENCV_DOWNLOAD_TRIES_LIST 1 CACHE STRING "List of download tries") # a list
|
||||
set(OPENCV_DOWNLOAD_PARAMS INACTIVITY_TIMEOUT 60 TIMEOUT 600 CACHE STRING "Download parameters to be passed to file(DOWNLAOD ...)")
|
||||
mark_as_advanced(OPENCV_DOWNLOAD_TRIES_LIST OPENCV_DOWNLOAD_PARAMS)
|
||||
|
||||
# Init download cache directory and log file and helper scripts
|
||||
if(NOT EXISTS "${OPENCV_DOWNLOAD_PATH}")
|
||||
file(MAKE_DIRECTORY ${OPENCV_DOWNLOAD_PATH})
|
||||
endif()
|
||||
if(NOT EXISTS "${OPENCV_DOWNLOAD_PATH}/.gitignore")
|
||||
file(WRITE "${OPENCV_DOWNLOAD_PATH}/.gitignore" "*\n")
|
||||
endif()
|
||||
file(WRITE "${OPENCV_DOWNLOAD_LOG}" "#use_cache \"${OPENCV_DOWNLOAD_PATH}\"\n")
|
||||
file(REMOVE "${OPENCV_DOWNLOAD_WITH_CURL}")
|
||||
file(REMOVE "${OPENCV_DOWNLOAD_WITH_WGET}")
|
||||
|
||||
function(ocv_download)
|
||||
cmake_parse_arguments(DL "UNPACK;RELATIVE_URL" "FILENAME;HASH;DESTINATION_DIR;ID;STATUS" "URL" ${ARGN})
|
||||
|
||||
function(ocv_download_log)
|
||||
file(APPEND "${OPENCV_DOWNLOAD_LOG}" "${ARGN}\n")
|
||||
endfunction()
|
||||
|
||||
ocv_assert(DL_FILENAME)
|
||||
ocv_assert(DL_HASH)
|
||||
ocv_assert(DL_URL)
|
||||
ocv_assert(DL_DESTINATION_DIR)
|
||||
if((NOT " ${DL_UNPARSED_ARGUMENTS}" STREQUAL " ")
|
||||
OR DL_FILENAME STREQUAL ""
|
||||
OR DL_HASH STREQUAL ""
|
||||
OR DL_URL STREQUAL ""
|
||||
OR DL_DESTINATION_DIR STREQUAL ""
|
||||
)
|
||||
set(msg_level FATAL_ERROR)
|
||||
if(DEFINED DL_STATUS)
|
||||
set(${DL_STATUS} FALSE PARENT_SCOPE)
|
||||
set(msg_level WARNING)
|
||||
endif()
|
||||
message(${msg_level} "ERROR: ocv_download() unsupported arguments: ${ARGV}")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if(DEFINED DL_STATUS)
|
||||
set(${DL_STATUS} TRUE PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
# Check CMake cache for already processed tasks
|
||||
string(FIND "${DL_DESTINATION_DIR}" "${CMAKE_BINARY_DIR}" DL_BINARY_PATH_POS)
|
||||
if(DL_BINARY_PATH_POS EQUAL 0)
|
||||
set(__file_id "${DL_DESTINATION_DIR}/${DL_FILENAME}")
|
||||
file(RELATIVE_PATH __file_id "${CMAKE_BINARY_DIR}" "${__file_id}")
|
||||
string(REGEX REPLACE "[^a-zA-Z0-9_]" "_" __file_id "${__file_id}")
|
||||
if(DL_ID)
|
||||
string(TOUPPER ${DL_ID} __id)
|
||||
string(REGEX REPLACE "[^a-zA-Z0-9_]" "_" __id "${__id}")
|
||||
set(OCV_DOWNLOAD_HASH_NAME "OCV_DOWNLOAD_${__id}_HASH_${__file_id}")
|
||||
else()
|
||||
set(OCV_DOWNLOAD_HASH_NAME "OCV_DOWNLOAD_HASH_${__file_id}")
|
||||
endif()
|
||||
if(" ${${OCV_DOWNLOAD_HASH_NAME}}" STREQUAL " ${DL_HASH}")
|
||||
ocv_download_log("#match_hash_in_cmake_cache \"${OCV_DOWNLOAD_HASH_NAME}\"")
|
||||
return()
|
||||
endif()
|
||||
unset("${OCV_DOWNLOAD_HASH_NAME}" CACHE)
|
||||
else()
|
||||
set(OCV_DOWNLOAD_HASH_NAME "")
|
||||
#message(WARNING "Download destination is not in CMAKE_BINARY_DIR=${CMAKE_BINARY_DIR}: ${DL_DESTINATION_DIR}")
|
||||
endif()
|
||||
|
||||
# Select first non-empty url
|
||||
foreach(url ${DL_URL})
|
||||
if(url)
|
||||
set(DL_URL "${url}")
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# Append filename to url if needed
|
||||
if(DL_RELATIVE_URL)
|
||||
set(DL_URL "${DL_URL}${DL_FILENAME}")
|
||||
endif()
|
||||
|
||||
set(mode "copy")
|
||||
if(DL_UNPACK)
|
||||
set(mode "unpack")
|
||||
endif()
|
||||
|
||||
# Log all calls to file
|
||||
ocv_download_log("#do_${mode} \"${DL_FILENAME}\" \"${DL_HASH}\" \"${DL_URL}\" \"${DL_DESTINATION_DIR}\"")
|
||||
# ... and to console
|
||||
set(__msg_prefix "")
|
||||
if(DL_ID)
|
||||
set(__msg_prefix "${DL_ID}: ")
|
||||
endif()
|
||||
message(STATUS "${__msg_prefix}Download: ${DL_FILENAME}")
|
||||
|
||||
# Copy mode: check if copy destination exists and is correct
|
||||
if(NOT DL_UNPACK)
|
||||
set(COPY_DESTINATION "${DL_DESTINATION_DIR}/${DL_FILENAME}")
|
||||
if(EXISTS "${COPY_DESTINATION}")
|
||||
ocv_download_log("#check_md5 \"${COPY_DESTINATION}\"")
|
||||
file(MD5 "${COPY_DESTINATION}" target_md5)
|
||||
if(target_md5 STREQUAL DL_HASH)
|
||||
ocv_download_log("#match_md5 \"${COPY_DESTINATION}\" \"${target_md5}\"")
|
||||
if(OCV_DOWNLOAD_HASH_NAME)
|
||||
set(${OCV_DOWNLOAD_HASH_NAME} "${DL_HASH}" CACHE INTERNAL "")
|
||||
endif()
|
||||
return()
|
||||
endif()
|
||||
ocv_download_log("#mismatch_md5 \"${COPY_DESTINATION}\" \"${target_md5}\"")
|
||||
else()
|
||||
ocv_download_log("#missing \"${COPY_DESTINATION}\"")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Check cache first
|
||||
if(DL_ID)
|
||||
string(TOLOWER "${DL_ID}" __id)
|
||||
string(REGEX REPLACE "[^a-zA-Z0-9_/ ]" "_" __id "${__id}")
|
||||
set(CACHE_CANDIDATE "${OPENCV_DOWNLOAD_PATH}/${__id}/${DL_HASH}-${DL_FILENAME}")
|
||||
else()
|
||||
set(CACHE_CANDIDATE "${OPENCV_DOWNLOAD_PATH}/${DL_HASH}-${DL_FILENAME}")
|
||||
endif()
|
||||
if(EXISTS "${CACHE_CANDIDATE}")
|
||||
ocv_download_log("#check_md5 \"${CACHE_CANDIDATE}\"")
|
||||
file(MD5 "${CACHE_CANDIDATE}" target_md5)
|
||||
if(NOT target_md5 STREQUAL DL_HASH)
|
||||
ocv_download_log("#mismatch_md5 \"${CACHE_CANDIDATE}\" \"${target_md5}\"")
|
||||
ocv_download_log("#delete \"${CACHE_CANDIDATE}\"")
|
||||
file(REMOVE ${CACHE_CANDIDATE})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Download
|
||||
if(NOT EXISTS "${CACHE_CANDIDATE}")
|
||||
ocv_download_log("#cmake_download \"${CACHE_CANDIDATE}\" \"${DL_URL}\"")
|
||||
foreach(try ${OPENCV_DOWNLOAD_TRIES_LIST})
|
||||
ocv_download_log("#try ${try}")
|
||||
file(DOWNLOAD "${DL_URL}" "${CACHE_CANDIDATE}"
|
||||
STATUS status
|
||||
LOG __log
|
||||
${OPENCV_DOWNLOAD_PARAMS})
|
||||
if(status EQUAL 0)
|
||||
break()
|
||||
endif()
|
||||
message(STATUS "Try ${try} failed")
|
||||
endforeach()
|
||||
if(NOT OPENCV_SKIP_FILE_DOWNLOAD_DUMP) # workaround problem with old CMake versions: "Invalid escape sequence"
|
||||
string(LENGTH "${__log}" __log_length)
|
||||
if(__log_length LESS 65536)
|
||||
string(REPLACE "\n" "\n# " __log "${__log}")
|
||||
ocv_download_log("# ${__log}\n")
|
||||
endif()
|
||||
endif()
|
||||
if(NOT status EQUAL 0)
|
||||
set(msg_level FATAL_ERROR)
|
||||
if(DEFINED DL_STATUS)
|
||||
set(${DL_STATUS} FALSE PARENT_SCOPE)
|
||||
set(msg_level WARNING)
|
||||
endif()
|
||||
if(status MATCHES "Couldn't resolve host name")
|
||||
message(STATUS "
|
||||
=======================================================================
|
||||
Couldn't download files from the Internet.
|
||||
Please check the Internet access on this host.
|
||||
=======================================================================
|
||||
")
|
||||
elseif(status MATCHES "Couldn't connect to server")
|
||||
message(STATUS "
|
||||
=======================================================================
|
||||
Couldn't connect to server from the Internet.
|
||||
Perhaps direct connections are not allowed in the current network.
|
||||
To use proxy please check/specify these environment variables:
|
||||
- http_proxy/https_proxy
|
||||
- and/or HTTP_PROXY/HTTPS_PROXY
|
||||
=======================================================================
|
||||
")
|
||||
endif()
|
||||
message(${msg_level} "${__msg_prefix}Download failed: ${status}
|
||||
For details please refer to the download log file:
|
||||
${OPENCV_DOWNLOAD_LOG}
|
||||
")
|
||||
# write helper scripts for failed downloads
|
||||
file(APPEND "${OPENCV_DOWNLOAD_WITH_CURL}" "curl --create-dirs --output \"${CACHE_CANDIDATE}\" \"${DL_URL}\"\n")
|
||||
file(APPEND "${OPENCV_DOWNLOAD_WITH_WGET}" "mkdir -p $(dirname ${CACHE_CANDIDATE}) && wget -O \"${CACHE_CANDIDATE}\" \"${DL_URL}\"\n")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Don't remove this code, because EXPECTED_MD5 parameter doesn't fail "file(DOWNLOAD)" step on wrong hash
|
||||
ocv_download_log("#check_md5 \"${CACHE_CANDIDATE}\"")
|
||||
file(MD5 "${CACHE_CANDIDATE}" target_md5)
|
||||
if(NOT target_md5 STREQUAL DL_HASH)
|
||||
ocv_download_log("#mismatch_md5 \"${CACHE_CANDIDATE}\" \"${target_md5}\"")
|
||||
set(msg_level FATAL_ERROR)
|
||||
if(DEFINED DL_STATUS)
|
||||
set(${DL_STATUS} FALSE PARENT_SCOPE)
|
||||
set(msg_level WARNING)
|
||||
endif()
|
||||
message(${msg_level} "${__msg_prefix}Hash mismatch: ${target_md5}")
|
||||
return()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Unpack or copy
|
||||
if(DL_UNPACK)
|
||||
if(EXISTS "${DL_DESTINATION_DIR}")
|
||||
ocv_download_log("#remove_unpack \"${DL_DESTINATION_DIR}\"")
|
||||
file(REMOVE_RECURSE "${DL_DESTINATION_DIR}")
|
||||
endif()
|
||||
ocv_download_log("#mkdir \"${DL_DESTINATION_DIR}\"")
|
||||
file(MAKE_DIRECTORY "${DL_DESTINATION_DIR}")
|
||||
ocv_download_log("#unpack \"${DL_DESTINATION_DIR}\" \"${CACHE_CANDIDATE}\"")
|
||||
execute_process(COMMAND "${CMAKE_COMMAND}" -E tar xzf "${CACHE_CANDIDATE}"
|
||||
WORKING_DIRECTORY "${DL_DESTINATION_DIR}"
|
||||
RESULT_VARIABLE res)
|
||||
if(NOT res EQUAL 0)
|
||||
message(FATAL_ERROR "${__msg_prefix}Unpack failed: ${res}")
|
||||
endif()
|
||||
else()
|
||||
ocv_download_log("#copy \"${COPY_DESTINATION}\" \"${CACHE_CANDIDATE}\"")
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CACHE_CANDIDATE}" "${COPY_DESTINATION}"
|
||||
RESULT_VARIABLE res)
|
||||
if(NOT res EQUAL 0)
|
||||
message(FATAL_ERROR "${__msg_prefix}Copy failed: ${res}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(OCV_DOWNLOAD_HASH_NAME)
|
||||
set(${OCV_DOWNLOAD_HASH_NAME} "${DL_HASH}" CACHE INTERNAL "")
|
||||
endif()
|
||||
endfunction()
|
|
@ -0,0 +1,53 @@
|
|||
# ----------------------------------------------------------------------------
|
||||
# Uninstall target, for "make uninstall"
|
||||
# ----------------------------------------------------------------------------
|
||||
CONFIGURE_FILE(
|
||||
"${OpenCV_SOURCE_DIR}/cmake/templates/cmake_uninstall.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
|
||||
@ONLY)
|
||||
|
||||
ADD_CUSTOM_TARGET(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
|
||||
if(ENABLE_SOLUTION_FOLDERS)
|
||||
set_target_properties(uninstall PROPERTIES FOLDER "CMakeTargets")
|
||||
endif()
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# target building all OpenCV modules
|
||||
# ----------------------------------------------------------------------------
|
||||
add_custom_target(opencv_modules)
|
||||
if(ENABLE_SOLUTION_FOLDERS)
|
||||
set_target_properties(opencv_modules PROPERTIES FOLDER "extra")
|
||||
endif()
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# targets building all tests
|
||||
# ----------------------------------------------------------------------------
|
||||
if(BUILD_TESTS)
|
||||
add_custom_target(opencv_tests)
|
||||
if(ENABLE_SOLUTION_FOLDERS)
|
||||
set_target_properties(opencv_tests PROPERTIES FOLDER "extra")
|
||||
endif()
|
||||
endif()
|
||||
if(BUILD_PERF_TESTS)
|
||||
add_custom_target(opencv_perf_tests)
|
||||
if(ENABLE_SOLUTION_FOLDERS)
|
||||
set_target_properties(opencv_perf_tests PROPERTIES FOLDER "extra")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Documentation
|
||||
if(BUILD_DOCS)
|
||||
add_custom_target(opencv_docs)
|
||||
add_custom_target(install_docs DEPENDS opencv_docs
|
||||
COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=docs -P "${CMAKE_BINARY_DIR}/cmake_install.cmake")
|
||||
endif()
|
||||
|
||||
# Samples
|
||||
if(BUILD_EXAMPLES)
|
||||
add_custom_target(opencv_samples)
|
||||
if(ENABLE_SOLUTION_FOLDERS)
|
||||
set_target_properties(opencv_samples PROPERTIES FOLDER "extra")
|
||||
endif()
|
||||
endif()
|
|
@ -0,0 +1,97 @@
|
|||
#COPYRIGHT
|
||||
#
|
||||
#All contributions by the University of California:
|
||||
#Copyright (c) 2014, 2015, The Regents of the University of California (Regents)
|
||||
#All rights reserved.
|
||||
#
|
||||
#All other contributions:
|
||||
#Copyright (c) 2014, 2015, the respective contributors
|
||||
#All rights reserved.
|
||||
#
|
||||
#Caffe uses a shared copyright model: each contributor holds copyright over
|
||||
#their contributions to Caffe. The project versioning records all such
|
||||
#contribution and copyright details. If a contributor wants to further mark
|
||||
#their specific copyright on a particular contribution, they should indicate
|
||||
#their copyright solely in the commit message of the change when it is
|
||||
#committed.
|
||||
#
|
||||
#LICENSE
|
||||
#
|
||||
#Redistribution and use in source and binary forms, with or without
|
||||
#modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
#1. Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
#ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
#WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
#DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
|
||||
#
|
||||
#CONTRIBUTION AGREEMENT
|
||||
#
|
||||
#By contributing to the BVLC/caffe repository through pull-request, comment,
|
||||
#or otherwise, the contributor releases their content to the
|
||||
#license and copyright terms herein.
|
||||
|
||||
|
||||
# Find the Atlas (and Lapack) libraries
|
||||
#
|
||||
# The following variables are optionally searched for defaults
|
||||
# Atlas_ROOT_DIR: Base directory where all Atlas components are found
|
||||
#
|
||||
# The following are set after configuration is done:
|
||||
# Atlas_FOUND
|
||||
# Atlas_INCLUDE_DIRS
|
||||
# Atlas_LIBRARIES
|
||||
# Atlas_LIBRARYRARY_DIRS
|
||||
|
||||
set(Atlas_INCLUDE_SEARCH_PATHS
|
||||
/usr/include/atlas
|
||||
/usr/include/atlas-base
|
||||
$ENV{Atlas_ROOT_DIR}
|
||||
$ENV{Atlas_ROOT_DIR}/include
|
||||
)
|
||||
|
||||
set(Atlas_LIB_SEARCH_PATHS
|
||||
/usr/lib/atlas
|
||||
/usr/lib/atlas-base
|
||||
$ENV{Atlas_ROOT_DIR}
|
||||
$ENV{Atlas_ROOT_DIR}/lib
|
||||
)
|
||||
|
||||
find_path(Atlas_CBLAS_INCLUDE_DIR NAMES cblas.h PATHS ${Atlas_INCLUDE_SEARCH_PATHS})
|
||||
find_path(Atlas_CLAPACK_INCLUDE_DIR NAMES lapacke.h PATHS ${Atlas_INCLUDE_SEARCH_PATHS})
|
||||
|
||||
find_library(Atlas_CBLAS_LIBRARY NAMES ptcblas_r ptcblas cblas_r cblas PATHS ${Atlas_LIB_SEARCH_PATHS})
|
||||
find_library(Atlas_BLAS_LIBRARY NAMES atlas_r atlas PATHS ${Atlas_LIB_SEARCH_PATHS})
|
||||
find_library(Atlas_LAPACK_LIBRARY NAMES lapack alapack_r alapack lapack_atlas PATHS ${Atlas_LIB_SEARCH_PATHS})
|
||||
|
||||
set(LOOKED_FOR
|
||||
Atlas_CBLAS_INCLUDE_DIR
|
||||
Atlas_CLAPACK_INCLUDE_DIR
|
||||
|
||||
Atlas_CBLAS_LIBRARY
|
||||
Atlas_BLAS_LIBRARY
|
||||
Atlas_LAPACK_LIBRARY
|
||||
)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Atlas DEFAULT_MSG ${LOOKED_FOR})
|
||||
|
||||
if(ATLAS_FOUND)
|
||||
set(Atlas_INCLUDE_DIR ${Atlas_CBLAS_INCLUDE_DIR} ${Atlas_CLAPACK_INCLUDE_DIR})
|
||||
set(Atlas_LIBRARIES ${Atlas_LAPACK_LIBRARY} ${Atlas_CBLAS_LIBRARY} ${Atlas_BLAS_LIBRARY})
|
||||
mark_as_advanced(${LOOKED_FOR})
|
||||
|
||||
message(STATUS "Found Atlas (include: ${Atlas_CBLAS_INCLUDE_DIR}, library: ${Atlas_BLAS_LIBRARY})")
|
||||
endif(ATLAS_FOUND)
|
|
@ -0,0 +1,44 @@
|
|||
# ----------------------------------------------------------------------------
|
||||
# Detect frameworks that may be used by 3rd-party libraries as well as OpenCV
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# --- HPX ---
|
||||
if(WITH_HPX)
|
||||
find_package(HPX REQUIRED)
|
||||
ocv_include_directories(${HPX_INCLUDE_DIRS})
|
||||
set(HAVE_HPX TRUE)
|
||||
endif(WITH_HPX)
|
||||
|
||||
# --- GCD ---
|
||||
if(APPLE AND NOT HAVE_TBB)
|
||||
set(HAVE_GCD 1)
|
||||
else()
|
||||
set(HAVE_GCD 0)
|
||||
endif()
|
||||
|
||||
# --- Concurrency ---
|
||||
if(MSVC AND NOT HAVE_TBB)
|
||||
set(_fname "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/concurrencytest.cpp")
|
||||
file(WRITE "${_fname}" "#if _MSC_VER < 1600\n#error\n#endif\nint main() { return 0; }\n")
|
||||
try_compile(HAVE_CONCURRENCY "${CMAKE_BINARY_DIR}" "${_fname}")
|
||||
file(REMOVE "${_fname}")
|
||||
else()
|
||||
set(HAVE_CONCURRENCY 0)
|
||||
endif()
|
||||
|
||||
# --- OpenMP ---
|
||||
if(WITH_OPENMP)
|
||||
find_package(OpenMP)
|
||||
if(OPENMP_FOUND)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
|
||||
endif()
|
||||
set(HAVE_OPENMP "${OPENMP_FOUND}")
|
||||
endif()
|
||||
|
||||
ocv_clear_vars(HAVE_PTHREADS_PF)
|
||||
if(WITH_PTHREADS_PF AND HAVE_PTHREAD)
|
||||
set(HAVE_PTHREADS_PF 1)
|
||||
else()
|
||||
set(HAVE_PTHREADS_PF 0)
|
||||
endif()
|
|
@ -0,0 +1,276 @@
|
|||
#
|
||||
# The script to detect Intel(R) Integrated Performance Primitives (IPP)
|
||||
# installation/package
|
||||
#
|
||||
# By default, ICV version will be used.
|
||||
# To use standalone IPP update cmake command line:
|
||||
# cmake ... -DIPPROOT=<path> ...
|
||||
#
|
||||
# Note: Backward compatibility is broken, IPPROOT environment path is ignored
|
||||
#
|
||||
#
|
||||
# On return this will define:
|
||||
#
|
||||
# HAVE_IPP - True if Intel IPP found
|
||||
# HAVE_IPP_ICV - True if Intel IPP ICV version is available
|
||||
# IPP_ROOT_DIR - root of IPP installation
|
||||
# IPP_INCLUDE_DIRS - IPP include folder
|
||||
# IPP_LIBRARIES - IPP libraries that are used by OpenCV
|
||||
# IPP_VERSION_STR - string with the newest detected IPP version
|
||||
# IPP_VERSION_MAJOR - numbers of IPP version (MAJOR.MINOR.BUILD)
|
||||
# IPP_VERSION_MINOR
|
||||
# IPP_VERSION_BUILD
|
||||
#
|
||||
# Created: 30 Dec 2010 by Vladimir Dudnik (vladimir.dudnik@intel.com)
|
||||
#
|
||||
|
||||
unset(HAVE_IPP CACHE)
|
||||
unset(HAVE_IPP_ICV)
|
||||
unset(IPP_ROOT_DIR)
|
||||
unset(IPP_INCLUDE_DIRS)
|
||||
unset(IPP_LIBRARIES)
|
||||
unset(IPP_VERSION_STR)
|
||||
unset(IPP_VERSION_MAJOR)
|
||||
unset(IPP_VERSION_MINOR)
|
||||
unset(IPP_VERSION_BUILD)
|
||||
|
||||
if (X86 AND UNIX AND NOT APPLE AND NOT ANDROID AND BUILD_SHARED_LIBS)
|
||||
message(STATUS "On 32-bit Linux Intel IPP can not currently be used with dynamic libs because of linker errors. Set BUILD_SHARED_LIBS=OFF")
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(IPP_X64 0)
|
||||
if(X86_64)
|
||||
set(IPP_X64 1)
|
||||
endif()
|
||||
|
||||
# This function detects Intel IPP version by analyzing .h file
|
||||
macro(ipp_get_version VERSION_FILE)
|
||||
unset(_VERSION_STR)
|
||||
unset(_MAJOR)
|
||||
unset(_MINOR)
|
||||
unset(_BUILD)
|
||||
|
||||
# read Intel IPP version info from file
|
||||
file(STRINGS ${VERSION_FILE} STR1 REGEX "IPP_VERSION_MAJOR")
|
||||
file(STRINGS ${VERSION_FILE} STR2 REGEX "IPP_VERSION_MINOR")
|
||||
file(STRINGS ${VERSION_FILE} STR3 REGEX "IPP_VERSION_BUILD")
|
||||
if("${STR3}" STREQUAL "")
|
||||
file(STRINGS ${VERSION_FILE} STR3 REGEX "IPP_VERSION_UPDATE")
|
||||
endif()
|
||||
file(STRINGS ${VERSION_FILE} STR4 REGEX "IPP_VERSION_STR")
|
||||
|
||||
# extract info and assign to variables
|
||||
string(REGEX MATCHALL "[0-9]+" _MAJOR ${STR1})
|
||||
string(REGEX MATCHALL "[0-9]+" _MINOR ${STR2})
|
||||
string(REGEX MATCHALL "[0-9]+" _BUILD ${STR3})
|
||||
string(REGEX MATCHALL "[0-9]+[.]+[0-9]+[^\"]+|[0-9]+[.]+[0-9]+" _VERSION_STR ${STR4})
|
||||
|
||||
# export info to parent scope
|
||||
set(IPP_VERSION_STR ${_VERSION_STR})
|
||||
set(IPP_VERSION_MAJOR ${_MAJOR})
|
||||
set(IPP_VERSION_MINOR ${_MINOR})
|
||||
set(IPP_VERSION_BUILD ${_BUILD})
|
||||
endmacro()
|
||||
|
||||
macro(_ipp_not_supported)
|
||||
message(STATUS ${ARGN})
|
||||
unset(HAVE_IPP)
|
||||
unset(HAVE_IPP_ICV)
|
||||
unset(IPP_VERSION_STR)
|
||||
return()
|
||||
endmacro()
|
||||
|
||||
# This macro uses IPP_ROOT_DIR variable
|
||||
# TODO Cleanup code after ICV package stabilization
|
||||
macro(ipp_detect_version)
|
||||
set(IPP_INCLUDE_DIRS ${IPP_ROOT_DIR}/include)
|
||||
|
||||
set(__msg)
|
||||
if(EXISTS ${IPP_ROOT_DIR}/include/ippicv_redefs.h)
|
||||
set(__msg " (ICV version)")
|
||||
set(HAVE_IPP_ICV 1)
|
||||
elseif(EXISTS ${IPP_ROOT_DIR}/include/ipp.h)
|
||||
# nothing
|
||||
else()
|
||||
_ipp_not_supported("Can't resolve Intel IPP directory: ${IPP_ROOT_DIR}")
|
||||
endif()
|
||||
|
||||
ipp_get_version(${IPP_INCLUDE_DIRS}/ippversion.h)
|
||||
ocv_assert(IPP_VERSION_STR VERSION_GREATER "1.0")
|
||||
|
||||
message(STATUS "found Intel IPP${__msg}: ${_MAJOR}.${_MINOR}.${_BUILD} [${IPP_VERSION_STR}]")
|
||||
message(STATUS "at: ${IPP_ROOT_DIR}")
|
||||
|
||||
if(IPP_VERSION_STR VERSION_LESS "7.0")
|
||||
_ipp_not_supported("Intel IPP ${IPP_VERSION_STR} is not supported")
|
||||
endif()
|
||||
|
||||
set(HAVE_IPP 1)
|
||||
|
||||
macro(_ipp_set_library_dir DIR)
|
||||
if(NOT EXISTS ${DIR})
|
||||
_ipp_not_supported("Intel IPP library directory not found")
|
||||
endif()
|
||||
set(IPP_LIBRARY_DIR ${DIR})
|
||||
endmacro()
|
||||
|
||||
if(APPLE AND NOT HAVE_IPP_ICV)
|
||||
_ipp_set_library_dir(${IPP_ROOT_DIR}/lib)
|
||||
elseif(IPP_X64)
|
||||
_ipp_set_library_dir(${IPP_ROOT_DIR}/lib/intel64)
|
||||
else()
|
||||
_ipp_set_library_dir(${IPP_ROOT_DIR}/lib/ia32)
|
||||
endif()
|
||||
|
||||
macro(_ipp_add_library name)
|
||||
# dynamic linking is only supported for standalone version of Intel IPP
|
||||
if (BUILD_WITH_DYNAMIC_IPP AND NOT HAVE_IPP_ICV)
|
||||
if (WIN32)
|
||||
set(IPP_LIB_PREFIX ${CMAKE_IMPORT_LIBRARY_PREFIX})
|
||||
set(IPP_LIB_SUFFIX ${CMAKE_IMPORT_LIBRARY_SUFFIX})
|
||||
else (WIN32)
|
||||
set(IPP_LIB_PREFIX ${CMAKE_SHARED_LIBRARY_PREFIX})
|
||||
set(IPP_LIB_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX})
|
||||
endif (WIN32)
|
||||
else ()
|
||||
set(IPP_LIB_PREFIX ${CMAKE_STATIC_LIBRARY_PREFIX})
|
||||
set(IPP_LIB_SUFFIX ${CMAKE_STATIC_LIBRARY_SUFFIX})
|
||||
endif ()
|
||||
if (EXISTS ${IPP_LIBRARY_DIR}/${IPP_LIB_PREFIX}${IPP_PREFIX}${name}${IPP_SUFFIX}${IPP_LIB_SUFFIX})
|
||||
if (BUILD_WITH_DYNAMIC_IPP AND NOT HAVE_IPP_ICV)
|
||||
# When using dynamic libraries from standalone Intel IPP it is your responsibility to install those on the target system
|
||||
list(APPEND IPP_LIBRARIES ${IPP_LIBRARY_DIR}/${IPP_LIB_PREFIX}${IPP_PREFIX}${name}${IPP_SUFFIX}${IPP_LIB_SUFFIX})
|
||||
else ()
|
||||
add_library(ipp${name} STATIC IMPORTED)
|
||||
set_target_properties(ipp${name} PROPERTIES
|
||||
IMPORTED_LINK_INTERFACE_LIBRARIES ""
|
||||
IMPORTED_LOCATION ${IPP_LIBRARY_DIR}/${IPP_LIB_PREFIX}${IPP_PREFIX}${name}${IPP_SUFFIX}${IPP_LIB_SUFFIX}
|
||||
)
|
||||
list(APPEND IPP_LIBRARIES ipp${name})
|
||||
if (NOT BUILD_SHARED_LIBS)
|
||||
# CMake doesn't support "install(TARGETS ${IPP_PREFIX}${name} " command with imported targets
|
||||
install(FILES ${IPP_LIBRARY_DIR}/${IPP_LIB_PREFIX}${IPP_PREFIX}${name}${IPP_SUFFIX}${IPP_LIB_SUFFIX}
|
||||
DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev)
|
||||
string(TOUPPER ${name} uname)
|
||||
set(IPP${uname}_INSTALL_PATH "${CMAKE_INSTALL_PREFIX}/${OPENCV_3P_LIB_INSTALL_PATH}/${IPP_LIB_PREFIX}${IPP_PREFIX}${name}${IPP_SUFFIX}${IPP_LIB_SUFFIX}" CACHE INTERNAL "" FORCE)
|
||||
set(IPP${uname}_LOCATION_PATH "${IPP_LIBRARY_DIR}/${IPP_LIB_PREFIX}${IPP_PREFIX}${name}${IPP_SUFFIX}${IPP_LIB_SUFFIX}" CACHE INTERNAL "" FORCE)
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "Can't find Intel IPP library: ${name} at ${IPP_LIBRARY_DIR}/${IPP_LIB_PREFIX}${IPP_PREFIX}${name}${IPP_SUFFIX}${IPP_LIB_SUFFIX}")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
set(IPP_PREFIX "ipp")
|
||||
if(IPP_VERSION_STR VERSION_LESS "8.0")
|
||||
if (BUILD_WITH_DYNAMIC_IPP AND NOT HAVE_IPP_ICV)
|
||||
set(IPP_SUFFIX "") # dynamic not threaded libs suffix Intel IPP 7.x
|
||||
else ()
|
||||
set(IPP_SUFFIX "_l") # static not threaded libs suffix Intel IPP 7.x
|
||||
endif ()
|
||||
else ()
|
||||
if(WIN32)
|
||||
if (BUILD_WITH_DYNAMIC_IPP AND NOT HAVE_IPP_ICV)
|
||||
set(IPP_SUFFIX "") # dynamic not threaded libs suffix Intel IPP 8.x for Windows
|
||||
else ()
|
||||
set(IPP_SUFFIX "mt") # static not threaded libs suffix Intel IPP 8.x for Windows
|
||||
endif ()
|
||||
else()
|
||||
set(IPP_SUFFIX "") # static not threaded libs suffix Intel IPP 8.x for Linux/OS X
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(HAVE_IPP_ICV)
|
||||
_ipp_add_library(icv)
|
||||
else()
|
||||
_ipp_add_library(cv)
|
||||
_ipp_add_library(i)
|
||||
_ipp_add_library(cc)
|
||||
_ipp_add_library(s)
|
||||
_ipp_add_library(vm)
|
||||
_ipp_add_library(core)
|
||||
|
||||
if(UNIX AND IPP_VERSION_MAJOR LESS 2017)
|
||||
get_filename_component(INTEL_COMPILER_LIBRARY_DIR ${IPP_ROOT_DIR}/../lib REALPATH)
|
||||
if(NOT EXISTS ${INTEL_COMPILER_LIBRARY_DIR})
|
||||
get_filename_component(INTEL_COMPILER_LIBRARY_DIR ${IPP_ROOT_DIR}/../compiler/lib REALPATH)
|
||||
endif()
|
||||
if(NOT EXISTS ${INTEL_COMPILER_LIBRARY_DIR})
|
||||
_ipp_not_supported("Intel IPP configuration error: can't find Intel compiler library dir ${INTEL_COMPILER_LIBRARY_DIR}")
|
||||
endif()
|
||||
if(NOT APPLE)
|
||||
if(IPP_X64)
|
||||
if(NOT EXISTS ${INTEL_COMPILER_LIBRARY_DIR}/intel64)
|
||||
message(SEND_ERROR "Intel compiler EM64T libraries not found")
|
||||
endif()
|
||||
set(INTEL_COMPILER_LIBRARY_DIR ${INTEL_COMPILER_LIBRARY_DIR}/intel64)
|
||||
else()
|
||||
if(NOT EXISTS ${INTEL_COMPILER_LIBRARY_DIR}/ia32)
|
||||
message(SEND_ERROR "Intel compiler IA32 libraries not found")
|
||||
endif()
|
||||
set(INTEL_COMPILER_LIBRARY_DIR ${INTEL_COMPILER_LIBRARY_DIR}/ia32)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
macro(_ipp_add_compiler_library name)
|
||||
if (EXISTS ${INTEL_COMPILER_LIBRARY_DIR}/${IPP_LIB_PREFIX}${name}${CMAKE_SHARED_LIBRARY_SUFFIX})
|
||||
list(APPEND IPP_LIBRARIES ${INTEL_COMPILER_LIBRARY_DIR}/${IPP_LIB_PREFIX}${name}${CMAKE_SHARED_LIBRARY_SUFFIX})
|
||||
else()
|
||||
message(STATUS "Can't find compiler library: ${name} at ${INTEL_COMPILER_LIBRARY_DIR}/${IPP_LIB_PREFIX}${name}${CMAKE_SHARED_LIBRARY_SUFFIX}")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
_ipp_add_compiler_library(irc)
|
||||
_ipp_add_compiler_library(imf)
|
||||
_ipp_add_compiler_library(svml)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#message(STATUS "Intel IPP libs: ${IPP_LIBRARIES}")
|
||||
endmacro()
|
||||
|
||||
# OPENCV_IPP_PATH is an environment variable for internal usage only, do not use it
|
||||
if(DEFINED ENV{OPENCV_IPP_PATH} AND NOT DEFINED IPPROOT)
|
||||
set(IPPROOT "$ENV{OPENCV_IPP_PATH}")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED IPPROOT)
|
||||
include("${OpenCV_SOURCE_DIR}/3rdparty/ippicv/ippicv.cmake")
|
||||
download_ippicv(ICV_PACKAGE_ROOT)
|
||||
if(NOT ICV_PACKAGE_ROOT)
|
||||
return()
|
||||
endif()
|
||||
set(IPPROOT "${ICV_PACKAGE_ROOT}/icv")
|
||||
ocv_install_3rdparty_licenses(ippicv "${IPPROOT}/readme.htm")
|
||||
if(WIN32)
|
||||
ocv_install_3rdparty_licenses(ippicv "${ICV_PACKAGE_ROOT}/EULA.rtf")
|
||||
else()
|
||||
ocv_install_3rdparty_licenses(ippicv "${ICV_PACKAGE_ROOT}/EULA.txt")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
file(TO_CMAKE_PATH "${IPPROOT}" __IPPROOT)
|
||||
if(EXISTS "${__IPPROOT}/include/ippversion.h")
|
||||
set(IPP_ROOT_DIR ${__IPPROOT})
|
||||
ipp_detect_version()
|
||||
endif()
|
||||
|
||||
|
||||
if(WIN32 AND MINGW AND NOT IPP_VERSION_MAJOR LESS 7)
|
||||
# Since Intel IPP built with Microsoft compiler and /GS option
|
||||
# ======================================================
|
||||
# From Windows SDK 7.1
|
||||
# (usually in "C:\Program Files\Microsoft Visual Studio 10.0\VC\lib"),
|
||||
# to avoid undefined reference to __security_cookie and _chkstk:
|
||||
set(MSV_RUNTMCHK "RunTmChk")
|
||||
set(IPP_LIBRARIES ${IPP_LIBRARIES} ${MSV_RUNTMCHK}${IPP_LIB_SUFFIX})
|
||||
|
||||
# To avoid undefined reference to _alldiv and _chkstk
|
||||
# ===================================================
|
||||
# NB: it may require a recompilation of w32api (after having modified
|
||||
# the file ntdll.def) to export the required functions
|
||||
# See http://code.opencv.org/issues/1906 for additional details
|
||||
set(MSV_NTDLL "ntdll")
|
||||
set(IPP_LIBRARIES ${IPP_LIBRARIES} ${MSV_NTDLL}${IPP_LIB_SUFFIX})
|
||||
endif()
|
|
@ -0,0 +1,205 @@
|
|||
#
|
||||
# The script to detect Intel(R) Integrated Performance Primitives Integration Wrappers (IPP Integration Wrappers)
|
||||
# installation/package
|
||||
#
|
||||
#
|
||||
# On return this will define:
|
||||
#
|
||||
# HAVE_IPP_IW - True if Intel IPP Integration Wrappers found
|
||||
# HAVE_IPP_IW_LL - True if Intel IPP Integration Wrappers found with Low Level API header
|
||||
# IPP_IW_PATH - Root of Intel IPP Integration Wrappers directory
|
||||
# IPP_IW_LIBRARIES - Intel IPP Integration Wrappers libraries
|
||||
# IPP_IW_INCLUDES - Intel IPP Integration Wrappers include folder
|
||||
#
|
||||
|
||||
unset(HAVE_IPP_IW CACHE)
|
||||
unset(HAVE_IPP_IW_LL CACHE)
|
||||
unset(IPP_IW_PATH)
|
||||
unset(IPP_IW_LIBRARIES)
|
||||
unset(IPP_IW_INCLUDES)
|
||||
unset(IW_CONFIG_DEBUG)
|
||||
#set(IW_CONFIG_DEBUG 1)
|
||||
|
||||
if(NOT HAVE_IPP)
|
||||
return()
|
||||
endif()
|
||||
|
||||
macro(ippiw_debugmsg MESSAGE)
|
||||
if(DEFINED IW_CONFIG_DEBUG)
|
||||
message(STATUS "${MESSAGE}")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(ippiw_done)
|
||||
foreach(__file ${IPP_IW_LICENSE_FILES})
|
||||
if(EXISTS "${__file}")
|
||||
ocv_install_3rdparty_licenses(ippiw "${__file}")
|
||||
endif()
|
||||
endforeach()
|
||||
return()
|
||||
endmacro()
|
||||
|
||||
file(TO_CMAKE_PATH "${IPPROOT}" IPPROOT)
|
||||
|
||||
# This function detects Intel IPP Integration Wrappers version by analyzing .h file
|
||||
macro(ippiw_setup PATH BUILD)
|
||||
set(FILE "${PATH}/include/iw/iw_version.h")
|
||||
if(${BUILD})
|
||||
ippiw_debugmsg("Checking sources: ${PATH}")
|
||||
else()
|
||||
ippiw_debugmsg("Checking binaries: ${PATH}")
|
||||
endif()
|
||||
if(EXISTS "${FILE}")
|
||||
ippiw_debugmsg("vfile\tfound")
|
||||
file(STRINGS "${FILE}" IW_VERSION_MAJOR REGEX "IW_VERSION_MAJOR")
|
||||
file(STRINGS "${FILE}" IW_VERSION_MINOR REGEX "IW_VERSION_MINOR")
|
||||
file(STRINGS "${FILE}" IW_VERSION_UPDATE REGEX "IW_VERSION_UPDATE")
|
||||
|
||||
file(STRINGS "${FILE}" IW_MIN_COMPATIBLE_IPP_MAJOR REGEX "IW_MIN_COMPATIBLE_IPP_MAJOR")
|
||||
file(STRINGS "${FILE}" IW_MIN_COMPATIBLE_IPP_MINOR REGEX "IW_MIN_COMPATIBLE_IPP_MINOR")
|
||||
file(STRINGS "${FILE}" IW_MIN_COMPATIBLE_IPP_UPDATE REGEX "IW_MIN_COMPATIBLE_IPP_UPDATE")
|
||||
|
||||
string(REGEX MATCH "[0-9]+" IW_MIN_COMPATIBLE_IPP_MAJOR ${IW_MIN_COMPATIBLE_IPP_MAJOR})
|
||||
string(REGEX MATCH "[0-9]+" IW_MIN_COMPATIBLE_IPP_MINOR ${IW_MIN_COMPATIBLE_IPP_MINOR})
|
||||
string(REGEX MATCH "[0-9]+" IW_MIN_COMPATIBLE_IPP_UPDATE ${IW_MIN_COMPATIBLE_IPP_UPDATE})
|
||||
|
||||
string(REGEX MATCH "[0-9]+" IW_VERSION_MAJOR ${IW_VERSION_MAJOR})
|
||||
string(REGEX MATCH "[0-9]+" IW_VERSION_MINOR ${IW_VERSION_MINOR})
|
||||
string(REGEX MATCH "[0-9]+" IW_VERSION_UPDATE ${IW_VERSION_UPDATE})
|
||||
|
||||
math(EXPR IPP_VERSION_EXP "${IPP_VERSION_MAJOR}*10000 + ${IPP_VERSION_MINOR}*100 + ${IPP_VERSION_BUILD}")
|
||||
math(EXPR IW_MIN_COMPATIBLE_IPP_EXP "${IW_MIN_COMPATIBLE_IPP_MAJOR}*10000 + ${IW_MIN_COMPATIBLE_IPP_MINOR}*100 + ${IW_MIN_COMPATIBLE_IPP_UPDATE}")
|
||||
|
||||
if((IPP_VERSION_EXP GREATER IW_MIN_COMPATIBLE_IPP_EXP) OR (IPP_VERSION_EXP EQUAL IW_MIN_COMPATIBLE_IPP_EXP))
|
||||
ippiw_debugmsg("vcheck\tpassed")
|
||||
if(${BUILD})
|
||||
# check sources
|
||||
if(EXISTS "${PATH}/src/iw_core.c")
|
||||
ippiw_debugmsg("sources\tyes")
|
||||
set(IPP_IW_PATH "${PATH}")
|
||||
message(STATUS "found Intel IPP Integration Wrappers sources: ${IW_VERSION_MAJOR}.${IW_VERSION_MINOR}.${IW_VERSION_UPDATE}")
|
||||
message(STATUS "at: ${IPP_IW_PATH}")
|
||||
|
||||
set(IPP_IW_LIBRARY ippiw)
|
||||
set(IPP_IW_INCLUDES "${IPP_IW_PATH}/include")
|
||||
set(IPP_IW_LIBRARIES ${IPP_IW_LIBRARY})
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${OpenCV_SOURCE_DIR}/3rdparty/ippicv/CMakeLists.txt" "${IPP_IW_PATH}/")
|
||||
add_subdirectory("${IPP_IW_PATH}/" ${OpenCV_BINARY_DIR}/3rdparty/ippiw)
|
||||
|
||||
set(HAVE_IPP_IW 1)
|
||||
set(FILE "${PATH}/include/iw/iw_ll.h") # check if Intel IPP Integration Wrappers is OpenCV specific
|
||||
if(EXISTS "${FILE}")
|
||||
set(HAVE_IPP_IW_LL 1)
|
||||
endif()
|
||||
ippiw_done()
|
||||
else()
|
||||
ippiw_debugmsg("sources\tno")
|
||||
endif()
|
||||
else()
|
||||
# check binaries
|
||||
if(IPP_X64)
|
||||
set(FILE "${PATH}/lib/intel64/${CMAKE_STATIC_LIBRARY_PREFIX}ipp_iw${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||
else()
|
||||
set(FILE "${PATH}/lib/ia32/${CMAKE_STATIC_LIBRARY_PREFIX}ipp_iw${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
||||
endif()
|
||||
if(EXISTS ${FILE})
|
||||
ippiw_debugmsg("binaries\tyes (64=${IPP_X64})")
|
||||
set(IPP_IW_PATH "${PATH}")
|
||||
message(STATUS "found Intel IPP Integration Wrappers binaries: ${IW_VERSION_MAJOR}.${IW_VERSION_MINOR}.${IW_VERSION_UPDATE}")
|
||||
message(STATUS "at: ${IPP_IW_PATH}")
|
||||
|
||||
add_library(ippiw STATIC IMPORTED)
|
||||
set_target_properties(ippiw PROPERTIES
|
||||
IMPORTED_LINK_INTERFACE_LIBRARIES ""
|
||||
IMPORTED_LOCATION "${FILE}"
|
||||
)
|
||||
if (NOT BUILD_SHARED_LIBS)
|
||||
# CMake doesn't support "install(TARGETS ${name} ...)" command with imported targets
|
||||
install(FILES "${FILE}"
|
||||
DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev)
|
||||
set(IPPIW_INSTALL_PATH "${CMAKE_INSTALL_PREFIX}/${OPENCV_3P_LIB_INSTALL_PATH}/${CMAKE_STATIC_LIBRARY_PREFIX}ipp_iw${CMAKE_STATIC_LIBRARY_SUFFIX}" CACHE INTERNAL "" FORCE)
|
||||
set(IPPIW_LOCATION_PATH "${FILE}" CACHE INTERNAL "" FORCE)
|
||||
endif()
|
||||
|
||||
set(IPP_IW_INCLUDES "${IPP_IW_PATH}/include")
|
||||
set(IPP_IW_LIBRARIES ippiw)
|
||||
|
||||
set(HAVE_IPP_IW 1)
|
||||
set(BUILD_IPP_IW 0)
|
||||
set(FILE "${PATH}/include/iw/iw_ll.h") # check if Intel IPP Integration Wrappers is OpenCV specific
|
||||
if(EXISTS "${FILE}")
|
||||
set(HAVE_IPP_IW_LL 1)
|
||||
endif()
|
||||
ippiw_done()
|
||||
else()
|
||||
ippiw_debugmsg("binaries\tno")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
ippiw_debugmsg("vcheck\tfailed")
|
||||
endif()
|
||||
else()
|
||||
ippiw_debugmsg("vfile\tnot found")
|
||||
endif()
|
||||
set(HAVE_IPP_IW 0)
|
||||
set(HAVE_IPP_IW_LL 0)
|
||||
endmacro()
|
||||
|
||||
# check build options first
|
||||
if(BUILD_IPP_IW)
|
||||
# custom path
|
||||
if(DEFINED IPPIWROOT)
|
||||
ippiw_setup("${IPPIWROOT}/" 1)
|
||||
message(STATUS "Can't find Intel IPP Integration Wrappers sources at: ${IPPIWROOT}")
|
||||
endif()
|
||||
|
||||
# local sources
|
||||
ippiw_setup("${OpenCV_SOURCE_DIR}/3rdparty/ippiw" 1)
|
||||
|
||||
set(IPPIW_ROOT "${IPPROOT}/../iw")
|
||||
set(IPP_IW_LICENSE_FILES ${IPP_IW_LICENSE_FILES_EXTRA}
|
||||
"${IPPIW_ROOT}/../support.txt"
|
||||
"${IPPIW_ROOT}/../third-party-programs.txt"
|
||||
"${IPPIW_ROOT}/../EULA.rtf"
|
||||
"${IPPIW_ROOT}/../EULA.txt"
|
||||
)
|
||||
|
||||
# Package sources
|
||||
get_filename_component(__PATH "${IPPROOT}/../iw/" ABSOLUTE)
|
||||
ippiw_setup("${__PATH}" 1)
|
||||
|
||||
# take Intel IPP Integration Wrappers from ICV package
|
||||
if(NOT HAVE_IPP_ICV)
|
||||
message(STATUS "Cannot find Intel IPP Integration Wrappers. Checking \"Intel IPP for OpenCV\" package")
|
||||
set(TEMP_ROOT 0)
|
||||
include("${OpenCV_SOURCE_DIR}/3rdparty/ippicv/ippicv.cmake")
|
||||
download_ippicv(TEMP_ROOT)
|
||||
set(IPPIW_ROOT "${TEMP_ROOT}/iw/")
|
||||
set(IPP_IW_LICENSE_FILES ${IPP_IW_LICENSE_FILES_EXTRA}
|
||||
"${IPPIW_ROOT}/../EULA.txt"
|
||||
"${IPPIW_ROOT}/../support.txt"
|
||||
"${IPPIW_ROOT}/../third-party-programs.txt"
|
||||
)
|
||||
|
||||
ippiw_setup("${IPPIW_ROOT}" 1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
# custom binaries
|
||||
if(DEFINED IPPIWROOT)
|
||||
ippiw_setup("${IPPIWROOT}/" 0)
|
||||
message(STATUS "Can't find Intel IPP Integration Wrappers binaries at: ${IPPIWROOT}")
|
||||
endif()
|
||||
|
||||
# check binaries in IPP folder
|
||||
ippiw_setup("${IPPROOT}/" 0)
|
||||
|
||||
# check binaries near IPP folder
|
||||
ippiw_setup("${IPPROOT}/../iw/" 0)
|
||||
|
||||
|
||||
set(HAVE_IPP_IW 0)
|
||||
set(HAVE_IPP_IW_LL 0)
|
||||
message(STATUS "Cannot find Intel IPP Integration Wrappers, optimizations will be limited. Use IPPIWROOT to set custom location")
|
||||
return()
|
|
@ -0,0 +1,177 @@
|
|||
macro(_find_header_file_in_dirs VAR NAME)
|
||||
unset(${VAR})
|
||||
unset(${VAR} CACHE)
|
||||
if(" ${ARGN}" STREQUAL " ")
|
||||
check_include_file("${NAME}" HAVE_${VAR})
|
||||
if(HAVE_${VAR})
|
||||
set(${VAR} "${NAME}") # fallback
|
||||
else()
|
||||
set(${VAR} "")
|
||||
endif()
|
||||
else()
|
||||
find_path(${VAR} "${NAME}" ${ARGN} NO_DEFAULT_PATH)
|
||||
if(${VAR})
|
||||
set(${VAR} "${${VAR}}/${NAME}")
|
||||
unset(${VAR} CACHE)
|
||||
else()
|
||||
unset(${VAR} CACHE)
|
||||
set(${VAR} "")
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(ocv_lapack_check)
|
||||
string(REGEX REPLACE "[^a-zA-Z0-9_]" "_" _lapack_impl "${LAPACK_IMPL}")
|
||||
message(STATUS "LAPACK(${LAPACK_IMPL}): LAPACK_LIBRARIES: ${LAPACK_LIBRARIES}")
|
||||
_find_header_file_in_dirs(OPENCV_CBLAS_H_PATH_${_lapack_impl} "${LAPACK_CBLAS_H}" "${LAPACK_INCLUDE_DIR}")
|
||||
_find_header_file_in_dirs(OPENCV_LAPACKE_H_PATH_${_lapack_impl} "${LAPACK_LAPACKE_H}" "${LAPACK_INCLUDE_DIR}")
|
||||
if(NOT OPENCV_CBLAS_H_PATH_${_lapack_impl} OR NOT OPENCV_LAPACKE_H_PATH_${_lapack_impl})
|
||||
message(WARNING "LAPACK(${LAPACK_IMPL}): CBLAS/LAPACK headers are not found in '${LAPACK_INCLUDE_DIR}'")
|
||||
unset(LAPACK_LIBRARIES)
|
||||
else()
|
||||
# adding proxy opencv_lapack.h header
|
||||
set(CBLAS_H_PROXY_PATH ${CMAKE_BINARY_DIR}/opencv_lapack.h)
|
||||
|
||||
set(_lapack_add_extern_c NOT (APPLE OR OPENCV_SKIP_LAPACK_EXTERN_C) OR OPENCV_FORCE_LAPACK_EXTERN_C)
|
||||
|
||||
set(_lapack_content "// This file is auto-generated\n")
|
||||
if(${_lapack_add_extern_c})
|
||||
list(APPEND _lapack_content "extern \"C\" {")
|
||||
endif()
|
||||
if(NOT OPENCV_SKIP_LAPACK_MSVC_FIX)
|
||||
list(APPEND _lapack_content "
|
||||
#ifdef _MSC_VER
|
||||
#include <complex.h>
|
||||
#define lapack_complex_float _Fcomplex
|
||||
#define lapack_complex_double _Dcomplex
|
||||
#endif
|
||||
")
|
||||
endif()
|
||||
list(APPEND _lapack_content "#include \"${OPENCV_CBLAS_H_PATH_${_lapack_impl}}\"")
|
||||
if(NOT "${OPENCV_CBLAS_H_PATH_${_lapack_impl}}" STREQUAL "${OPENCV_LAPACKE_H_PATH_${_lapack_impl}}")
|
||||
list(APPEND _lapack_content "#include \"${OPENCV_LAPACKE_H_PATH_${_lapack_impl}}\"")
|
||||
endif()
|
||||
if(${_lapack_add_extern_c})
|
||||
list(APPEND _lapack_content "}")
|
||||
endif()
|
||||
|
||||
string(REPLACE ";" "\n" _lapack_content "${_lapack_content}")
|
||||
ocv_update_file("${CBLAS_H_PROXY_PATH}" "${_lapack_content}")
|
||||
|
||||
try_compile(__VALID_LAPACK
|
||||
"${OpenCV_BINARY_DIR}"
|
||||
"${OpenCV_SOURCE_DIR}/cmake/checks/lapack_check.cpp"
|
||||
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${LAPACK_INCLUDE_DIR}\;${CMAKE_BINARY_DIR}"
|
||||
"-DLINK_DIRECTORIES:STRING=${LAPACK_LINK_LIBRARIES}"
|
||||
"-DLINK_LIBRARIES:STRING=${LAPACK_LIBRARIES}"
|
||||
OUTPUT_VARIABLE TRY_OUT
|
||||
)
|
||||
if(NOT __VALID_LAPACK)
|
||||
#message(FATAL_ERROR "LAPACK: check build log:\n${TRY_OUT}")
|
||||
message(STATUS "LAPACK(${LAPACK_IMPL}): Can't build LAPACK check code. This LAPACK version is not supported.")
|
||||
unset(LAPACK_LIBRARIES)
|
||||
else()
|
||||
message(STATUS "LAPACK(${LAPACK_IMPL}): Support is enabled.")
|
||||
ocv_include_directories(${LAPACK_INCLUDE_DIR})
|
||||
set(HAVE_LAPACK 1)
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
if(WITH_LAPACK)
|
||||
ocv_update(LAPACK_IMPL "Unknown")
|
||||
if(NOT OPENCV_LAPACK_FIND_PACKAGE_ONLY)
|
||||
if(NOT LAPACK_LIBRARIES AND NOT OPENCV_LAPACK_DISABLE_MKL)
|
||||
include(cmake/OpenCVFindMKL.cmake)
|
||||
if(HAVE_MKL)
|
||||
set(LAPACK_INCLUDE_DIR ${MKL_INCLUDE_DIRS})
|
||||
set(LAPACK_LIBRARIES ${MKL_LIBRARIES})
|
||||
set(LAPACK_CBLAS_H "mkl_cblas.h")
|
||||
set(LAPACK_LAPACKE_H "mkl_lapack.h")
|
||||
set(LAPACK_IMPL "MKL")
|
||||
ocv_lapack_check()
|
||||
endif()
|
||||
endif()
|
||||
if(NOT LAPACK_LIBRARIES)
|
||||
include(cmake/OpenCVFindOpenBLAS.cmake)
|
||||
if(OpenBLAS_FOUND)
|
||||
set(LAPACK_INCLUDE_DIR ${OpenBLAS_INCLUDE_DIR})
|
||||
set(LAPACK_LIBRARIES ${OpenBLAS_LIB})
|
||||
set(LAPACK_CBLAS_H "cblas.h")
|
||||
set(LAPACK_LAPACKE_H "lapacke.h")
|
||||
set(LAPACK_IMPL "OpenBLAS")
|
||||
ocv_lapack_check()
|
||||
endif()
|
||||
endif()
|
||||
if(NOT LAPACK_LIBRARIES AND UNIX)
|
||||
include(cmake/OpenCVFindAtlas.cmake)
|
||||
if(ATLAS_FOUND)
|
||||
set(LAPACK_INCLUDE_DIR ${Atlas_INCLUDE_DIR})
|
||||
set(LAPACK_LIBRARIES ${Atlas_LIBRARIES})
|
||||
set(LAPACK_CBLAS_H "cblas.h")
|
||||
set(LAPACK_LAPACKE_H "lapacke.h")
|
||||
set(LAPACK_IMPL "Atlas")
|
||||
ocv_lapack_check()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT LAPACK_LIBRARIES)
|
||||
if(WIN32 AND NOT OPENCV_LAPACK_SHARED_LIBS)
|
||||
set(BLA_STATIC 1)
|
||||
endif()
|
||||
find_package(LAPACK)
|
||||
if(LAPACK_FOUND)
|
||||
if(NOT DEFINED LAPACKE_INCLUDE_DIR)
|
||||
find_path(LAPACKE_INCLUDE_DIR "lapacke.h")
|
||||
endif()
|
||||
if(NOT DEFINED MKL_LAPACKE_INCLUDE_DIR)
|
||||
find_path(MKL_LAPACKE_INCLUDE_DIR "mkl_lapack.h")
|
||||
endif()
|
||||
if(MKL_LAPACKE_INCLUDE_DIR AND NOT OPENCV_LAPACK_DISABLE_MKL)
|
||||
set(LAPACK_INCLUDE_DIR ${MKL_LAPACKE_INCLUDE_DIR})
|
||||
set(LAPACK_CBLAS_H "mkl_cblas.h")
|
||||
set(LAPACK_LAPACKE_H "mkl_lapack.h")
|
||||
set(LAPACK_IMPL "LAPACK/MKL")
|
||||
ocv_lapack_check()
|
||||
endif()
|
||||
if(NOT HAVE_LAPACK)
|
||||
if(LAPACKE_INCLUDE_DIR)
|
||||
set(LAPACK_INCLUDE_DIR ${LAPACKE_INCLUDE_DIR})
|
||||
set(LAPACK_CBLAS_H "cblas.h")
|
||||
set(LAPACK_LAPACKE_H "lapacke.h")
|
||||
set(LAPACK_IMPL "LAPACK/Generic")
|
||||
ocv_lapack_check()
|
||||
elseif(APPLE)
|
||||
set(LAPACK_CBLAS_H "Accelerate/Accelerate.h")
|
||||
set(LAPACK_LAPACKE_H "Accelerate/Accelerate.h")
|
||||
set(LAPACK_IMPL "LAPACK/Apple")
|
||||
ocv_lapack_check()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
if(NOT HAVE_LAPACK)
|
||||
unset(LAPACK_LIBRARIES)
|
||||
unset(LAPACK_LIBRARIES CACHE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT LAPACK_LIBRARIES AND APPLE AND NOT OPENCV_LAPACK_FIND_PACKAGE_ONLY)
|
||||
set(LAPACK_INCLUDE_DIR "")
|
||||
set(LAPACK_LIBRARIES "-framework Accelerate")
|
||||
set(LAPACK_CBLAS_H "Accelerate/Accelerate.h")
|
||||
set(LAPACK_LAPACKE_H "Accelerate/Accelerate.h")
|
||||
set(LAPACK_IMPL "Apple")
|
||||
ocv_lapack_check()
|
||||
endif()
|
||||
|
||||
if(NOT HAVE_LAPACK AND LAPACK_LIBRARIES AND LAPACK_CBLAS_H AND LAPACK_LAPACKE_H)
|
||||
ocv_lapack_check()
|
||||
endif()
|
||||
|
||||
set(LAPACK_INCLUDE_DIR ${LAPACK_INCLUDE_DIR} CACHE PATH "Path to BLAS include dir" FORCE)
|
||||
set(LAPACK_CBLAS_H ${LAPACK_CBLAS_H} CACHE STRING "Alternative name of cblas.h" FORCE)
|
||||
set(LAPACK_LAPACKE_H ${LAPACK_LAPACKE_H} CACHE STRING "Alternative name of lapacke.h" FORCE)
|
||||
set(LAPACK_LIBRARIES ${LAPACK_LIBRARIES} CACHE STRING "Names of BLAS & LAPACK binaries (.so, .dll, .a, .lib)" FORCE)
|
||||
set(LAPACK_IMPL ${LAPACK_IMPL} CACHE STRING "Lapack implementation id" FORCE)
|
||||
endif()
|
|
@ -0,0 +1,114 @@
|
|||
# - Find Latex
|
||||
# This module finds if Latex is installed and determines where the
|
||||
# executables are. This code sets the following variables:
|
||||
#
|
||||
# LATEX_COMPILER: path to the LaTeX compiler
|
||||
# PDFLATEX_COMPILER: path to the PdfLaTeX compiler
|
||||
# BIBTEX_COMPILER: path to the BibTeX compiler
|
||||
# MAKEINDEX_COMPILER: path to the MakeIndex compiler
|
||||
# DVIPS_CONVERTER: path to the DVIPS converter
|
||||
# PS2PDF_CONVERTER: path to the PS2PDF converter
|
||||
# LATEX2HTML_CONVERTER: path to the LaTeX2Html converter
|
||||
#
|
||||
|
||||
IF (WIN32)
|
||||
|
||||
# Try to find the MikTex binary path (look for its package manager).
|
||||
|
||||
FIND_PATH(MIKTEX_BINARY_PATH mpm.exe
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\MiK\\MiKTeX\\CurrentVersion\\MiKTeX;Install Root]/miktex/bin"
|
||||
DOC
|
||||
"Path to the MikTex binary directory."
|
||||
)
|
||||
MARK_AS_ADVANCED(MIKTEX_BINARY_PATH)
|
||||
|
||||
# Try to find the GhostScript binary path (look for gswin32).
|
||||
|
||||
GET_FILENAME_COMPONENT(GHOSTSCRIPT_BINARY_PATH_FROM_REGISTERY_8_00
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\AFPL Ghostscript\\8.00;GS_DLL]" PATH
|
||||
)
|
||||
|
||||
GET_FILENAME_COMPONENT(GHOSTSCRIPT_BINARY_PATH_FROM_REGISTERY_7_04
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\AFPL Ghostscript\\7.04;GS_DLL]" PATH
|
||||
)
|
||||
|
||||
FIND_PATH(GHOSTSCRIPT_BINARY_PATH gswin32.exe
|
||||
${GHOSTSCRIPT_BINARY_PATH_FROM_REGISTERY_8_00}
|
||||
${GHOSTSCRIPT_BINARY_PATH_FROM_REGISTERY_7_04}
|
||||
DOC "Path to the GhostScript binary directory."
|
||||
)
|
||||
MARK_AS_ADVANCED(GHOSTSCRIPT_BINARY_PATH)
|
||||
|
||||
FIND_PATH(GHOSTSCRIPT_LIBRARY_PATH ps2pdf13.bat
|
||||
"${GHOSTSCRIPT_BINARY_PATH}/../lib"
|
||||
DOC "Path to the GhostScript library directory."
|
||||
)
|
||||
MARK_AS_ADVANCED(GHOSTSCRIPT_LIBRARY_PATH)
|
||||
|
||||
ENDIF (WIN32)
|
||||
|
||||
FIND_HOST_PROGRAM(LATEX_COMPILER
|
||||
NAMES latex
|
||||
PATHS ${MIKTEX_BINARY_PATH}
|
||||
/usr/bin /usr/texbin
|
||||
)
|
||||
|
||||
FIND_HOST_PROGRAM(PDFLATEX_COMPILER
|
||||
NAMES pdflatex
|
||||
PATHS ${MIKTEX_BINARY_PATH}
|
||||
/usr/bin /usr/texbin
|
||||
)
|
||||
|
||||
FIND_HOST_PROGRAM(BIBTEX_COMPILER
|
||||
NAMES bibtex
|
||||
PATHS ${MIKTEX_BINARY_PATH}
|
||||
/usr/bin /usr/texbin
|
||||
)
|
||||
|
||||
FIND_HOST_PROGRAM(MAKEINDEX_COMPILER
|
||||
NAMES makeindex
|
||||
PATHS ${MIKTEX_BINARY_PATH}
|
||||
/usr/bin /usr/texbin
|
||||
)
|
||||
|
||||
FIND_HOST_PROGRAM(DVIPS_CONVERTER
|
||||
NAMES dvips
|
||||
PATHS ${MIKTEX_BINARY_PATH}
|
||||
/usr/bin /usr/texbin
|
||||
)
|
||||
|
||||
FIND_HOST_PROGRAM(DVIPDF_CONVERTER
|
||||
NAMES dvipdfm dvipdft dvipdf
|
||||
PATHS ${MIKTEX_BINARY_PATH}
|
||||
/usr/bin /usr/texbin
|
||||
)
|
||||
|
||||
IF (WIN32)
|
||||
FIND_HOST_PROGRAM(PS2PDF_CONVERTER
|
||||
NAMES ps2pdf14.bat
|
||||
PATHS ${GHOSTSCRIPT_LIBRARY_PATH}
|
||||
)
|
||||
ELSE (WIN32)
|
||||
FIND_HOST_PROGRAM(PS2PDF_CONVERTER
|
||||
NAMES ps2pdf14 ps2pdf
|
||||
PATHS /usr/bin /usr/texbin
|
||||
)
|
||||
ENDIF (WIN32)
|
||||
|
||||
FIND_HOST_PROGRAM(LATEX2HTML_CONVERTER
|
||||
NAMES latex2html
|
||||
PATHS ${MIKTEX_BINARY_PATH}
|
||||
/usr/bin /usr/texbin
|
||||
)
|
||||
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
LATEX_COMPILER
|
||||
PDFLATEX_COMPILER
|
||||
BIBTEX_COMPILER
|
||||
MAKEINDEX_COMPILER
|
||||
DVIPS_CONVERTER
|
||||
DVIPDF_CONVERTER
|
||||
PS2PDF_CONVERTER
|
||||
LATEX2HTML_CONVERTER
|
||||
)
|
|
@ -0,0 +1,94 @@
|
|||
# ----------------------------------------------------------------------------
|
||||
# Detect 3rd-party GUI libraries
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
#--- Win32 UI ---
|
||||
ocv_clear_vars(HAVE_WIN32UI)
|
||||
if(WITH_WIN32UI)
|
||||
try_compile(HAVE_WIN32UI
|
||||
"${OpenCV_BINARY_DIR}"
|
||||
"${OpenCV_SOURCE_DIR}/cmake/checks/win32uitest.cpp"
|
||||
CMAKE_FLAGS "-DLINK_LIBRARIES:STRING=user32;gdi32")
|
||||
endif()
|
||||
|
||||
# --- QT4 ---
|
||||
ocv_clear_vars(HAVE_QT HAVE_QT5)
|
||||
if(WITH_QT)
|
||||
if(NOT WITH_QT EQUAL 4)
|
||||
find_package(Qt5 COMPONENTS Core Gui Widgets Test Concurrent REQUIRED NO_MODULE)
|
||||
if(Qt5_FOUND)
|
||||
set(HAVE_QT5 ON)
|
||||
set(HAVE_QT ON)
|
||||
find_package(Qt5 COMPONENTS OpenGL QUIET)
|
||||
if(Qt5OpenGL_FOUND)
|
||||
set(QT_QTOPENGL_FOUND ON)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT HAVE_QT)
|
||||
find_package(Qt4 REQUIRED QtCore QtGui QtTest)
|
||||
if(QT4_FOUND)
|
||||
set(HAVE_QT TRUE)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# --- GTK ---
|
||||
ocv_clear_vars(HAVE_GTK HAVE_GTK3 HAVE_GTHREAD HAVE_GTKGLEXT)
|
||||
if(WITH_GTK AND NOT HAVE_QT)
|
||||
if(NOT WITH_GTK_2_X)
|
||||
ocv_check_modules(GTK3 gtk+-3.0)
|
||||
if(HAVE_GTK3)
|
||||
ocv_append_build_options(HIGHGUI GTK3)
|
||||
set(HAVE_GTK TRUE)
|
||||
endif()
|
||||
endif()
|
||||
if(NOT HAVE_GTK)
|
||||
ocv_check_modules(GTK2 gtk+-2.0)
|
||||
if(HAVE_GTK2)
|
||||
if (GTK2_VERSION VERSION_LESS MIN_VER_GTK)
|
||||
message (FATAL_ERROR "GTK support requires a minimum version of ${MIN_VER_GTK} (${GTK2_VERSION} found)")
|
||||
else()
|
||||
ocv_append_build_options(HIGHGUI GTK2)
|
||||
set(HAVE_GTK TRUE)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
ocv_check_modules(GTHREAD gthread-2.0)
|
||||
if(HAVE_GTK AND NOT HAVE_GTHREAD)
|
||||
message(FATAL_ERROR "gthread not found. This library is required when building with GTK support")
|
||||
else()
|
||||
ocv_append_build_options(HIGHGUI GTHREAD)
|
||||
endif()
|
||||
if(WITH_OPENGL AND NOT HAVE_GTK3)
|
||||
ocv_check_modules(GTKGLEXT gtkglext-1.0)
|
||||
if(HAVE_GTKGLEXT)
|
||||
ocv_append_build_options(HIGHGUI GTKGLEXT)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# --- OpenGl ---
|
||||
ocv_clear_vars(HAVE_OPENGL HAVE_QT_OPENGL)
|
||||
if(WITH_OPENGL)
|
||||
if(WITH_WIN32UI OR (HAVE_QT AND QT_QTOPENGL_FOUND) OR HAVE_GTKGLEXT)
|
||||
find_package (OpenGL QUIET)
|
||||
if(OPENGL_FOUND)
|
||||
set(HAVE_OPENGL TRUE)
|
||||
list(APPEND OPENCV_LINKER_LIBS ${OPENGL_LIBRARIES})
|
||||
if(QT_QTOPENGL_FOUND)
|
||||
set(HAVE_QT_OPENGL TRUE)
|
||||
else()
|
||||
ocv_include_directories(${OPENGL_INCLUDE_DIR})
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif(WITH_OPENGL)
|
||||
|
||||
# --- Cocoa ---
|
||||
if(APPLE)
|
||||
if(NOT IOS AND CV_CLANG)
|
||||
set(HAVE_COCOA YES)
|
||||
endif()
|
||||
endif()
|
|
@ -0,0 +1,276 @@
|
|||
# ----------------------------------------------------------------------------
|
||||
# Detect 3rd-party image IO libraries
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# --- zlib (required) ---
|
||||
if(BUILD_ZLIB)
|
||||
ocv_clear_vars(ZLIB_FOUND)
|
||||
else()
|
||||
find_package(ZLIB "${MIN_VER_ZLIB}")
|
||||
if(ZLIB_FOUND AND ANDROID)
|
||||
if(ZLIB_LIBRARIES MATCHES "/usr/(lib|lib32|lib64)/libz.so$")
|
||||
set(ZLIB_LIBRARIES z)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT ZLIB_FOUND)
|
||||
ocv_clear_vars(ZLIB_LIBRARY ZLIB_LIBRARIES ZLIB_INCLUDE_DIRS)
|
||||
|
||||
set(ZLIB_LIBRARY zlib)
|
||||
add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/zlib")
|
||||
set(ZLIB_INCLUDE_DIRS "${${ZLIB_LIBRARY}_SOURCE_DIR}" "${${ZLIB_LIBRARY}_BINARY_DIR}")
|
||||
set(ZLIB_LIBRARIES ${ZLIB_LIBRARY})
|
||||
|
||||
ocv_parse_header2(ZLIB "${${ZLIB_LIBRARY}_SOURCE_DIR}/zlib.h" ZLIB_VERSION)
|
||||
endif()
|
||||
|
||||
# --- libjpeg (optional) ---
|
||||
if(WITH_JPEG)
|
||||
if(BUILD_JPEG)
|
||||
ocv_clear_vars(JPEG_FOUND)
|
||||
else()
|
||||
include(FindJPEG)
|
||||
endif()
|
||||
|
||||
if(NOT JPEG_FOUND)
|
||||
ocv_clear_vars(JPEG_LIBRARY JPEG_LIBRARIES JPEG_INCLUDE_DIR)
|
||||
|
||||
if(NOT BUILD_JPEG_TURBO_DISABLE)
|
||||
set(JPEG_LIBRARY libjpeg-turbo)
|
||||
set(JPEG_LIBRARIES ${JPEG_LIBRARY})
|
||||
add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/libjpeg-turbo")
|
||||
set(JPEG_INCLUDE_DIR "${${JPEG_LIBRARY}_SOURCE_DIR}/src")
|
||||
else()
|
||||
set(JPEG_LIBRARY libjpeg)
|
||||
set(JPEG_LIBRARIES ${JPEG_LIBRARY})
|
||||
add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/libjpeg")
|
||||
set(JPEG_INCLUDE_DIR "${${JPEG_LIBRARY}_SOURCE_DIR}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
macro(ocv_detect_jpeg_version header_file)
|
||||
if(NOT DEFINED JPEG_LIB_VERSION AND EXISTS "${header_file}")
|
||||
ocv_parse_header("${header_file}" JPEG_VERSION_LINES JPEG_LIB_VERSION)
|
||||
endif()
|
||||
endmacro()
|
||||
ocv_detect_jpeg_version("${JPEG_INCLUDE_DIR}/jpeglib.h")
|
||||
if(DEFINED CMAKE_CXX_LIBRARY_ARCHITECTURE)
|
||||
ocv_detect_jpeg_version("${JPEG_INCLUDE_DIR}/${CMAKE_CXX_LIBRARY_ARCHITECTURE}/jconfig.h")
|
||||
endif()
|
||||
# no needed for strict platform check here, both files 64/32 should contain the same version
|
||||
ocv_detect_jpeg_version("${JPEG_INCLUDE_DIR}/jconfig-64.h")
|
||||
ocv_detect_jpeg_version("${JPEG_INCLUDE_DIR}/jconfig-32.h")
|
||||
ocv_detect_jpeg_version("${JPEG_INCLUDE_DIR}/jconfig.h")
|
||||
ocv_detect_jpeg_version("${${JPEG_LIBRARY}_BINARY_DIR}/jconfig.h")
|
||||
if(NOT DEFINED JPEG_LIB_VERSION)
|
||||
set(JPEG_LIB_VERSION "unknown")
|
||||
endif()
|
||||
set(HAVE_JPEG YES)
|
||||
endif()
|
||||
|
||||
# --- libtiff (optional, should be searched after zlib and libjpeg) ---
|
||||
if(WITH_TIFF)
|
||||
if(BUILD_TIFF)
|
||||
ocv_clear_vars(TIFF_FOUND)
|
||||
else()
|
||||
include(FindTIFF)
|
||||
if(TIFF_FOUND)
|
||||
ocv_parse_header("${TIFF_INCLUDE_DIR}/tiff.h" TIFF_VERSION_LINES TIFF_VERSION_CLASSIC TIFF_VERSION_BIG TIFF_VERSION TIFF_BIGTIFF_VERSION)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT TIFF_FOUND)
|
||||
ocv_clear_vars(TIFF_LIBRARY TIFF_LIBRARIES TIFF_INCLUDE_DIR)
|
||||
|
||||
set(TIFF_LIBRARY libtiff)
|
||||
set(TIFF_LIBRARIES ${TIFF_LIBRARY})
|
||||
add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/libtiff")
|
||||
set(TIFF_INCLUDE_DIR "${${TIFF_LIBRARY}_SOURCE_DIR}" "${${TIFF_LIBRARY}_BINARY_DIR}")
|
||||
ocv_parse_header("${${TIFF_LIBRARY}_SOURCE_DIR}/tiff.h" TIFF_VERSION_LINES TIFF_VERSION_CLASSIC TIFF_VERSION_BIG TIFF_VERSION TIFF_BIGTIFF_VERSION)
|
||||
endif()
|
||||
|
||||
if(TIFF_VERSION_CLASSIC AND NOT TIFF_VERSION)
|
||||
set(TIFF_VERSION ${TIFF_VERSION_CLASSIC})
|
||||
endif()
|
||||
|
||||
if(TIFF_BIGTIFF_VERSION AND NOT TIFF_VERSION_BIG)
|
||||
set(TIFF_VERSION_BIG ${TIFF_BIGTIFF_VERSION})
|
||||
endif()
|
||||
|
||||
if(NOT TIFF_VERSION_STRING AND TIFF_INCLUDE_DIR)
|
||||
list(GET TIFF_INCLUDE_DIR 0 _TIFF_INCLUDE_DIR)
|
||||
if(EXISTS "${_TIFF_INCLUDE_DIR}/tiffvers.h")
|
||||
file(STRINGS "${_TIFF_INCLUDE_DIR}/tiffvers.h" tiff_version_str REGEX "^#define[\t ]+TIFFLIB_VERSION_STR[\t ]+\"LIBTIFF, Version .*")
|
||||
string(REGEX REPLACE "^#define[\t ]+TIFFLIB_VERSION_STR[\t ]+\"LIBTIFF, Version +([^ \\n]*).*" "\\1" TIFF_VERSION_STRING "${tiff_version_str}")
|
||||
unset(tiff_version_str)
|
||||
endif()
|
||||
unset(_TIFF_INCLUDE_DIR)
|
||||
endif()
|
||||
|
||||
set(HAVE_TIFF YES)
|
||||
endif()
|
||||
|
||||
# --- libwebp (optional) ---
|
||||
|
||||
if(WITH_WEBP)
|
||||
if(BUILD_WEBP)
|
||||
ocv_clear_vars(WEBP_FOUND WEBP_LIBRARY WEBP_LIBRARIES WEBP_INCLUDE_DIR)
|
||||
else()
|
||||
include(cmake/OpenCVFindWebP.cmake)
|
||||
if(WEBP_FOUND)
|
||||
set(HAVE_WEBP 1)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# --- Add libwebp to 3rdparty/libwebp and compile it if not available ---
|
||||
if(WITH_WEBP AND NOT WEBP_FOUND
|
||||
AND (NOT ANDROID OR HAVE_CPUFEATURES)
|
||||
)
|
||||
|
||||
set(WEBP_LIBRARY libwebp)
|
||||
set(WEBP_LIBRARIES ${WEBP_LIBRARY})
|
||||
|
||||
add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/libwebp")
|
||||
set(WEBP_INCLUDE_DIR "${${WEBP_LIBRARY}_SOURCE_DIR}/src")
|
||||
set(HAVE_WEBP 1)
|
||||
endif()
|
||||
|
||||
if(NOT WEBP_VERSION AND WEBP_INCLUDE_DIR)
|
||||
ocv_clear_vars(ENC_MAJ_VERSION ENC_MIN_VERSION ENC_REV_VERSION)
|
||||
if(EXISTS "${WEBP_INCLUDE_DIR}/enc/vp8enci.h")
|
||||
ocv_parse_header("${WEBP_INCLUDE_DIR}/enc/vp8enci.h" WEBP_VERSION_LINES ENC_MAJ_VERSION ENC_MIN_VERSION ENC_REV_VERSION)
|
||||
set(WEBP_VERSION "${ENC_MAJ_VERSION}.${ENC_MIN_VERSION}.${ENC_REV_VERSION}")
|
||||
elseif(EXISTS "${WEBP_INCLUDE_DIR}/webp/encode.h")
|
||||
file(STRINGS "${WEBP_INCLUDE_DIR}/webp/encode.h" WEBP_ENCODER_ABI_VERSION REGEX "#define[ \t]+WEBP_ENCODER_ABI_VERSION[ \t]+([x0-9a-f]+)" )
|
||||
if(WEBP_ENCODER_ABI_VERSION MATCHES "#define[ \t]+WEBP_ENCODER_ABI_VERSION[ \t]+([x0-9a-f]+)")
|
||||
set(WEBP_ENCODER_ABI_VERSION "${CMAKE_MATCH_1}")
|
||||
set(WEBP_VERSION "encoder: ${WEBP_ENCODER_ABI_VERSION}")
|
||||
else()
|
||||
unset(WEBP_ENCODER_ABI_VERSION)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# --- libjasper (optional, should be searched after libjpeg) ---
|
||||
if(WITH_JASPER)
|
||||
if(BUILD_JASPER)
|
||||
ocv_clear_vars(JASPER_FOUND)
|
||||
else()
|
||||
include(FindJasper)
|
||||
endif()
|
||||
|
||||
if(NOT JASPER_FOUND)
|
||||
ocv_clear_vars(JASPER_LIBRARY JASPER_LIBRARIES JASPER_INCLUDE_DIR)
|
||||
|
||||
set(JASPER_LIBRARY libjasper)
|
||||
set(JASPER_LIBRARIES ${JASPER_LIBRARY})
|
||||
add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/libjasper")
|
||||
set(JASPER_INCLUDE_DIR "${${JASPER_LIBRARY}_SOURCE_DIR}")
|
||||
endif()
|
||||
|
||||
set(HAVE_JASPER YES)
|
||||
|
||||
if(NOT JASPER_VERSION_STRING)
|
||||
ocv_parse_header2(JASPER "${JASPER_INCLUDE_DIR}/jasper/jas_config.h" JAS_VERSION "")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# --- libpng (optional, should be searched after zlib) ---
|
||||
if(WITH_PNG)
|
||||
if(BUILD_PNG)
|
||||
ocv_clear_vars(PNG_FOUND)
|
||||
else()
|
||||
include(FindPNG)
|
||||
if(PNG_FOUND)
|
||||
include(CheckIncludeFile)
|
||||
check_include_file("${PNG_PNG_INCLUDE_DIR}/libpng/png.h" HAVE_LIBPNG_PNG_H)
|
||||
if(HAVE_LIBPNG_PNG_H)
|
||||
ocv_parse_header("${PNG_PNG_INCLUDE_DIR}/libpng/png.h" PNG_VERSION_LINES PNG_LIBPNG_VER_MAJOR PNG_LIBPNG_VER_MINOR PNG_LIBPNG_VER_RELEASE)
|
||||
else()
|
||||
ocv_parse_header("${PNG_PNG_INCLUDE_DIR}/png.h" PNG_VERSION_LINES PNG_LIBPNG_VER_MAJOR PNG_LIBPNG_VER_MINOR PNG_LIBPNG_VER_RELEASE)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT PNG_FOUND)
|
||||
ocv_clear_vars(PNG_LIBRARY PNG_LIBRARIES PNG_INCLUDE_DIR PNG_PNG_INCLUDE_DIR HAVE_LIBPNG_PNG_H PNG_DEFINITIONS)
|
||||
|
||||
set(PNG_LIBRARY libpng)
|
||||
set(PNG_LIBRARIES ${PNG_LIBRARY})
|
||||
add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/libpng")
|
||||
set(PNG_INCLUDE_DIR "${${PNG_LIBRARY}_SOURCE_DIR}")
|
||||
set(PNG_DEFINITIONS "")
|
||||
ocv_parse_header("${PNG_INCLUDE_DIR}/png.h" PNG_VERSION_LINES PNG_LIBPNG_VER_MAJOR PNG_LIBPNG_VER_MINOR PNG_LIBPNG_VER_RELEASE)
|
||||
endif()
|
||||
|
||||
set(HAVE_PNG YES)
|
||||
set(PNG_VERSION "${PNG_LIBPNG_VER_MAJOR}.${PNG_LIBPNG_VER_MINOR}.${PNG_LIBPNG_VER_RELEASE}")
|
||||
endif()
|
||||
|
||||
# --- OpenEXR (optional) ---
|
||||
if(WITH_OPENEXR)
|
||||
ocv_clear_vars(HAVE_OPENEXR)
|
||||
if(NOT BUILD_OPENEXR)
|
||||
include("${OpenCV_SOURCE_DIR}/cmake/OpenCVFindOpenEXR.cmake")
|
||||
endif()
|
||||
|
||||
if(OPENEXR_FOUND)
|
||||
set(HAVE_OPENEXR YES)
|
||||
else()
|
||||
ocv_clear_vars(OPENEXR_INCLUDE_PATHS OPENEXR_LIBRARIES OPENEXR_ILMIMF_LIBRARY OPENEXR_VERSION)
|
||||
|
||||
set(OPENEXR_LIBRARIES IlmImf)
|
||||
add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/openexr")
|
||||
if(OPENEXR_VERSION) # check via TARGET doesn't work
|
||||
set(HAVE_OPENEXR YES)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# --- GDAL (optional) ---
|
||||
if(WITH_GDAL)
|
||||
find_package(GDAL QUIET)
|
||||
|
||||
if(NOT GDAL_FOUND)
|
||||
set(HAVE_GDAL NO)
|
||||
ocv_clear_vars(GDAL_VERSION GDAL_LIBRARIES)
|
||||
else()
|
||||
set(HAVE_GDAL YES)
|
||||
ocv_include_directories(${GDAL_INCLUDE_DIR})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (WITH_GDCM)
|
||||
find_package(GDCM QUIET)
|
||||
if(NOT GDCM_FOUND)
|
||||
set(HAVE_GDCM NO)
|
||||
ocv_clear_vars(GDCM_VERSION GDCM_LIBRARIES)
|
||||
else()
|
||||
set(HAVE_GDCM YES)
|
||||
# include(${GDCM_USE_FILE})
|
||||
set(GDCM_LIBRARIES gdcmMSFF) # GDCM does not set this variable for some reason
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_IMGCODEC_HDR)
|
||||
set(HAVE_IMGCODEC_HDR ON)
|
||||
elseif(DEFINED WITH_IMGCODEC_HDR)
|
||||
set(HAVE_IMGCODEC_HDR OFF)
|
||||
endif()
|
||||
if(WITH_IMGCODEC_SUNRASTER)
|
||||
set(HAVE_IMGCODEC_SUNRASTER ON)
|
||||
elseif(DEFINED WITH_IMGCODEC_SUNRASTER)
|
||||
set(HAVE_IMGCODEC_SUNRASTER OFF)
|
||||
endif()
|
||||
if(WITH_IMGCODEC_PXM)
|
||||
set(HAVE_IMGCODEC_PXM ON)
|
||||
elseif(DEFINED WITH_IMGCODEC_PXM)
|
||||
set(HAVE_IMGCODEC_PXM OFF)
|
||||
endif()
|
||||
if(WITH_IMGCODEC_PFM)
|
||||
set(HAVE_IMGCODEC_PFM ON)
|
||||
elseif(DEFINED WITH_IMGCODEC_PFM)
|
||||
set(HAVE_IMGCODEC_PFM OFF)
|
||||
endif()
|
|
@ -0,0 +1,141 @@
|
|||
# ----------------------------------------------------------------------------
|
||||
# Detect other 3rd-party performance and math libraries
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# --- TBB ---
|
||||
if(WITH_TBB)
|
||||
include("${OpenCV_SOURCE_DIR}/cmake/OpenCVDetectTBB.cmake")
|
||||
endif(WITH_TBB)
|
||||
|
||||
# --- IPP ---
|
||||
if(WITH_IPP)
|
||||
include("${OpenCV_SOURCE_DIR}/cmake/OpenCVFindIPP.cmake")
|
||||
if(HAVE_IPP)
|
||||
include("${OpenCV_SOURCE_DIR}/cmake/OpenCVFindIPPIW.cmake")
|
||||
if(HAVE_IPP_IW)
|
||||
ocv_include_directories(${IPP_IW_INCLUDES})
|
||||
list(APPEND OPENCV_LINKER_LIBS ${IPP_IW_LIBRARIES})
|
||||
endif()
|
||||
ocv_include_directories(${IPP_INCLUDE_DIRS})
|
||||
list(APPEND OPENCV_LINKER_LIBS ${IPP_LIBRARIES})
|
||||
|
||||
# Details: #10229
|
||||
if(ANDROID AND NOT OPENCV_SKIP_ANDROID_IPP_FIX_1)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--exclude-libs,libippicv.a -Wl,--exclude-libs,libippiw.a ${CMAKE_SHARED_LINKER_FLAGS}")
|
||||
elseif(ANDROID AND NOT OPENCV_SKIP_ANDROID_IPP_FIX_2)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,-Bsymbolic ${CMAKE_SHARED_LINKER_FLAGS}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# --- CUDA ---
|
||||
if(WITH_CUDA)
|
||||
include("${OpenCV_SOURCE_DIR}/cmake/OpenCVDetectCUDA.cmake")
|
||||
if(NOT HAVE_CUDA)
|
||||
message(WARNING "OpenCV is not able to find/configure CUDA SDK (required by WITH_CUDA).
|
||||
CUDA support will be disabled in OpenCV build.
|
||||
To eliminate this warning remove WITH_CUDA=ON CMake configuration option.
|
||||
")
|
||||
endif()
|
||||
endif(WITH_CUDA)
|
||||
|
||||
# --- Eigen ---
|
||||
if(WITH_EIGEN AND NOT HAVE_EIGEN)
|
||||
find_package(Eigen3 QUIET)
|
||||
|
||||
if(Eigen3_FOUND)
|
||||
if(TARGET Eigen3::Eigen)
|
||||
# Use Eigen3 imported target if possible
|
||||
list(APPEND OPENCV_LINKER_LIBS Eigen3::Eigen)
|
||||
set(HAVE_EIGEN 1)
|
||||
else()
|
||||
if(DEFINED EIGEN3_INCLUDE_DIRS)
|
||||
set(EIGEN_INCLUDE_PATH ${EIGEN3_INCLUDE_DIRS})
|
||||
set(HAVE_EIGEN 1)
|
||||
elseif(DEFINED EIGEN3_INCLUDE_DIR)
|
||||
set(EIGEN_INCLUDE_PATH ${EIGEN3_INCLUDE_DIR})
|
||||
set(HAVE_EIGEN 1)
|
||||
endif()
|
||||
endif()
|
||||
if(HAVE_EIGEN)
|
||||
if(DEFINED EIGEN3_WORLD_VERSION) # CMake module
|
||||
set(EIGEN_WORLD_VERSION ${EIGEN3_WORLD_VERSION})
|
||||
set(EIGEN_MAJOR_VERSION ${EIGEN3_MAJOR_VERSION})
|
||||
set(EIGEN_MINOR_VERSION ${EIGEN3_MINOR_VERSION})
|
||||
else() # Eigen config file
|
||||
set(EIGEN_WORLD_VERSION ${EIGEN3_VERSION_MAJOR})
|
||||
set(EIGEN_MAJOR_VERSION ${EIGEN3_VERSION_MINOR})
|
||||
set(EIGEN_MINOR_VERSION ${EIGEN3_VERSION_PATCH})
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT HAVE_EIGEN)
|
||||
if(NOT EIGEN_INCLUDE_PATH OR NOT EXISTS "${EIGEN_INCLUDE_PATH}")
|
||||
set(__find_paths "")
|
||||
set(__find_path_extra_options "")
|
||||
if(NOT CMAKE_CROSSCOMPILING)
|
||||
list(APPEND __find_paths /opt)
|
||||
endif()
|
||||
if(DEFINED ENV{EIGEN_ROOT})
|
||||
set(__find_paths "$ENV{EIGEN_ROOT}/include")
|
||||
list(APPEND __find_path_extra_options NO_DEFAULT_PATH)
|
||||
else()
|
||||
set(__find_paths ENV ProgramFiles ENV ProgramW6432)
|
||||
endif()
|
||||
find_path(EIGEN_INCLUDE_PATH "Eigen/Core"
|
||||
PATHS ${__find_paths}
|
||||
PATH_SUFFIXES include/eigen3 include/eigen2 Eigen/include/eigen3 Eigen/include/eigen2
|
||||
DOC "The path to Eigen3/Eigen2 headers"
|
||||
${__find_path_extra_options}
|
||||
)
|
||||
endif()
|
||||
if(EIGEN_INCLUDE_PATH AND EXISTS "${EIGEN_INCLUDE_PATH}")
|
||||
ocv_parse_header("${EIGEN_INCLUDE_PATH}/Eigen/src/Core/util/Macros.h" EIGEN_VERSION_LINES EIGEN_WORLD_VERSION EIGEN_MAJOR_VERSION EIGEN_MINOR_VERSION)
|
||||
set(HAVE_EIGEN 1)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
if(HAVE_EIGEN)
|
||||
if(EIGEN_INCLUDE_PATH AND EXISTS "${EIGEN_INCLUDE_PATH}")
|
||||
ocv_include_directories(SYSTEM ${EIGEN_INCLUDE_PATH})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# --- Clp ---
|
||||
# Ubuntu: sudo apt-get install coinor-libclp-dev coinor-libcoinutils-dev
|
||||
ocv_clear_vars(HAVE_CLP)
|
||||
if(WITH_CLP)
|
||||
if(UNIX)
|
||||
ocv_check_modules(CLP clp)
|
||||
if(CLP_FOUND)
|
||||
set(HAVE_CLP TRUE)
|
||||
if(NOT ${CLP_INCLUDE_DIRS} STREQUAL "")
|
||||
ocv_include_directories(${CLP_INCLUDE_DIRS})
|
||||
endif()
|
||||
list(APPEND OPENCV_LINKER_LIBS ${CLP_LIBRARIES})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT CLP_FOUND)
|
||||
find_path(CLP_INCLUDE_PATH "coin"
|
||||
PATHS "/usr/local/include" "/usr/include" "/opt/include"
|
||||
DOC "The path to Clp headers")
|
||||
if(CLP_INCLUDE_PATH)
|
||||
ocv_include_directories(${CLP_INCLUDE_PATH} "${CLP_INCLUDE_PATH}/coin")
|
||||
get_filename_component(_CLP_LIBRARY_DIR "${CLP_INCLUDE_PATH}/../lib" ABSOLUTE)
|
||||
set(CLP_LIBRARY_DIR "${_CLP_LIBRARY_DIR}" CACHE PATH "Full path of Clp library directory")
|
||||
link_directories(${CLP_LIBRARY_DIR})
|
||||
if(UNIX)
|
||||
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} Clp CoinUtils m)
|
||||
else()
|
||||
if(MINGW)
|
||||
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} Clp CoinUtils)
|
||||
else()
|
||||
set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} libClp libCoinUtils)
|
||||
endif()
|
||||
endif()
|
||||
set(HAVE_CLP TRUE)
|
||||
endif()
|
||||
endif()
|
||||
endif(WITH_CLP)
|
|
@ -0,0 +1,20 @@
|
|||
# --- Extra HighGUI and VideoIO libs on Windows ---
|
||||
if(WIN32)
|
||||
list(APPEND HIGHGUI_LIBRARIES comctl32 gdi32 ole32 setupapi ws2_32)
|
||||
endif(WIN32)
|
||||
|
||||
# --- VA & VA_INTEL ---
|
||||
if(WITH_VA_INTEL)
|
||||
include("${OpenCV_SOURCE_DIR}/cmake/OpenCVFindVA_INTEL.cmake")
|
||||
if(VA_INTEL_IOCL_INCLUDE_DIR)
|
||||
ocv_include_directories(${VA_INTEL_IOCL_INCLUDE_DIR})
|
||||
endif()
|
||||
set(WITH_VA YES)
|
||||
endif(WITH_VA_INTEL)
|
||||
|
||||
if(WITH_VA)
|
||||
include("${OpenCV_SOURCE_DIR}/cmake/OpenCVFindVA.cmake")
|
||||
if(VA_INCLUDE_DIR)
|
||||
ocv_include_directories(${VA_INCLUDE_DIR})
|
||||
endif()
|
||||
endif(WITH_VA)
|
|
@ -0,0 +1,140 @@
|
|||
#
|
||||
# The script to detect Intel(R) Math Kernel Library (MKL)
|
||||
# installation/package
|
||||
#
|
||||
# Parameters:
|
||||
# MKL_WITH_TBB
|
||||
#
|
||||
# On return this will define:
|
||||
#
|
||||
# HAVE_MKL - True if Intel MKL found
|
||||
# MKL_ROOT_DIR - root of MKL installation
|
||||
# MKL_INCLUDE_DIRS - MKL include folder
|
||||
# MKL_LIBRARIES - MKL libraries that are used by OpenCV
|
||||
#
|
||||
|
||||
macro (mkl_find_lib VAR NAME DIRS)
|
||||
find_path(${VAR} ${NAME} ${DIRS} NO_DEFAULT_PATH)
|
||||
set(${VAR} ${${VAR}}/${NAME})
|
||||
unset(${VAR} CACHE)
|
||||
endmacro()
|
||||
|
||||
macro(mkl_fail)
|
||||
set(HAVE_MKL OFF)
|
||||
set(MKL_ROOT_DIR "${MKL_ROOT_DIR}" CACHE PATH "Path to MKL directory")
|
||||
return()
|
||||
endmacro()
|
||||
|
||||
macro(get_mkl_version VERSION_FILE)
|
||||
# read MKL version info from file
|
||||
file(STRINGS ${VERSION_FILE} STR1 REGEX "__INTEL_MKL__")
|
||||
file(STRINGS ${VERSION_FILE} STR2 REGEX "__INTEL_MKL_MINOR__")
|
||||
file(STRINGS ${VERSION_FILE} STR3 REGEX "__INTEL_MKL_UPDATE__")
|
||||
#file(STRINGS ${VERSION_FILE} STR4 REGEX "INTEL_MKL_VERSION")
|
||||
|
||||
# extract info and assign to variables
|
||||
string(REGEX MATCHALL "[0-9]+" MKL_VERSION_MAJOR ${STR1})
|
||||
string(REGEX MATCHALL "[0-9]+" MKL_VERSION_MINOR ${STR2})
|
||||
string(REGEX MATCHALL "[0-9]+" MKL_VERSION_UPDATE ${STR3})
|
||||
set(MKL_VERSION_STR "${MKL_VERSION_MAJOR}.${MKL_VERSION_MINOR}.${MKL_VERSION_UPDATE}" CACHE STRING "MKL version" FORCE)
|
||||
endmacro()
|
||||
|
||||
|
||||
if(NOT DEFINED MKL_USE_MULTITHREAD)
|
||||
OCV_OPTION(MKL_WITH_TBB "Use MKL with TBB multithreading" OFF)#ON IF WITH_TBB)
|
||||
OCV_OPTION(MKL_WITH_OPENMP "Use MKL with OpenMP multithreading" OFF)#ON IF WITH_OPENMP)
|
||||
endif()
|
||||
|
||||
#check current MKL_ROOT_DIR
|
||||
if(NOT MKL_ROOT_DIR OR NOT EXISTS "${MKL_ROOT_DIR}/include/mkl.h")
|
||||
set(mkl_root_paths "${MKL_ROOT_DIR}")
|
||||
if(DEFINED ENV{MKLROOT})
|
||||
list(APPEND mkl_root_paths "$ENV{MKLROOT}")
|
||||
endif()
|
||||
|
||||
if(WITH_MKL AND NOT mkl_root_paths)
|
||||
if(WIN32)
|
||||
set(ProgramFilesx86 "ProgramFiles(x86)")
|
||||
list(APPEND mkl_root_paths $ENV{${ProgramFilesx86}}/IntelSWTools/compilers_and_libraries/windows/mkl)
|
||||
endif()
|
||||
if(UNIX)
|
||||
list(APPEND mkl_root_paths "/opt/intel/mkl")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_path(MKL_ROOT_DIR include/mkl.h PATHS ${mkl_root_paths})
|
||||
endif()
|
||||
|
||||
set(MKL_INCLUDE_DIRS "${MKL_ROOT_DIR}/include" CACHE PATH "Path to MKL include directory")
|
||||
|
||||
if(NOT MKL_ROOT_DIR
|
||||
OR NOT EXISTS "${MKL_ROOT_DIR}"
|
||||
OR NOT EXISTS "${MKL_INCLUDE_DIRS}"
|
||||
OR NOT EXISTS "${MKL_INCLUDE_DIRS}/mkl_version.h"
|
||||
)
|
||||
mkl_fail()
|
||||
endif()
|
||||
|
||||
get_mkl_version(${MKL_INCLUDE_DIRS}/mkl_version.h)
|
||||
|
||||
#determine arch
|
||||
if(CMAKE_CXX_SIZEOF_DATA_PTR EQUAL 8)
|
||||
set(MKL_X64 1)
|
||||
set(MKL_ARCH "intel64")
|
||||
|
||||
include(CheckTypeSize)
|
||||
CHECK_TYPE_SIZE(int _sizeof_int)
|
||||
if (_sizeof_int EQUAL 4)
|
||||
set(MKL_ARCH_SUFFIX "lp64")
|
||||
else()
|
||||
set(MKL_ARCH_SUFFIX "ilp64")
|
||||
endif()
|
||||
else()
|
||||
set(MKL_ARCH "ia32")
|
||||
set(MKL_ARCH_SUFFIX "c")
|
||||
endif()
|
||||
|
||||
if(MKL_VERSION_STR VERSION_GREATER "11.3.0" OR MKL_VERSION_STR VERSION_EQUAL "11.3.0")
|
||||
set(mkl_lib_find_paths
|
||||
${MKL_ROOT_DIR}/lib
|
||||
${MKL_ROOT_DIR}/lib/${MKL_ARCH} ${MKL_ROOT_DIR}/../tbb/lib/${MKL_ARCH})
|
||||
|
||||
set(mkl_lib_list "mkl_intel_${MKL_ARCH_SUFFIX}")
|
||||
|
||||
if(MKL_WITH_TBB)
|
||||
list(APPEND mkl_lib_list mkl_tbb_thread tbb)
|
||||
elseif(MKL_WITH_OPENMP)
|
||||
if(MSVC)
|
||||
list(APPEND mkl_lib_list mkl_intel_thread libiomp5md)
|
||||
else()
|
||||
list(APPEND mkl_lib_list mkl_gnu_thread)
|
||||
endif()
|
||||
else()
|
||||
list(APPEND mkl_lib_list mkl_sequential)
|
||||
endif()
|
||||
|
||||
list(APPEND mkl_lib_list mkl_core)
|
||||
else()
|
||||
message(STATUS "MKL version ${MKL_VERSION_STR} is not supported")
|
||||
mkl_fail()
|
||||
endif()
|
||||
|
||||
set(MKL_LIBRARIES "")
|
||||
foreach(lib ${mkl_lib_list})
|
||||
find_library(${lib} ${lib} ${mkl_lib_find_paths})
|
||||
mark_as_advanced(${lib})
|
||||
if(NOT ${lib})
|
||||
mkl_fail()
|
||||
endif()
|
||||
list(APPEND MKL_LIBRARIES ${${lib}})
|
||||
endforeach()
|
||||
|
||||
message(STATUS "Found MKL ${MKL_VERSION_STR} at: ${MKL_ROOT_DIR}")
|
||||
set(HAVE_MKL ON)
|
||||
set(MKL_ROOT_DIR "${MKL_ROOT_DIR}" CACHE PATH "Path to MKL directory")
|
||||
set(MKL_INCLUDE_DIRS "${MKL_INCLUDE_DIRS}" CACHE PATH "Path to MKL include directory")
|
||||
set(MKL_LIBRARIES "${MKL_LIBRARIES}" CACHE STRING "MKL libraries")
|
||||
if(UNIX AND NOT MKL_LIBRARIES_DONT_HACK)
|
||||
#it's ugly but helps to avoid cyclic lib problem
|
||||
set(MKL_LIBRARIES ${MKL_LIBRARIES} ${MKL_LIBRARIES} ${MKL_LIBRARIES} "-lpthread" "-lm" "-ldl")
|
||||
endif()
|
|
@ -0,0 +1,106 @@
|
|||
#COPYRIGHT
|
||||
#
|
||||
#All contributions by the University of California:
|
||||
#Copyright (c) 2014, 2015, The Regents of the University of California (Regents)
|
||||
#All rights reserved.
|
||||
#
|
||||
#All other contributions:
|
||||
#Copyright (c) 2014, 2015, the respective contributors
|
||||
#All rights reserved.
|
||||
#
|
||||
#Caffe uses a shared copyright model: each contributor holds copyright over
|
||||
#their contributions to Caffe. The project versioning records all such
|
||||
#contribution and copyright details. If a contributor wants to further mark
|
||||
#their specific copyright on a particular contribution, they should indicate
|
||||
#their copyright solely in the commit message of the change when it is
|
||||
#committed.
|
||||
#
|
||||
#LICENSE
|
||||
#
|
||||
#Redistribution and use in source and binary forms, with or without
|
||||
#modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
#1. Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer.
|
||||
#2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
#ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
#WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
#DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
|
||||
#
|
||||
#CONTRIBUTION AGREEMENT
|
||||
#
|
||||
#By contributing to the BVLC/caffe repository through pull-request, comment,
|
||||
#or otherwise, the contributor releases their content to the
|
||||
#license and copyright terms herein.
|
||||
|
||||
SET(Open_BLAS_INCLUDE_SEARCH_PATHS
|
||||
$ENV{OpenBLAS_HOME}
|
||||
$ENV{OpenBLAS_HOME}/include
|
||||
/opt/OpenBLAS/include
|
||||
/usr/local/include/openblas
|
||||
/usr/include/openblas
|
||||
/usr/local/include/openblas-base
|
||||
/usr/include/openblas-base
|
||||
/usr/local/include
|
||||
/usr/include
|
||||
)
|
||||
|
||||
SET(Open_BLAS_LIB_SEARCH_PATHS
|
||||
$ENV{OpenBLAS}cd
|
||||
$ENV{OpenBLAS}/lib
|
||||
$ENV{OpenBLAS_HOME}
|
||||
$ENV{OpenBLAS_HOME}/lib
|
||||
/opt/OpenBLAS/lib
|
||||
/usr/local/lib64
|
||||
/usr/local/lib
|
||||
/lib/openblas-base
|
||||
/lib64/
|
||||
/lib/
|
||||
/usr/lib/openblas-base
|
||||
/usr/lib64
|
||||
/usr/lib
|
||||
)
|
||||
|
||||
FIND_PATH(OpenBLAS_INCLUDE_DIR NAMES cblas.h PATHS ${Open_BLAS_INCLUDE_SEARCH_PATHS} NO_DEFAULT_PATH)
|
||||
FIND_LIBRARY(OpenBLAS_LIB NAMES openblas PATHS ${Open_BLAS_LIB_SEARCH_PATHS} NO_DEFAULT_PATH)
|
||||
|
||||
SET(OpenBLAS_FOUND ON)
|
||||
|
||||
# Check include files
|
||||
IF(NOT OpenBLAS_INCLUDE_DIR)
|
||||
SET(OpenBLAS_FOUND OFF)
|
||||
MESSAGE(STATUS "Could not find OpenBLAS include. Turning OpenBLAS_FOUND off")
|
||||
ENDIF()
|
||||
|
||||
# Check libraries
|
||||
IF(NOT OpenBLAS_LIB)
|
||||
SET(OpenBLAS_FOUND OFF)
|
||||
MESSAGE(STATUS "Could not find OpenBLAS lib. Turning OpenBLAS_FOUND off")
|
||||
ENDIF()
|
||||
|
||||
IF (OpenBLAS_FOUND)
|
||||
IF (NOT OpenBLAS_FIND_QUIETLY)
|
||||
MESSAGE(STATUS "Found OpenBLAS libraries: ${OpenBLAS_LIB}")
|
||||
MESSAGE(STATUS "Found OpenBLAS include: ${OpenBLAS_INCLUDE_DIR}")
|
||||
ENDIF (NOT OpenBLAS_FIND_QUIETLY)
|
||||
ELSE (OpenBLAS_FOUND)
|
||||
IF (OpenBLAS_FIND_REQUIRED)
|
||||
MESSAGE(FATAL_ERROR "Could not find OpenBLAS")
|
||||
ENDIF (OpenBLAS_FIND_REQUIRED)
|
||||
ENDIF (OpenBLAS_FOUND)
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
OpenBLAS_INCLUDE_DIR
|
||||
OpenBLAS_LIB
|
||||
OpenBLAS
|
||||
)
|
|
@ -0,0 +1,142 @@
|
|||
# The script is taken from http://code.google.com/p/nvidia-texture-tools/
|
||||
|
||||
#
|
||||
# Try to find OpenEXR's libraries, and include path.
|
||||
# Once done this will define:
|
||||
#
|
||||
# OPENEXR_FOUND = OpenEXR found.
|
||||
# OPENEXR_INCLUDE_PATHS = OpenEXR include directories.
|
||||
# OPENEXR_LIBRARIES = libraries that are needed to use OpenEXR.
|
||||
#
|
||||
|
||||
SET(OPENEXR_LIBRARIES "")
|
||||
SET(OPENEXR_LIBSEARCH_SUFFIXES "")
|
||||
file(TO_CMAKE_PATH "$ENV{ProgramFiles}" ProgramFiles_ENV_PATH)
|
||||
|
||||
if(WIN32)
|
||||
SET(OPENEXR_ROOT "C:/Deploy" CACHE STRING "Path to the OpenEXR \"Deploy\" folder")
|
||||
if(X86_64)
|
||||
SET(OPENEXR_LIBSEARCH_SUFFIXES x64/Release x64 x64/Debug)
|
||||
elseif(MSVC)
|
||||
SET(OPENEXR_LIBSEARCH_SUFFIXES Win32/Release Win32 Win32/Debug)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
SET(SEARCH_PATHS
|
||||
"${OPENEXR_ROOT}"
|
||||
/usr
|
||||
/usr/local
|
||||
/sw
|
||||
/opt
|
||||
"${ProgramFiles_ENV_PATH}/OpenEXR")
|
||||
|
||||
MACRO(FIND_OPENEXR_LIBRARY LIBRARY_NAME LIBRARY_SUFFIX)
|
||||
string(TOUPPER "${LIBRARY_NAME}" LIBRARY_NAME_UPPER)
|
||||
FIND_LIBRARY(OPENEXR_${LIBRARY_NAME_UPPER}_LIBRARY
|
||||
NAMES ${LIBRARY_NAME}${LIBRARY_SUFFIX}
|
||||
PATH_SUFFIXES ${OPENEXR_LIBSEARCH_SUFFIXES}
|
||||
NO_DEFAULT_PATH
|
||||
PATHS "${SEARCH_PATH}/lib" "${SEARCH_PATH}/lib/static")
|
||||
ENDMACRO()
|
||||
|
||||
FOREACH(SEARCH_PATH ${SEARCH_PATHS})
|
||||
FIND_PATH(OPENEXR_INCLUDE_PATH ImfRgbaFile.h
|
||||
PATH_SUFFIXES OpenEXR
|
||||
NO_DEFAULT_PATH
|
||||
PATHS
|
||||
"${SEARCH_PATH}/include")
|
||||
|
||||
IF (OPENEXR_INCLUDE_PATH)
|
||||
SET(OPENEXR_VERSION_FILE "${OPENEXR_INCLUDE_PATH}/OpenEXRConfig.h")
|
||||
IF (EXISTS ${OPENEXR_VERSION_FILE})
|
||||
FILE (STRINGS ${OPENEXR_VERSION_FILE} contents REGEX "#define OPENEXR_VERSION_MAJOR ")
|
||||
IF (${contents} MATCHES "#define OPENEXR_VERSION_MAJOR ([0-9]+)")
|
||||
SET(OPENEXR_VERSION_MAJOR "${CMAKE_MATCH_1}")
|
||||
ENDIF ()
|
||||
FILE (STRINGS ${OPENEXR_VERSION_FILE} contents REGEX "#define OPENEXR_VERSION_MINOR ")
|
||||
IF (${contents} MATCHES "#define OPENEXR_VERSION_MINOR ([0-9]+)")
|
||||
SET(OPENEXR_VERSION_MINOR "${CMAKE_MATCH_1}")
|
||||
ENDIF ()
|
||||
ENDIF ()
|
||||
ENDIF ()
|
||||
|
||||
IF (OPENEXR_VERSION_MAJOR AND OPENEXR_VERSION_MINOR)
|
||||
set(OPENEXR_VERSION "${OPENEXR_VERSION_MAJOR}_${OPENEXR_VERSION_MINOR}")
|
||||
ENDIF ()
|
||||
|
||||
SET(LIBRARY_SUFFIXES
|
||||
"-${OPENEXR_VERSION}"
|
||||
"-${OPENEXR_VERSION}_s"
|
||||
"-${OPENEXR_VERSION}_d"
|
||||
"-${OPEXEXR_VERSION}_s_d"
|
||||
""
|
||||
"_s"
|
||||
"_d"
|
||||
"_s_d")
|
||||
|
||||
FOREACH(LIBRARY_SUFFIX ${LIBRARY_SUFFIXES})
|
||||
FIND_OPENEXR_LIBRARY("Half" ${LIBRARY_SUFFIX})
|
||||
FIND_OPENEXR_LIBRARY("Iex" ${LIBRARY_SUFFIX})
|
||||
FIND_OPENEXR_LIBRARY("Imath" ${LIBRARY_SUFFIX})
|
||||
FIND_OPENEXR_LIBRARY("IlmImf" ${LIBRARY_SUFFIX})
|
||||
FIND_OPENEXR_LIBRARY("IlmThread" ${LIBRARY_SUFFIX})
|
||||
IF (OPENEXR_INCLUDE_PATH AND OPENEXR_IMATH_LIBRARY AND OPENEXR_ILMIMF_LIBRARY AND OPENEXR_IEX_LIBRARY AND OPENEXR_HALF_LIBRARY)
|
||||
SET(OPENEXR_FOUND TRUE)
|
||||
BREAK()
|
||||
ENDIF()
|
||||
UNSET(OPENEXR_IMATH_LIBRARY)
|
||||
UNSET(OPENEXR_ILMIMF_LIBRARY)
|
||||
UNSET(OPENEXR_IEX_LIBRARY)
|
||||
UNSET(OPENEXR_ILMTHREAD_LIBRARY)
|
||||
UNSET(OPENEXR_HALF_LIBRARY)
|
||||
ENDFOREACH()
|
||||
|
||||
IF (OPENEXR_FOUND)
|
||||
BREAK()
|
||||
ENDIF()
|
||||
|
||||
UNSET(OPENEXR_INCLUDE_PATH)
|
||||
UNSET(OPENEXR_VERSION_FILE)
|
||||
UNSET(OPENEXR_VERSION_MAJOR)
|
||||
UNSET(OPENEXR_VERSION_MINOR)
|
||||
UNSET(OPENEXR_VERSION)
|
||||
ENDFOREACH()
|
||||
|
||||
IF (OPENEXR_FOUND)
|
||||
SET(OPENEXR_INCLUDE_PATHS ${OPENEXR_INCLUDE_PATH} CACHE PATH "The include paths needed to use OpenEXR")
|
||||
SET(OPENEXR_LIBRARIES ${OPENEXR_IMATH_LIBRARY} ${OPENEXR_ILMIMF_LIBRARY} ${OPENEXR_IEX_LIBRARY} ${OPENEXR_HALF_LIBRARY} ${OPENEXR_ILMTHREAD_LIBRARY} CACHE STRING "The libraries needed to use OpenEXR" FORCE)
|
||||
ENDIF ()
|
||||
|
||||
IF(OPENEXR_FOUND)
|
||||
IF(NOT OPENEXR_FIND_QUIETLY)
|
||||
MESSAGE(STATUS "Found OpenEXR: ${OPENEXR_ILMIMF_LIBRARY}")
|
||||
ENDIF()
|
||||
if(PKG_CONFIG_FOUND AND NOT OPENEXR_VERSION)
|
||||
get_filename_component(OPENEXR_LIB_PATH "${OPENEXR_ILMIMF_LIBRARY}" PATH)
|
||||
if(EXISTS "${OPENEXR_LIB_PATH}/pkgconfig/OpenEXR.pc")
|
||||
execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --modversion "${OPENEXR_LIB_PATH}/pkgconfig/OpenEXR.pc"
|
||||
RESULT_VARIABLE PKG_CONFIG_PROCESS
|
||||
OUTPUT_VARIABLE OPENEXR_VERSION
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
|
||||
if(NOT PKG_CONFIG_PROCESS EQUAL 0)
|
||||
SET(OPENEXR_VERSION "Unknown")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
if(NOT OPENEXR_VERSION)
|
||||
SET(OPENEXR_VERSION "Unknown")
|
||||
endif()
|
||||
ELSE()
|
||||
IF(OPENEXR_FIND_REQUIRED)
|
||||
MESSAGE(FATAL_ERROR "Could not find OpenEXR library")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
OPENEXR_INCLUDE_PATHS
|
||||
OPENEXR_LIBRARIES
|
||||
OPENEXR_ILMIMF_LIBRARY
|
||||
OPENEXR_IMATH_LIBRARY
|
||||
OPENEXR_IEX_LIBRARY
|
||||
OPENEXR_HALF_LIBRARY
|
||||
OPENEXR_ILMTHREAD_LIBRARY)
|
|
@ -0,0 +1,76 @@
|
|||
# If protobuf is found - libprotobuf target is available
|
||||
|
||||
set(HAVE_PROTOBUF FALSE)
|
||||
|
||||
if(NOT WITH_PROTOBUF)
|
||||
return()
|
||||
endif()
|
||||
|
||||
ocv_option(BUILD_PROTOBUF "Force to build libprotobuf from sources" ON)
|
||||
ocv_option(PROTOBUF_UPDATE_FILES "Force rebuilding .proto files (protoc should be available)" OFF)
|
||||
|
||||
function(get_protobuf_version version include)
|
||||
file(STRINGS "${include}/google/protobuf/stubs/common.h" ver REGEX "#define GOOGLE_PROTOBUF_VERSION [0-9]+")
|
||||
string(REGEX MATCHALL "[0-9]+" ver ${ver})
|
||||
math(EXPR major "${ver} / 1000000")
|
||||
math(EXPR minor "${ver} / 1000 % 1000")
|
||||
math(EXPR patch "${ver} % 1000")
|
||||
set(${version} "${major}.${minor}.${patch}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
if(BUILD_PROTOBUF)
|
||||
add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/protobuf")
|
||||
set(HAVE_PROTOBUF TRUE)
|
||||
else()
|
||||
unset(Protobuf_VERSION CACHE)
|
||||
find_package(Protobuf QUIET)
|
||||
|
||||
# Backwards compatibility
|
||||
# Define camel case versions of input variables
|
||||
foreach(UPPER
|
||||
PROTOBUF_FOUND
|
||||
PROTOBUF_LIBRARY
|
||||
PROTOBUF_INCLUDE_DIR
|
||||
PROTOBUF_VERSION
|
||||
)
|
||||
if (DEFINED ${UPPER})
|
||||
string(REPLACE "PROTOBUF_" "Protobuf_" Camel ${UPPER})
|
||||
if (NOT DEFINED ${Camel})
|
||||
set(${Camel} ${${UPPER}})
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
# end of compatibility block
|
||||
|
||||
if(Protobuf_FOUND)
|
||||
if(TARGET protobuf::libprotobuf)
|
||||
add_library(libprotobuf INTERFACE IMPORTED)
|
||||
set_target_properties(libprotobuf PROPERTIES
|
||||
INTERFACE_LINK_LIBRARIES protobuf::libprotobuf
|
||||
)
|
||||
else()
|
||||
add_library(libprotobuf UNKNOWN IMPORTED)
|
||||
set_target_properties(libprotobuf PROPERTIES
|
||||
IMPORTED_LOCATION "${Protobuf_LIBRARY}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${Protobuf_INCLUDE_DIR}"
|
||||
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${Protobuf_INCLUDE_DIR}"
|
||||
)
|
||||
get_protobuf_version(Protobuf_VERSION "${Protobuf_INCLUDE_DIR}")
|
||||
endif()
|
||||
set(HAVE_PROTOBUF TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(HAVE_PROTOBUF AND PROTOBUF_UPDATE_FILES AND NOT COMMAND PROTOBUF_GENERATE_CPP)
|
||||
find_package(Protobuf QUIET)
|
||||
if(NOT COMMAND PROTOBUF_GENERATE_CPP)
|
||||
message(FATAL_ERROR "PROTOBUF_GENERATE_CPP command is not available")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(HAVE_PROTOBUF)
|
||||
list(APPEND CUSTOM_STATUS protobuf)
|
||||
list(APPEND CUSTOM_STATUS_protobuf " Protobuf:"
|
||||
BUILD_PROTOBUF THEN "build (${Protobuf_VERSION})"
|
||||
ELSE "${Protobuf_LIBRARY} (${Protobuf_VERSION})")
|
||||
endif()
|
|
@ -0,0 +1,21 @@
|
|||
# Main variables:
|
||||
# HAVE_VA for conditional compilation OpenCV with/without libva
|
||||
|
||||
if(UNIX AND NOT ANDROID)
|
||||
find_path(
|
||||
VA_INCLUDE_DIR
|
||||
NAMES va/va.h
|
||||
PATHS "/usr/include"
|
||||
PATH_SUFFIXES include
|
||||
DOC "Path to libva headers")
|
||||
endif()
|
||||
|
||||
if(VA_INCLUDE_DIR)
|
||||
set(HAVE_VA TRUE)
|
||||
if(NOT DEFINED VA_LIBRARIES)
|
||||
set(VA_LIBRARIES "va" "va-drm")
|
||||
endif()
|
||||
else()
|
||||
set(HAVE_VA FALSE)
|
||||
message(WARNING "libva installation is not found.")
|
||||
endif()
|
|
@ -0,0 +1,32 @@
|
|||
# Main variables:
|
||||
# VA_INTEL_IOCL_INCLUDE_DIR to use VA_INTEL
|
||||
# HAVE_VA_INTEL for conditional compilation OpenCV with/without VA_INTEL
|
||||
|
||||
# VA_INTEL_IOCL_ROOT - root of Intel OCL installation
|
||||
|
||||
if(UNIX AND NOT ANDROID)
|
||||
if($ENV{VA_INTEL_IOCL_ROOT})
|
||||
set(VA_INTEL_IOCL_ROOT $ENV{VA_INTEL_IOCL_ROOT})
|
||||
else()
|
||||
set(VA_INTEL_IOCL_ROOT "/opt/intel/opencl")
|
||||
endif()
|
||||
|
||||
find_path(
|
||||
VA_INTEL_IOCL_INCLUDE_DIR
|
||||
NAMES CL/va_ext.h
|
||||
PATHS ${VA_INTEL_IOCL_ROOT}
|
||||
PATH_SUFFIXES include
|
||||
DOC "Path to Intel OpenCL headers")
|
||||
endif()
|
||||
|
||||
if(VA_INTEL_IOCL_INCLUDE_DIR)
|
||||
set(HAVE_VA_INTEL TRUE)
|
||||
if(NOT DEFINED VA_INTEL_LIBRARIES)
|
||||
set(VA_INTEL_LIBRARIES "va" "va-drm")
|
||||
endif()
|
||||
else()
|
||||
set(HAVE_VA_INTEL FALSE)
|
||||
message(WARNING "Intel OpenCL installation is not found.")
|
||||
endif()
|
||||
|
||||
mark_as_advanced(FORCE VA_INTEL_IOCL_INCLUDE_DIR)
|
|
@ -0,0 +1,33 @@
|
|||
#=============================================================================
|
||||
# Find WebP library
|
||||
#=============================================================================
|
||||
# Find the native WebP headers and libraries.
|
||||
#
|
||||
# WEBP_INCLUDE_DIRS - where to find webp/decode.h, etc.
|
||||
# WEBP_LIBRARIES - List of libraries when using webp.
|
||||
# WEBP_FOUND - True if webp is found.
|
||||
#=============================================================================
|
||||
|
||||
# Look for the header file.
|
||||
|
||||
unset(WEBP_FOUND)
|
||||
|
||||
FIND_PATH(WEBP_INCLUDE_DIR NAMES webp/decode.h)
|
||||
|
||||
if(NOT WEBP_INCLUDE_DIR)
|
||||
unset(WEBP_FOUND)
|
||||
else()
|
||||
MARK_AS_ADVANCED(WEBP_INCLUDE_DIR)
|
||||
|
||||
# Look for the library.
|
||||
FIND_LIBRARY(WEBP_LIBRARY NAMES webp)
|
||||
MARK_AS_ADVANCED(WEBP_LIBRARY)
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set WEBP_FOUND to TRUE if
|
||||
# all listed variables are TRUE
|
||||
INCLUDE(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(WebP DEFAULT_MSG WEBP_LIBRARY WEBP_INCLUDE_DIR)
|
||||
|
||||
SET(WEBP_LIBRARIES ${WEBP_LIBRARY})
|
||||
SET(WEBP_INCLUDE_DIRS ${WEBP_INCLUDE_DIR})
|
||||
endif()
|
|
@ -0,0 +1,49 @@
|
|||
if (NOT GENERATE_ABI_DESCRIPTOR)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(filename "opencv_abi.xml")
|
||||
set(path1 "${CMAKE_BINARY_DIR}/${filename}")
|
||||
|
||||
set(modules "${OPENCV_MODULES_PUBLIC}")
|
||||
ocv_list_filterout(modules "opencv_ts")
|
||||
|
||||
message(STATUS "Generating ABI compliance checker configuration: ${filename}")
|
||||
|
||||
if (OPENCV_VCSVERSION AND NOT OPENCV_VCSVERSION STREQUAL "unknown")
|
||||
set(OPENCV_ABI_VERSION "${OPENCV_VCSVERSION}")
|
||||
else()
|
||||
set(OPENCV_ABI_VERSION "${OPENCV_VERSION}")
|
||||
endif()
|
||||
|
||||
# Headers
|
||||
set(OPENCV_ABI_HEADERS "{RELPATH}/${OPENCV_INCLUDE_INSTALL_PATH}")
|
||||
|
||||
# Libraries
|
||||
set(OPENCV_ABI_LIBRARIES "{RELPATH}/${OPENCV_LIB_INSTALL_PATH}")
|
||||
|
||||
foreach(mod ${OPENCV_MODULES_BUILD})
|
||||
string(REGEX REPLACE "^opencv_" "" mod "${mod}")
|
||||
if(NOT OPENCV_MODULE_opencv_${mod}_CLASS STREQUAL "PUBLIC"
|
||||
OR NOT "${OPENCV_MODULE_opencv_${mod}_LOCATION}" STREQUAL "${OpenCV_SOURCE_DIR}/modules/${mod}" # opencv_contrib
|
||||
)
|
||||
# headers
|
||||
foreach(h ${OPENCV_MODULE_opencv_${mod}_HEADERS})
|
||||
file(RELATIVE_PATH h "${OPENCV_MODULE_opencv_${mod}_LOCATION}/include" "${h}")
|
||||
list(APPEND OPENCV_ABI_SKIP_HEADERS "${h}")
|
||||
endforeach()
|
||||
# libraries
|
||||
if(TARGET opencv_${mod}) # opencv_world
|
||||
list(APPEND OPENCV_ABI_SKIP_LIBRARIES "\$<TARGET_FILE_NAME:opencv_${mod}>")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
string(REPLACE ";" "\n " OPENCV_ABI_SKIP_HEADERS "${OPENCV_ABI_SKIP_HEADERS}")
|
||||
string(REPLACE ";" "\n " OPENCV_ABI_SKIP_LIBRARIES "${OPENCV_ABI_SKIP_LIBRARIES}")
|
||||
|
||||
# Options
|
||||
set(OPENCV_ABI_GCC_OPTIONS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_RELEASE} -DOPENCV_ABI_CHECK=1 -DCV_DNN_DONT_ADD_INLINE_NS=1")
|
||||
string(REGEX REPLACE "([^ ]) +([^ ])" "\\1\\n \\2" OPENCV_ABI_GCC_OPTIONS "${OPENCV_ABI_GCC_OPTIONS}")
|
||||
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/templates/opencv_abi.xml.in" "${path1}.base")
|
||||
file(GENERATE OUTPUT "${path1}" INPUT "${path1}.base")
|
|
@ -0,0 +1,81 @@
|
|||
if(ANDROID)
|
||||
# --------------------------------------------------------------------------------------------
|
||||
# Installation for Android ndk-build makefile: OpenCV.mk
|
||||
# Part 1/2: ${BIN_DIR}/OpenCV.mk -> For use *without* "make install"
|
||||
# Part 2/2: ${BIN_DIR}/unix-install/OpenCV.mk -> For use with "make install"
|
||||
# -------------------------------------------------------------------------------------------
|
||||
|
||||
# build type
|
||||
if(BUILD_SHARED_LIBS)
|
||||
set(OPENCV_LIBTYPE_CONFIGMAKE "SHARED")
|
||||
else()
|
||||
set(OPENCV_LIBTYPE_CONFIGMAKE "STATIC")
|
||||
endif()
|
||||
|
||||
if(BUILD_FAT_JAVA_LIB)
|
||||
set(OPENCV_LIBTYPE_CONFIGMAKE "SHARED")
|
||||
set(OPENCV_STATIC_LIBTYPE_CONFIGMAKE "STATIC")
|
||||
else()
|
||||
set(OPENCV_STATIC_LIBTYPE_CONFIGMAKE ${OPENCV_LIBTYPE_CONFIGMAKE})
|
||||
endif()
|
||||
|
||||
# build the list of opencv libs and dependencies for all modules
|
||||
ocv_get_all_libs(OPENCV_MODULES OPENCV_EXTRA_COMPONENTS OPENCV_3RDPARTY_COMPONENTS)
|
||||
|
||||
# list -> string
|
||||
foreach(_var OPENCV_MODULES OPENCV_EXTRA_COMPONENTS OPENCV_3RDPARTY_COMPONENTS)
|
||||
set(var "${_var}_CONFIGMAKE")
|
||||
set(${var} "")
|
||||
foreach(lib ${${_var}})
|
||||
set(lib_name "${lib}")
|
||||
if(TARGET ${lib})
|
||||
get_target_property(_output ${lib} IMPORTED_LOCATION)
|
||||
if(NOT _output)
|
||||
get_target_property(output_name ${lib} OUTPUT_NAME)
|
||||
if(output_name)
|
||||
set(lib_name "${output_name}")
|
||||
endif()
|
||||
else()
|
||||
ocv_get_libname(lib_name "${_output}")
|
||||
endif()
|
||||
endif()
|
||||
set(${var} "${${var}} ${lib_name}")
|
||||
endforeach()
|
||||
string(STRIP "${${var}}" ${var})
|
||||
endforeach()
|
||||
|
||||
# replace 'opencv_<module>' -> '<module>''
|
||||
string(REPLACE "opencv_" "" OPENCV_MODULES_CONFIGMAKE "${OPENCV_MODULES_CONFIGMAKE}")
|
||||
|
||||
if(BUILD_FAT_JAVA_LIB)
|
||||
set(OPENCV_LIBS_CONFIGMAKE java4)
|
||||
else()
|
||||
set(OPENCV_LIBS_CONFIGMAKE "${OPENCV_MODULES_CONFIGMAKE}")
|
||||
endif()
|
||||
|
||||
# -------------------------------------------------------------------------------------------
|
||||
# Part 1/2: ${BIN_DIR}/OpenCV.mk -> For use *without* "make install"
|
||||
# -------------------------------------------------------------------------------------------
|
||||
set(OPENCV_INCLUDE_DIRS_CONFIGCMAKE "\"${OPENCV_CONFIG_FILE_INCLUDE_DIR}\" \"${OpenCV_SOURCE_DIR}/include\" \"${OpenCV_SOURCE_DIR}/include/opencv\"")
|
||||
set(OPENCV_BASE_INCLUDE_DIR_CONFIGCMAKE "\"${OpenCV_SOURCE_DIR}\"")
|
||||
set(OPENCV_LIBS_DIR_CONFIGCMAKE "\$(OPENCV_THIS_DIR)/lib/\$(OPENCV_TARGET_ARCH_ABI)")
|
||||
set(OPENCV_LIBS_ARCHIVE_DIR_CONFIGCMAKE "\$(OPENCV_THIS_DIR)/lib/\$(OPENCV_TARGET_ARCH_ABI)")
|
||||
set(OPENCV_3RDPARTY_LIBS_DIR_CONFIGCMAKE "\$(OPENCV_THIS_DIR)/3rdparty/lib/\$(OPENCV_TARGET_ARCH_ABI)")
|
||||
|
||||
configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCV.mk.in" "${CMAKE_BINARY_DIR}/OpenCV.mk" @ONLY)
|
||||
configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCV-abi.mk.in" "${CMAKE_BINARY_DIR}/OpenCV-${ANDROID_NDK_ABI_NAME}.mk" @ONLY)
|
||||
|
||||
# -------------------------------------------------------------------------------------------
|
||||
# Part 2/2: ${BIN_DIR}/unix-install/OpenCV.mk -> For use with "make install"
|
||||
# -------------------------------------------------------------------------------------------
|
||||
set(OPENCV_INCLUDE_DIRS_CONFIGCMAKE "\"\$(LOCAL_PATH)/\$(OPENCV_THIS_DIR)/include/opencv\" \"\$(LOCAL_PATH)/\$(OPENCV_THIS_DIR)/include\"")
|
||||
set(OPENCV_BASE_INCLUDE_DIR_CONFIGCMAKE "")
|
||||
set(OPENCV_LIBS_DIR_CONFIGCMAKE "\$(OPENCV_THIS_DIR)/../libs/\$(OPENCV_TARGET_ARCH_ABI)")
|
||||
set(OPENCV_LIBS_ARCHIVE_DIR_CONFIGCMAKE "\$(OPENCV_THIS_DIR)/../staticlibs/\$(OPENCV_TARGET_ARCH_ABI)")
|
||||
set(OPENCV_3RDPARTY_LIBS_DIR_CONFIGCMAKE "\$(OPENCV_THIS_DIR)/../3rdparty/libs/\$(OPENCV_TARGET_ARCH_ABI)")
|
||||
|
||||
configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCV.mk.in" "${CMAKE_BINARY_DIR}/unix-install/OpenCV.mk" @ONLY)
|
||||
configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/OpenCV-abi.mk.in" "${CMAKE_BINARY_DIR}/unix-install/OpenCV-${ANDROID_NDK_ABI_NAME}.mk" @ONLY)
|
||||
install(FILES ${CMAKE_BINARY_DIR}/unix-install/OpenCV.mk DESTINATION ${OPENCV_CONFIG_INSTALL_PATH} COMPONENT dev)
|
||||
install(FILES ${CMAKE_BINARY_DIR}/unix-install/OpenCV-${ANDROID_NDK_ABI_NAME}.mk DESTINATION ${OPENCV_CONFIG_INSTALL_PATH} COMPONENT dev)
|
||||
endif(ANDROID)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue