Merge remote-tracking branch 'remotes/origin/master' into tvl1_chambolle

Conflicts:
	modules/video/doc/motion_analysis_and_object_tracking.rst
This commit is contained in:
Ernest Galbrun 2014-08-17 22:08:12 +02:00
commit fae69df9a9
601 changed files with 38192 additions and 444389 deletions

View File

@ -162,6 +162,7 @@ OCV_OPTION(WITH_OPENCLAMDBLAS "Include AMD OpenCL BLAS library support" ON
OCV_OPTION(WITH_DIRECTX "Include DirectX support" ON IF WIN32 )
OCV_OPTION(WITH_INTELPERC "Include Intel Perceptual Computing support" OFF IF WIN32 )
OCV_OPTION(WITH_IPP_A "Include Intel IPP_A support" OFF IF (MSVC OR X86 OR X86_64) )
OCV_OPTION(WITH_GDAL "Include GDAL Support" OFF IF (NOT ANDROID AND NOT IOS) )
# OpenCV build components
# ===================================================
@ -337,6 +338,9 @@ if(DEFINED CMAKE_DEBUG_POSTFIX)
set(OPENCV_DEBUG_POSTFIX "${CMAKE_DEBUG_POSTFIX}")
endif()
if(INSTALL_CREATE_DISTRIB AND BUILD_SHARED_LIBS AND NOT DEFINED BUILD_opencv_world)
set(BUILD_opencv_world ON CACHE INTERNAL "")
endif()
# ----------------------------------------------------------------------------
# Path for build/platform -specific headers
@ -554,7 +558,6 @@ endif()
# ----------------------------------------------------------------------------
# Finalization: generate configuration-based files
# ----------------------------------------------------------------------------
ocv_track_build_dependencies()
# Generate platform-dependent and configuration-dependent headers
include(cmake/OpenCVGenHeaders.cmake)
@ -811,6 +814,12 @@ else()
status(" OpenEXR:" "NO")
endif()
if( WITH_GDAL )
status(" GDAL:" GDAL_FOUND THEN "${GDAL_LIBRARY}")
else()
status(" GDAL:" "NO")
endif()
# ========================== VIDEO IO ==========================
status("")
status(" Video I/O:")
@ -999,18 +1008,34 @@ endif()
# ========================== python ==========================
status("")
status(" Python:")
status(" Interpreter:" PYTHONINTERP_FOUND THEN "${PYTHON_EXECUTABLE} (ver ${PYTHON_VERSION_STRING})" ELSE NO)
if(BUILD_opencv_python)
if(PYTHONLIBS_VERSION_STRING)
status(" Libraries:" HAVE_opencv_python THEN "${PYTHON_LIBRARIES} (ver ${PYTHONLIBS_VERSION_STRING})" ELSE NO)
status(" Python 2:")
status(" Interpreter:" PYTHON2INTERP_FOUND THEN "${PYTHON2_EXECUTABLE} (ver ${PYTHON2_VERSION_STRING})" ELSE NO)
if(BUILD_opencv_python2)
if(PYTHON2LIBS_VERSION_STRING)
status(" Libraries:" HAVE_opencv_python2 THEN "${PYTHON2_LIBRARIES} (ver ${PYTHON2LIBS_VERSION_STRING})" ELSE NO)
else()
status(" Libraries:" HAVE_opencv_python THEN "${PYTHON_LIBRARIES}" ELSE NO)
status(" Libraries:" HAVE_opencv_python2 THEN "${PYTHON2_LIBRARIES}" ELSE NO)
endif()
status(" numpy:" PYTHON_NUMPY_INCLUDE_DIRS THEN "${PYTHON_NUMPY_INCLUDE_DIRS} (ver ${PYTHON_NUMPY_VERSION})" ELSE "NO (Python wrappers can not be generated)")
status(" packages path:" PYTHON_EXECUTABLE THEN "${PYTHON_PACKAGES_PATH}" ELSE "-")
status(" numpy:" PYTHON2_NUMPY_INCLUDE_DIRS THEN "${PYTHON2_NUMPY_INCLUDE_DIRS} (ver ${PYTHON2_NUMPY_VERSION})" ELSE "NO (Python wrappers can not be generated)")
status(" packages path:" PYTHON2_EXECUTABLE THEN "${PYTHON2_PACKAGES_PATH}" ELSE "-")
endif()
status("")
status(" Python 3:")
status(" Interpreter:" PYTHON3INTERP_FOUND THEN "${PYTHON3_EXECUTABLE} (ver ${PYTHON3_VERSION_STRING})" ELSE NO)
if(BUILD_opencv_python3)
if(PYTHON3LIBS_VERSION_STRING)
status(" Libraries:" HAVE_opencv_python3 THEN "${PYTHON3_LIBRARIES} (ver ${PYTHON3LIBS_VERSION_STRING})" ELSE NO)
else()
status(" Libraries:" HAVE_opencv_python3 THEN "${PYTHON3_LIBRARIES}" ELSE NO)
endif()
status(" numpy:" PYTHON3_NUMPY_INCLUDE_DIRS THEN "${PYTHON3_NUMPY_INCLUDE_DIRS} (ver ${PYTHON3_NUMPY_VERSION})" ELSE "NO (Python3 wrappers can not be generated)")
status(" packages path:" PYTHON3_EXECUTABLE THEN "${PYTHON3_PACKAGES_PATH}" ELSE "-")
endif()
status("")
status(" Python (for build):" PYTHON_DEFAULT_AVAILABLE THEN "${PYTHON_DEFAULT_EXECUTABLE}" ELSE NO)
# ========================== java ==========================
status("")
status(" Java:")

View File

@ -1,4 +1,4 @@
set(OPENCV_TRAINCASCADE_DEPS opencv_core opencv_ml opencv_imgproc opencv_photo opencv_objdetect opencv_imgcodecs opencv_videoio opencv_highgui opencv_calib3d opencv_video opencv_features2d)
set(OPENCV_TRAINCASCADE_DEPS opencv_core opencv_imgproc opencv_objdetect opencv_imgcodecs opencv_highgui opencv_calib3d opencv_features2d)
ocv_check_dependencies(${OPENCV_TRAINCASCADE_DEPS})
if(NOT OCV_DEPENDENCIES_FOUND)
@ -6,21 +6,18 @@ if(NOT OCV_DEPENDENCIES_FOUND)
endif()
project(traincascade)
ocv_include_directories("${CMAKE_CURRENT_SOURCE_DIR}" "${OpenCV_SOURCE_DIR}/include/opencv")
ocv_include_modules(${OPENCV_TRAINCASCADE_DEPS})
set(traincascade_files traincascade.cpp
cascadeclassifier.cpp cascadeclassifier.h
boost.cpp boost.h features.cpp traincascade_features.h
haarfeatures.cpp haarfeatures.h
lbpfeatures.cpp lbpfeatures.h
HOGfeatures.cpp HOGfeatures.h
imagestorage.cpp imagestorage.h)
set(the_target opencv_traincascade)
add_executable(${the_target} ${traincascade_files})
target_link_libraries(${the_target} ${OPENCV_TRAINCASCADE_DEPS})
ocv_target_include_directories(${the_target} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}" "${OpenCV_SOURCE_DIR}/include/opencv")
ocv_target_include_modules(${the_target} ${OPENCV_TRAINCASCADE_DEPS})
file(GLOB SRCS *.cpp)
file(GLOB HDRS *.h*)
set(traincascade_files ${SRCS} ${HDRS})
ocv_add_executable(${the_target} ${traincascade_files})
ocv_target_link_libraries(${the_target} ${OPENCV_TRAINCASCADE_DEPS})
set_target_properties(${the_target} PROPERTIES
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"

View File

@ -187,11 +187,11 @@ void CvHOGEvaluator::integralHistogram(const Mat &img, vector<Mat> &histogram, M
for( y = 0; y < gradSize.height; y++ )
{
const uchar* currPtr = img.data + img.step*ymap[y];
const uchar* prevPtr = img.data + img.step*ymap[y-1];
const uchar* nextPtr = img.data + img.step*ymap[y+1];
float* gradPtr = (float*)grad.ptr(y);
uchar* qanglePtr = (uchar*)qangle.ptr(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++ )
{
@ -226,9 +226,9 @@ void CvHOGEvaluator::integralHistogram(const Mat &img, vector<Mat> &histogram, M
int magStep = (int)( grad.step / sizeof(float) );
for( binIdx = 0; binIdx < nbins; binIdx++ )
{
histBuf = (float*)histogram[binIdx].data;
magBuf = (const float*)grad.data;
binsBuf = (const uchar*)qangle.data;
histBuf = histogram[binIdx].ptr<float>();
magBuf = grad.ptr<float>();
binsBuf = qangle.ptr();
memset( histBuf, 0, histSize.width * sizeof(histBuf[0]) );
histBuf += histStep + 1;

View File

@ -2,7 +2,7 @@
#define _OPENCV_BOOST_H_
#include "traincascade_features.h"
#include "ml.h"
#include "old_ml.hpp"
struct CvCascadeBoostParams : CvBoostParams
{

View File

@ -7,8 +7,6 @@
#include "lbpfeatures.h"
#include "HOGfeatures.h" //new
#include "boost.h"
#include "cv.h"
#include "cxcore.h"
#define CC_CASCADE_FILENAME "cascade.xml"
#define CC_PARAMS_FILENAME "params.xml"

View File

@ -13,9 +13,9 @@ float calcNormFactor( const Mat& sum, const Mat& sqSum )
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 = (const int*)sum.data;
const int *sp = sum.ptr<int>();
int valSum = sp[p0] - sp[p1] - sp[p2] + sp[p3];
const double *sqp = (const double *)sqSum.data;
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) );
}

View File

@ -98,7 +98,7 @@ bool CvCascadeImageReader::NegReader::get( Mat& _img )
return false;
Mat mat( winSize.height, winSize.width, CV_8UC1,
(void*)(img.data + point.y * img.step + point.x * img.elemSize()), img.step );
(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 )

2165
apps/traincascade/old_ml.hpp Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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, filles 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

View File

@ -1,6 +1,4 @@
#include "opencv2/core.hpp"
#include "cv.h"
#include "cascadeclassifier.h"
using namespace std;

View File

@ -2,9 +2,6 @@
#define _OPENCV_FEATURES_H_
#include "imagestorage.h"
#include "cxcore.h"
#include "cv.h"
#include "ml.h"
#include <stdio.h>
#define FEATURES "features"

View File

@ -280,9 +280,6 @@ macro(add_android_project target path)
string(REGEX REPLACE "LOCAL_MODULE[ ]*:=[ ]*([a-zA-Z_][a-zA-Z_0-9]*)[ ]*" "\\1" JNI_LIB_NAME "${JNI_LIB_NAME}")
if(JNI_LIB_NAME)
ocv_include_modules_recurse(${android_proj_NATIVE_DEPS})
ocv_include_directories("${path}/jni")
if(NATIVE_APP_GLUE)
include_directories(${ANDROID_NDK}/sources/android/native_app_glue)
list(APPEND android_proj_jni_files ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c)
@ -291,7 +288,9 @@ macro(add_android_project target path)
endif()
add_library(${JNI_LIB_NAME} MODULE ${android_proj_jni_files})
target_link_libraries(${JNI_LIB_NAME} ${OPENCV_LINKER_LIBS} ${android_proj_NATIVE_DEPS})
ocv_target_include_modules_recurse(${JNI_LIB_NAME} ${android_proj_NATIVE_DEPS})
ocv_target_include_directories(${JNI_LIB_NAME} "${path}/jni")
ocv_target_link_libraries(${JNI_LIB_NAME} ${OPENCV_LINKER_LIBS} ${android_proj_NATIVE_DEPS})
set_target_properties(${JNI_LIB_NAME} PROPERTIES
OUTPUT_NAME "${JNI_LIB_NAME}"

View File

@ -188,6 +188,8 @@ if(CUDA_FOUND)
# 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}}")
endforeach()
if(BUILD_SHARED_LIBS)

View File

@ -1,101 +1,240 @@
if(WIN32 AND NOT PYTHON_EXECUTABLE)
# 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} 2.7 "${MIN_VER_PYTHON}")
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()
find_host_package(PythonInterp 2.7)
if(NOT PYTHONINTERP_FOUND)
find_host_package(PythonInterp "${MIN_VER_PYTHON}")
# 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)
ocv_check_environment_variables(${executable})
if(${executable})
set(PYTHON_EXECUTABLE "${${executable}}")
endif()
if(WIN32 AND NOT ${executable})
# 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(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()
find_host_package(PythonInterp "${preferred_version}")
if(NOT PYTHONINTERP_FOUND)
find_host_package(PythonInterp "${min_version}")
endif()
if(PYTHONINTERP_FOUND)
# 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})
# 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 IOS)
ocv_check_environment_variables(${library_env} ${include_dir_env})
if(${library})
set(PYTHON_LIBRARY "${${library_env}}")
endif()
if(${include_dir})
set(PYTHON_INCLUDE_DIR "${${include_dir_env}}")
endif()
# not using _version_string here, because it might not conform to the CMake version format
find_host_package(PythonLibs "${_version_major_minor}.${_version_patch}" EXACT)
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})
# Clear find_host_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()
if(EXISTS "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}/${${packages_path}}")
set(_packages_path "lib${LIB_SUFFIX}/${_packages_path}")
else()
set(_packages_path "lib/${_packages_path}")
endif()
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")
message(STATUS " PYTHON2_NUMPY_INCLUDE_DIRS")
message(STATUS " PYTHON3_INCLUDE_PATH")
message(STATUS " PYTHON3_LIBRARIES")
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}" PARENT_SCOPE)
set(${executable} "${_executable}" CACHE FILEPATH "Path to Python interpretor")
set(${version_string} "${_version_string}" PARENT_SCOPE)
set(${version_major} "${_version_major}" PARENT_SCOPE)
set(${version_minor} "${_version_minor}" PARENT_SCOPE)
set(${libs_found} "${_libs_found}" PARENT_SCOPE)
set(${libs_version_string} "${_libs_version_string}" PARENT_SCOPE)
set(${libraries} "${_libraries}" PARENT_SCOPE)
set(${library} "${_library}" CACHE FILEPATH "Path to Python library")
set(${debug_libraries} "${_debug_libraries}" PARENT_SCOPE)
set(${debug_library} "${_debug_library}" CACHE FILEPATH "Path to Python debug")
set(${include_path} "${_include_path}" PARENT_SCOPE)
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}" PARENT_SCOPE)
endfunction(find_python)
find_python(2.7 "${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)
find_python(3.4 "${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)
# Use Python 2 as default Python interpreter
if(PYTHON2LIBS_FOUND)
set(PYTHON_DEFAULT_AVAILABLE "TRUE")
set(PYTHON_DEFAULT_EXECUTABLE "${PYTHON2_EXECUTABLE}")
endif()
unset(HAVE_SPHINX CACHE)
if(PYTHONINTERP_FOUND)
set(PYTHON_VERSION_MAJOR_MINOR "${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}")
if(NOT ANDROID AND NOT IOS)
ocv_check_environment_variables(PYTHON_LIBRARY PYTHON_INCLUDE_DIR)
# not using PYTHON_VERSION_STRING here, because it might not conform to the CMake version format
find_host_package(PythonLibs "${PYTHON_VERSION_MAJOR_MINOR}.${PYTHON_VERSION_PATCH}" EXACT)
endif()
if(NOT ANDROID AND NOT IOS)
if(CMAKE_HOST_UNIX)
execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "from distutils.sysconfig import *; print(get_python_lib())"
RESULT_VARIABLE PYTHON_CVPY_PROCESS
OUTPUT_VARIABLE PYTHON_STD_PACKAGES_PATH
OUTPUT_STRIP_TRAILING_WHITESPACE)
if("${PYTHON_STD_PACKAGES_PATH}" MATCHES "site-packages")
set(_PYTHON_PACKAGES_PATH "python${PYTHON_VERSION_MAJOR_MINOR}/site-packages")
else() #debian based assumed, install to the dist-packages.
set(_PYTHON_PACKAGES_PATH "python${PYTHON_VERSION_MAJOR_MINOR}/dist-packages")
endif()
if(EXISTS "${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX}/${PYTHON_PACKAGES_PATH}")
set(_PYTHON_PACKAGES_PATH "lib${LIB_SUFFIX}/${_PYTHON_PACKAGES_PATH}")
else()
set(_PYTHON_PACKAGES_PATH "lib/${_PYTHON_PACKAGES_PATH}")
endif()
elseif(CMAKE_HOST_WIN32)
get_filename_component(PYTHON_PATH "${PYTHON_EXECUTABLE}" PATH)
file(TO_CMAKE_PATH "${PYTHON_PATH}" PYTHON_PATH)
if(NOT EXISTS "${PYTHON_PATH}/Lib/site-packages")
unset(PYTHON_PATH)
get_filename_component(PYTHON_PATH "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${PYTHON_VERSION_MAJOR_MINOR}\\InstallPath]" ABSOLUTE)
if(NOT PYTHON_PATH)
get_filename_component(PYTHON_PATH "[HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${PYTHON_VERSION_MAJOR_MINOR}\\InstallPath]" ABSOLUTE)
endif()
file(TO_CMAKE_PATH "${PYTHON_PATH}" PYTHON_PATH)
endif()
set(_PYTHON_PACKAGES_PATH "${PYTHON_PATH}/Lib/site-packages")
endif()
SET(PYTHON_PACKAGES_PATH "${_PYTHON_PACKAGES_PATH}" CACHE PATH "Where to install the python packages.")
if(NOT PYTHON_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 " PYTHON_INCLUDE_PATH")
message(STATUS " PYTHON_LIBRARIES")
message(STATUS " PYTHON_NUMPY_INCLUDE_DIRS")
else()
# Attempt to discover the NumPy include directory. If this succeeds, then build python API with NumPy
execute_process(COMMAND "${PYTHON_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 PYTHON_NUMPY_PROCESS
OUTPUT_VARIABLE PYTHON_NUMPY_INCLUDE_DIRS
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT PYTHON_NUMPY_PROCESS EQUAL 0)
unset(PYTHON_NUMPY_INCLUDE_DIRS)
endif()
endif()
endif()
if(PYTHON_NUMPY_INCLUDE_DIRS)
file(TO_CMAKE_PATH "${PYTHON_NUMPY_INCLUDE_DIRS}" _PYTHON_NUMPY_INCLUDE_DIRS)
set(PYTHON_NUMPY_INCLUDE_DIRS ${_PYTHON_NUMPY_INCLUDE_DIRS} CACHE PATH "Path to numpy headers")
if(CMAKE_CROSSCOMPILING)
if(NOT PYTHON_NUMPY_VERSION)
set(PYTHON_NUMPY_VERSION "undefined - cannot be probed because of the cross-compilation")
endif()
else()
execute_process(COMMAND "${PYTHON_EXECUTABLE}" -c "import numpy; print(numpy.version.version)"
RESULT_VARIABLE PYTHON_NUMPY_PROCESS
OUTPUT_VARIABLE PYTHON_NUMPY_VERSION
OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()
endif()
endif(NOT ANDROID AND NOT IOS)
endif()
if(BUILD_DOCS)
find_host_program(SPHINX_BUILD sphinx-build)
find_host_program(PLANTUML plantuml)

View File

@ -198,3 +198,15 @@ if(WITH_OPENEXR)
set(HAVE_OPENEXR YES)
endif()
# --- GDAL (optional) ---
if(WITH_GDAL)
find_package(GDAL)
if(NOT GDAL_FOUND)
ocv_clear_vars(GDAL_LIBRARY GDAL_INCLUDE_DIR)
set(HAVE_GDAL NO)
else()
set(HAVE_GDAL YES)
endif()
endif()

View File

@ -1,5 +1,6 @@
set(MIN_VER_CMAKE 2.8.7)
set(MIN_VER_CUDA 4.2)
set(MIN_VER_PYTHON 2.6)
set(MIN_VER_PYTHON2 2.6)
set(MIN_VER_PYTHON3 3.2)
set(MIN_VER_ZLIB 1.2.3)
set(MIN_VER_GTK 2.18.0)

View File

@ -6,16 +6,19 @@
# Global variables:
#
# OPENCV_MODULE_${the_module}_LOCATION
# OPENCV_MODULE_${the_module}_BINARY_DIR
# OPENCV_MODULE_${the_module}_DESCRIPTION
# OPENCV_MODULE_${the_module}_CLASS - PUBLIC|INTERNAL|BINDINGS
# OPENCV_MODULE_${the_module}_HEADERS
# OPENCV_MODULE_${the_module}_SOURCES
# OPENCV_MODULE_${the_module}_DEPS - final flattened set of module dependencies
# OPENCV_MODULE_${the_module}_DEPS_TO_LINK - differs from above for world build only
# OPENCV_MODULE_${the_module}_DEPS_EXT - non-module dependencies
# OPENCV_MODULE_${the_module}_REQ_DEPS
# OPENCV_MODULE_${the_module}_OPT_DEPS
# OPENCV_MODULE_${the_module}_PRIVATE_REQ_DEPS
# OPENCV_MODULE_${the_module}_PRIVATE_OPT_DEPS
# OPENCV_MODULE_${the_module}_IS_PART_OF_WORLD
# HAVE_${the_module} - for fast check of module availability
# To control the setup of the module you could also set:
@ -53,6 +56,7 @@ foreach(mod ${OPENCV_MODULES_BUILD} ${OPENCV_MODULES_DISABLED_USER} ${OPENCV_MOD
unset(OPENCV_MODULE_${mod}_OPT_DEPS CACHE)
unset(OPENCV_MODULE_${mod}_PRIVATE_REQ_DEPS CACHE)
unset(OPENCV_MODULE_${mod}_PRIVATE_OPT_DEPS CACHE)
unset(OPENCV_MODULE_${mod}_LINK_DEPS CACHE)
endforeach()
# clean modules info which needs to be recalculated
@ -61,6 +65,7 @@ set(OPENCV_MODULES_BUILD "" CACHE INTERNAL "List of OpenCV modules incl
set(OPENCV_MODULES_DISABLED_USER "" CACHE INTERNAL "List of OpenCV modules explicitly disabled by user")
set(OPENCV_MODULES_DISABLED_AUTO "" CACHE INTERNAL "List of OpenCV modules implicitly disabled due to dependencies")
set(OPENCV_MODULES_DISABLED_FORCE "" CACHE INTERNAL "List of OpenCV modules which can not be build in current configuration")
unset(OPENCV_WORLD_MODULES CACHE)
# adds dependencies to OpenCV module
# Usage:
@ -68,6 +73,7 @@ set(OPENCV_MODULES_DISABLED_FORCE "" CACHE INTERNAL "List of OpenCV modules whic
# Notes:
# * <list of dependencies> - can include full names of modules or full pathes to shared/static libraries or cmake targets
macro(ocv_add_dependencies full_modname)
ocv_debug_message("ocv_add_dependencies(" ${full_modname} ${ARGN} ")")
#we don't clean the dependencies here to allow this macro several times for every module
foreach(d "REQUIRED" ${ARGN})
if(d STREQUAL "REQUIRED")
@ -105,6 +111,7 @@ endmacro()
# Example:
# ocv_add_module(yaom INTERNAL opencv_core opencv_highgui opencv_flann OPTIONAL opencv_cuda)
macro(ocv_add_module _name)
ocv_debug_message("ocv_add_module(" ${_name} ${ARGN} ")")
string(TOLOWER "${_name}" name)
string(REGEX REPLACE "^opencv_" "" ${name} "${name}")
set(the_module opencv_${name})
@ -134,6 +141,8 @@ macro(ocv_add_module _name)
set(OPENCV_MODULE_${the_module}_DESCRIPTION "${the_description}" CACHE INTERNAL "Brief description of ${the_module} module")
set(OPENCV_MODULE_${the_module}_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}" CACHE INTERNAL "Location of ${the_module} module sources")
set(OPENCV_MODULE_${the_module}_LINK_DEPS "" CACHE INTERNAL "")
# parse list of dependencies
if("${ARGV1}" STREQUAL "INTERNAL" OR "${ARGV1}" STREQUAL "BINDINGS")
set(OPENCV_MODULE_${the_module}_CLASS "${ARGV1}" CACHE INTERNAL "The category of the module")
@ -150,8 +159,14 @@ macro(ocv_add_module _name)
endif()
# add self to the world dependencies
if(NOT DEFINED OPENCV_MODULE_IS_PART_OF_WORLD AND NOT OPENCV_MODULE_${the_module}_CLASS STREQUAL "BINDINGS" OR OPENCV_MODULE_IS_PART_OF_WORLD)
if((NOT DEFINED OPENCV_MODULE_IS_PART_OF_WORLD AND NOT OPENCV_MODULE_${the_module}_CLASS STREQUAL "BINDINGS"
AND NOT OPENCV_PROCESSING_EXTRA_MODULES)
OR OPENCV_MODULE_IS_PART_OF_WORLD
)
set(OPENCV_MODULE_${the_module}_IS_PART_OF_WORLD ON CACHE INTERNAL "")
ocv_add_dependencies(opencv_world OPTIONAL ${the_module})
else()
set(OPENCV_MODULE_${the_module}_IS_PART_OF_WORLD OFF CACHE INTERNAL "")
endif()
if(BUILD_${the_module})
@ -164,12 +179,15 @@ macro(ocv_add_module _name)
# stop processing of current file
return()
else(OPENCV_INITIAL_PASS)
else()
set(OPENCV_MODULE_${the_module}_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}" CACHE INTERNAL "")
if(NOT BUILD_${the_module})
return() # extra protection from redefinition
endif()
project(${the_module})
endif(OPENCV_INITIAL_PASS)
if((NOT OPENCV_MODULE_${the_module}_IS_PART_OF_WORLD AND NOT ${the_module} STREQUAL opencv_world) OR NOT ${BUILD_opencv_world})
project(${the_module})
endif()
endif()
endmacro()
# excludes module from current configuration
@ -200,7 +218,11 @@ macro(ocv_glob_modules)
# collect modules
set(OPENCV_INITIAL_PASS ON)
set(OPENCV_PROCESSING_EXTRA_MODULES 0)
foreach(__path ${ARGN})
if("${__path}" STREQUAL "EXTRA")
set(OPENCV_PROCESSING_EXTRA_MODULES 1)
endif()
get_filename_component(__path "${__path}" ABSOLUTE)
list(FIND __directories_observed "${__path}" __pathIdx)
@ -222,16 +244,7 @@ macro(ocv_glob_modules)
endif()
list(APPEND __directories_observed "${__modpath}")
if(OCV_MODULE_RELOCATE_ON_INITIAL_PASS)
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${mod}/.${mod}")
file(COPY "${__modpath}/CMakeLists.txt" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/${mod}/.${mod}")
add_subdirectory("${CMAKE_CURRENT_BINARY_DIR}/${mod}/.${mod}" "${CMAKE_CURRENT_BINARY_DIR}/${mod}/.${mod}")
if("${OPENCV_MODULE_opencv_${mod}_LOCATION}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}/${mod}/.${mod}")
set(OPENCV_MODULE_opencv_${mod}_LOCATION "${__modpath}" CACHE PATH "" FORCE)
endif()
else()
add_subdirectory("${__modpath}" "${CMAKE_CURRENT_BINARY_DIR}/${mod}/.${mod}")
endif()
add_subdirectory("${__modpath}" "${CMAKE_CURRENT_BINARY_DIR}/${mod}/.${mod}")
endif()
endforeach()
endif()
@ -244,15 +257,31 @@ macro(ocv_glob_modules)
# create modules
set(OPENCV_INITIAL_PASS OFF PARENT_SCOPE)
set(OPENCV_INITIAL_PASS OFF)
foreach(m ${OPENCV_MODULES_BUILD})
if(m MATCHES "^opencv_")
string(REGEX REPLACE "^opencv_" "" __shortname "${m}")
add_subdirectory("${OPENCV_MODULE_${m}_LOCATION}" "${CMAKE_CURRENT_BINARY_DIR}/${__shortname}")
else()
message(WARNING "Check module name: ${m}")
add_subdirectory("${OPENCV_MODULE_${m}_LOCATION}" "${CMAKE_CURRENT_BINARY_DIR}/${m}")
endif()
endforeach()
if(${BUILD_opencv_world})
add_subdirectory("${OPENCV_MODULE_opencv_world_LOCATION}" "${CMAKE_CURRENT_BINARY_DIR}/world")
foreach(m ${OPENCV_MODULES_BUILD})
if(NOT OPENCV_MODULE_${m}_IS_PART_OF_WORLD AND NOT ${m} STREQUAL opencv_world)
message(STATUS "Processing module ${m}...")
if(m MATCHES "^opencv_")
string(REGEX REPLACE "^opencv_" "" __shortname "${m}")
add_subdirectory("${OPENCV_MODULE_${m}_LOCATION}" "${CMAKE_CURRENT_BINARY_DIR}/${__shortname}")
else()
message(WARNING "Check module name: ${m}")
add_subdirectory("${OPENCV_MODULE_${m}_LOCATION}" "${CMAKE_CURRENT_BINARY_DIR}/${m}")
endif()
endif()
endforeach()
else()
foreach(m ${OPENCV_MODULES_BUILD})
if(m MATCHES "^opencv_")
string(REGEX REPLACE "^opencv_" "" __shortname "${m}")
add_subdirectory("${OPENCV_MODULE_${m}_LOCATION}" "${CMAKE_CURRENT_BINARY_DIR}/${__shortname}")
else()
message(WARNING "Check module name: ${m}")
add_subdirectory("${OPENCV_MODULE_${m}_LOCATION}" "${CMAKE_CURRENT_BINARY_DIR}/${m}")
endif()
endforeach()
endif()
unset(__shortname)
endmacro()
@ -394,11 +423,36 @@ function(__ocv_resolve_dependencies)
__ocv_sort_modules_by_deps(OPENCV_MODULE_${m}_DEPS)
ocv_list_sort(OPENCV_MODULE_${m}_DEPS_EXT)
set(LINK_DEPS ${OPENCV_MODULE_${m}_DEPS})
# process world
if(BUILD_opencv_world)
if(OPENCV_MODULE_${m}_IS_PART_OF_WORLD)
list(APPEND OPENCV_WORLD_MODULES ${m})
endif()
foreach(m2 ${OPENCV_MODULES_BUILD})
if(OPENCV_MODULE_${m2}_IS_PART_OF_WORLD)
if(";${LINK_DEPS};" MATCHES ";${m2};")
list(REMOVE_ITEM LINK_DEPS ${m2})
if(NOT (";${LINK_DEPS};" MATCHES ";opencv_world;") AND NOT (${m} STREQUAL opencv_world))
list(APPEND LINK_DEPS opencv_world)
endif()
endif()
if(${m} STREQUAL opencv_world)
list(APPEND OPENCV_MODULE_opencv_world_DEPS_EXT ${OPENCV_MODULE_${m2}_DEPS_EXT})
endif()
endif()
endforeach()
endif()
set(OPENCV_MODULE_${m}_DEPS ${OPENCV_MODULE_${m}_DEPS} CACHE INTERNAL "Flattened dependencies of ${m} module")
set(OPENCV_MODULE_${m}_DEPS_EXT ${OPENCV_MODULE_${m}_DEPS_EXT} CACHE INTERNAL "Extra dependencies of ${m} module")
set(OPENCV_MODULE_${m}_DEPS_TO_LINK ${LINK_DEPS} CACHE INTERNAL "Flattened dependencies of ${m} module (for linker)")
# message(STATUS " module deps: ${OPENCV_MODULE_${m}_DEPS}")
# message(STATUS " extra deps: ${OPENCV_MODULE_${m}_DEPS_EXT}")
# message(STATUS " module deps of ${m}: ${OPENCV_MODULE_${m}_DEPS}")
# message(STATUS " module link deps of ${m}: ${OPENCV_MODULE_${m}_DEPS_TO_LINK}")
# message(STATUS " extra deps of ${m}: ${OPENCV_MODULE_${m}_DEPS_EXT}")
# message(STATUS "")
endforeach()
__ocv_sort_modules_by_deps(OPENCV_MODULES_BUILD)
@ -406,6 +460,7 @@ function(__ocv_resolve_dependencies)
set(OPENCV_MODULES_PUBLIC ${OPENCV_MODULES_PUBLIC} CACHE INTERNAL "List of OpenCV modules marked for export")
set(OPENCV_MODULES_BUILD ${OPENCV_MODULES_BUILD} CACHE INTERNAL "List of OpenCV modules included into the build")
set(OPENCV_MODULES_DISABLED_AUTO ${OPENCV_MODULES_DISABLED_AUTO} CACHE INTERNAL "List of OpenCV modules implicitly disabled due to dependencies")
set(OPENCV_WORLD_MODULES ${OPENCV_WORLD_MODULES} CACHE INTERNAL "List of OpenCV modules included into the world")
endfunction()
@ -422,18 +477,31 @@ macro(ocv_include_modules)
endforeach()
endmacro()
# setup include paths for the list of passed modules and recursively add dependent modules
macro(ocv_include_modules_recurse)
# setup include paths for the list of passed modules
macro(ocv_target_include_modules target)
foreach(d ${ARGN})
if(d MATCHES "^opencv_" AND HAVE_${d})
if (EXISTS "${OPENCV_MODULE_${d}_LOCATION}/include")
ocv_include_directories("${OPENCV_MODULE_${d}_LOCATION}/include")
endif()
if(OPENCV_MODULE_${d}_DEPS)
ocv_include_modules(${OPENCV_MODULE_${d}_DEPS})
ocv_target_include_directories(${target} "${OPENCV_MODULE_${d}_LOCATION}/include")
endif()
elseif(EXISTS "${d}")
ocv_include_directories("${d}")
ocv_target_include_directories(${target} "${d}")
endif()
endforeach()
endmacro()
# setup include paths for the list of passed modules and recursively add dependent modules
macro(ocv_target_include_modules_recurse target)
foreach(d ${ARGN})
if(d MATCHES "^opencv_" AND HAVE_${d})
if (EXISTS "${OPENCV_MODULE_${d}_LOCATION}/include")
ocv_target_include_directories(${target} "${OPENCV_MODULE_${d}_LOCATION}/include")
endif()
if(OPENCV_MODULE_${d}_DEPS)
ocv_target_include_modules(${target} ${OPENCV_MODULE_${d}_DEPS})
endif()
elseif(EXISTS "${d}")
ocv_target_include_directories(${target} "${d}")
endif()
endforeach()
endmacro()
@ -441,11 +509,12 @@ endmacro()
# setup include path for OpenCV headers for specified module
# ocv_module_include_directories(<extra include directories/extra include modules>)
macro(ocv_module_include_directories)
ocv_include_directories("${OPENCV_MODULE_${the_module}_LOCATION}/include"
"${OPENCV_MODULE_${the_module}_LOCATION}/src"
"${CMAKE_CURRENT_BINARY_DIR}" # for precompiled headers
)
ocv_include_modules(${OPENCV_MODULE_${the_module}_DEPS} ${ARGN})
ocv_target_include_directories(${the_module}
"${OPENCV_MODULE_${the_module}_LOCATION}/include"
"${OPENCV_MODULE_${the_module}_LOCATION}/src"
"${CMAKE_CURRENT_BINARY_DIR}" # for precompiled headers
)
ocv_target_include_modules(${the_module} ${OPENCV_MODULE_${the_module}_DEPS} ${ARGN})
endmacro()
@ -454,6 +523,8 @@ endmacro()
# Usage:
# ocv_set_module_sources([HEADERS] <list of files> [SOURCES] <list of files>)
macro(ocv_set_module_sources)
ocv_debug_message("ocv_set_module_sources(" ${ARGN} ")")
set(OPENCV_MODULE_${the_module}_HEADERS "")
set(OPENCV_MODULE_${the_module}_SOURCES "")
@ -481,85 +552,107 @@ endmacro()
# Usage:
# ocv_glob_module_sources([EXCLUDE_CUDA] <extra sources&headers in the same format as used in ocv_set_module_sources>)
macro(ocv_glob_module_sources)
ocv_debug_message("ocv_glob_module_sources(" ${ARGN} ")")
set(_argn ${ARGN})
list(FIND _argn "EXCLUDE_CUDA" exclude_cuda)
if(NOT exclude_cuda EQUAL -1)
list(REMOVE_AT _argn ${exclude_cuda})
endif()
file(GLOB_RECURSE lib_srcs "src/*.cpp")
file(GLOB_RECURSE lib_int_hdrs "src/*.hpp" "src/*.h")
file(GLOB lib_hdrs "include/opencv2/*.hpp" "include/opencv2/${name}/*.hpp" "include/opencv2/${name}/*.h")
file(GLOB lib_hdrs_detail "include/opencv2/${name}/detail/*.hpp" "include/opencv2/${name}/detail/*.h")
file(GLOB_RECURSE lib_srcs_apple "src/*.mm")
file(GLOB_RECURSE lib_srcs
"${CMAKE_CURRENT_LIST_DIR}/src/*.cpp"
)
file(GLOB_RECURSE lib_int_hdrs
"${CMAKE_CURRENT_LIST_DIR}/src/*.hpp"
"${CMAKE_CURRENT_LIST_DIR}/src/*.h"
)
file(GLOB lib_hdrs
"${CMAKE_CURRENT_LIST_DIR}/include/opencv2/*.hpp"
"${CMAKE_CURRENT_LIST_DIR}/include/opencv2/${name}/*.hpp"
"${CMAKE_CURRENT_LIST_DIR}/include/opencv2/${name}/*.h"
)
file(GLOB lib_hdrs_detail
"${CMAKE_CURRENT_LIST_DIR}/include/opencv2/${name}/detail/*.hpp"
"${CMAKE_CURRENT_LIST_DIR}/include/opencv2/${name}/detail/*.h"
)
if (APPLE)
file(GLOB_RECURSE lib_srcs_apple
"${CMAKE_CURRENT_LIST_DIR}/src/*.mm"
)
list(APPEND lib_srcs ${lib_srcs_apple})
endif()
ocv_source_group("Src" DIRBASE "${CMAKE_CURRENT_SOURCE_DIR}/src" FILES ${lib_srcs} ${lib_int_hdrs})
ocv_source_group("Include" DIRBASE "${CMAKE_CURRENT_SOURCE_DIR}/include" FILES ${lib_hdrs} ${lib_hdrs_detail})
ocv_source_group("Src" DIRBASE "${CMAKE_CURRENT_LIST_DIR}/src" FILES ${lib_srcs} ${lib_int_hdrs})
ocv_source_group("Include" DIRBASE "${CMAKE_CURRENT_LIST_DIR}/include" FILES ${lib_hdrs} ${lib_hdrs_detail})
if (exclude_cuda EQUAL -1)
file(GLOB lib_cuda_srcs "src/cuda/*.cu")
set(cuda_objs "")
set(lib_cuda_hdrs "")
if(HAVE_CUDA)
ocv_include_directories(${CUDA_INCLUDE_DIRS})
file(GLOB lib_cuda_hdrs "src/cuda/*.hpp")
ocv_cuda_compile(cuda_objs ${lib_cuda_srcs} ${lib_cuda_hdrs})
source_group("Src\\Cuda" FILES ${lib_cuda_srcs} ${lib_cuda_hdrs})
endif()
else()
set(cuda_objs "")
set(lib_cuda_srcs "")
set(lib_cuda_hdrs "")
set(lib_cuda_srcs "")
set(lib_cuda_hdrs "")
if(HAVE_CUDA AND exclude_cuda EQUAL -1)
file(GLOB lib_cuda_srcs
"${CMAKE_CURRENT_LIST_DIR}/src/cuda/*.cu"
)
file(GLOB lib_cuda_hdrs
"${CMAKE_CURRENT_LIST_DIR}/src/cuda/*.hpp"
)
source_group("Src\\Cuda" FILES ${lib_cuda_srcs} ${lib_cuda_hdrs})
endif()
file(GLOB cl_kernels "src/opencl/*.cl")
file(GLOB cl_kernels
"${CMAKE_CURRENT_LIST_DIR}/src/opencl/*.cl"
)
if(cl_kernels)
set(OCL_NAME opencl_kernels_${name})
ocv_include_directories(${OPENCL_INCLUDE_DIRS})
string(REGEX REPLACE "opencv_" "" the_module_barename "${the_module}")
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.cpp" "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.hpp"
COMMAND ${CMAKE_COMMAND} -DMODULE_NAME="${the_module_barename}" -DCL_DIR="${CMAKE_CURRENT_SOURCE_DIR}/src/opencl" -DOUTPUT="${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.cpp" -P "${OpenCV_SOURCE_DIR}/cmake/cl2cpp.cmake"
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${OCL_NAME}.cpp" "${CMAKE_CURRENT_BINARY_DIR}/${OCL_NAME}.hpp"
COMMAND ${CMAKE_COMMAND} -DMODULE_NAME="${name}" -DCL_DIR="${CMAKE_CURRENT_LIST_DIR}/src/opencl" -DOUTPUT="${CMAKE_CURRENT_BINARY_DIR}/${OCL_NAME}.cpp" -P "${OpenCV_SOURCE_DIR}/cmake/cl2cpp.cmake"
DEPENDS ${cl_kernels} "${OpenCV_SOURCE_DIR}/cmake/cl2cpp.cmake")
ocv_source_group("Src\\opencl\\kernels" FILES ${cl_kernels})
ocv_source_group("Src\\opencl\\kernels\\autogenerated" FILES "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.cpp" "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.hpp")
list(APPEND lib_srcs ${cl_kernels} "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.cpp" "${CMAKE_CURRENT_BINARY_DIR}/opencl_kernels.hpp")
ocv_source_group("Src\\opencl\\kernels\\autogenerated" FILES "${CMAKE_CURRENT_BINARY_DIR}/${OCL_NAME}.cpp" "${CMAKE_CURRENT_BINARY_DIR}/${OCL_NAME}.hpp")
list(APPEND lib_srcs ${cl_kernels} "${CMAKE_CURRENT_BINARY_DIR}/${OCL_NAME}.cpp" "${CMAKE_CURRENT_BINARY_DIR}/${OCL_NAME}.hpp")
endif()
ocv_set_module_sources(${_argn} HEADERS ${lib_hdrs} ${lib_hdrs_detail}
SOURCES ${lib_srcs} ${lib_int_hdrs} ${cuda_objs} ${lib_cuda_srcs} ${lib_cuda_hdrs})
SOURCES ${lib_srcs} ${lib_int_hdrs} ${lib_cuda_srcs} ${lib_cuda_hdrs})
endmacro()
# creates OpenCV module in current folder
# creates new target, configures standard dependencies, compilers flags, install rules
# Usage:
# ocv_create_module(<extra link dependencies>)
# ocv_create_module(SKIP_LINK)
# ocv_create_module()
macro(ocv_create_module)
ocv_debug_message("ocv_create_module(" ${ARGN} ")")
set(OPENCV_MODULE_${the_module}_LINK_DEPS "${OPENCV_MODULE_${the_module}_LINK_DEPS};${ARGN}" CACHE INTERNAL "")
if(${BUILD_opencv_world} AND OPENCV_MODULE_${the_module}_IS_PART_OF_WORLD)
# nothing
set(the_module_target opencv_world)
else()
_ocv_create_module(${ARGN})
set(the_module_target ${the_module})
endif()
endmacro()
macro(_ocv_create_module)
# The condition we ought to be testing here is whether ocv_add_precompiled_headers will
# be called at some point in the future. We can't look into the future, though,
# so this will have to do.
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/precomp.hpp")
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/precomp.hpp" AND NOT ${the_module} STREQUAL opencv_world)
get_native_precompiled_header(${the_module} precomp.hpp)
endif()
add_library(${the_module} ${OPENCV_MODULE_TYPE} ${OPENCV_MODULE_${the_module}_HEADERS} ${OPENCV_MODULE_${the_module}_SOURCES}
ocv_add_library(${the_module} ${OPENCV_MODULE_TYPE} ${OPENCV_MODULE_${the_module}_HEADERS} ${OPENCV_MODULE_${the_module}_SOURCES}
"${OPENCV_CONFIG_FILE_INCLUDE_DIR}/cvconfig.h" "${OPENCV_CONFIG_FILE_INCLUDE_DIR}/opencv2/opencv_modules.hpp"
${${the_module}_pch})
if(NOT the_module STREQUAL opencv_ts)
set_target_properties(${the_module} PROPERTIES COMPILE_DEFINITIONS OPENCV_NOSTL)
endif()
if(NOT "${ARGN}" STREQUAL "SKIP_LINK")
target_link_libraries(${the_module} ${OPENCV_MODULE_${the_module}_DEPS})
target_link_libraries(${the_module} LINK_INTERFACE_LIBRARIES ${OPENCV_MODULE_${the_module}_DEPS})
target_link_libraries(${the_module} ${OPENCV_MODULE_${the_module}_DEPS_EXT} ${OPENCV_LINKER_LIBS} ${IPP_LIBS} ${ARGN})
if (HAVE_CUDA)
target_link_libraries(${the_module} ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY})
endif()
ocv_target_link_libraries(${the_module} ${OPENCV_MODULE_${the_module}_DEPS_TO_LINK})
ocv_target_link_libraries(${the_module} LINK_INTERFACE_LIBRARIES ${OPENCV_MODULE_${the_module}_DEPS_TO_LINK})
ocv_target_link_libraries(${the_module} ${OPENCV_MODULE_${the_module}_DEPS_EXT} ${OPENCV_LINKER_LIBS} ${IPP_LIBS} ${ARGN})
if (HAVE_CUDA)
ocv_target_link_libraries(${the_module} ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY})
endif()
add_dependencies(opencv_modules ${the_module})
@ -614,13 +707,16 @@ macro(ocv_create_module)
endif()
endforeach()
endif()
_ocv_add_precompiled_headers(${the_module})
endmacro()
# opencv precompiled headers macro (can add pch to modules and tests)
# this macro must be called after any "add_definitions" commands, otherwise precompiled headers will not work
# Usage:
# ocv_add_precompiled_headers(${the_module})
macro(ocv_add_precompiled_headers the_target)
macro(_ocv_add_precompiled_headers the_target)
ocv_debug_message("ocv_add_precompiled_headers(" ${the_target} ${ARGN} ")")
if("${the_target}" MATCHES "^opencv_test_.*$")
SET(pch_path "test/test_")
elseif("${the_target}" MATCHES "^opencv_perf_.*$")
@ -637,6 +733,7 @@ endmacro()
# Usage:
# ocv_define_module(module_name [INTERNAL] [EXCLUDE_CUDA] [REQUIRED] [<list of dependencies>] [OPTIONAL <list of optional dependencies>])
macro(ocv_define_module module_name)
ocv_debug_message("ocv_define_module(" ${module_name} ${ARGN} ")")
set(_argn ${ARGN})
set(exclude_cuda "")
foreach(arg ${_argn})
@ -647,10 +744,9 @@ macro(ocv_define_module module_name)
endforeach()
ocv_add_module(${module_name} ${_argn})
ocv_module_include_directories()
ocv_glob_module_sources(${exclude_cuda})
ocv_module_include_directories()
ocv_create_module()
ocv_add_precompiled_headers(${the_module})
ocv_add_accuracy_tests()
ocv_add_perf_tests()
@ -685,7 +781,7 @@ macro(__ocv_parse_test_sources tests_type)
set(__file_group_name "")
set(__file_group_sources "")
elseif(arg STREQUAL "DEPENDS_ON")
set(__currentvar "OPENCV_TEST_${the_module}_DEPS")
set(__currentvar "OPENCV_${tests_type}_${the_module}_DEPS")
elseif("${__currentvar}" STREQUAL "__file_group_sources" AND NOT __file_group_name)
set(__file_group_name "${arg}")
else()
@ -700,20 +796,20 @@ endmacro()
# this is a command for adding OpenCV performance tests to the module
# ocv_add_perf_tests(<extra_dependencies>)
function(ocv_add_perf_tests)
set(perf_path "${CMAKE_CURRENT_SOURCE_DIR}/perf")
ocv_debug_message("ocv_add_perf_tests(" ${ARGN} ")")
set(perf_path "${CMAKE_CURRENT_LIST_DIR}/perf")
if(BUILD_PERF_TESTS AND EXISTS "${perf_path}")
__ocv_parse_test_sources(PERF ${ARGN})
# opencv_imgcodecs is required for imread/imwrite
set(perf_deps ${the_module} opencv_ts opencv_imgcodecs ${OPENCV_PERF_${the_module}_DEPS} ${OPENCV_MODULE_opencv_ts_DEPS})
set(perf_deps ${the_module} opencv_ts opencv_imgcodecs ${OPENCV_MODULE_${the_module}_DEPS} ${OPENCV_MODULE_opencv_ts_DEPS})
ocv_check_dependencies(${perf_deps})
if(OCV_DEPENDENCIES_FOUND)
set(the_target "opencv_perf_${name}")
# project(${the_target})
ocv_module_include_directories(${perf_deps} "${perf_path}")
if(NOT OPENCV_PERF_${the_module}_SOURCES)
file(GLOB_RECURSE perf_srcs "${perf_path}/*.cpp")
file(GLOB_RECURSE perf_hdrs "${perf_path}/*.hpp" "${perf_path}/*.h")
@ -722,10 +818,13 @@ function(ocv_add_perf_tests)
set(OPENCV_PERF_${the_module}_SOURCES ${perf_srcs} ${perf_hdrs})
endif()
get_native_precompiled_header(${the_target} perf_precomp.hpp)
if(NOT BUILD_opencv_world)
get_native_precompiled_header(${the_target} perf_precomp.hpp)
endif()
add_executable(${the_target} ${OPENCV_PERF_${the_module}_SOURCES} ${${the_target}_pch})
target_link_libraries(${the_target} ${OPENCV_MODULE_${the_module}_DEPS} ${perf_deps} ${OPENCV_LINKER_LIBS})
ocv_add_executable(${the_target} ${OPENCV_PERF_${the_module}_SOURCES} ${${the_target}_pch})
ocv_target_include_modules(${the_target} ${perf_deps} "${perf_path}")
ocv_target_link_libraries(${the_target} ${OPENCV_MODULE_${the_module}_DEPS} ${perf_deps} ${OPENCV_LINKER_LIBS})
add_dependencies(opencv_perf_tests ${the_target})
# Additional target properties
@ -738,8 +837,9 @@ function(ocv_add_perf_tests)
set_target_properties(${the_target} PROPERTIES FOLDER "tests performance")
endif()
ocv_add_precompiled_headers(${the_target})
if(NOT BUILD_opencv_world)
_ocv_add_precompiled_headers(${the_target})
endif()
else(OCV_DEPENDENCIES_FOUND)
# TODO: warn about unsatisfied dependencies
endif(OCV_DEPENDENCIES_FOUND)
@ -752,21 +852,19 @@ endfunction()
# this is a command for adding OpenCV accuracy/regression tests to the module
# ocv_add_accuracy_tests([FILES <source group name> <list of sources>] [DEPENDS_ON] <list of extra dependencies>)
function(ocv_add_accuracy_tests)
set(test_path "${CMAKE_CURRENT_SOURCE_DIR}/test")
ocv_check_dependencies(${test_deps})
ocv_debug_message("ocv_add_accuracy_tests(" ${ARGN} ")")
set(test_path "${CMAKE_CURRENT_LIST_DIR}/test")
if(BUILD_TESTS AND EXISTS "${test_path}")
__ocv_parse_test_sources(TEST ${ARGN})
# opencv_imgcodecs is required for imread/imwrite
set(test_deps ${the_module} opencv_ts opencv_imgcodecs opencv_videoio ${OPENCV_TEST_${the_module}_DEPS} ${OPENCV_MODULE_opencv_ts_DEPS})
set(test_deps ${the_module} opencv_ts opencv_imgcodecs opencv_videoio ${OPENCV_MODULE_${the_module}_DEPS} ${OPENCV_MODULE_opencv_ts_DEPS})
ocv_check_dependencies(${test_deps})
if(OCV_DEPENDENCIES_FOUND)
set(the_target "opencv_test_${name}")
# project(${the_target})
ocv_module_include_directories(${test_deps} "${test_path}")
if(NOT OPENCV_TEST_${the_module}_SOURCES)
file(GLOB_RECURSE test_srcs "${test_path}/*.cpp")
file(GLOB_RECURSE test_hdrs "${test_path}/*.hpp" "${test_path}/*.h")
@ -775,10 +873,13 @@ function(ocv_add_accuracy_tests)
set(OPENCV_TEST_${the_module}_SOURCES ${test_srcs} ${test_hdrs})
endif()
get_native_precompiled_header(${the_target} test_precomp.hpp)
add_executable(${the_target} ${OPENCV_TEST_${the_module}_SOURCES} ${${the_target}_pch})
if(NOT BUILD_opencv_world)
get_native_precompiled_header(${the_target} test_precomp.hpp)
endif()
target_link_libraries(${the_target} ${OPENCV_MODULE_${the_module}_DEPS} ${test_deps} ${OPENCV_LINKER_LIBS})
ocv_add_executable(${the_target} ${OPENCV_TEST_${the_module}_SOURCES} ${${the_target}_pch})
ocv_target_include_modules(${the_target} ${test_deps} "${test_path}")
ocv_target_link_libraries(${the_target} ${OPENCV_MODULE_${the_module}_DEPS} ${test_deps} ${OPENCV_LINKER_LIBS})
add_dependencies(opencv_tests ${the_target})
# Additional target properties
@ -795,7 +896,9 @@ function(ocv_add_accuracy_tests)
get_target_property(LOC ${the_target} LOCATION)
add_test(${the_target} "${LOC}")
ocv_add_precompiled_headers(${the_target})
if(NOT BUILD_opencv_world)
_ocv_add_precompiled_headers(${the_target})
endif()
else(OCV_DEPENDENCIES_FOUND)
# TODO: warn about unsatisfied dependencies
endif(OCV_DEPENDENCIES_FOUND)
@ -807,6 +910,8 @@ function(ocv_add_accuracy_tests)
endfunction()
function(ocv_add_samples)
ocv_debug_message("ocv_add_samples(" ${ARGN} ")")
set(samples_path "${CMAKE_CURRENT_SOURCE_DIR}/samples")
string(REGEX REPLACE "^opencv_" "" module_id ${the_module})
@ -816,15 +921,14 @@ function(ocv_add_samples)
if(OCV_DEPENDENCIES_FOUND)
file(GLOB sample_sources "${samples_path}/*.cpp")
ocv_include_modules(${OPENCV_MODULE_${the_module}_DEPS})
foreach(source ${sample_sources})
get_filename_component(name "${source}" NAME_WE)
set(the_target "example_${module_id}_${name}")
add_executable(${the_target} "${source}")
target_link_libraries(${the_target} ${samples_deps})
ocv_add_executable(${the_target} "${source}")
ocv_target_include_modules(${the_target} ${samples_deps})
ocv_target_link_libraries(${the_target} ${samples_deps})
set_target_properties(${the_target} PROPERTIES PROJECT_LABEL "(sample) ${name}")
if(ENABLE_SOLUTION_FOLDERS)
@ -847,82 +951,3 @@ function(ocv_add_samples)
PERMISSIONS OWNER_READ GROUP_READ WORLD_READ COMPONENT samples)
endif()
endfunction()
# internal macro; finds all link dependencies of the module
# should be used at the end of CMake processing
macro(__ocv_track_module_link_dependencies the_module optkind)
set(${the_module}_MODULE_DEPS_${optkind} "")
set(${the_module}_EXTRA_DEPS_${optkind} "")
get_target_property(__module_type ${the_module} TYPE)
if(__module_type STREQUAL "STATIC_LIBRARY")
#in case of static library we have to inherit its dependencies (in right order!!!)
if(NOT DEFINED ${the_module}_LIB_DEPENDS_${optkind})
ocv_split_libs_list(${the_module}_LIB_DEPENDS ${the_module}_LIB_DEPENDS_DBG ${the_module}_LIB_DEPENDS_OPT)
endif()
set(__resolved_deps "")
set(__mod_depends ${${the_module}_LIB_DEPENDS_${optkind}})
set(__has_cycle FALSE)
while(__mod_depends)
list(GET __mod_depends 0 __dep)
list(REMOVE_AT __mod_depends 0)
if(__dep STREQUAL the_module)
set(__has_cycle TRUE)
else()#if("${OPENCV_MODULES_BUILD}" MATCHES "(^|;)${__dep}(;|$)")
ocv_regex_escape(__rdep "${__dep}")
if(__resolved_deps MATCHES "(^|;)${__rdep}(;|$)")
#all dependencies of this module are already resolved
list(APPEND ${the_module}_MODULE_DEPS_${optkind} "${__dep}")
else()
get_target_property(__module_type ${__dep} TYPE)
if(__module_type STREQUAL "STATIC_LIBRARY")
if(NOT DEFINED ${__dep}_LIB_DEPENDS_${optkind})
ocv_split_libs_list(${__dep}_LIB_DEPENDS ${__dep}_LIB_DEPENDS_DBG ${__dep}_LIB_DEPENDS_OPT)
endif()
list(INSERT __mod_depends 0 ${${__dep}_LIB_DEPENDS_${optkind}} ${__dep})
list(APPEND __resolved_deps "${__dep}")
elseif(NOT __module_type)
list(APPEND ${the_module}_EXTRA_DEPS_${optkind} "${__dep}")
endif()
endif()
#else()
# get_target_property(__dep_location "${__dep}" LOCATION)
endif()
endwhile()
ocv_list_unique(${the_module}_MODULE_DEPS_${optkind})
#ocv_list_reverse(${the_module}_MODULE_DEPS_${optkind})
ocv_list_unique(${the_module}_EXTRA_DEPS_${optkind})
#ocv_list_reverse(${the_module}_EXTRA_DEPS_${optkind})
if(__has_cycle)
# not sure if it can work
list(APPEND ${the_module}_MODULE_DEPS_${optkind} "${the_module}")
endif()
unset(__dep_location)
unset(__mod_depends)
unset(__resolved_deps)
unset(__has_cycle)
unset(__rdep)
endif()#STATIC_LIBRARY
unset(__module_type)
#message("${the_module}_MODULE_DEPS_${optkind}")
#message(" ${${the_module}_MODULE_DEPS_${optkind}}")
#message(" ${OPENCV_MODULE_${the_module}_DEPS}")
#message("")
#message("${the_module}_EXTRA_DEPS_${optkind}")
#message(" ${${the_module}_EXTRA_DEPS_${optkind}}")
#message("")
endmacro()
# creates lists of build dependencies needed for external projects
macro(ocv_track_build_dependencies)
foreach(m ${OPENCV_MODULES_BUILD})
__ocv_track_module_link_dependencies("${m}" OPT)
__ocv_track_module_link_dependencies("${m}" DBG)
endforeach()
endmacro()

View File

@ -68,6 +68,15 @@ MACRO(_PCH_GET_COMPILE_FLAGS _out_compile_flags)
endif()
ENDFOREACH(item)
get_target_property(DIRINC ${_PCH_current_target} INCLUDE_DIRECTORIES )
FOREACH(item ${DIRINC})
if(item MATCHES "^${OpenCV_SOURCE_DIR}/modules/")
LIST(APPEND ${_out_compile_flags} "${_PCH_include_prefix}\"${item}\"")
else()
LIST(APPEND ${_out_compile_flags} "${_PCH_isystem_prefix}\"${item}\"")
endif()
ENDFOREACH(item)
GET_DIRECTORY_PROPERTY(_directory_flags DEFINITIONS)
GET_DIRECTORY_PROPERTY(_global_definitions DIRECTORY ${OpenCV_SOURCE_DIR} DEFINITIONS)
#MESSAGE("_directory_flags ${_directory_flags} ${_global_definitions}" )
@ -254,6 +263,9 @@ MACRO(ADD_PRECOMPILED_HEADER _targetName _input)
endif()
endif()
get_target_property(DIRINC ${_targetName} INCLUDE_DIRECTORIES)
set_target_properties(${_targetName}_pch_dephelp PROPERTIES INCLUDE_DIRECTORIES "${DIRINC}")
#MESSAGE("_compile_FLAGS: ${_compile_FLAGS}")
#message("COMMAND ${CMAKE_CXX_COMPILER} ${_compile_FLAGS} -x c++-header -o ${_output} ${_input}")

View File

@ -42,6 +42,11 @@ macro(ocv_assert)
endif()
endmacro()
macro(ocv_debug_message)
# string(REPLACE ";" " " __msg "${ARGN}")
# message(STATUS "${__msg}")
endmacro()
macro(ocv_check_environment_variables)
foreach(_var ${ARGN})
if(NOT DEFINED ${_var} AND DEFINED ENV{${_var}})
@ -53,8 +58,18 @@ macro(ocv_check_environment_variables)
endforeach()
endmacro()
# rename modules target to world if needed
macro(_ocv_fix_target target_var)
if(BUILD_opencv_world)
if(OPENCV_MODULE_${${target_var}}_IS_PART_OF_WORLD)
set(${target_var} opencv_world)
endif()
endif()
endmacro()
# adds include directories in such way that directories from the OpenCV source tree go first
function(ocv_include_directories)
ocv_debug_message("ocv_include_directories( ${ARGN} )")
set(__add_before "")
foreach(dir ${ARGN})
get_filename_component(__abs_dir "${dir}" ABSOLUTE)
@ -67,6 +82,30 @@ function(ocv_include_directories)
include_directories(BEFORE ${__add_before})
endfunction()
# adds include directories in such way that directories from the OpenCV source tree go first
function(ocv_target_include_directories target)
_ocv_fix_target(target)
set(__params "")
foreach(dir ${ARGN})
get_filename_component(__abs_dir "${dir}" ABSOLUTE)
if("${__abs_dir}" MATCHES "^${OpenCV_SOURCE_DIR}" OR "${__abs_dir}" MATCHES "^${OpenCV_BINARY_DIR}")
list(APPEND __params "${__abs_dir}")
else()
list(APPEND __params "${dir}")
endif()
endforeach()
if(HAVE_CUDA OR CMAKE_VERSION VERSION_LESS 2.8.11)
include_directories(${__params})
else()
if(TARGET ${target})
target_include_directories(${target} PRIVATE ${__params})
else()
set(__new_inc "${OCV_TARGET_INCLUDE_DIRS_${target}};${__params}")
set(OCV_TARGET_INCLUDE_DIRS_${target} "${__new_inc}" CACHE INTERNAL "")
endif()
endif()
endfunction()
# clears all passed variables
macro(ocv_clear_vars)
foreach(_var ${ARGN})
@ -295,8 +334,8 @@ endfunction()
macro(ocv_finalize_status)
if(NOT OPENCV_SKIP_STATUS_FINALIZATION)
if(TARGET opencv_core)
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${OPENCV_BUILD_INFO_FILE}" "${opencv_core_BINARY_DIR}/version_string.inc" OUTPUT_QUIET)
if(DEFINED OPENCV_MODULE_opencv_core_BINARY_DIR)
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${OPENCV_BUILD_INFO_FILE}" "${OPENCV_MODULE_opencv_core_BINARY_DIR}/version_string.inc" OUTPUT_QUIET)
endif()
endif()
endmacro()
@ -533,16 +572,20 @@ function(ocv_install_target)
# message(STATUS "Process ${__target} dst=${__dst}...")
if(DEFINED __dst)
get_target_property(fname ${__target} LOCATION_DEBUG)
if(fname MATCHES "\\.lib$")
string(REGEX REPLACE "\\.lib$" ".pdb" fname "${fname}")
install(FILES ${fname} DESTINATION ${__dst} CONFIGURATIONS Debug)
endif()
if(CMAKE_VERSION VERSION_LESS 2.8.12)
get_target_property(fname ${__target} LOCATION_DEBUG)
if(fname MATCHES "\\.lib$")
string(REGEX REPLACE "\\.lib$" ".pdb" fname "${fname}")
install(FILES ${fname} DESTINATION ${__dst} CONFIGURATIONS Debug)
endif()
get_target_property(fname ${__target} LOCATION_RELEASE)
if(fname MATCHES "\\.lib$")
string(REGEX REPLACE "\\.lib$" ".pdb" fname "${fname}")
install(FILES ${fname} DESTINATION ${__dst} CONFIGURATIONS Release)
get_target_property(fname ${__target} LOCATION_RELEASE)
if(fname MATCHES "\\.lib$")
string(REGEX REPLACE "\\.lib$" ".pdb" fname "${fname}")
install(FILES ${fname} DESTINATION ${__dst} CONFIGURATIONS Release)
endif()
else()
# CMake 2.8.12 brokes PDB support in STATIC libraries for MSVS
endif()
endif()
endif()
@ -637,6 +680,9 @@ endmacro()
################################################################################################
# short command to setup source group
function(ocv_source_group group)
if(BUILD_opencv_world AND OPENCV_MODULE_${the_module}_IS_PART_OF_WORLD)
set(group "${the_module}\\${group}")
endif()
cmake_parse_arguments(SG "" "DIRBASE" "GLOB;GLOB_RECURSE;FILES" ${ARGN})
set(files "")
if(SG_FILES)
@ -669,3 +715,55 @@ function(ocv_source_group group)
source_group(${group} FILES ${files})
endif()
endfunction()
function(ocv_target_link_libraries target)
_ocv_fix_target(target)
set(LINK_DEPS ${ARGN})
# process world
if(BUILD_opencv_world)
foreach(m ${OPENCV_MODULES_BUILD})
if(OPENCV_MODULE_${m}_IS_PART_OF_WORLD)
if(";${LINK_DEPS};" MATCHES ";${m};")
list(REMOVE_ITEM LINK_DEPS ${m})
if(NOT (";${LINK_DEPS};" MATCHES ";opencv_world;"))
list(APPEND LINK_DEPS opencv_world)
endif()
endif()
endif()
endforeach()
endif()
target_link_libraries(${target} ${LINK_DEPS})
endfunction()
function(_ocv_append_target_includes target)
if(DEFINED OCV_TARGET_INCLUDE_DIRS_${target})
target_include_directories(${target} PRIVATE ${OCV_TARGET_INCLUDE_DIRS_${target}})
unset(OCV_TARGET_INCLUDE_DIRS_${target} CACHE)
endif()
endfunction()
function(ocv_add_executable target)
add_executable(${target} ${ARGN})
_ocv_append_target_includes(${target})
endfunction()
function(ocv_add_library target)
set(cuda_objs "")
if(HAVE_CUDA)
set(cuda_srcs "")
foreach(var ${ARGN})
if(var MATCHES ".cu")
list(APPEND cuda_srcs ${var})
endif()
endforeach()
if(cuda_srcs)
ocv_include_directories(${CUDA_INCLUDE_DIRS})
ocv_cuda_compile(cuda_objs ${lib_cuda_srcs} ${lib_cuda_hdrs})
endif()
endif()
add_library(${target} ${ARGN} ${cuda_objs})
_ocv_append_target_includes(${target})
endfunction()

View File

@ -141,6 +141,7 @@ SET(OpenCV_VERSION_STATUS "@OPENCV_VERSION_STATUS@")
# ====================================================================
SET(OpenCV_LIB_COMPONENTS @OPENCV_MODULES_CONFIGCMAKE@)
SET(OpenCV_WORLD_COMPONENTS @OPENCV_WORLD_MODULES@)
# ==============================================================
# Extra include directories, needed by OpenCV 2 new structure
@ -200,8 +201,8 @@ foreach(__cvcomponent ${OpenCV_FIND_COMPONENTS})
message(WARNING "${__cvcomponent} is required but was not found")
endif()
#indicate that module is NOT found
string(TOUPPER "${__cvcomponent}" __cvcomponent)
set(${__cvcomponent}_FOUND "${__cvcomponent}_FOUND-NOTFOUND")
string(TOUPPER "${__cvcomponent}" __cvcomponentUP)
set(${__cvcomponentUP}_FOUND "${__cvcomponentUP}_FOUND-NOTFOUND")
else()
list(APPEND OpenCV_FIND_COMPONENTS_ ${__cvcomponent})
# Not using list(APPEND) here, because OpenCV_LIBS may not exist yet.
@ -209,8 +210,31 @@ foreach(__cvcomponent ${OpenCV_FIND_COMPONENTS})
# to find_package(OpenCV) with different component lists add up.
set(OpenCV_LIBS ${OpenCV_LIBS} "${__cvcomponent}")
#indicate that module is found
string(TOUPPER "${__cvcomponent}" __cvcomponent)
set(${__cvcomponent}_FOUND 1)
string(TOUPPER "${__cvcomponent}" __cvcomponentUP)
set(${__cvcomponentUP}_FOUND 1)
endif()
if(OpenCV_SHARED AND ";${OpenCV_WORLD_COMPONENTS};" MATCHES ";${__cvcomponent};" AND NOT TARGET ${__cvcomponent})
get_target_property(__implib_dbg opencv_world IMPORTED_IMPLIB_DEBUG)
get_target_property(__implib_release opencv_world IMPORTED_IMPLIB_RELEASE)
get_target_property(__location_dbg opencv_world IMPORTED_LOCATION_DEBUG)
get_target_property(__location_release opencv_world IMPORTED_LOCATION_RELEASE)
add_library(${__cvcomponent} SHARED IMPORTED)
if(__location_dbg)
set_property(TARGET ${__cvcomponent} APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
set_target_properties(${__cvcomponent} PROPERTIES
IMPORTED_IMPLIB_DEBUG "${__implib_dbg}"
IMPORTED_LINK_INTERFACE_LIBRARIES_DEBUG ""
IMPORTED_LOCATION_DEBUG "${__location_dbg}"
)
endif()
if(__location_release)
set_property(TARGET ${__cvcomponent} APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(${__cvcomponent} PROPERTIES
IMPORTED_IMPLIB_RELEASE "${__implib_release}"
IMPORTED_LINK_INTERFACE_LIBRARIES_RELEASE ""
IMPORTED_LOCATION_RELEASE "${__location_release}"
)
endif()
endif()
endforeach()
set(OpenCV_FIND_COMPONENTS ${OpenCV_FIND_COMPONENTS_})
@ -321,6 +345,7 @@ macro(ocv_check_dependencies)
set(OCV_DEPENDENCIES_FOUND TRUE)
foreach(d ${ARGN})
if(NOT TARGET ${d})
message(WARNING "OpenCV: Can't resolve dependency: ${d}")
set(OCV_DEPENDENCIES_FOUND FALSE)
break()
endif()
@ -346,6 +371,10 @@ macro(ocv_include_modules)
include_directories(BEFORE "${OpenCV_INCLUDE_DIRS}")
endmacro()
macro(ocv_target_link_libraries)
target_link_libraries(${ARGN})
endmacro()
# remove all matching elements from the list
macro(ocv_list_filterout lst regex)
foreach(item ${${lst}})

View File

@ -76,6 +76,9 @@
/* ffmpeg in Gentoo */
#cmakedefine HAVE_GENTOO_FFMPEG
/* Geospatial Data Abstraction Library */
#cmakedefine HAVE_GDAL
/* GStreamer multimedia framework */
#cmakedefine HAVE_GSTREAMER

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -33,7 +33,7 @@ if(BUILD_DOCS AND HAVE_SPHINX)
endif()
endforeach()
set(FIXED_ORDER_MODULES core imgproc imgcodecs videoio highgui video calib3d features2d objdetect ml flann photo stitching nonfree contrib legacy)
set(FIXED_ORDER_MODULES core imgproc imgcodecs videoio highgui video calib3d features2d objdetect ml flann photo stitching)
list(REMOVE_ITEM BASE_MODULES ${FIXED_ORDER_MODULES})
@ -105,8 +105,8 @@ if(BUILD_DOCS AND HAVE_SPHINX)
COMMAND ${SPHINX_BUILD} ${BUILD_PLANTUML} -b latex -c "${CMAKE_CURRENT_SOURCE_DIR}" "${DOC_FAKE_ROOT}" .
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/pics ${CMAKE_CURRENT_BINARY_DIR}/doc/opencv1/pics
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/mymath.sty ${CMAKE_CURRENT_BINARY_DIR}
COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/patch_refman_latex.py" opencv2refman.tex
COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/patch_refman_latex.py" opencv2manager.tex
COMMAND ${PYTHON_DEFAULT_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/patch_refman_latex.py" opencv2refman.tex
COMMAND ${PYTHON_DEFAULT_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/patch_refman_latex.py" opencv2manager.tex
COMMAND ${CMAKE_COMMAND} -E echo "Generating opencv2refman.pdf"
COMMAND ${PDFLATEX_COMPILER} -interaction=batchmode opencv2refman.tex
COMMAND ${PDFLATEX_COMPILER} -interaction=batchmode opencv2refman.tex

View File

@ -0,0 +1,112 @@
.. _Bindings_Basics:
How OpenCV-Python Bindings Works?
************************************
Goal
=====
Learn:
* How OpenCV-Python bindings are generated?
* How to extend new OpenCV modules to Python?
How OpenCV-Python bindings are generated?
=========================================
In OpenCV, all algorithms are implemented in C++. But these algorithms can be used from different languages like Python, Java etc. This is made possible by the bindings generators. These generators create a bridge between C++ and Python which enables users to call C++ functions from Python. To get a complete picture of what is happening in background, a good knowledge of Python/C API is required. A simple example on extending C++ functions to Python can be found in official Python documentation[1]. So extending all functions in OpenCV to Python by writing their wrapper functions manually is a time-consuming task. So OpenCV does it in a more intelligent way. OpenCV generates these wrapper functions automatically from the C++ headers using some Python scripts which are located in ``modules/python/src2``. We will look into what they do.
First, ``modules/python/CMakeFiles.txt`` is a CMake script which checks the modules to be extended to Python. It will automatically check all the modules to be extended and grab their header files. These header files contain list of all classes, functions, constants etc. for that particular modules.
Second, these header files are passed to a Python script, ``modules/python/src2/gen2.py``. This is the Python bindings generator script. It calls another Python script ``modules/python/src2/hdr_parser.py``. This is the header parser script. This header parser splits the complete header file into small Python lists. So these lists contain all details about a particular function, class etc. For example, a function will be parsed to get a list containing function name, return type, input arguments, argument types etc. Final list contains details of all the functions, structs, classes etc. in that header file.
But header parser doesn't parse all the functions/classes in the header file. The developer has to specify which functions should be exported to Python. For that, there are certain macros added to the beginning of these declarations which enables the header parser to identify functions to be parsed. These macros are added by the developer who programs the particular function. In short, the developer decides which functions should be extended to Python and which are not. Details of those macros will be given in next session.
So header parser returns a final big list of parsed functions. Our generator script (gen2.py) will create wrapper functions for all the functions/classes/enums/structs parsed by header parser (You can find these header files during compilation in the ``build/modules/python/`` folder as ``pyopencv_generated_*.h`` files). But there may be some basic OpenCV datatypes like Mat, Vec4i, Size. They need to be extended manually. For example, a Mat type should be extended to Numpy array, Size should be extended to a tuple of two integers etc. Similarly, there may be some complex structs/classes/functions etc. which need to be extended manually. All such manual wrapper functions are placed in ``modules/python/src2/pycv2.hpp``.
So now only thing left is the compilation of these wrapper files which gives us **cv2** module. So when you call a function, say ``res = equalizeHist(img1,img2)`` in Python, you pass two numpy arrays and you expect another numpy array as the output. So these numpy arrays are converted to ``cv::Mat`` and then calls the ``equalizeHist()`` function in C++. Final result, ``res`` will be converted back into a Numpy array. So in short, almost all operations are done in C++ which gives us almost same speed as that of C++.
So this is the basic version of how OpenCV-Python bindings are generated.
How to extend new modules to Python?
=====================================
Header parser parse the header files based on some wrapper macros added to function declaration. Enumeration constants don't need any wrapper macros. They are automatically wrapped. But remaining functions, classes etc. need wrapper macros.
Functions are extended using ``CV_EXPORTS_W`` macro. An example is shown below.
.. code-block:: cpp
CV_EXPORTS_W void equalizeHist( InputArray src, OutputArray dst );
Header parser can understand the input and output arguments from keywords like ``InputArray, OutputArray`` etc. But sometimes, we may need to hardcode inputs and outputs. For that, macros like ``CV_OUT, CV_IN_OUT`` etc. are used.
.. code-block:: cpp
CV_EXPORTS_W void minEnclosingCircle( InputArray points,
CV_OUT Point2f& center, CV_OUT float& radius );
For large classes also, ``CV_EXPORTS_W`` is used. To extend class methods, ``CV_WRAP`` is used. Similarly, ``CV_PROP`` is used for class fields.
.. code-block:: cpp
class CV_EXPORTS_W CLAHE : public Algorithm
{
public:
CV_WRAP virtual void apply(InputArray src, OutputArray dst) = 0;
CV_WRAP virtual void setClipLimit(double clipLimit) = 0;
CV_WRAP virtual double getClipLimit() const = 0;
}
Overloaded functions can be extended using ``CV_EXPORTS_AS``. But we need to pass a new name so that each function will be called by that name in Python. Take the case of integral function below. Three functions are available, so each one is named with a suffix in Python. Similarly ``CV_WRAP_AS`` can be used to wrap overloaded methods.
.. code-block:: cpp
//! computes the integral image
CV_EXPORTS_W void integral( InputArray src, OutputArray sum, int sdepth = -1 );
//! computes the integral image and integral for the squared image
CV_EXPORTS_AS(integral2) void integral( InputArray src, OutputArray sum,
OutputArray sqsum, int sdepth = -1, int sqdepth = -1 );
//! computes the integral image, integral for the squared image and the tilted integral image
CV_EXPORTS_AS(integral3) void integral( InputArray src, OutputArray sum,
OutputArray sqsum, OutputArray tilted,
int sdepth = -1, int sqdepth = -1 );
Small classes/structs are extended using ``CV_EXPORTS_W_SIMPLE``. These structs are passed by value to C++ functions. Examples are KeyPoint, Match etc. Their methods are extended by ``CV_WRAP`` and fields are extended by ``CV_PROP_RW``.
.. code-block:: cpp
class CV_EXPORTS_W_SIMPLE DMatch
{
public:
CV_WRAP DMatch();
CV_WRAP DMatch(int _queryIdx, int _trainIdx, float _distance);
CV_WRAP DMatch(int _queryIdx, int _trainIdx, int _imgIdx, float _distance);
CV_PROP_RW int queryIdx; // query descriptor index
CV_PROP_RW int trainIdx; // train descriptor index
CV_PROP_RW int imgIdx; // train image index
CV_PROP_RW float distance;
};
Some other small classes/structs can be exported using ``CV_EXPORTS_W_MAP`` where it is exported to a Python native dictionary. Moments() is an example of it.
.. code-block:: cpp
class CV_EXPORTS_W_MAP Moments
{
public:
//! spatial moments
CV_PROP_RW double m00, m10, m01, m20, m11, m02, m30, m21, m12, m03;
//! central moments
CV_PROP_RW double mu20, mu11, mu02, mu30, mu21, mu12, mu03;
//! central normalized moments
CV_PROP_RW double nu20, nu11, nu02, nu30, nu21, nu12, nu03;
};
So these are the major extension macros available in OpenCV. Typically, a developer has to put proper macros in their appropriate positions. Rest is done by generator scripts. Sometimes, there may be an exceptional cases where generator scripts cannot create the wrappers. Such functions need to be handled manually. But most of the time, a code written according to OpenCV coding guidelines will be automatically wrapped by generator scripts.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@ -0,0 +1,36 @@
.. _PY_Table-Of-Content-Bindings:
OpenCV-Python Bindings
--------------------------------
Here, you will learn how OpenCV-Python bindings are generated.
* :ref:`Bindings_Basics`
.. tabularcolumns:: m{100pt} m{300pt}
.. cssclass:: toctableopencv
=========== ======================================================
|bind1| Learn how OpenCV-Python bindings are generated.
=========== ======================================================
.. |bind1| image:: images/nlm_icon.jpg
:height: 90pt
:width: 90pt
.. raw:: latex
\pagebreak
.. We use a custom table of content format and as the table of content only informs Sphinx about the hierarchy of the files, no need to show it.
.. toctree::
:hidden:
../py_bindings_basics/py_bindings_basics

View File

@ -159,6 +159,20 @@ OpenCV-Python Tutorials
:alt: OD Icon
* :ref:`PY_Table-Of-Content-Bindings`
.. tabularcolumns:: m{100pt} m{300pt}
.. cssclass:: toctableopencv
=========== =====================================================================
|PyBin| In this section, we will see how OpenCV-Python bindings are generated
=========== =====================================================================
.. |PyBin| image:: images/obj_icon.jpg
:height: 80pt
:width: 80pt
:alt: OD Icon
.. raw:: latex
@ -178,3 +192,4 @@ OpenCV-Python Tutorials
py_ml/py_table_of_contents_ml/py_table_of_contents_ml
py_photo/py_table_of_contents_photo/py_table_of_contents_photo
py_objdetect/py_table_of_contents_objdetect/py_table_of_contents_objdetect
py_bindings/py_table_of_contents_bindings/py_table_of_contents_bindings

View File

@ -23,7 +23,7 @@ Theory
Code
====
This tutorial code's is shown lines below. You can also download it from `here <https://github.com/Itseez/opencv/tree/master/samples/cpp/tutorial_code/features2D/SURF_descriptor.cpp>`_
This tutorial code's is shown lines below.
.. code-block:: cpp
@ -32,9 +32,10 @@ This tutorial code's is shown lines below. You can also download it from `here <
#include "opencv2/core.hpp"
#include "opencv2/features2d.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/nonfree.hpp"
#include "opencv2/xfeatures2d.hpp"
using namespace cv;
using namespace cv::xfeatures2d;
void readme();
@ -50,25 +51,19 @@ This tutorial code's is shown lines below. You can also download it from `here <
if( !img_1.data || !img_2.data )
{ return -1; }
//-- Step 1: Detect the keypoints using SURF Detector
//-- Step 1: Detect the keypoints using SURF Detector, compute the descriptors
int minHessian = 400;
SurfFeatureDetector detector( minHessian );
Ptr<SURF> detector = SURF::create();
detector->setMinHessian(minHessian);
std::vector<KeyPoint> keypoints_1, keypoints_2;
detector.detect( img_1, keypoints_1 );
detector.detect( img_2, keypoints_2 );
//-- Step 2: Calculate descriptors (feature vectors)
SurfDescriptorExtractor extractor;
Mat descriptors_1, descriptors_2;
extractor.compute( img_1, keypoints_1, descriptors_1 );
extractor.compute( img_2, keypoints_2, descriptors_2 );
detector->detectAndCompute( img_1, keypoints_1, descriptors_1 );
detector->detectAndCompute( img_2, keypoints_2, descriptors_2 );
//-- Step 3: Matching descriptor vectors with a brute force matcher
//-- Step 2: Matching descriptor vectors with a brute force matcher
BFMatcher matcher(NORM_L2);
std::vector< DMatch > matches;
matcher.match( descriptors_1, descriptors_2, matches );

View File

@ -22,7 +22,7 @@ Theory
Code
====
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/features2D/SURF_detector.cpp>`_
This tutorial code's is shown lines below.
.. code-block:: cpp
@ -30,11 +30,11 @@ This tutorial code's is shown lines below. You can also download it from `here <
#include <iostream>
#include "opencv2/core.hpp"
#include "opencv2/features2d.hpp"
#include "opencv2/nonfree/features2d.hpp"
#include "opencv2/xfeatures2d.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/nonfree.hpp"
using namespace cv;
using namespace cv::xfeatures2d;
void readme();
@ -53,12 +53,12 @@ This tutorial code's is shown lines below. You can also download it from `here <
//-- Step 1: Detect the keypoints using SURF Detector
int minHessian = 400;
SurfFeatureDetector detector( minHessian );
Ptr<SURF> detector = SURF::create( minHessian );
std::vector<KeyPoint> keypoints_1, keypoints_2;
detector.detect( img_1, keypoints_1 );
detector.detect( img_2, keypoints_2 );
detector->detect( img_1, keypoints_1 );
detector->detect( img_2, keypoints_2 );
//-- Draw keypoints
Mat img_keypoints_1; Mat img_keypoints_2;

View File

@ -19,10 +19,116 @@ Theory
Code
====
This tutorial code's is shown lines below. You can also download it from `here <https://github.com/Itseez/opencv/tree/master/samples/cpp/tutorial_code/features2D/SURF_FlannMatcher.cpp>`_
This tutorial code's is shown lines below.
.. code-block:: cpp
/**
* @file SURF_FlannMatcher
* @brief SURF detector + descriptor + FLANN Matcher
* @author A. Huaman
*/
#include <stdio.h>
#include <iostream>
#include <stdio.h>
#include <iostream>
#include "opencv2/core.hpp"
#include "opencv2/features2d.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/xfeatures2d.hpp"
using namespace std;
using namespace cv;
using namespace cv::xfeatures2d;
void readme();
/**
* @function main
* @brief Main function
*/
int main( int argc, char** argv )
{
if( argc != 3 )
{ readme(); return -1; }
Mat img_1 = imread( argv[1], IMREAD_GRAYSCALE );
Mat img_2 = imread( argv[2], IMREAD_GRAYSCALE );
if( !img_1.data || !img_2.data )
{ std::cout<< " --(!) Error reading images " << std::endl; return -1; }
//-- Step 1: Detect the keypoints using SURF Detector
int minHessian = 400;
SurfFeatureDetector detector( minHessian );
std::vector<KeyPoint> keypoints_1, keypoints_2;
detector.detect( img_1, keypoints_1 );
detector.detect( img_2, keypoints_2 );
//-- Step 2: Calculate descriptors (feature vectors)
SurfDescriptorExtractor extractor;
Mat descriptors_1, descriptors_2;
extractor.compute( img_1, keypoints_1, descriptors_1 );
extractor.compute( img_2, keypoints_2, descriptors_2 );
//-- Step 3: Matching descriptor vectors using FLANN matcher
FlannBasedMatcher matcher;
std::vector< DMatch > matches;
matcher.match( descriptors_1, descriptors_2, matches );
double max_dist = 0; double min_dist = 100;
//-- Quick calculation of max and min distances between keypoints
for( int i = 0; i < descriptors_1.rows; i++ )
{ double dist = matches[i].distance;
if( dist < min_dist ) min_dist = dist;
if( dist > max_dist ) max_dist = dist;
}
printf("-- Max dist : %f \n", max_dist );
printf("-- Min dist : %f \n", min_dist );
//-- Draw only "good" matches (i.e. whose distance is less than 2*min_dist,
//-- or a small arbitary value ( 0.02 ) in the event that min_dist is very
//-- small)
//-- PS.- radiusMatch can also be used here.
std::vector< DMatch > good_matches;
for( int i = 0; i < descriptors_1.rows; i++ )
{ if( matches[i].distance <= max(2*min_dist, 0.02) )
{ good_matches.push_back( matches[i]); }
}
//-- Draw only "good" matches
Mat img_matches;
drawMatches( img_1, keypoints_1, img_2, keypoints_2,
good_matches, img_matches, Scalar::all(-1), Scalar::all(-1),
vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS );
//-- Show detected matches
imshow( "Good Matches", img_matches );
for( int i = 0; i < (int)good_matches.size(); i++ )
{ printf( "-- Good Match [%d] Keypoint 1: %d -- Keypoint 2: %d \n", i, good_matches[i].queryIdx, good_matches[i].trainIdx ); }
waitKey(0);
return 0;
}
/**
* @function readme
*/
void readme()
{ std::cout << " Usage: ./SURF_FlannMatcher <img1> <img2>" << std::endl; }
.. literalinclude:: ../../../../samples/cpp/tutorial_code/features2D/SURF_FlannMatcher.cpp
:language: cpp
Explanation
============

View File

@ -20,7 +20,7 @@ Theory
Code
====
This tutorial code's is shown lines below. You can also download it from `here <http://code.opencv.org/projects/opencv/repository/revisions/master/raw/samples/cpp/tutorial_code/features2D/SURF_Homography.cpp>`_
This tutorial code's is shown lines below.
.. code-block:: cpp
@ -30,9 +30,10 @@ This tutorial code's is shown lines below. You can also download it from `here <
#include "opencv2/features2d.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/calib3d.hpp"
#include "opencv2/nonfree.hpp"
#include "opencv2/xfeatures2d.hpp"
using namespace cv;
using namespace cv::xfeatures2d;
void readme();

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

View File

@ -0,0 +1,113 @@
.. _Raster_IO_GDAL:
Reading Geospatial Raster files with GDAL
*****************************************
Geospatial raster data is a heavily used product in Geographic Information
Systems and Photogrammetry. Raster data typically can represent imagery
and Digital Elevation Models (DEM). The standard library for loading
GIS imagery is the Geographic Data Abstraction Library (GDAL). In this example, we
will show techniques for loading GIS raster formats using native OpenCV functions.
In addition, we will show some an example of how OpenCV can use this data for
novel and interesting purposes.
Goals
=====
The primary objectives for this tutorial:
.. container:: enumeratevisibleitemswithsquare
+ How to use OpenCV imread to load satellite imagery.
+ How to use OpenCV imread to load SRTM Digital Elevation Models
+ Given the corner coordinates of both the image and DEM, correllate the elevation data to the image to find elevations for each pixel.
+ Show a basic, easy-to-implement example of a terrain heat map.
+ Show a basic use of DEM data coupled with ortho-rectified imagery.
To implement these goals, the following code takes a Digital Elevation Model as well as a GeoTiff image of San Francisco as input.
The image and DEM data is processed and generates a terrain heat map of the image as well as labels areas of the city which would
be affected should the water level of the bay rise 10, 50, and 100 meters.
Code
====
.. literalinclude:: ../../../../samples/cpp/tutorial_code/HighGUI/GDAL_IO/gdal-image.cpp
:language: cpp
:linenos:
:tab-width: 4
How to Read Raster Data using GDAL
======================================
This demonstration uses the default OpenCV :ocv:func:`imread` function. The primary difference is that in order to force GDAL to load the
image, you must use the appropriate flag.
.. code-block:: cpp
cv::Mat image = cv::imread( argv[1], cv::IMREAD_LOAD_GDAL );
When loading digital elevation models, the actual numeric value of each pixel is essential
and cannot be scaled or truncated. For example, with image data a pixel represented as a double with a value of 1 has
an equal appearance to a pixel which is represented as an unsigned character with a value of 255.
With terrain data, the pixel value represents the elevation in meters. In order to ensure that OpenCV preserves the native value,
use the GDAL flag in imread with the ANYDEPTH flag.
.. code-block:: cpp
cv::Mat dem = cv::imread( argv[2], cv::IMREAD_LOAD_GDAL | cv::IMREAD_ANYDEPTH );
If you know beforehand the type of DEM model you are loading, then it may be a safe bet to test the ``Mat::type()`` or ``Mat::depth()``
using an assert or other mechanism. NASA or DOD specification documents can provide the input types for various
elevation models. The major types, SRTM and DTED, are both signed shorts.
Notes
=====
Lat/Lon (Geodetic) Coordinates should normally be avoided
---------------------------------------------------------
The Geodetic Coordinate System is a spherical coordinate system, meaning that using them with Cartesian mathematics is technically incorrect. This
demo uses them to increase the readability and is accurate enough to make the point. A better coordinate system would be Universal Transverse Mercator.
Finding the corner coordinates
------------------------------
One easy method to find the corner coordinates of an image is to use the command-line tool ``gdalinfo``. For imagery which is ortho-rectified and contains
the projection information, you can use the `USGS EarthExplorer <http://http://earthexplorer.usgs.gov>`_.
.. code-block:: bash
$> gdalinfo N37W123.hgt
Driver: SRTMHGT/SRTMHGT File Format
Files: N37W123.hgt
Size is 3601, 3601
Coordinate System is:
GEOGCS["WGS 84",
DATUM["WGS_1984",
... more output ...
Corner Coordinates:
Upper Left (-123.0001389, 38.0001389) (123d 0' 0.50"W, 38d 0' 0.50"N)
Lower Left (-123.0001389, 36.9998611) (123d 0' 0.50"W, 36d59'59.50"N)
Upper Right (-121.9998611, 38.0001389) (121d59'59.50"W, 38d 0' 0.50"N)
Lower Right (-121.9998611, 36.9998611) (121d59'59.50"W, 36d59'59.50"N)
Center (-122.5000000, 37.5000000) (122d30' 0.00"W, 37d30' 0.00"N)
... more output ...
Results
=======
Below is the output of the program. Use the first image as the input. For the DEM model, download the SRTM file located at the USGS here. `http://dds.cr.usgs.gov/srtm/version2_1/SRTM1/Region_04/N37W123.hgt.zip <http://dds.cr.usgs.gov/srtm/version2_1/SRTM1/Region_04/N37W123.hgt.zip>`_
.. image:: images/output.jpg
.. image:: images/heat-map.jpg
.. image:: images/flood-zone.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

View File

@ -64,6 +64,26 @@ This section contains valuable tutorials about how to read/save your image/video
:height: 90pt
:width: 90pt
+
.. tabularcolumns:: m{100pt} m{300pt}
.. cssclass:: toctableopencv
=============== ======================================================
|hGDAL_IO| *Title:* :ref:`Raster_IO_GDAL`
*Compatibility:* > OpenCV 2.0
*Author:* |Author_MarvinS|
Read common GIS Raster and DEM files to display and manipulate geographic data.
=============== ======================================================
.. |hGDAL_IO| image:: images/gdal-io.jpg
:height: 90pt
:width: 90pt
.. raw:: latex
@ -75,3 +95,4 @@ This section contains valuable tutorials about how to read/save your image/video
../trackbar/trackbar
../video-input-psnr-ssim/video-input-psnr-ssim
../video-write/video-write
../raster-gdal/raster_io_gdal

View File

@ -5,7 +5,7 @@
Introduction into Android Development
*************************************
This guide was designed to help you in learning Android development basics and seting up your
This guide was designed to help you in learning Android development basics and setting up your
working environment quickly. It was written with Windows 7 in mind, though it would work with Linux
(Ubuntu), Mac OS X and any other OS supported by Android SDK.

View File

@ -398,7 +398,7 @@ Now modify src/main/java/HelloOpenCV.java so it contains the following Java code
// Draw a bounding box around each face.
for (Rect rect : faceDetections.toArray()) {
Core.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(0, 255, 0));
Imgproc.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(0, 255, 0));
}
// Save the visualized detection.

View File

@ -4,4 +4,4 @@ if(NOT OPENCV_MODULES_PATH)
set(OPENCV_MODULES_PATH "${CMAKE_CURRENT_SOURCE_DIR}")
endif()
ocv_glob_modules(${OPENCV_MODULES_PATH} ${OPENCV_EXTRA_MODULES_PATH})
ocv_glob_modules(${OPENCV_MODULES_PATH} EXTRA ${OPENCV_EXTRA_MODULES_PATH})

View File

@ -46,7 +46,7 @@ ADD_LIBRARY(${the_target} SHARED camera_wrapper.h camera_wrapper.cpp)
string(REGEX REPLACE "[.]" "_" LIBRARY_DEF ${ANDROID_VERSION})
add_definitions(-DANDROID_r${LIBRARY_DEF})
target_link_libraries(${the_target} c m dl utils camera_client binder log)
ocv_target_link_libraries(${the_target} c m dl utils camera_client binder log)
if(NOT ANDROID_VERSION VERSION_LESS "3.0.0")
target_link_libraries(${the_target} gui )

View File

@ -760,6 +760,27 @@ They are
:math:`[R_2, -t]`.
By decomposing ``E``, you can only get the direction of the translation, so the function returns unit ``t``.
decomposeHomographyMat
--------------------------
Decompose a homography matrix to rotation(s), translation(s) and plane normal(s).
.. ocv:function:: int decomposeHomographyMat( InputArray H, InputArray K, OutputArrayOfArrays rotations, OutputArrayOfArrays translations, OutputArrayOfArrays normals)
:param H: The input homography matrix between two images.
:param K: The input intrinsic camera calibration matrix.
:param rotations: Array of rotation matrices.
:param translations: Array of translation matrices.
:param normals: Array of plane normal matrices.
This function extracts relative camera motion between two views observing a planar object from the homography ``H`` induced by the plane.
The intrinsic camera matrix ``K`` must also be provided. The function may return up to four mathematical solution sets. At least two of the
solutions may further be invalidated if point correspondences are available by applying positive depth constraint (all points must be in front of the camera).
The decomposition method is described in detail in [Malis]_.
recoverPose
---------------
@ -862,7 +883,7 @@ is minimized. If the parameter ``method`` is set to the default value 0, the fun
uses all the point pairs to compute an initial homography estimate with a simple least-squares scheme.
However, if not all of the point pairs (
:math:`srcPoints_i`,:math:`dstPoints_i` ) fit the rigid perspective transformation (that is, there
:math:`srcPoints_i`, :math:`dstPoints_i` ) fit the rigid perspective transformation (that is, there
are some outliers), this initial estimate will be poor.
In this case, you can use one of the two robust methods. Both methods, ``RANSAC`` and ``LMeDS`` , try many different random subsets
of the corresponding point pairs (of four pairs each), estimate
@ -885,7 +906,7 @@ if there are no outliers and the noise is rather small, use the default method (
The function is used to find initial intrinsic and extrinsic matrices.
Homography matrix is determined up to a scale. Thus, it is normalized so that
:math:`h_{33}=1` .
:math:`h_{33}=1`. Note that whenever an H matrix cannot be estimated, an empty one will be returned.
.. seealso::
@ -1500,6 +1521,364 @@ The function reconstructs 3-dimensional points (in homogeneous coordinates) by u
:ocv:func:`reprojectImageTo3D`
fisheye
----------
The methods in this namespace use a so-called fisheye camera model. ::
namespace fisheye
{
//! projects 3D points using fisheye model
void projectPoints(InputArray objectPoints, OutputArray imagePoints, const Affine3d& affine,
InputArray K, InputArray D, double alpha = 0, OutputArray jacobian = noArray());
//! projects points using fisheye model
void projectPoints(InputArray objectPoints, OutputArray imagePoints, InputArray rvec, InputArray tvec,
InputArray K, InputArray D, double alpha = 0, OutputArray jacobian = noArray());
//! distorts 2D points using fisheye model
void distortPoints(InputArray undistorted, OutputArray distorted, InputArray K, InputArray D, double alpha = 0);
//! undistorts 2D points using fisheye model
void undistortPoints(InputArray distorted, OutputArray undistorted,
InputArray K, InputArray D, InputArray R = noArray(), InputArray P = noArray());
//! computing undistortion and rectification maps for image transform by cv::remap()
//! If D is empty zero distortion is used, if R or P is empty identity matrixes are used
void initUndistortRectifyMap(InputArray K, InputArray D, InputArray R, InputArray P,
const cv::Size& size, int m1type, OutputArray map1, OutputArray map2);
//! undistorts image, optionally changes resolution and camera matrix.
void undistortImage(InputArray distorted, OutputArray undistorted,
InputArray K, InputArray D, InputArray Knew = cv::noArray(), const Size& new_size = Size());
//! estimates new camera matrix for undistortion or rectification
void estimateNewCameraMatrixForUndistortRectify(InputArray K, InputArray D, const Size &image_size, InputArray R,
OutputArray P, double balance = 0.0, const Size& new_size = Size(), double fov_scale = 1.0);
//! performs camera calibaration
double calibrate(InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints, const Size& image_size,
InputOutputArray K, InputOutputArray D, OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs, int flags = 0,
TermCriteria criteria = TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 100, DBL_EPSILON));
//! stereo rectification estimation
void stereoRectify(InputArray K1, InputArray D1, InputArray K2, InputArray D2, const Size &imageSize, InputArray R, InputArray tvec,
OutputArray R1, OutputArray R2, OutputArray P1, OutputArray P2, OutputArray Q, int flags, const Size &newImageSize = Size(),
double balance = 0.0, double fov_scale = 1.0);
//! performs stereo calibration
double stereoCalibrate(InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints1, InputArrayOfArrays imagePoints2,
InputOutputArray K1, InputOutputArray D1, InputOutputArray K2, InputOutputArray D2, Size imageSize,
OutputArray R, OutputArray T, int flags = CALIB_FIX_INTRINSIC,
TermCriteria criteria = TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 100, DBL_EPSILON));
};
Definitions:
Let P be a point in 3D of coordinates X in the world reference frame (stored in the matrix X)
The coordinate vector of P in the camera reference frame is:
.. class:: center
.. math::
Xc = R X + T
where R is the rotation matrix corresponding to the rotation vector om: R = rodrigues(om);
call x, y and z the 3 coordinates of Xc:
.. class:: center
.. math::
x = Xc_1 \\
y = Xc_2 \\
z = Xc_3
The pinehole projection coordinates of P is [a; b] where
.. class:: center
.. math::
a = x / z \ and \ b = y / z \\
r^2 = a^2 + b^2 \\
\theta = atan(r)
Fisheye distortion:
.. class:: center
.. math::
\theta_d = \theta (1 + k_1 \theta^2 + k_2 \theta^4 + k_3 \theta^6 + k_4 \theta^8)
The distorted point coordinates are [x'; y'] where
..class:: center
.. math::
x' = (\theta_d / r) x \\
y' = (\theta_d / r) y
Finally, convertion into pixel coordinates: The final pixel coordinates vector [u; v] where:
.. class:: center
.. math::
u = f_x (x' + \alpha y') + c_x \\
v = f_y yy + c_y
fisheye::projectPoints
---------------------------
Projects points using fisheye model
.. ocv:function:: void fisheye::projectPoints(InputArray objectPoints, OutputArray imagePoints, const Affine3d& affine, InputArray K, InputArray D, double alpha = 0, OutputArray jacobian = noArray())
.. ocv:function:: void fisheye::projectPoints(InputArray objectPoints, OutputArray imagePoints, InputArray rvec, InputArray tvec, InputArray K, InputArray D, double alpha = 0, OutputArray jacobian = noArray())
:param objectPoints: Array of object points, 1xN/Nx1 3-channel (or ``vector<Point3f>`` ), where N is the number of points in the view.
:param rvec: Rotation vector. See :ocv:func:`Rodrigues` for details.
:param tvec: Translation vector.
:param K: Camera matrix :math:`K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{_1}`.
:param D: Input vector of distortion coefficients :math:`(k_1, k_2, k_3, k_4)`.
:param alpha: The skew coefficient.
:param imagePoints: Output array of image points, 2xN/Nx2 1-channel or 1xN/Nx1 2-channel, or ``vector<Point2f>``.
:param jacobian: Optional output 2Nx15 jacobian matrix of derivatives of image points with respect to components of the focal lengths, coordinates of the principal point, distortion coefficients, rotation vector, translation vector, and the skew. In the old interface different components of the jacobian are returned via different output parameters.
The function computes projections of 3D points to the image plane given intrinsic and extrinsic camera parameters. Optionally, the function computes Jacobians - matrices of partial derivatives of image points coordinates (as functions of all the input parameters) with respect to the particular parameters, intrinsic and/or extrinsic.
fisheye::distortPoints
-------------------------
Distorts 2D points using fisheye model.
.. ocv:function:: void fisheye::distortPoints(InputArray undistorted, OutputArray distorted, InputArray K, InputArray D, double alpha = 0)
:param undistorted: Array of object points, 1xN/Nx1 2-channel (or ``vector<Point2f>`` ), where N is the number of points in the view.
:param K: Camera matrix :math:`K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{_1}`.
:param D: Input vector of distortion coefficients :math:`(k_1, k_2, k_3, k_4)`.
:param alpha: The skew coefficient.
:param distorted: Output array of image points, 1xN/Nx1 2-channel, or ``vector<Point2f>`` .
fisheye::undistortPoints
-----------------------------
Undistorts 2D points using fisheye model
.. ocv:function:: void fisheye::undistortPoints(InputArray distorted, OutputArray undistorted, InputArray K, InputArray D, InputArray R = noArray(), InputArray P = noArray())
:param distorted: Array of object points, 1xN/Nx1 2-channel (or ``vector<Point2f>`` ), where N is the number of points in the view.
:param K: Camera matrix :math:`K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{_1}`.
:param D: Input vector of distortion coefficients :math:`(k_1, k_2, k_3, k_4)`.
:param R: Rectification transformation in the object space: 3x3 1-channel, or vector: 3x1/1x3 1-channel or 1x1 3-channel
:param P: New camera matrix (3x3) or new projection matrix (3x4)
:param undistorted: Output array of image points, 1xN/Nx1 2-channel, or ``vector<Point2f>`` .
fisheye::initUndistortRectifyMap
-------------------------------------
Computes undistortion and rectification maps for image transform by cv::remap(). If D is empty zero distortion is used, if R or P is empty identity matrixes are used.
.. ocv:function:: void fisheye::initUndistortRectifyMap(InputArray K, InputArray D, InputArray R, InputArray P, const cv::Size& size, int m1type, OutputArray map1, OutputArray map2)
:param K: Camera matrix :math:`K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{_1}`.
:param D: Input vector of distortion coefficients :math:`(k_1, k_2, k_3, k_4)`.
:param R: Rectification transformation in the object space: 3x3 1-channel, or vector: 3x1/1x3 1-channel or 1x1 3-channel
:param P: New camera matrix (3x3) or new projection matrix (3x4)
:param size: Undistorted image size.
:param m1type: Type of the first output map that can be CV_32FC1 or CV_16SC2 . See convertMaps() for details.
:param map1: The first output map.
:param map2: The second output map.
fisheye::undistortImage
-----------------------
Transforms an image to compensate for fisheye lens distortion.
.. ocv:function:: void fisheye::undistortImage(InputArray distorted, OutputArray undistorted, InputArray K, InputArray D, InputArray Knew = cv::noArray(), const Size& new_size = Size())
:param distorted: image with fisheye lens distortion.
:param K: Camera matrix :math:`K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{_1}`.
:param D: Input vector of distortion coefficients :math:`(k_1, k_2, k_3, k_4)`.
:param Knew: Camera matrix of the distorted image. By default, it is the identity matrix but you may additionally scale and shift the result by using a different matrix.
:param undistorted: Output image with compensated fisheye lens distortion.
The function transforms an image to compensate radial and tangential lens distortion.
The function is simply a combination of
:ocv:func:`fisheye::initUndistortRectifyMap` (with unity ``R`` ) and
:ocv:func:`remap` (with bilinear interpolation). See the former function for details of the transformation being performed.
See below the results of undistortImage.
* a\) result of :ocv:func:`undistort` of perspective camera model (all possible coefficients (k_1, k_2, k_3, k_4, k_5, k_6) of distortion were optimized under calibration)
* b\) result of :ocv:func:`fisheye::undistortImage` of fisheye camera model (all possible coefficients (k_1, k_2, k_3, k_4) of fisheye distortion were optimized under calibration)
* c\) original image was captured with fisheye lens
Pictures a) and b) almost the same. But if we consider points of image located far from the center of image, we can notice that on image a) these points are distorted.
.. image:: pics/fisheye_undistorted.jpg
fisheye::estimateNewCameraMatrixForUndistortRectify
----------------------------------------------------------
Estimates new camera matrix for undistortion or rectification.
.. ocv:function:: void fisheye::estimateNewCameraMatrixForUndistortRectify(InputArray K, InputArray D, const Size &image_size, InputArray R, OutputArray P, double balance = 0.0, const Size& new_size = Size(), double fov_scale = 1.0)
:param K: Camera matrix :math:`K = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{_1}`.
:param D: Input vector of distortion coefficients :math:`(k_1, k_2, k_3, k_4)`.
:param R: Rectification transformation in the object space: 3x3 1-channel, or vector: 3x1/1x3 1-channel or 1x1 3-channel
:param P: New camera matrix (3x3) or new projection matrix (3x4)
:param balance: Sets the new focal length in range between the min focal length and the max focal length. Balance is in range of [0, 1].
:param fov_scale: Divisor for new focal length.
fisheye::stereoRectify
------------------------------
Stereo rectification for fisheye camera model
.. ocv:function:: void fisheye::stereoRectify(InputArray K1, InputArray D1, InputArray K2, InputArray D2, const Size &imageSize, InputArray R, InputArray tvec, OutputArray R1, OutputArray R2, OutputArray P1, OutputArray P2, OutputArray Q, int flags, const Size &newImageSize = Size(), double balance = 0.0, double fov_scale = 1.0)
:param K1: First camera matrix.
:param K2: Second camera matrix.
:param D1: First camera distortion parameters.
:param D2: Second camera distortion parameters.
:param imageSize: Size of the image used for stereo calibration.
:param rotation: Rotation matrix between the coordinate systems of the first and the second cameras.
:param tvec: Translation vector between coordinate systems of the cameras.
:param R1: Output 3x3 rectification transform (rotation matrix) for the first camera.
:param R2: Output 3x3 rectification transform (rotation matrix) for the second camera.
:param P1: Output 3x4 projection matrix in the new (rectified) coordinate systems for the first camera.
:param P2: Output 3x4 projection matrix in the new (rectified) coordinate systems for the second camera.
:param Q: Output :math:`4 \times 4` disparity-to-depth mapping matrix (see :ocv:func:`reprojectImageTo3D` ).
:param flags: Operation flags that may be zero or ``CV_CALIB_ZERO_DISPARITY`` . If the flag is set, the function makes the principal points of each camera have the same pixel coordinates in the rectified views. And if the flag is not set, the function may still shift the images in the horizontal or vertical direction (depending on the orientation of epipolar lines) to maximize the useful image area.
:param alpha: Free scaling parameter. If it is -1 or absent, the function performs the default scaling. Otherwise, the parameter should be between 0 and 1. ``alpha=0`` means that the rectified images are zoomed and shifted so that only valid pixels are visible (no black areas after rectification). ``alpha=1`` means that the rectified image is decimated and shifted so that all the pixels from the original images from the cameras are retained in the rectified images (no source image pixels are lost). Obviously, any intermediate value yields an intermediate result between those two extreme cases.
:param newImageSize: New image resolution after rectification. The same size should be passed to :ocv:func:`initUndistortRectifyMap` (see the ``stereo_calib.cpp`` sample in OpenCV samples directory). When (0,0) is passed (default), it is set to the original ``imageSize`` . Setting it to larger value can help you preserve details in the original image, especially when there is a big radial distortion.
:param roi1: Optional output rectangles inside the rectified images where all the pixels are valid. If ``alpha=0`` , the ROIs cover the whole images. Otherwise, they are likely to be smaller (see the picture below).
:param roi2: Optional output rectangles inside the rectified images where all the pixels are valid. If ``alpha=0`` , the ROIs cover the whole images. Otherwise, they are likely to be smaller (see the picture below).
:param balance: Sets the new focal length in range between the min focal length and the max focal length. Balance is in range of [0, 1].
:param fov_scale: Divisor for new focal length.
fisheye::calibrate
----------------------------
Performs camera calibaration
.. ocv:function:: double fisheye::calibrate(InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints, const Size& image_size, InputOutputArray K, InputOutputArray D, OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs, int flags = 0, TermCriteria criteria = TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 100, DBL_EPSILON))
:param objectPoints: vector of vectors of calibration pattern points in the calibration pattern coordinate space.
:param imagePoints: vector of vectors of the projections of calibration pattern points. ``imagePoints.size()`` and ``objectPoints.size()`` and ``imagePoints[i].size()`` must be equal to ``objectPoints[i].size()`` for each ``i``.
:param image_size: Size of the image used only to initialize the intrinsic camera matrix.
:param K: Output 3x3 floating-point camera matrix :math:`A = \vecthreethree{f_x}{0}{c_x}{0}{f_y}{c_y}{0}{0}{1}` . If ``fisheye::CALIB_USE_INTRINSIC_GUESS``/ is specified, some or all of ``fx, fy, cx, cy`` must be initialized before calling the function.
:param D: Output vector of distortion coefficients :math:`(k_1, k_2, k_3, k_4)`.
:param rvecs: Output vector of rotation vectors (see :ocv:func:`Rodrigues` ) estimated for each pattern view. That is, each k-th rotation vector together with the corresponding k-th translation vector (see the next output parameter description) brings the calibration pattern from the model coordinate space (in which object points are specified) to the world coordinate space, that is, a real position of the calibration pattern in the k-th pattern view (k=0.. *M* -1).
:param tvecs: Output vector of translation vectors estimated for each pattern view.
:param flags: Different flags that may be zero or a combination of the following values:
* **fisheye::CALIB_USE_INTRINSIC_GUESS** ``cameraMatrix`` contains valid initial values of ``fx, fy, cx, cy`` that are optimized further. Otherwise, ``(cx, cy)`` is initially set to the image center ( ``imageSize`` is used), and focal distances are computed in a least-squares fashion.
* **fisheye::CALIB_RECOMPUTE_EXTRINSIC** Extrinsic will be recomputed after each iteration of intrinsic optimization.
* **fisheye::CALIB_CHECK_COND** The functions will check validity of condition number.
* **fisheye::CALIB_FIX_SKEW** Skew coefficient (alpha) is set to zero and stay zero.
* **fisheye::CALIB_FIX_K1..4** Selected distortion coefficients are set to zeros and stay zero.
:param criteria: Termination criteria for the iterative optimization algorithm.
fisheye::stereoCalibrate
----------------------------
Performs stereo calibration
.. ocv:function:: double fisheye::stereoCalibrate(InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints1, InputArrayOfArrays imagePoints2, InputOutputArray K1, InputOutputArray D1, InputOutputArray K2, InputOutputArray D2, Size imageSize, OutputArray R, OutputArray T, int flags = CALIB_FIX_INTRINSIC, TermCriteria criteria = TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 100, DBL_EPSILON))
:param objectPoints: Vector of vectors of the calibration pattern points.
:param imagePoints1: Vector of vectors of the projections of the calibration pattern points, observed by the first camera.
:param imagePoints2: Vector of vectors of the projections of the calibration pattern points, observed by the second camera.
:param K1: Input/output first camera matrix: :math:`\vecthreethree{f_x^{(j)}}{0}{c_x^{(j)}}{0}{f_y^{(j)}}{c_y^{(j)}}{0}{0}{1}` , :math:`j = 0,\, 1` . If any of ``fisheye::CALIB_USE_INTRINSIC_GUESS`` , ``fisheye::CV_CALIB_FIX_INTRINSIC`` are specified, some or all of the matrix components must be initialized.
:param D1: Input/output vector of distortion coefficients :math:`(k_1, k_2, k_3, k_4)` of 4 elements.
:param K2: Input/output second camera matrix. The parameter is similar to ``K1`` .
:param D2: Input/output lens distortion coefficients for the second camera. The parameter is similar to ``D1`` .
:param imageSize: Size of the image used only to initialize intrinsic camera matrix.
:param R: Output rotation matrix between the 1st and the 2nd camera coordinate systems.
:param T: Output translation vector between the coordinate systems of the cameras.
:param flags: Different flags that may be zero or a combination of the following values:
* **fisheye::CV_CALIB_FIX_INTRINSIC** Fix ``K1, K2?`` and ``D1, D2?`` so that only ``R, T`` matrices are estimated.
* **fisheye::CALIB_USE_INTRINSIC_GUESS** ``K1, K2`` contains valid initial values of ``fx, fy, cx, cy`` that are optimized further. Otherwise, ``(cx, cy)`` is initially set to the image center (``imageSize`` is used), and focal distances are computed in a least-squares fashion.
* **fisheye::CALIB_RECOMPUTE_EXTRINSIC** Extrinsic will be recomputed after each iteration of intrinsic optimization.
* **fisheye::CALIB_CHECK_COND** The functions will check validity of condition number.
* **fisheye::CALIB_FIX_SKEW** Skew coefficient (alpha) is set to zero and stay zero.
* **fisheye::CALIB_FIX_K1..4** Selected distortion coefficients are set to zeros and stay zero.
:param criteria: Termination criteria for the iterative optimization algorithm.
.. [BT98] Birchfield, S. and Tomasi, C. A pixel dissimilarity measure that is insensitive to image sampling. IEEE Transactions on Pattern Analysis and Machine Intelligence. 1998.
@ -1518,3 +1897,5 @@ The function reconstructs 3-dimensional points (in homogeneous coordinates) by u
.. [Slabaugh] Slabaugh, G.G. Computing Euler angles from a rotation matrix. http://www.soi.city.ac.uk/~sbbh653/publications/euler.pdf (verified: 2013-04-15)
.. [Zhang2000] Z. Zhang. A Flexible New Technique for Camera Calibration. IEEE Transactions on Pattern Analysis and Machine Intelligence, 22(11):1330-1334, 2000.
.. [Malis] Malis, E. and Vargas, M. Deeper understanding of the homography decomposition for vision-based control, Research Report 6303, INRIA (2007)

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

View File

@ -46,6 +46,7 @@
#include "opencv2/core.hpp"
#include "opencv2/features2d.hpp"
#include "opencv2/core/affine.hpp"
namespace cv
{
@ -314,6 +315,11 @@ CV_EXPORTS_W int estimateAffine3D(InputArray src, InputArray dst,
double ransacThreshold = 3, double confidence = 0.99);
CV_EXPORTS_W int decomposeHomographyMat(InputArray H,
InputArray K,
OutputArrayOfArrays rotations,
OutputArrayOfArrays translations,
OutputArrayOfArrays normals);
class CV_EXPORTS_W StereoMatcher : public Algorithm
{
@ -411,6 +417,66 @@ CV_EXPORTS_W Ptr<StereoSGBM> createStereoSGBM(int minDisparity, int numDispariti
int speckleWindowSize = 0, int speckleRange = 0,
int mode = StereoSGBM::MODE_SGBM);
namespace fisheye
{
enum{
CALIB_USE_INTRINSIC_GUESS = 1,
CALIB_RECOMPUTE_EXTRINSIC = 2,
CALIB_CHECK_COND = 4,
CALIB_FIX_SKEW = 8,
CALIB_FIX_K1 = 16,
CALIB_FIX_K2 = 32,
CALIB_FIX_K3 = 64,
CALIB_FIX_K4 = 128,
CALIB_FIX_INTRINSIC = 256
};
//! projects 3D points using fisheye model
CV_EXPORTS void projectPoints(InputArray objectPoints, OutputArray imagePoints, const Affine3d& affine,
InputArray K, InputArray D, double alpha = 0, OutputArray jacobian = noArray());
//! projects points using fisheye model
CV_EXPORTS void projectPoints(InputArray objectPoints, OutputArray imagePoints, InputArray rvec, InputArray tvec,
InputArray K, InputArray D, double alpha = 0, OutputArray jacobian = noArray());
//! distorts 2D points using fisheye model
CV_EXPORTS void distortPoints(InputArray undistorted, OutputArray distorted, InputArray K, InputArray D, double alpha = 0);
//! undistorts 2D points using fisheye model
CV_EXPORTS void undistortPoints(InputArray distorted, OutputArray undistorted,
InputArray K, InputArray D, InputArray R = noArray(), InputArray P = noArray());
//! computing undistortion and rectification maps for image transform by cv::remap()
//! If D is empty zero distortion is used, if R or P is empty identity matrixes are used
CV_EXPORTS void initUndistortRectifyMap(InputArray K, InputArray D, InputArray R, InputArray P,
const cv::Size& size, int m1type, OutputArray map1, OutputArray map2);
//! undistorts image, optionally changes resolution and camera matrix. If Knew zero identity matrix is used
CV_EXPORTS void undistortImage(InputArray distorted, OutputArray undistorted,
InputArray K, InputArray D, InputArray Knew = cv::noArray(), const Size& new_size = Size());
//! estimates new camera matrix for undistortion or rectification
CV_EXPORTS void estimateNewCameraMatrixForUndistortRectify(InputArray K, InputArray D, const Size &image_size, InputArray R,
OutputArray P, double balance = 0.0, const Size& new_size = Size(), double fov_scale = 1.0);
//! performs camera calibaration
CV_EXPORTS double calibrate(InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints, const Size& image_size,
InputOutputArray K, InputOutputArray D, OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs, int flags = 0,
TermCriteria criteria = TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 100, DBL_EPSILON));
//! stereo rectification estimation
CV_EXPORTS void stereoRectify(InputArray K1, InputArray D1, InputArray K2, InputArray D2, const Size &imageSize, InputArray R, InputArray tvec,
OutputArray R1, OutputArray R2, OutputArray P1, OutputArray P2, OutputArray Q, int flags, const Size &newImageSize = Size(),
double balance = 0.0, double fov_scale = 1.0);
//! performs stereo calibaration
CV_EXPORTS double stereoCalibrate(InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints1, InputArrayOfArrays imagePoints2,
InputOutputArray K1, InputOutputArray D1, InputOutputArray K2, InputOutputArray D2, Size imageSize,
OutputArray R, OutputArray T, int flags = CALIB_FIX_INTRINSIC,
TermCriteria criteria = TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 100, DBL_EPSILON));
}
} // cv
#endif

View File

@ -40,7 +40,7 @@
//
//M*/
#include "perf_precomp.hpp"
#include "../perf_precomp.hpp"
#include "opencv2/ts/ocl_perf.hpp"
#ifdef HAVE_OPENCL

View File

@ -1939,7 +1939,7 @@ void cv::drawChessboardCorners( InputOutputArray _image, Size patternSize,
Mat image = _image.getMat(); CvMat c_image = _image.getMat();
int nelems = corners.checkVector(2, CV_32F, true);
CV_Assert(nelems >= 0);
cvDrawChessboardCorners( &c_image, patternSize, (CvPoint2D32f*)corners.data,
cvDrawChessboardCorners( &c_image, patternSize, corners.ptr<CvPoint2D32f>(),
nelems, patternWasFound );
}

View File

@ -2998,15 +2998,15 @@ static void collectCalibrationData( InputArrayOfArrays objectPoints,
int ni1 = imgpt1.checkVector(2, CV_32F);
CV_Assert( ni > 0 && ni == ni1 );
npoints.at<int>(i) = ni;
memcpy( objPtData + j, objpt.data, ni*sizeof(objPtData[0]) );
memcpy( imgPtData1 + j, imgpt1.data, ni*sizeof(imgPtData1[0]) );
memcpy( objPtData + j, objpt.ptr(), ni*sizeof(objPtData[0]) );
memcpy( imgPtData1 + j, imgpt1.ptr(), ni*sizeof(imgPtData1[0]) );
if( imgPtData2 )
{
Mat imgpt2 = imagePoints2.getMat(i);
int ni2 = imgpt2.checkVector(2, CV_32F);
CV_Assert( ni == ni2 );
memcpy( imgPtData2 + j, imgpt2.data, ni*sizeof(imgPtData2[0]) );
memcpy( imgPtData2 + j, imgpt2.ptr(), ni*sizeof(imgPtData2[0]) );
}
}
}
@ -3245,13 +3245,13 @@ double cv::calibrateCamera( InputArrayOfArrays _objectPoints,
{
_rvecs.create(3, 1, CV_64F, i, true);
Mat rv = _rvecs.getMat(i);
memcpy(rv.data, rvecM.ptr<double>(i), 3*sizeof(double));
memcpy(rv.ptr(), rvecM.ptr<double>(i), 3*sizeof(double));
}
if( tvecs_needed )
{
_tvecs.create(3, 1, CV_64F, i, true);
Mat tv = _tvecs.getMat(i);
memcpy(tv.data, tvecM.ptr<double>(i), 3*sizeof(double));
memcpy(tv.ptr(), tvecM.ptr<double>(i), 3*sizeof(double));
}
}
cameraMatrix.copyTo(_cameraMatrix);
@ -3472,7 +3472,7 @@ void cv::decomposeProjectionMatrix( InputArray _projMatrix, OutputArray _cameraM
if( _eulerAngles.needed() )
{
_eulerAngles.create(3, 1, CV_64F, -1, true);
p_eulerAngles = (CvPoint3D64f*)_eulerAngles.getMat().data;
p_eulerAngles = _eulerAngles.getMat().ptr<CvPoint3D64f>();
}
cvDecomposeProjectionMatrix(&c_projMatrix, &c_cameraMatrix, &c_rotMatrix,

View File

@ -40,6 +40,7 @@
//
//M*/
#include "precomp.hpp"
#include "circlesgrid.hpp"
#include <limits>
//#define DEBUG_CIRCLES

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,61 @@
#ifndef FISHEYE_INTERNAL_H
#define FISHEYE_INTERNAL_H
#include "precomp.hpp"
namespace cv { namespace internal {
struct CV_EXPORTS IntrinsicParams
{
Vec2d f;
Vec2d c;
Vec4d k;
double alpha;
std::vector<int> isEstimate;
IntrinsicParams();
IntrinsicParams(Vec2d f, Vec2d c, Vec4d k, double alpha = 0);
IntrinsicParams operator+(const Mat& a);
IntrinsicParams& operator =(const Mat& a);
void Init(const cv::Vec2d& f, const cv::Vec2d& c, const cv::Vec4d& k = Vec4d(0,0,0,0), const double& alpha = 0);
};
void projectPoints(cv::InputArray objectPoints, cv::OutputArray imagePoints,
cv::InputArray _rvec,cv::InputArray _tvec,
const IntrinsicParams& param, cv::OutputArray jacobian);
void ComputeExtrinsicRefine(const Mat& imagePoints, const Mat& objectPoints, Mat& rvec,
Mat& tvec, Mat& J, const int MaxIter,
const IntrinsicParams& param, const double thresh_cond);
CV_EXPORTS Mat ComputeHomography(Mat m, Mat M);
CV_EXPORTS Mat NormalizePixels(const Mat& imagePoints, const IntrinsicParams& param);
void InitExtrinsics(const Mat& _imagePoints, const Mat& _objectPoints, const IntrinsicParams& param, Mat& omckk, Mat& Tckk);
void CalibrateExtrinsics(InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints,
const IntrinsicParams& param, const int check_cond,
const double thresh_cond, InputOutputArray omc, InputOutputArray Tc);
void ComputeJacobians(InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints,
const IntrinsicParams& param, InputArray omc, InputArray Tc,
const int& check_cond, const double& thresh_cond, Mat& JJ2_inv, Mat& ex3);
CV_EXPORTS void EstimateUncertainties(InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints,
const IntrinsicParams& params, InputArray omc, InputArray Tc,
IntrinsicParams& errors, Vec2d& std_err, double thresh_cond, int check_cond, double& rms);
void dAB(cv::InputArray A, InputArray B, OutputArray dABdA, OutputArray dABdB);
void JRodriguesMatlab(const Mat& src, Mat& dst);
void compose_motion(InputArray _om1, InputArray _T1, InputArray _om2, InputArray _T2,
Mat& om3, Mat& T3, Mat& dom3dom1, Mat& dom3dT1, Mat& dom3dom2,
Mat& dom3dT2, Mat& dT3dom1, Mat& dT3dT1, Mat& dT3dom2, Mat& dT3dT2);
double median(const Mat& row);
Vec3d median3d(InputArray m);
}}
#endif

View File

@ -61,7 +61,7 @@ public:
Mat EE = Mat(Vt.t()).colRange(5, 9) * 1.0;
Mat A(10, 20, CV_64F);
EE = EE.t();
getCoeffMat((double*)EE.data, (double*)A.data);
getCoeffMat(EE.ptr<double>(), A.ptr<double>());
EE = EE.t();
A = A.colRange(0, 10).inv() * A.colRange(10, 20);
@ -137,7 +137,7 @@ public:
cv::Mat Evec = EE.col(0) * xs.back() + EE.col(1) * ys.back() + EE.col(2) * zs.back() + EE.col(3);
Evec /= norm(Evec);
memcpy(e + count * 9, Evec.data, 9 * sizeof(double));
memcpy(e + count * 9, Evec.ptr(), 9 * sizeof(double));
count++;
}

View File

@ -767,8 +767,8 @@ void cv::computeCorrespondEpilines( InputArray _points, int whichImage,
if( depth == CV_32S || depth == CV_32F )
{
const Point* ptsi = (const Point*)points.data;
const Point2f* ptsf = (const Point2f*)points.data;
const Point* ptsi = points.ptr<Point>();
const Point2f* ptsf = points.ptr<Point2f>();
Point3f* dstf = lines.ptr<Point3f>();
for( int i = 0; i < npoints; i++ )
{
@ -784,7 +784,7 @@ void cv::computeCorrespondEpilines( InputArray _points, int whichImage,
}
else
{
const Point2d* ptsd = (const Point2d*)points.data;
const Point2d* ptsd = points.ptr<Point2d>();
Point3d* dstd = lines.ptr<Point3d>();
for( int i = 0; i < npoints; i++ )
{
@ -829,8 +829,8 @@ void cv::convertPointsFromHomogeneous( InputArray _src, OutputArray _dst )
{
if( cn == 3 )
{
const Point3i* sptr = (const Point3i*)src.data;
Point2f* dptr = (Point2f*)dst.data;
const Point3i* sptr = src.ptr<Point3i>();
Point2f* dptr = dst.ptr<Point2f>();
for( i = 0; i < npoints; i++ )
{
float scale = sptr[i].z != 0 ? 1.f/sptr[i].z : 1.f;
@ -839,8 +839,8 @@ void cv::convertPointsFromHomogeneous( InputArray _src, OutputArray _dst )
}
else
{
const Vec4i* sptr = (const Vec4i*)src.data;
Point3f* dptr = (Point3f*)dst.data;
const Vec4i* sptr = src.ptr<Vec4i>();
Point3f* dptr = dst.ptr<Point3f>();
for( i = 0; i < npoints; i++ )
{
float scale = sptr[i][3] != 0 ? 1.f/sptr[i][3] : 1.f;
@ -852,8 +852,8 @@ void cv::convertPointsFromHomogeneous( InputArray _src, OutputArray _dst )
{
if( cn == 3 )
{
const Point3f* sptr = (const Point3f*)src.data;
Point2f* dptr = (Point2f*)dst.data;
const Point3f* sptr = src.ptr<Point3f>();
Point2f* dptr = dst.ptr<Point2f>();
for( i = 0; i < npoints; i++ )
{
float scale = sptr[i].z != 0.f ? 1.f/sptr[i].z : 1.f;
@ -862,8 +862,8 @@ void cv::convertPointsFromHomogeneous( InputArray _src, OutputArray _dst )
}
else
{
const Vec4f* sptr = (const Vec4f*)src.data;
Point3f* dptr = (Point3f*)dst.data;
const Vec4f* sptr = src.ptr<Vec4f>();
Point3f* dptr = dst.ptr<Point3f>();
for( i = 0; i < npoints; i++ )
{
float scale = sptr[i][3] != 0.f ? 1.f/sptr[i][3] : 1.f;
@ -875,8 +875,8 @@ void cv::convertPointsFromHomogeneous( InputArray _src, OutputArray _dst )
{
if( cn == 3 )
{
const Point3d* sptr = (const Point3d*)src.data;
Point2d* dptr = (Point2d*)dst.data;
const Point3d* sptr = src.ptr<Point3d>();
Point2d* dptr = dst.ptr<Point2d>();
for( i = 0; i < npoints; i++ )
{
double scale = sptr[i].z != 0. ? 1./sptr[i].z : 1.;
@ -885,8 +885,8 @@ void cv::convertPointsFromHomogeneous( InputArray _src, OutputArray _dst )
}
else
{
const Vec4d* sptr = (const Vec4d*)src.data;
Point3d* dptr = (Point3d*)dst.data;
const Vec4d* sptr = src.ptr<Vec4d>();
Point3d* dptr = dst.ptr<Point3d>();
for( i = 0; i < npoints; i++ )
{
double scale = sptr[i][3] != 0.f ? 1./sptr[i][3] : 1.;
@ -928,15 +928,15 @@ void cv::convertPointsToHomogeneous( InputArray _src, OutputArray _dst )
{
if( cn == 2 )
{
const Point2i* sptr = (const Point2i*)src.data;
Point3i* dptr = (Point3i*)dst.data;
const Point2i* sptr = src.ptr<Point2i>();
Point3i* dptr = dst.ptr<Point3i>();
for( i = 0; i < npoints; i++ )
dptr[i] = Point3i(sptr[i].x, sptr[i].y, 1);
}
else
{
const Point3i* sptr = (const Point3i*)src.data;
Vec4i* dptr = (Vec4i*)dst.data;
const Point3i* sptr = src.ptr<Point3i>();
Vec4i* dptr = dst.ptr<Vec4i>();
for( i = 0; i < npoints; i++ )
dptr[i] = Vec4i(sptr[i].x, sptr[i].y, sptr[i].z, 1);
}
@ -945,15 +945,15 @@ void cv::convertPointsToHomogeneous( InputArray _src, OutputArray _dst )
{
if( cn == 2 )
{
const Point2f* sptr = (const Point2f*)src.data;
Point3f* dptr = (Point3f*)dst.data;
const Point2f* sptr = src.ptr<Point2f>();
Point3f* dptr = dst.ptr<Point3f>();
for( i = 0; i < npoints; i++ )
dptr[i] = Point3f(sptr[i].x, sptr[i].y, 1.f);
}
else
{
const Point3f* sptr = (const Point3f*)src.data;
Vec4f* dptr = (Vec4f*)dst.data;
const Point3f* sptr = src.ptr<Point3f>();
Vec4f* dptr = dst.ptr<Vec4f>();
for( i = 0; i < npoints; i++ )
dptr[i] = Vec4f(sptr[i].x, sptr[i].y, sptr[i].z, 1.f);
}
@ -962,15 +962,15 @@ void cv::convertPointsToHomogeneous( InputArray _src, OutputArray _dst )
{
if( cn == 2 )
{
const Point2d* sptr = (const Point2d*)src.data;
Point3d* dptr = (Point3d*)dst.data;
const Point2d* sptr = src.ptr<Point2d>();
Point3d* dptr = dst.ptr<Point3d>();
for( i = 0; i < npoints; i++ )
dptr[i] = Point3d(sptr[i].x, sptr[i].y, 1.);
}
else
{
const Point3d* sptr = (const Point3d*)src.data;
Vec4d* dptr = (Vec4d*)dst.data;
const Point3d* sptr = src.ptr<Point3d>();
Vec4d* dptr = dst.ptr<Vec4d>();
for( i = 0; i < npoints; i++ )
dptr[i] = Vec4d(sptr[i].x, sptr[i].y, sptr[i].z, 1.);
}

View File

@ -0,0 +1,482 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// This is a homography decomposition implementation contributed to OpenCV
// by Samson Yilma. It implements the homography decomposition algorithm
// descriped in the research report:
// Malis, E and Vargas, M, "Deeper understanding of the homography decomposition
// for vision-based control", Research Report 6303, INRIA (2007)
//
// 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) 2014, Samson Yilma¸ (samson_yilma@yahoo.com), all rights reserved.
//
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "precomp.hpp"
#include <memory>
namespace cv
{
namespace HomographyDecomposition
{
//struct to hold solutions of homography decomposition
typedef struct _CameraMotion {
cv::Matx33d R; //!< rotation matrix
cv::Vec3d n; //!< normal of the plane the camera is looking at
cv::Vec3d t; //!< translation vector
} CameraMotion;
inline int signd(const double x)
{
return ( x >= 0 ? 1 : -1 );
}
class HomographyDecomp {
public:
HomographyDecomp() {}
virtual ~HomographyDecomp() {}
virtual void decomposeHomography(const cv::Matx33d& H, const cv::Matx33d& K,
std::vector<CameraMotion>& camMotions);
bool isRotationValid(const cv::Matx33d& R, const double epsilon=0.01);
protected:
bool passesSameSideOfPlaneConstraint(CameraMotion& motion);
virtual void decompose(std::vector<CameraMotion>& camMotions) = 0;
const cv::Matx33d& getHnorm() const {
return _Hnorm;
}
private:
cv::Matx33d normalize(const cv::Matx33d& H, const cv::Matx33d& K);
void removeScale();
cv::Matx33d _Hnorm;
};
class HomographyDecompZhang : public HomographyDecomp {
public:
HomographyDecompZhang():HomographyDecomp() {}
virtual ~HomographyDecompZhang() {}
private:
virtual void decompose(std::vector<CameraMotion>& camMotions);
bool findMotionFrom_tstar_n(const cv::Vec3d& tstar, const cv::Vec3d& n, CameraMotion& motion);
};
class HomographyDecompInria : public HomographyDecomp {
public:
HomographyDecompInria():HomographyDecomp() {}
virtual ~HomographyDecompInria() {}
private:
virtual void decompose(std::vector<CameraMotion>& camMotions);
double oppositeOfMinor(const cv::Matx33d& M, const int row, const int col);
void findRmatFrom_tstar_n(const cv::Vec3d& tstar, const cv::Vec3d& n, const double v, cv::Matx33d& R);
};
// normalizes homography with intrinsic camera parameters
Matx33d HomographyDecomp::normalize(const Matx33d& H, const Matx33d& K)
{
return K.inv() * H * K;
}
void HomographyDecomp::removeScale()
{
Mat W;
SVD::compute(_Hnorm, W);
_Hnorm = _Hnorm * (1.0/W.at<double>(1));
}
/*! This checks that the input is a pure rotation matrix 'm'.
* The conditions for this are: R' * R = I and det(R) = 1 (proper rotation matrix)
*/
bool HomographyDecomp::isRotationValid(const Matx33d& R, const double epsilon)
{
Matx33d RtR = R.t() * R;
Matx33d I(1,0,0, 0,1,0, 0,0,1);
if (norm(RtR, I, NORM_INF) > epsilon)
return false;
return (fabs(determinant(R) - 1.0) < epsilon);
}
bool HomographyDecomp::passesSameSideOfPlaneConstraint(CameraMotion& motion)
{
typedef Matx<double, 1, 1> Matx11d;
Matx31d t = Matx31d(motion.t);
Matx31d n = Matx31d(motion.n);
Matx11d proj = n.t() * motion.R.t() * t;
if ( (1 + proj(0, 0) ) <= 0 )
return false;
return true;
}
//!main routine to decompose homography
void HomographyDecomp::decomposeHomography(const Matx33d& H, const cv::Matx33d& K,
std::vector<CameraMotion>& camMotions)
{
//normalize homography matrix with intrinsic camera matrix
_Hnorm = normalize(H, K);
//remove scale of the normalized homography
removeScale();
//apply decomposition
decompose(camMotions);
}
/* function computes R&t from tstar, and plane normal(n) using
R = H * inv(I + tstar*transpose(n) );
t = R * tstar;
returns true if computed R&t is a valid solution
*/
bool HomographyDecompZhang::findMotionFrom_tstar_n(const cv::Vec3d& tstar, const cv::Vec3d& n, CameraMotion& motion)
{
Matx31d tstar_m = Mat(tstar);
Matx31d n_m = Mat(n);
Matx33d temp = tstar_m * n_m.t();
temp(0, 0) += 1.0;
temp(1, 1) += 1.0;
temp(2, 2) += 1.0;
motion.R = getHnorm() * temp.inv();
motion.t = motion.R * tstar;
motion.n = n;
return passesSameSideOfPlaneConstraint(motion);
}
void HomographyDecompZhang::decompose(std::vector<CameraMotion>& camMotions)
{
Mat W, U, Vt;
SVD::compute(getHnorm(), W, U, Vt);
double lambda1=W.at<double>(0);
double lambda3=W.at<double>(2);
double lambda1m3 = (lambda1-lambda3);
double lambda1m3_2 = lambda1m3*lambda1m3;
double lambda1t3 = lambda1*lambda3;
double t1 = 1.0/(2.0*lambda1t3);
double t2 = sqrt(1.0+4.0*lambda1t3/lambda1m3_2);
double t12 = t1*t2;
double e1 = -t1 + t12; //t1*(-1.0f + t2 );
double e3 = -t1 - t12; //t1*(-1.0f - t2);
double e1_2 = e1*e1;
double e3_2 = e3*e3;
double nv1p = sqrt(e1_2*lambda1m3_2 + 2*e1*(lambda1t3-1) + 1.0);
double nv3p = sqrt(e3_2*lambda1m3_2 + 2*e3*(lambda1t3-1) + 1.0);
double v1p[3], v3p[3];
v1p[0]=Vt.at<double>(0)*nv1p, v1p[1]=Vt.at<double>(1)*nv1p, v1p[2]=Vt.at<double>(2)*nv1p;
v3p[0]=Vt.at<double>(6)*nv3p, v3p[1]=Vt.at<double>(7)*nv3p, v3p[2]=Vt.at<double>(8)*nv3p;
/*The eight solutions are
(A): tstar = +- (v1p - v3p)/(e1 -e3), n = +- (e1*v3p - e3*v1p)/(e1-e3)
(B): tstar = +- (v1p + v3p)/(e1 -e3), n = +- (e1*v3p + e3*v1p)/(e1-e3)
*/
double v1pmv3p[3], v1ppv3p[3];
double e1v3me3v1[3], e1v3pe3v1[3];
double inv_e1me3 = 1.0/(e1-e3);
for(int kk=0;kk<3;++kk){
v1pmv3p[kk] = v1p[kk]-v3p[kk];
v1ppv3p[kk] = v1p[kk]+v3p[kk];
}
for(int kk=0; kk<3; ++kk){
double e1v3 = e1*v3p[kk];
double e3v1=e3*v1p[kk];
e1v3me3v1[kk] = e1v3-e3v1;
e1v3pe3v1[kk] = e1v3+e3v1;
}
Vec3d tstar_p, tstar_n;
Vec3d n_p, n_n;
///Solution group A
for(int kk=0; kk<3; ++kk) {
tstar_p[kk] = v1pmv3p[kk]*inv_e1me3;
tstar_n[kk] = -tstar_p[kk];
n_p[kk] = e1v3me3v1[kk]*inv_e1me3;
n_n[kk] = -n_p[kk];
}
CameraMotion cmotion;
//(A) Four different combinations for solution A
// (i) (+, +)
if (findMotionFrom_tstar_n(tstar_p, n_p, cmotion))
camMotions.push_back(cmotion);
// (ii) (+, -)
if (findMotionFrom_tstar_n(tstar_p, n_n, cmotion))
camMotions.push_back(cmotion);
// (iii) (-, +)
if (findMotionFrom_tstar_n(tstar_n, n_p, cmotion))
camMotions.push_back(cmotion);
// (iv) (-, -)
if (findMotionFrom_tstar_n(tstar_n, n_n, cmotion))
camMotions.push_back(cmotion);
//////////////////////////////////////////////////////////////////
///Solution group B
for(int kk=0;kk<3;++kk){
tstar_p[kk] = v1ppv3p[kk]*inv_e1me3;
tstar_n[kk] = -tstar_p[kk];
n_p[kk] = e1v3pe3v1[kk]*inv_e1me3;
n_n[kk] = -n_p[kk];
}
//(B) Four different combinations for solution B
// (i) (+, +)
if (findMotionFrom_tstar_n(tstar_p, n_p, cmotion))
camMotions.push_back(cmotion);
// (ii) (+, -)
if (findMotionFrom_tstar_n(tstar_p, n_n, cmotion))
camMotions.push_back(cmotion);
// (iii) (-, +)
if (findMotionFrom_tstar_n(tstar_n, n_p, cmotion))
camMotions.push_back(cmotion);
// (iv) (-, -)
if (findMotionFrom_tstar_n(tstar_n, n_n, cmotion))
camMotions.push_back(cmotion);
}
double HomographyDecompInria::oppositeOfMinor(const Matx33d& M, const int row, const int col)
{
int x1 = col == 0 ? 1 : 0;
int x2 = col == 2 ? 1 : 2;
int y1 = row == 0 ? 1 : 0;
int y2 = row == 2 ? 1 : 2;
return (M(y1, x2) * M(y2, x1) - M(y1, x1) * M(y2, x2));
}
//computes R = H( I - (2/v)*te_star*ne_t )
void HomographyDecompInria::findRmatFrom_tstar_n(const cv::Vec3d& tstar, const cv::Vec3d& n, const double v, cv::Matx33d& R)
{
Matx31d tstar_m = Matx31d(tstar);
Matx31d n_m = Matx31d(n);
Matx33d I(1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0, 1.0);
R = getHnorm() * (I - (2/v) * tstar_m * n_m.t() );
}
void HomographyDecompInria::decompose(std::vector<CameraMotion>& camMotions)
{
const double epsilon = 0.001;
Matx33d S;
//S = H'H - I
S = getHnorm().t() * getHnorm();
S(0, 0) -= 1.0;
S(1, 1) -= 1.0;
S(2, 2) -= 1.0;
//check if H is rotation matrix
if( norm(S, NORM_INF) < epsilon) {
CameraMotion motion;
motion.R = Matx33d(getHnorm());
motion.t = Vec3d(0, 0, 0);
motion.n = Vec3d(0, 0, 0);
camMotions.push_back(motion);
return;
}
//! Compute nvectors
Vec3d npa, npb;
double M00 = oppositeOfMinor(S, 0, 0);
double M11 = oppositeOfMinor(S, 1, 1);
double M22 = oppositeOfMinor(S, 2, 2);
double rtM00 = sqrt(M00);
double rtM11 = sqrt(M11);
double rtM22 = sqrt(M22);
double M01 = oppositeOfMinor(S, 0, 1);
double M12 = oppositeOfMinor(S, 1, 2);
double M02 = oppositeOfMinor(S, 0, 2);
int e12 = signd(M12);
int e02 = signd(M02);
int e01 = signd(M01);
double nS00 = abs(S(0, 0));
double nS11 = abs(S(1, 1));
double nS22 = abs(S(2, 2));
//find max( |Sii| ), i=0, 1, 2
int indx = 0;
if(nS00 < nS11){
indx = 1;
if( nS11 < nS22 )
indx = 2;
}
else {
if(nS00 < nS22 )
indx = 2;
}
switch (indx) {
case 0:
npa[0] = S(0, 0), npb[0] = S(0, 0);
npa[1] = S(0, 1) + rtM22, npb[1] = S(0, 1) - rtM22;
npa[2] = S(0, 2) + e12 * rtM11, npb[2] = S(0, 2) - e12 * rtM11;
break;
case 1:
npa[0] = S(0, 1) + rtM22, npb[0] = S(0, 1) - rtM22;
npa[1] = S(1, 1), npb[1] = S(1, 1);
npa[2] = S(1, 2) - e02 * rtM00, npb[2] = S(1, 2) + e02 * rtM00;
break;
case 2:
npa[0] = S(0, 2) + e01 * rtM11, npb[0] = S(0, 2) - e01 * rtM11;
npa[1] = S(1, 2) + rtM00, npb[1] = S(1, 2) - rtM00;
npa[2] = S(2, 2), npb[2] = S(2, 2);
break;
default:
break;
}
double traceS = S(0, 0) + S(1, 1) + S(2, 2);
double v = 2.0 * sqrt(1 + traceS - M00 - M11 - M22);
double ESii = signd(S(indx, indx)) ;
double r_2 = 2 + traceS + v;
double nt_2 = 2 + traceS - v;
double r = sqrt(r_2);
double n_t = sqrt(nt_2);
Vec3d na = npa / norm(npa);
Vec3d nb = npb / norm(npb);
double half_nt = 0.5 * n_t;
double esii_t_r = ESii * r;
Vec3d ta_star = half_nt * (esii_t_r * nb - n_t * na);
Vec3d tb_star = half_nt * (esii_t_r * na - n_t * nb);
camMotions.resize(4);
Matx33d Ra, Rb;
Vec3d ta, tb;
//Ra, ta, na
findRmatFrom_tstar_n(ta_star, na, v, Ra);
ta = Ra * ta_star;
camMotions[0].R = Ra;
camMotions[0].t = ta;
camMotions[0].n = na;
//Ra, -ta, -na
camMotions[1].R = Ra;
camMotions[1].t = -ta;
camMotions[1].n = -na;
//Rb, tb, nb
findRmatFrom_tstar_n(tb_star, nb, v, Rb);
tb = Rb * tb_star;
camMotions[2].R = Rb;
camMotions[2].t = tb;
camMotions[2].n = nb;
//Rb, -tb, -nb
camMotions[3].R = Rb;
camMotions[3].t = -tb;
camMotions[3].n = -nb;
}
} //namespace HomographyDecomposition
// function decomposes image-to-image homography to rotation and translation matrices
int decomposeHomographyMat(InputArray _H,
InputArray _K,
OutputArrayOfArrays _rotations,
OutputArrayOfArrays _translations,
OutputArrayOfArrays _normals)
{
using namespace std;
using namespace HomographyDecomposition;
Mat H = _H.getMat().reshape(1, 3);
CV_Assert(H.cols == 3 && H.rows == 3);
Mat K = _K.getMat().reshape(1, 3);
CV_Assert(K.cols == 3 && K.rows == 3);
auto_ptr<HomographyDecomp> hdecomp(new HomographyDecompInria);
vector<CameraMotion> motions;
hdecomp->decomposeHomography(H, K, motions);
int nsols = static_cast<int>(motions.size());
int depth = CV_64F; //double precision matrices used in CameraMotion struct
if (_rotations.needed()) {
_rotations.create(nsols, 1, depth);
for (int k = 0; k < nsols; ++k ) {
_rotations.getMatRef(k) = Mat(motions[k].R);
}
}
if (_translations.needed()) {
_translations.create(nsols, 1, depth);
for (int k = 0; k < nsols; ++k ) {
_translations.getMatRef(k) = Mat(motions[k].t);
}
}
if (_normals.needed()) {
_normals.create(nsols, 1, depth);
for (int k = 0; k < nsols; ++k ) {
_normals.getMatRef(k) = Mat(motions[k].n);
}
}
return nsols;
}
} //namespace cv

View File

@ -113,12 +113,12 @@ public:
int d1 = m1.channels() > 1 ? m1.channels() : m1.cols;
int d2 = m2.channels() > 1 ? m2.channels() : m2.cols;
int count = m1.checkVector(d1), count2 = m2.checkVector(d2);
const int *m1ptr = (const int*)m1.data, *m2ptr = (const int*)m2.data;
const int *m1ptr = m1.ptr<int>(), *m2ptr = m2.ptr<int>();
ms1.create(modelPoints, 1, CV_MAKETYPE(m1.depth(), d1));
ms2.create(modelPoints, 1, CV_MAKETYPE(m2.depth(), d2));
int *ms1ptr = (int*)ms1.data, *ms2ptr = (int*)ms2.data;
int *ms1ptr = ms1.ptr<int>(), *ms2ptr = ms2.ptr<int>();
CV_Assert( count >= modelPoints && count == count2 );
CV_Assert( (esz1 % sizeof(int)) == 0 && (esz2 % sizeof(int)) == 0 );
@ -343,7 +343,7 @@ public:
else
errf = err;
CV_Assert( errf.isContinuous() && errf.type() == CV_32F && (int)errf.total() == count );
std::sort((int*)errf.data, (int*)errf.data + count);
std::sort(errf.ptr<int>(), errf.ptr<int>() + count);
double median = count % 2 != 0 ?
errf.at<float>(count/2) : (errf.at<float>(count/2-1) + errf.at<float>(count/2))*0.5;

View File

@ -139,11 +139,13 @@ namespace cv
CameraParameters camera;
};
template <typename OpointType, typename IpointType>
static void pnpTask(const std::vector<char>& pointsMask, const Mat& objectPoints, const Mat& imagePoints,
const Parameters& params, std::vector<int>& inliers, Mat& rvec, Mat& tvec,
const Mat& rvecInit, const Mat& tvecInit, Mutex& resultsMutex)
{
Mat modelObjectPoints(1, MIN_POINTS_COUNT, CV_32FC3), modelImagePoints(1, MIN_POINTS_COUNT, CV_32FC2);
Mat modelObjectPoints(1, MIN_POINTS_COUNT, CV_MAKETYPE(DataDepth<OpointType>::value, 3));
Mat modelImagePoints(1, MIN_POINTS_COUNT, CV_MAKETYPE(DataDepth<IpointType>::value, 2));
for (int i = 0, colIndex = 0; i < (int)pointsMask.size(); i++)
{
if (pointsMask[i])
@ -162,7 +164,7 @@ namespace cv
for (int i = 0; i < MIN_POINTS_COUNT; i++)
for (int j = i + 1; j < MIN_POINTS_COUNT; j++)
{
if (norm(modelObjectPoints.at<Vec3f>(0, i) - modelObjectPoints.at<Vec3f>(0, j)) < eps)
if (norm(modelObjectPoints.at<Vec<OpointType,3> >(0, i) - modelObjectPoints.at<Vec<OpointType,3> >(0, j)) < eps)
num_same_points++;
}
if (num_same_points > 0)
@ -176,7 +178,7 @@ namespace cv
params.useExtrinsicGuess, params.flags);
std::vector<Point2f> projected_points;
std::vector<Point_<OpointType> > projected_points;
projected_points.resize(objectPoints.cols);
projectPoints(objectPoints, localRvec, localTvec, params.camera.intrinsics, params.camera.distortion, projected_points);
@ -186,9 +188,11 @@ namespace cv
std::vector<int> localInliers;
for (int i = 0; i < objectPoints.cols; i++)
{
Point2f p(imagePoints.at<Vec2f>(0, i)[0], imagePoints.at<Vec2f>(0, i)[1]);
//Although p is a 2D point it needs the same type as the object points to enable the norm calculation
Point_<OpointType> p((OpointType)imagePoints.at<Vec<IpointType,2> >(0, i)[0],
(OpointType)imagePoints.at<Vec<IpointType,2> >(0, i)[1]);
if ((norm(p - projected_points[i]) < params.reprojectionError)
&& (rotatedPoints.at<Vec3f>(0, i)[2] > 0)) //hack
&& (rotatedPoints.at<Vec<OpointType,3> >(0, i)[2] > 0)) //hack
{
localInliers.push_back(i);
}
@ -208,6 +212,30 @@ namespace cv
}
}
static void pnpTask(const std::vector<char>& pointsMask, const Mat& objectPoints, const Mat& imagePoints,
const Parameters& params, std::vector<int>& inliers, Mat& rvec, Mat& tvec,
const Mat& rvecInit, const Mat& tvecInit, Mutex& resultsMutex)
{
CV_Assert(objectPoints.depth() == CV_64F || objectPoints.depth() == CV_32F);
CV_Assert(imagePoints.depth() == CV_64F || imagePoints.depth() == CV_32F);
const bool objectDoublePrecision = objectPoints.depth() == CV_64F;
const bool imageDoublePrecision = imagePoints.depth() == CV_64F;
if(objectDoublePrecision)
{
if(imageDoublePrecision)
pnpTask<double, double>(pointsMask, objectPoints, imagePoints, params, inliers, rvec, tvec, rvecInit, tvecInit, resultsMutex);
else
pnpTask<double, float>(pointsMask, objectPoints, imagePoints, params, inliers, rvec, tvec, rvecInit, tvecInit, resultsMutex);
}
else
{
if(imageDoublePrecision)
pnpTask<float, double>(pointsMask, objectPoints, imagePoints, params, inliers, rvec, tvec, rvecInit, tvecInit, resultsMutex);
else
pnpTask<float, float>(pointsMask, objectPoints, imagePoints, params, inliers, rvec, tvec, rvecInit, tvecInit, resultsMutex);
}
}
class PnPSolver
{
public:
@ -283,10 +311,10 @@ void cv::solvePnPRansac(InputArray _opoints, InputArray _ipoints,
Mat cameraMatrix = _cameraMatrix.getMat(), distCoeffs = _distCoeffs.getMat();
CV_Assert(opoints.isContinuous());
CV_Assert(opoints.depth() == CV_32F);
CV_Assert(opoints.depth() == CV_32F || opoints.depth() == CV_64F);
CV_Assert((opoints.rows == 1 && opoints.channels() == 3) || opoints.cols*opoints.channels() == 3);
CV_Assert(ipoints.isContinuous());
CV_Assert(ipoints.depth() == CV_32F);
CV_Assert(ipoints.depth() == CV_32F || ipoints.depth() == CV_64F);
CV_Assert((ipoints.rows == 1 && ipoints.channels() == 2) || ipoints.cols*ipoints.channels() == 2);
_rvec.create(3, 1, CV_64FC1);
@ -322,7 +350,7 @@ void cv::solvePnPRansac(InputArray _opoints, InputArray _ipoints,
if (flags != P3P)
{
int i, pointsCount = (int)localInliers.size();
Mat inlierObjectPoints(1, pointsCount, CV_32FC3), inlierImagePoints(1, pointsCount, CV_32FC2);
Mat inlierObjectPoints(1, pointsCount, CV_MAKE_TYPE(opoints.depth(), 3)), inlierImagePoints(1, pointsCount, CV_MAKE_TYPE(ipoints.depth(), 2));
for (i = 0; i < pointsCount; i++)
{
int index = localInliers[i];

View File

@ -48,7 +48,7 @@
#include "precomp.hpp"
#include <stdio.h>
#include <limits>
#include "opencl_kernels.hpp"
#include "opencl_kernels_calib3d.hpp"
namespace cv
{
@ -114,7 +114,7 @@ static void prefilterNorm( const Mat& src, Mat& dst, int winsize, int ftzero, uc
int scale_g = winsize*winsize/8, scale_s = (1024 + scale_g)/(scale_g*2);
const int OFS = 256*5, TABSZ = OFS*2 + 256;
uchar tab[TABSZ];
const uchar* sptr = src.data;
const uchar* sptr = src.ptr();
int srcstep = (int)src.step;
Size size = src.size();
@ -294,10 +294,10 @@ static void findStereoCorrespondenceBM_SSE2( const Mat& left, const Mat& right,
ushort *sad, *hsad0, *hsad, *hsad_sub;
int *htext;
uchar *cbuf0, *cbuf;
const uchar* lptr0 = left.data + lofs;
const uchar* rptr0 = right.data + rofs;
const uchar* lptr0 = left.ptr() + lofs;
const uchar* rptr0 = right.ptr() + rofs;
const uchar *lptr, *lptr_sub, *rptr;
short* dptr = (short*)disp.data;
short* dptr = disp.ptr<short>();
int sstep = (int)left.step;
int dstep = (int)(disp.step/sizeof(dptr[0]));
int cstep = (height + dy0 + dy1)*ndisp;
@ -357,7 +357,7 @@ static void findStereoCorrespondenceBM_SSE2( const Mat& left, const Mat& right,
for( x = 0; x < width1; x++, dptr++ )
{
short* costptr = cost.data ? (short*)cost.data + lofs + x : &costbuf;
short* costptr = cost.data ? cost.ptr<short>() + lofs + x : &costbuf;
int x0 = x - wsz2 - 1, x1 = x + wsz2;
const uchar* cbuf_sub = cbuf0 + ((x0 + wsz2 + 1) % (wsz + 1))*cstep - dy0*ndisp;
cbuf = cbuf0 + ((x1 + wsz2 + 1) % (wsz + 1))*cstep - dy0*ndisp;
@ -542,10 +542,10 @@ findStereoCorrespondenceBM( const Mat& left, const Mat& right,
int *sad, *hsad0, *hsad, *hsad_sub, *htext;
uchar *cbuf0, *cbuf;
const uchar* lptr0 = left.data + lofs;
const uchar* rptr0 = right.data + rofs;
const uchar* lptr0 = left.ptr() + lofs;
const uchar* rptr0 = right.ptr() + rofs;
const uchar *lptr, *lptr_sub, *rptr;
short* dptr = (short*)disp.data;
short* dptr = disp.ptr<short>();
int sstep = (int)left.step;
int dstep = (int)(disp.step/sizeof(dptr[0]));
int cstep = (height+dy0+dy1)*ndisp;
@ -596,7 +596,7 @@ findStereoCorrespondenceBM( const Mat& left, const Mat& right,
for( x = 0; x < width1; x++, dptr++ )
{
int* costptr = cost.data ? (int*)cost.data + lofs + x : &costbuf;
int* costptr = cost.data ? cost.ptr<int>() + lofs + x : &costbuf;
int x0 = x - wsz2 - 1, x1 = x + wsz2;
const uchar* cbuf_sub = cbuf0 + ((x0 + wsz2 + 1) % (wsz + 1))*cstep - dy0*ndisp;
cbuf = cbuf0 + ((x1 + wsz2 + 1) % (wsz + 1))*cstep - dy0*ndisp;
@ -803,7 +803,7 @@ struct FindStereoCorrespInvoker : public ParallelLoopBody
int cols = left->cols, rows = left->rows;
int _row0 = std::min(cvRound(range.start * rows / nstripes), rows);
int _row1 = std::min(cvRound(range.end * rows / nstripes), rows);
uchar *ptr = slidingSumBuf->data + range.start * stripeBufSize;
uchar *ptr = slidingSumBuf->ptr() + range.start * stripeBufSize;
int FILTERED = (state->minDisparity - 1)*16;
Rect roi = validDisparityRect & Rect(0, _row0, cols, _row1 - _row0);
@ -988,7 +988,7 @@ public:
if( slidingSumBuf.cols < bufSize )
slidingSumBuf.create( 1, bufSize, CV_8U );
uchar *_buf = slidingSumBuf.data;
uchar *_buf = slidingSumBuf.ptr();
parallel_for_(Range(0, 2), PrefilterInvoker(left0, right0, left, right, _buf, _buf + bufSize1, &params), 1);

View File

@ -383,12 +383,12 @@ static void computeDisparitySGBM( const Mat& img1, const Mat& img2,
width*16*img1.channels()*sizeof(PixType) + // temp buffer for computing per-pixel cost
width*(sizeof(CostType) + sizeof(DispType)) + 1024; // disp2cost + disp2
if( !buffer.data || !buffer.isContinuous() ||
if( buffer.empty() || !buffer.isContinuous() ||
buffer.cols*buffer.rows*buffer.elemSize() < totalBufSize )
buffer.create(1, (int)totalBufSize, CV_8U);
// summary cost over different (nDirs) directions
CostType* Cbuf = (CostType*)alignPtr(buffer.data, ALIGN);
CostType* Cbuf = (CostType*)alignPtr(buffer.ptr(), ALIGN);
CostType* Sbuf = Cbuf + CSBufSize;
CostType* hsumBuf = Sbuf + CSBufSize;
CostType* pixDiff = hsumBuf + costBufSize*hsumBufNRows;
@ -982,10 +982,10 @@ void filterSpecklesImpl(cv::Mat& img, int newVal, int maxSpeckleSize, int maxDif
int width = img.cols, height = img.rows, npixels = width*height;
size_t bufSize = npixels*(int)(sizeof(Point2s) + sizeof(int) + sizeof(uchar));
if( !_buf.isContinuous() || !_buf.data || _buf.cols*_buf.rows*_buf.elemSize() < bufSize )
if( !_buf.isContinuous() || _buf.empty() || _buf.cols*_buf.rows*_buf.elemSize() < bufSize )
_buf.create(1, (int)bufSize, CV_8U);
uchar* buf = _buf.data;
uchar* buf = _buf.ptr();
int i, j, dstep = (int)(img.step/sizeof(T));
int* labels = (int*)buf;
buf += npixels*sizeof(labels[0]);
@ -1097,10 +1097,10 @@ void cv::filterSpeckles( InputOutputArray _img, double _newval, int maxSpeckleSi
if ((int)status >= 0)
{
if (type == CV_8UC1)
status = ippiMarkSpeckles_8u_C1IR((Ipp8u *)img.data, (int)img.step, roisize,
status = ippiMarkSpeckles_8u_C1IR(img.ptr<Ipp8u>(), (int)img.step, roisize,
(Ipp8u)newVal, maxSpeckleSize, (Ipp8u)maxDiff, ippiNormL1, buffer);
else
status = ippiMarkSpeckles_16s_C1IR((Ipp16s *)img.data, (int)img.step, roisize,
status = ippiMarkSpeckles_16s_C1IR(img.ptr<Ipp16s>(), (int)img.step, roisize,
(Ipp16s)newVal, maxSpeckleSize, (Ipp16s)maxDiff, ippiNormL1, buffer);
}

View File

@ -40,7 +40,7 @@
//
//M*/
#include "test_precomp.hpp"
#include "../test_precomp.hpp"
#include "cvconfig.h"
#include "opencv2/ts/ocl_test.hpp"

View File

@ -773,10 +773,10 @@ void CV_CameraCalibrationTest_CPP::calibrate( int imageCount, int* pointCounts,
flags );
assert( cameraMatrix.type() == CV_64FC1 );
memcpy( _cameraMatrix, cameraMatrix.data, 9*sizeof(double) );
memcpy( _cameraMatrix, cameraMatrix.ptr(), 9*sizeof(double) );
assert( cameraMatrix.type() == CV_64FC1 );
memcpy( _distortionCoeffs, distCoeffs.data, 4*sizeof(double) );
memcpy( _distortionCoeffs, distCoeffs.ptr(), 4*sizeof(double) );
vector<Mat>::iterator rvecsIt = rvecs.begin();
vector<Mat>::iterator tvecsIt = tvecs.begin();
@ -788,8 +788,8 @@ void CV_CameraCalibrationTest_CPP::calibrate( int imageCount, int* pointCounts,
{
Mat r9( 3, 3, CV_64FC1 );
Rodrigues( *rvecsIt, r9 );
memcpy( rm, r9.data, 9*sizeof(double) );
memcpy( tm, tvecsIt->data, 3*sizeof(double) );
memcpy( rm, r9.ptr(), 9*sizeof(double) );
memcpy( tm, tvecsIt->ptr(), 3*sizeof(double) );
}
}
@ -1430,7 +1430,7 @@ void CV_StereoCalibrationTest::run( int )
{
Mat left = imread(imglist[i*2]);
Mat right = imread(imglist[i*2+1]);
if(!left.data || !right.data)
if(left.empty() || right.empty())
{
ts->printf( cvtest::TS::LOG, "Can not load images %s and %s, testcase %d\n",
imglist[i*2].c_str(), imglist[i*2+1].c_str(), testcase );
@ -1722,7 +1722,7 @@ double CV_StereoCalibrationTest_C::calibrateStereoCamera( const vector<vector<Po
for( int i = 0, ni = 0, j = 0; i < nimages; i++, j += ni )
{
ni = (int)objectPoints[i].size();
((int*)npoints.data)[i] = ni;
npoints.ptr<int>()[i] = ni;
std::copy(objectPoints[i].begin(), objectPoints[i].end(), objPtData + j);
std::copy(imagePoints1[i].begin(), imagePoints1[i].end(), imgPtData + j);
std::copy(imagePoints2[i].begin(), imagePoints2[i].end(), imgPtData2 + j);

View File

@ -0,0 +1,613 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
// By downloading, copying, installing or using the software you agree to this license.
// If you do not agree to this license, do not download, install,
// copy or use the software.
//
//
// License Agreement
// For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "test_precomp.hpp"
#include <opencv2/ts/cuda_test.hpp>
#include "../src/fisheye.hpp"
class fisheyeTest : public ::testing::Test {
protected:
const static cv::Size imageSize;
const static cv::Matx33d K;
const static cv::Vec4d D;
const static cv::Matx33d R;
const static cv::Vec3d T;
std::string datasets_repository_path;
virtual void SetUp() {
datasets_repository_path = combine(cvtest::TS::ptr()->get_data_path(), "cv/cameracalibration/fisheye");
}
protected:
std::string combine(const std::string& _item1, const std::string& _item2);
cv::Mat mergeRectification(const cv::Mat& l, const cv::Mat& r);
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// TESTS::
TEST_F(fisheyeTest, projectPoints)
{
double cols = this->imageSize.width,
rows = this->imageSize.height;
const int N = 20;
cv::Mat distorted0(1, N*N, CV_64FC2), undist1, undist2, distorted1, distorted2;
undist2.create(distorted0.size(), CV_MAKETYPE(distorted0.depth(), 3));
cv::Vec2d* pts = distorted0.ptr<cv::Vec2d>();
cv::Vec2d c(this->K(0, 2), this->K(1, 2));
for(int y = 0, k = 0; y < N; ++y)
for(int x = 0; x < N; ++x)
{
cv::Vec2d point(x*cols/(N-1.f), y*rows/(N-1.f));
pts[k++] = (point - c) * 0.85 + c;
}
cv::fisheye::undistortPoints(distorted0, undist1, this->K, this->D);
cv::Vec2d* u1 = undist1.ptr<cv::Vec2d>();
cv::Vec3d* u2 = undist2.ptr<cv::Vec3d>();
for(int i = 0; i < (int)distorted0.total(); ++i)
u2[i] = cv::Vec3d(u1[i][0], u1[i][1], 1.0);
cv::fisheye::distortPoints(undist1, distorted1, this->K, this->D);
cv::fisheye::projectPoints(undist2, distorted2, cv::Vec3d::all(0), cv::Vec3d::all(0), this->K, this->D);
EXPECT_MAT_NEAR(distorted0, distorted1, 1e-10);
EXPECT_MAT_NEAR(distorted0, distorted2, 1e-10);
}
TEST_F(fisheyeTest, DISABLED_undistortImage)
{
cv::Matx33d K = this->K;
cv::Mat D = cv::Mat(this->D);
std::string file = combine(datasets_repository_path, "/calib-3_stereo_from_JY/left/stereo_pair_014.jpg");
cv::Matx33d newK = K;
cv::Mat distorted = cv::imread(file), undistorted;
{
newK(0, 0) = 100;
newK(1, 1) = 100;
cv::fisheye::undistortImage(distorted, undistorted, K, D, newK);
cv::Mat correct = cv::imread(combine(datasets_repository_path, "new_f_100.png"));
if (correct.empty())
CV_Assert(cv::imwrite(combine(datasets_repository_path, "new_f_100.png"), undistorted));
else
EXPECT_MAT_NEAR(correct, undistorted, 1e-10);
}
{
double balance = 1.0;
cv::fisheye::estimateNewCameraMatrixForUndistortRectify(K, D, distorted.size(), cv::noArray(), newK, balance);
cv::fisheye::undistortImage(distorted, undistorted, K, D, newK);
cv::Mat correct = cv::imread(combine(datasets_repository_path, "balance_1.0.png"));
if (correct.empty())
CV_Assert(cv::imwrite(combine(datasets_repository_path, "balance_1.0.png"), undistorted));
else
EXPECT_MAT_NEAR(correct, undistorted, 1e-10);
}
{
double balance = 0.0;
cv::fisheye::estimateNewCameraMatrixForUndistortRectify(K, D, distorted.size(), cv::noArray(), newK, balance);
cv::fisheye::undistortImage(distorted, undistorted, K, D, newK);
cv::Mat correct = cv::imread(combine(datasets_repository_path, "balance_0.0.png"));
if (correct.empty())
CV_Assert(cv::imwrite(combine(datasets_repository_path, "balance_0.0.png"), undistorted));
else
EXPECT_MAT_NEAR(correct, undistorted, 1e-10);
}
}
TEST_F(fisheyeTest, jacobians)
{
int n = 10;
cv::Mat X(1, n, CV_64FC3);
cv::Mat om(3, 1, CV_64F), T(3, 1, CV_64F);
cv::Mat f(2, 1, CV_64F), c(2, 1, CV_64F);
cv::Mat k(4, 1, CV_64F);
double alpha;
cv::RNG r;
r.fill(X, cv::RNG::NORMAL, 2, 1);
X = cv::abs(X) * 10;
r.fill(om, cv::RNG::NORMAL, 0, 1);
om = cv::abs(om);
r.fill(T, cv::RNG::NORMAL, 0, 1);
T = cv::abs(T); T.at<double>(2) = 4; T *= 10;
r.fill(f, cv::RNG::NORMAL, 0, 1);
f = cv::abs(f) * 1000;
r.fill(c, cv::RNG::NORMAL, 0, 1);
c = cv::abs(c) * 1000;
r.fill(k, cv::RNG::NORMAL, 0, 1);
k*= 0.5;
alpha = 0.01*r.gaussian(1);
cv::Mat x1, x2, xpred;
cv::Matx33d K(f.at<double>(0), alpha * f.at<double>(0), c.at<double>(0),
0, f.at<double>(1), c.at<double>(1),
0, 0, 1);
cv::Mat jacobians;
cv::fisheye::projectPoints(X, x1, om, T, K, k, alpha, jacobians);
//test on T:
cv::Mat dT(3, 1, CV_64FC1);
r.fill(dT, cv::RNG::NORMAL, 0, 1);
dT *= 1e-9*cv::norm(T);
cv::Mat T2 = T + dT;
cv::fisheye::projectPoints(X, x2, om, T2, K, k, alpha, cv::noArray());
xpred = x1 + cv::Mat(jacobians.colRange(11,14) * dT).reshape(2, 1);
CV_Assert (cv::norm(x2 - xpred) < 1e-10);
//test on om:
cv::Mat dom(3, 1, CV_64FC1);
r.fill(dom, cv::RNG::NORMAL, 0, 1);
dom *= 1e-9*cv::norm(om);
cv::Mat om2 = om + dom;
cv::fisheye::projectPoints(X, x2, om2, T, K, k, alpha, cv::noArray());
xpred = x1 + cv::Mat(jacobians.colRange(8,11) * dom).reshape(2, 1);
CV_Assert (cv::norm(x2 - xpred) < 1e-10);
//test on f:
cv::Mat df(2, 1, CV_64FC1);
r.fill(df, cv::RNG::NORMAL, 0, 1);
df *= 1e-9*cv::norm(f);
cv::Matx33d K2 = K + cv::Matx33d(df.at<double>(0), df.at<double>(0) * alpha, 0, 0, df.at<double>(1), 0, 0, 0, 0);
cv::fisheye::projectPoints(X, x2, om, T, K2, k, alpha, cv::noArray());
xpred = x1 + cv::Mat(jacobians.colRange(0,2) * df).reshape(2, 1);
CV_Assert (cv::norm(x2 - xpred) < 1e-10);
//test on c:
cv::Mat dc(2, 1, CV_64FC1);
r.fill(dc, cv::RNG::NORMAL, 0, 1);
dc *= 1e-9*cv::norm(c);
K2 = K + cv::Matx33d(0, 0, dc.at<double>(0), 0, 0, dc.at<double>(1), 0, 0, 0);
cv::fisheye::projectPoints(X, x2, om, T, K2, k, alpha, cv::noArray());
xpred = x1 + cv::Mat(jacobians.colRange(2,4) * dc).reshape(2, 1);
CV_Assert (cv::norm(x2 - xpred) < 1e-10);
//test on k:
cv::Mat dk(4, 1, CV_64FC1);
r.fill(dk, cv::RNG::NORMAL, 0, 1);
dk *= 1e-9*cv::norm(k);
cv::Mat k2 = k + dk;
cv::fisheye::projectPoints(X, x2, om, T, K, k2, alpha, cv::noArray());
xpred = x1 + cv::Mat(jacobians.colRange(4,8) * dk).reshape(2, 1);
CV_Assert (cv::norm(x2 - xpred) < 1e-10);
//test on alpha:
cv::Mat dalpha(1, 1, CV_64FC1);
r.fill(dalpha, cv::RNG::NORMAL, 0, 1);
dalpha *= 1e-9*cv::norm(f);
double alpha2 = alpha + dalpha.at<double>(0);
K2 = K + cv::Matx33d(0, f.at<double>(0) * dalpha.at<double>(0), 0, 0, 0, 0, 0, 0, 0);
cv::fisheye::projectPoints(X, x2, om, T, K, k, alpha2, cv::noArray());
xpred = x1 + cv::Mat(jacobians.col(14) * dalpha).reshape(2, 1);
CV_Assert (cv::norm(x2 - xpred) < 1e-10);
}
TEST_F(fisheyeTest, Calibration)
{
const int n_images = 34;
std::vector<std::vector<cv::Point2d> > imagePoints(n_images);
std::vector<std::vector<cv::Point3d> > objectPoints(n_images);
const std::string folder =combine(datasets_repository_path, "calib-3_stereo_from_JY");
cv::FileStorage fs_left(combine(folder, "left.xml"), cv::FileStorage::READ);
CV_Assert(fs_left.isOpened());
for(int i = 0; i < n_images; ++i)
fs_left[cv::format("image_%d", i )] >> imagePoints[i];
fs_left.release();
cv::FileStorage fs_object(combine(folder, "object.xml"), cv::FileStorage::READ);
CV_Assert(fs_object.isOpened());
for(int i = 0; i < n_images; ++i)
fs_object[cv::format("image_%d", i )] >> objectPoints[i];
fs_object.release();
int flag = 0;
flag |= cv::fisheye::CALIB_RECOMPUTE_EXTRINSIC;
flag |= cv::fisheye::CALIB_CHECK_COND;
flag |= cv::fisheye::CALIB_FIX_SKEW;
cv::Matx33d K;
cv::Vec4d D;
cv::fisheye::calibrate(objectPoints, imagePoints, imageSize, K, D,
cv::noArray(), cv::noArray(), flag, cv::TermCriteria(3, 20, 1e-6));
EXPECT_MAT_NEAR(K, this->K, 1e-10);
EXPECT_MAT_NEAR(D, this->D, 1e-10);
}
TEST_F(fisheyeTest, Homography)
{
const int n_images = 1;
std::vector<std::vector<cv::Point2d> > imagePoints(n_images);
std::vector<std::vector<cv::Point3d> > objectPoints(n_images);
const std::string folder =combine(datasets_repository_path, "calib-3_stereo_from_JY");
cv::FileStorage fs_left(combine(folder, "left.xml"), cv::FileStorage::READ);
CV_Assert(fs_left.isOpened());
for(int i = 0; i < n_images; ++i)
fs_left[cv::format("image_%d", i )] >> imagePoints[i];
fs_left.release();
cv::FileStorage fs_object(combine(folder, "object.xml"), cv::FileStorage::READ);
CV_Assert(fs_object.isOpened());
for(int i = 0; i < n_images; ++i)
fs_object[cv::format("image_%d", i )] >> objectPoints[i];
fs_object.release();
cv::internal::IntrinsicParams param;
param.Init(cv::Vec2d(cv::max(imageSize.width, imageSize.height) / CV_PI, cv::max(imageSize.width, imageSize.height) / CV_PI),
cv::Vec2d(imageSize.width / 2.0 - 0.5, imageSize.height / 2.0 - 0.5));
cv::Mat _imagePoints (imagePoints[0]);
cv::Mat _objectPoints(objectPoints[0]);
cv::Mat imagePointsNormalized = NormalizePixels(_imagePoints, param).reshape(1).t();
_objectPoints = _objectPoints.reshape(1).t();
cv::Mat objectPointsMean, covObjectPoints;
int Np = imagePointsNormalized.cols;
cv::calcCovarMatrix(_objectPoints, covObjectPoints, objectPointsMean, cv::COVAR_NORMAL | cv::COVAR_COLS);
cv::SVD svd(covObjectPoints);
cv::Mat R(svd.vt);
if (cv::norm(R(cv::Rect(2, 0, 1, 2))) < 1e-6)
R = cv::Mat::eye(3,3, CV_64FC1);
if (cv::determinant(R) < 0)
R = -R;
cv::Mat T = -R * objectPointsMean;
cv::Mat X_new = R * _objectPoints + T * cv::Mat::ones(1, Np, CV_64FC1);
cv::Mat H = cv::internal::ComputeHomography(imagePointsNormalized, X_new.rowRange(0, 2));
cv::Mat M = cv::Mat::ones(3, X_new.cols, CV_64FC1);
X_new.rowRange(0, 2).copyTo(M.rowRange(0, 2));
cv::Mat mrep = H * M;
cv::divide(mrep, cv::Mat::ones(3,1, CV_64FC1) * mrep.row(2).clone(), mrep);
cv::Mat merr = (mrep.rowRange(0, 2) - imagePointsNormalized).t();
cv::Vec2d std_err;
cv::meanStdDev(merr.reshape(2), cv::noArray(), std_err);
std_err *= sqrt((double)merr.reshape(2).total() / (merr.reshape(2).total() - 1));
cv::Vec2d correct_std_err(0.00516740156010384, 0.00644205331553901);
EXPECT_MAT_NEAR(std_err, correct_std_err, 1e-12);
}
TEST_F(fisheyeTest, EtimateUncertainties)
{
const int n_images = 34;
std::vector<std::vector<cv::Point2d> > imagePoints(n_images);
std::vector<std::vector<cv::Point3d> > objectPoints(n_images);
const std::string folder =combine(datasets_repository_path, "calib-3_stereo_from_JY");
cv::FileStorage fs_left(combine(folder, "left.xml"), cv::FileStorage::READ);
CV_Assert(fs_left.isOpened());
for(int i = 0; i < n_images; ++i)
fs_left[cv::format("image_%d", i )] >> imagePoints[i];
fs_left.release();
cv::FileStorage fs_object(combine(folder, "object.xml"), cv::FileStorage::READ);
CV_Assert(fs_object.isOpened());
for(int i = 0; i < n_images; ++i)
fs_object[cv::format("image_%d", i )] >> objectPoints[i];
fs_object.release();
int flag = 0;
flag |= cv::fisheye::CALIB_RECOMPUTE_EXTRINSIC;
flag |= cv::fisheye::CALIB_CHECK_COND;
flag |= cv::fisheye::CALIB_FIX_SKEW;
cv::Matx33d K;
cv::Vec4d D;
std::vector<cv::Vec3d> rvec;
std::vector<cv::Vec3d> tvec;
cv::fisheye::calibrate(objectPoints, imagePoints, imageSize, K, D,
rvec, tvec, flag, cv::TermCriteria(3, 20, 1e-6));
cv::internal::IntrinsicParams param, errors;
cv::Vec2d err_std;
double thresh_cond = 1e6;
int check_cond = 1;
param.Init(cv::Vec2d(K(0,0), K(1,1)), cv::Vec2d(K(0,2), K(1, 2)), D);
param.isEstimate = std::vector<int>(9, 1);
param.isEstimate[4] = 0;
errors.isEstimate = param.isEstimate;
double rms;
cv::internal::EstimateUncertainties(objectPoints, imagePoints, param, rvec, tvec,
errors, err_std, thresh_cond, check_cond, rms);
EXPECT_MAT_NEAR(errors.f, cv::Vec2d(1.29837104202046, 1.31565641071524), 1e-10);
EXPECT_MAT_NEAR(errors.c, cv::Vec2d(0.890439368129246, 0.816096854937896), 1e-10);
EXPECT_MAT_NEAR(errors.k, cv::Vec4d(0.00516248605191506, 0.0168181467500934, 0.0213118690274604, 0.00916010877545648), 1e-10);
EXPECT_MAT_NEAR(err_std, cv::Vec2d(0.187475975266883, 0.185678953263995), 1e-10);
CV_Assert(abs(rms - 0.263782587133546) < 1e-10);
CV_Assert(errors.alpha == 0);
}
TEST_F(fisheyeTest, rectify)
{
const std::string folder =combine(datasets_repository_path, "calib-3_stereo_from_JY");
cv::Size calibration_size = this->imageSize, requested_size = calibration_size;
cv::Matx33d K1 = this->K, K2 = K1;
cv::Mat D1 = cv::Mat(this->D), D2 = D1;
cv::Vec3d T = this->T;
cv::Matx33d R = this->R;
double balance = 0.0, fov_scale = 1.1;
cv::Mat R1, R2, P1, P2, Q;
cv::fisheye::stereoRectify(K1, D1, K2, D2, calibration_size, R, T, R1, R2, P1, P2, Q,
cv::CALIB_ZERO_DISPARITY, requested_size, balance, fov_scale);
cv::Mat lmapx, lmapy, rmapx, rmapy;
//rewrite for fisheye
cv::fisheye::initUndistortRectifyMap(K1, D1, R1, P1, requested_size, CV_32F, lmapx, lmapy);
cv::fisheye::initUndistortRectifyMap(K2, D2, R2, P2, requested_size, CV_32F, rmapx, rmapy);
cv::Mat l, r, lundist, rundist;
cv::VideoCapture lcap(combine(folder, "left/stereo_pair_%03d.jpg")),
rcap(combine(folder, "right/stereo_pair_%03d.jpg"));
for(int i = 0;; ++i)
{
lcap >> l; rcap >> r;
if (l.empty() || r.empty())
break;
int ndisp = 128;
cv::rectangle(l, cv::Rect(255, 0, 829, l.rows-1), cv::Scalar(0, 0, 255));
cv::rectangle(r, cv::Rect(255, 0, 829, l.rows-1), cv::Scalar(0, 0, 255));
cv::rectangle(r, cv::Rect(255-ndisp, 0, 829+ndisp ,l.rows-1), cv::Scalar(0, 0, 255));
cv::remap(l, lundist, lmapx, lmapy, cv::INTER_LINEAR);
cv::remap(r, rundist, rmapx, rmapy, cv::INTER_LINEAR);
cv::Mat rectification = mergeRectification(lundist, rundist);
cv::Mat correct = cv::imread(combine(datasets_repository_path, cv::format("rectification_AB_%03d.png", i)));
if (correct.empty())
cv::imwrite(combine(datasets_repository_path, cv::format("rectification_AB_%03d.png", i)), rectification);
else
EXPECT_MAT_NEAR(correct, rectification, 1e-10);
}
}
TEST_F(fisheyeTest, stereoCalibrate)
{
const int n_images = 34;
const std::string folder =combine(datasets_repository_path, "calib-3_stereo_from_JY");
std::vector<std::vector<cv::Point2d> > leftPoints(n_images);
std::vector<std::vector<cv::Point2d> > rightPoints(n_images);
std::vector<std::vector<cv::Point3d> > objectPoints(n_images);
cv::FileStorage fs_left(combine(folder, "left.xml"), cv::FileStorage::READ);
CV_Assert(fs_left.isOpened());
for(int i = 0; i < n_images; ++i)
fs_left[cv::format("image_%d", i )] >> leftPoints[i];
fs_left.release();
cv::FileStorage fs_right(combine(folder, "right.xml"), cv::FileStorage::READ);
CV_Assert(fs_right.isOpened());
for(int i = 0; i < n_images; ++i)
fs_right[cv::format("image_%d", i )] >> rightPoints[i];
fs_right.release();
cv::FileStorage fs_object(combine(folder, "object.xml"), cv::FileStorage::READ);
CV_Assert(fs_object.isOpened());
for(int i = 0; i < n_images; ++i)
fs_object[cv::format("image_%d", i )] >> objectPoints[i];
fs_object.release();
cv::Matx33d K1, K2, R;
cv::Vec3d T;
cv::Vec4d D1, D2;
int flag = 0;
flag |= cv::fisheye::CALIB_RECOMPUTE_EXTRINSIC;
flag |= cv::fisheye::CALIB_CHECK_COND;
flag |= cv::fisheye::CALIB_FIX_SKEW;
// flag |= cv::fisheye::CALIB_FIX_INTRINSIC;
cv::fisheye::stereoCalibrate(objectPoints, leftPoints, rightPoints,
K1, D1, K2, D2, imageSize, R, T, flag,
cv::TermCriteria(3, 12, 0));
cv::Matx33d R_correct( 0.9975587205950972, 0.06953016383322372, 0.006492709911733523,
-0.06956823121068059, 0.9975601387249519, 0.005833595226966235,
-0.006071257768382089, -0.006271040135405457, 0.9999619062167968);
cv::Vec3d T_correct(-0.099402724724121, 0.00270812139265413, 0.00129330292472699);
cv::Matx33d K1_correct (561.195925927249, 0, 621.282400272412,
0, 562.849402029712, 380.555455380889,
0, 0, 1);
cv::Matx33d K2_correct (560.395452535348, 0, 678.971652040359,
0, 561.90171021422, 380.401340535339,
0, 0, 1);
cv::Vec4d D1_correct (-7.44253716539556e-05, -0.00702662033932424, 0.00737569823650885, -0.00342230256441771);
cv::Vec4d D2_correct (-0.0130785435677431, 0.0284434505383497, -0.0360333869900506, 0.0144724062347222);
EXPECT_MAT_NEAR(R, R_correct, 1e-10);
EXPECT_MAT_NEAR(T, T_correct, 1e-10);
EXPECT_MAT_NEAR(K1, K1_correct, 1e-10);
EXPECT_MAT_NEAR(K2, K2_correct, 1e-10);
EXPECT_MAT_NEAR(D1, D1_correct, 1e-10);
EXPECT_MAT_NEAR(D2, D2_correct, 1e-10);
}
TEST_F(fisheyeTest, stereoCalibrateFixIntrinsic)
{
const int n_images = 34;
const std::string folder =combine(datasets_repository_path, "calib-3_stereo_from_JY");
std::vector<std::vector<cv::Point2d> > leftPoints(n_images);
std::vector<std::vector<cv::Point2d> > rightPoints(n_images);
std::vector<std::vector<cv::Point3d> > objectPoints(n_images);
cv::FileStorage fs_left(combine(folder, "left.xml"), cv::FileStorage::READ);
CV_Assert(fs_left.isOpened());
for(int i = 0; i < n_images; ++i)
fs_left[cv::format("image_%d", i )] >> leftPoints[i];
fs_left.release();
cv::FileStorage fs_right(combine(folder, "right.xml"), cv::FileStorage::READ);
CV_Assert(fs_right.isOpened());
for(int i = 0; i < n_images; ++i)
fs_right[cv::format("image_%d", i )] >> rightPoints[i];
fs_right.release();
cv::FileStorage fs_object(combine(folder, "object.xml"), cv::FileStorage::READ);
CV_Assert(fs_object.isOpened());
for(int i = 0; i < n_images; ++i)
fs_object[cv::format("image_%d", i )] >> objectPoints[i];
fs_object.release();
cv::Matx33d R;
cv::Vec3d T;
int flag = 0;
flag |= cv::fisheye::CALIB_RECOMPUTE_EXTRINSIC;
flag |= cv::fisheye::CALIB_CHECK_COND;
flag |= cv::fisheye::CALIB_FIX_SKEW;
flag |= cv::fisheye::CALIB_FIX_INTRINSIC;
cv::Matx33d K1 (561.195925927249, 0, 621.282400272412,
0, 562.849402029712, 380.555455380889,
0, 0, 1);
cv::Matx33d K2 (560.395452535348, 0, 678.971652040359,
0, 561.90171021422, 380.401340535339,
0, 0, 1);
cv::Vec4d D1 (-7.44253716539556e-05, -0.00702662033932424, 0.00737569823650885, -0.00342230256441771);
cv::Vec4d D2 (-0.0130785435677431, 0.0284434505383497, -0.0360333869900506, 0.0144724062347222);
cv::fisheye::stereoCalibrate(objectPoints, leftPoints, rightPoints,
K1, D1, K2, D2, imageSize, R, T, flag,
cv::TermCriteria(3, 12, 0));
cv::Matx33d R_correct( 0.9975587205950972, 0.06953016383322372, 0.006492709911733523,
-0.06956823121068059, 0.9975601387249519, 0.005833595226966235,
-0.006071257768382089, -0.006271040135405457, 0.9999619062167968);
cv::Vec3d T_correct(-0.099402724724121, 0.00270812139265413, 0.00129330292472699);
EXPECT_MAT_NEAR(R, R_correct, 1e-10);
EXPECT_MAT_NEAR(T, T_correct, 1e-10);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// fisheyeTest::
const cv::Size fisheyeTest::imageSize(1280, 800);
const cv::Matx33d fisheyeTest::K(558.478087865323, 0, 620.458515360843,
0, 560.506767351568, 381.939424848348,
0, 0, 1);
const cv::Vec4d fisheyeTest::D(-0.0014613319981768, -0.00329861110580401, 0.00605760088590183, -0.00374209380722371);
const cv::Matx33d fisheyeTest::R ( 9.9756700084424932e-01, 6.9698277640183867e-02, 1.4929569991321144e-03,
-6.9711825162322980e-02, 9.9748249845531767e-01, 1.2997180766418455e-02,
-5.8331736398316541e-04,-1.3069635393884985e-02, 9.9991441852366736e-01);
const cv::Vec3d fisheyeTest::T(-9.9217369356044638e-02, 3.1741831972356663e-03, 1.8551007952921010e-04);
std::string fisheyeTest::combine(const std::string& _item1, const std::string& _item2)
{
std::string item1 = _item1, item2 = _item2;
std::replace(item1.begin(), item1.end(), '\\', '/');
std::replace(item2.begin(), item2.end(), '\\', '/');
if (item1.empty())
return item2;
if (item2.empty())
return item1;
char last = item1[item1.size()-1];
return item1 + (last != '/' ? "/" : "") + item2;
}
cv::Mat fisheyeTest::mergeRectification(const cv::Mat& l, const cv::Mat& r)
{
CV_Assert(l.type() == r.type() && l.size() == r.size());
cv::Mat merged(l.rows, l.cols * 2, l.type());
cv::Mat lpart = merged.colRange(0, l.cols);
cv::Mat rpart = merged.colRange(l.cols, merged.cols);
l.copyTo(lpart);
r.copyTo(rpart);
for(int i = 0; i < l.rows; i+=20)
cv::line(merged, cv::Point(0, i), cv::Point(merged.cols, i), cv::Scalar(0, 255, 0));
return merged;
}

View File

@ -1021,12 +1021,12 @@ void CV_FundamentalMatTest::prepare_to_validation( int test_case_idx )
cv::gemm( T, invA2, 1, Mat(), 0, F0 );
F0 *= 1./f0[8];
uchar* status = test_mat[TEMP][1].data;
uchar* status = test_mat[TEMP][1].ptr();
double err_level = method <= CV_FM_8POINT ? 1 : get_success_error_level( test_case_idx, OUTPUT, 1 );
uchar* mtfm1 = test_mat[REF_OUTPUT][1].data;
uchar* mtfm2 = test_mat[OUTPUT][1].data;
double* f_prop1 = (double*)test_mat[REF_OUTPUT][0].data;
double* f_prop2 = (double*)test_mat[OUTPUT][0].data;
uchar* mtfm1 = test_mat[REF_OUTPUT][1].ptr();
uchar* mtfm2 = test_mat[OUTPUT][1].ptr();
double* f_prop1 = test_mat[REF_OUTPUT][0].ptr<double>();
double* f_prop2 = test_mat[OUTPUT][0].ptr<double>();
int i, pt_count = test_mat[INPUT][2].cols;
Mat p1( 1, pt_count, CV_64FC2 );
@ -1357,12 +1357,12 @@ void CV_EssentialMatTest::prepare_to_validation( int test_case_idx )
cv::gemm( T1, T2, 1, Mat(), 0, F0 );
F0 *= 1./f0[8];
uchar* status = test_mat[TEMP][1].data;
uchar* status = test_mat[TEMP][1].ptr();
double err_level = get_success_error_level( test_case_idx, OUTPUT, 1 );
uchar* mtfm1 = test_mat[REF_OUTPUT][1].data;
uchar* mtfm2 = test_mat[OUTPUT][1].data;
double* e_prop1 = (double*)test_mat[REF_OUTPUT][0].data;
double* e_prop2 = (double*)test_mat[OUTPUT][0].data;
uchar* mtfm1 = test_mat[REF_OUTPUT][1].ptr();
uchar* mtfm2 = test_mat[OUTPUT][1].ptr();
double* e_prop1 = test_mat[REF_OUTPUT][0].ptr<double>();
double* e_prop2 = test_mat[OUTPUT][0].ptr<double>();
Mat E_prop2 = Mat(3, 1, CV_64F, e_prop2);
int i, pt_count = test_mat[INPUT][2].cols;
@ -1407,8 +1407,8 @@ void CV_EssentialMatTest::prepare_to_validation( int test_case_idx )
double* pose_prop1 = (double*)test_mat[REF_OUTPUT][2].data;
double* pose_prop2 = (double*)test_mat[OUTPUT][2].data;
double* pose_prop1 = test_mat[REF_OUTPUT][2].ptr<double>();
double* pose_prop2 = test_mat[OUTPUT][2].ptr<double>();
double terr1 = cvtest::norm(Rt0.col(3) / norm(Rt0.col(3)) + test_mat[TEMP][3], NORM_L2);
double terr2 = cvtest::norm(Rt0.col(3) / norm(Rt0.col(3)) - test_mat[TEMP][3], NORM_L2);
Mat rvec;

View File

@ -0,0 +1,138 @@
/*M///////////////////////////////////////////////////////////////////////////////////////
//
// This is a test file for the function decomposeHomography contributed to OpenCV
// by Samson Yilma.
//
// 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) 2014, Samson Yilma¸ (samson_yilma@yahoo.com), all rights reserved.
//
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistribution's of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistribution's in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * The name of the copyright holders may not be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "test_precomp.hpp"
#include "opencv2/calib3d.hpp"
#include <vector>
using namespace cv;
using namespace std;
class CV_HomographyDecompTest: public cvtest::BaseTest {
public:
CV_HomographyDecompTest()
{
buildTestDataSet();
}
protected:
void run(int)
{
vector<Mat> rotations;
vector<Mat> translations;
vector<Mat> normals;
decomposeHomographyMat(_H, _K, rotations, translations, normals);
//there should be at least 1 solution
ASSERT_GT(static_cast<int>(rotations.size()), 0);
ASSERT_GT(static_cast<int>(translations.size()), 0);
ASSERT_GT(static_cast<int>(normals.size()), 0);
ASSERT_EQ(rotations.size(), normals.size());
ASSERT_EQ(translations.size(), normals.size());
ASSERT_TRUE(containsValidMotion(rotations, translations, normals));
decomposeHomographyMat(_H, _K, rotations, noArray(), noArray());
ASSERT_GT(static_cast<int>(rotations.size()), 0);
}
private:
void buildTestDataSet()
{
_K = Matx33d(640, 0.0, 320,
0, 640, 240,
0, 0, 1);
_H = Matx33d(2.649157564634028, 4.583875997496426, 70.694447785121326,
-1.072756858861583, 3.533262150437228, 1513.656999614321649,
0.001303887589576, 0.003042206876298, 1.000000000000000
);
//expected solution for the given homography and intrinsic matrices
_R = Matx33d(0.43307983549125, 0.545749113549648, -0.717356090899523,
-0.85630229674426, 0.497582023798831, -0.138414255706431,
0.281404038139784, 0.67421809131173, 0.682818960388909);
_t = Vec3d(1.826751712278038, 1.264718492450820, 0.195080809998819);
_n = Vec3d(0.244875830334816, 0.480857890778889, 0.841909446789566);
}
bool containsValidMotion(std::vector<Mat>& rotations,
std::vector<Mat>& translations,
std::vector<Mat>& normals
)
{
double max_error = 1.0e-3;
vector<Mat>::iterator riter = rotations.begin();
vector<Mat>::iterator titer = translations.begin();
vector<Mat>::iterator niter = normals.begin();
for (;
riter != rotations.end() && titer != translations.end() && niter != normals.end();
++riter, ++titer, ++niter) {
double rdist = norm(*riter, _R, NORM_INF);
double tdist = norm(*titer, _t, NORM_INF);
double ndist = norm(*niter, _n, NORM_INF);
if ( rdist < max_error
&& tdist < max_error
&& ndist < max_error )
return true;
}
return false;
}
Matx33d _R, _K, _H;
Vec3d _t, _n;
};
TEST(Calib3d_DecomposeHomography, regression) { CV_HomographyDecompTest test; test.safe_run(); }

View File

@ -142,7 +142,7 @@ protected:
Mat_<double> res = Q * Mat_<double>(4, 1, from);
res /= res(3, 0);
out3d_t pixel_exp = *(Vec3d*)res.data;
out3d_t pixel_exp = *res.ptr<Vec3d>();
out3d_t pixel_out = _3dImg(y, x);
const int largeZValue = 10000; /* see documentation */

View File

@ -1,6 +1,5 @@
set(the_description "The Core Functionality")
ocv_add_module(core PRIVATE_REQUIRED ${ZLIB_LIBRARIES} "${OPENCL_LIBRARIES}" OPTIONAL opencv_cudev)
ocv_module_include_directories(${ZLIB_INCLUDE_DIRS})
if(HAVE_WINRT_CX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /ZW")
@ -19,11 +18,11 @@ file(GLOB lib_cuda_hdrs_detail "include/opencv2/${name}/cuda/detail/*.hpp" "incl
source_group("Cuda Headers" FILES ${lib_cuda_hdrs})
source_group("Cuda Headers\\Detail" FILES ${lib_cuda_hdrs_detail})
ocv_glob_module_sources(SOURCES "${opencv_core_BINARY_DIR}/version_string.inc"
ocv_glob_module_sources(SOURCES "${OPENCV_MODULE_opencv_core_BINARY_DIR}/version_string.inc"
HEADERS ${lib_cuda_hdrs} ${lib_cuda_hdrs_detail})
ocv_module_include_directories(${the_module} ${ZLIB_INCLUDE_DIRS})
ocv_create_module()
ocv_add_precompiled_headers(${the_module})
ocv_add_accuracy_tests()
ocv_add_perf_tests()

View File

@ -845,7 +845,6 @@ For convenience, the following types from the OpenCV C API already have such a s
that calls the appropriate release function:
* ``CvCapture``
* :ocv:struct:`CvDTreeSplit`
* :ocv:struct:`CvFileStorage`
* ``CvHaarClassifierCascade``
* :ocv:struct:`CvMat`
@ -2326,6 +2325,69 @@ Returns the matrix iterator and sets it to the after-last matrix element.
The methods return the matrix read-only or read-write iterators, set to the point following the last matrix element.
Mat::forEach
------------
Invoke with arguments functor, and runs the functor over all matrix element.
.. ocv:function:: template<typename _Tp, typename Functor> void Mat::forEach(Functor operation)
.. ocv:function:: template<typename _Tp, typename Functor> void Mat::forEach(Functor operation) const
The methos runs operation in parallel. Operation is passed by arguments. Operation have to be a function pointer, a function object or a lambda(C++11).
All of below operation is equal. Put 0xFF to first channel of all matrix elements. ::
Mat image(1920, 1080, CV_8UC3);
typedef cv::Point3_<uint8_t> Pixel;
// first. raw pointer access.
for (int r = 0; r < image.rows; ++r) {
Pixel* ptr = image.ptr<Pixel>(0, r);
const Pixel* ptr_end = ptr + image.cols;
for (; ptr != ptr_end; ++ptr) {
ptr->x = 255;
}
}
// Using MatIterator. (Simple but there are a Iterator's overhead)
for (Pixel &p : cv::Mat_<Pixel>(image)) {
p.x = 255;
}
// Parallel execution with function object.
struct Operator {
void operator ()(Pixel &pixel, const int * position) {
pixel.x = 255;
}
};
image.forEach<Pixel>(Operator());
// Parallel execution using C++11 lambda.
image.forEach<Pixel>([](Pixel &p, const int * position) -> void {
p.x = 255;
});
position parameter is index of current pixel. ::
// Creating 3D matrix (255 x 255 x 255) typed uint8_t,
// and initialize all elements by the value which equals elements position.
// i.e. pixels (x,y,z) = (1,2,3) is (b,g,r) = (1,2,3).
int sizes[] = { 255, 255, 255 };
typedef cv::Point3_<uint8_t> Pixel;
Mat_<Pixel> image = Mat::zeros(3, sizes, CV_8UC3);
image.forEachWithPosition([&](Pixel& pixel, const int position[]) -> void{
pixel.x = position[0];
pixel.y = position[1];
pixel.z = position[2];
});
Mat\_
-----
.. ocv:class:: Mat_
@ -2988,13 +3050,13 @@ The class provides the following features for all derived classes:
Here is example of SIFT use in your application via Algorithm interface: ::
#include "opencv2/opencv.hpp"
#include "opencv2/nonfree.hpp"
#include "opencv2/xfeatures2d.hpp"
using namespace cv::xfeatures2d;
...
initModule_nonfree(); // to load SURF/SIFT etc.
Ptr<Feature2D> sift = Algorithm::create<Feature2D>("Feature2D.SIFT");
Ptr<Feature2D> sift = SIFT::create();
FileStorage fs("sift_params.xml", FileStorage::READ);
if( fs.isOpened() ) // if we have file with parameters, read them
@ -3004,7 +3066,7 @@ Here is example of SIFT use in your application via Algorithm interface: ::
}
else // else modify the parameters and store them; user can later edit the file to use different parameters
{
sift->set("contrastThreshold", 0.01f); // lower the contrast threshold, compared to the default value
sift->setContrastThreshold(0.01f); // lower the contrast threshold, compared to the default value
{
WriteStructContext ws(fs, "sift_params", CV_NODE_MAP);
@ -3014,7 +3076,7 @@ Here is example of SIFT use in your application via Algorithm interface: ::
Mat image = imread("myimage.png", 0), descriptors;
vector<KeyPoint> keypoints;
(*sift)(image, noArray(), keypoints, descriptors);
sift->detectAndCompute(image, noArray(), keypoints, descriptors);
Algorithm::name
---------------

View File

@ -10,10 +10,10 @@ core. The Core Functionality
old_basic_structures
dynamic_structures
operations_on_arrays
drawing_functions
xml_yaml_persistence
old_xml_yaml_persistence
clustering
utility_and_system_functions_and_macros
opengl_interop
ipp_async_converters
optim

View File

@ -3405,12 +3405,11 @@ and want to compute value of the "virtual" pixel ``Point(-5, 100)`` in a floatin
borderInterpolate(-5, img.cols, BORDER_WRAP));
Normally, the function is not called directly. It is used inside :ocv:class:`FilterEngine`
and :ocv:func:`copyMakeBorder` to compute tables for quick extrapolation.
Normally, the function is not called directly. It is used inside filtering functions
and also in :ocv:func:`copyMakeBorder`.
.. seealso::
:ocv:class:`FilterEngine`,
:ocv:func:`copyMakeBorder`
@ -3443,7 +3442,7 @@ Forms a border around an image.
The function copies the source image into the middle of the destination image. The areas to the
left, to the right, above and below the copied source image will be filled with extrapolated pixels.
This is not what :ocv:class:`FilterEngine` or filtering functions based on it do (they extrapolate
This is not what filtering functions based on it do (they extrapolate
pixels on-fly), but what other more complex functions, including your own, may do to simplify image
boundary handling.

341
modules/core/doc/optim.rst Normal file
View File

@ -0,0 +1,341 @@
Optimization Algorithms
=======================
.. highlight:: cpp
The algorithms in this section minimize or maximize function value within specified constraints or without any constraints.
solveLP
--------------------
Solve given (non-integer) linear programming problem using the Simplex Algorithm (Simplex Method).
What we mean here by "linear programming problem" (or LP problem, for short) can be
formulated as:
.. math::
\mbox{Maximize } c\cdot x\\
\mbox{Subject to:}\\
Ax\leq b\\
x\geq 0
Where :math:`c` is fixed *1*-by-*n* row-vector, :math:`A` is fixed *m*-by-*n* matrix, :math:`b` is fixed *m*-by-*1* column vector and
:math:`x` is an arbitrary *n*-by-*1* column vector, which satisfies the constraints.
Simplex algorithm is one of many algorithms that are designed to handle this sort of problems efficiently. Although it is not optimal in theoretical
sense (there exist algorithms that can solve any problem written as above in polynomial type, while simplex method degenerates to exponential time
for some special cases), it is well-studied, easy to implement and is shown to work well for real-life purposes.
The particular implementation is taken almost verbatim from **Introduction to Algorithms, third edition**
by T. H. Cormen, C. E. Leiserson, R. L. Rivest and Clifford Stein. In particular, the Bland's rule
(`http://en.wikipedia.org/wiki/Bland%27s\_rule <http://en.wikipedia.org/wiki/Bland%27s_rule>`_) is used to prevent cycling.
.. ocv:function:: int solveLP(const Mat& Func, const Mat& Constr, Mat& z)
:param Func: This row-vector corresponds to :math:`c` in the LP problem formulation (see above). It should contain 32- or 64-bit floating point numbers. As a convenience, column-vector may be also submitted, in the latter case it is understood to correspond to :math:`c^T`.
:param Constr: *m*-by-*n\+1* matrix, whose rightmost column corresponds to :math:`b` in formulation above and the remaining to :math:`A`. It should containt 32- or 64-bit floating point numbers.
:param z: The solution will be returned here as a column-vector - it corresponds to :math:`c` in the formulation above. It will contain 64-bit floating point numbers.
:return: One of the return codes:
::
//!the return codes for solveLP() function
enum
{
SOLVELP_UNBOUNDED = -2, //problem is unbounded (target function can achieve arbitrary high values)
SOLVELP_UNFEASIBLE = -1, //problem is unfeasible (there are no points that satisfy all the constraints imposed)
SOLVELP_SINGLE = 0, //there is only one maximum for target function
SOLVELP_MULTI = 1 //there are multiple maxima for target function - the arbitrary one is returned
};
DownhillSolver
---------------------------------
.. ocv:class:: DownhillSolver
This class is used to perform the non-linear non-constrained *minimization* of a function, defined on an *n*-dimensional Euclidean space,
using the **Nelder-Mead method**, also known as **downhill simplex method**. The basic idea about the method can be obtained from
(`http://en.wikipedia.org/wiki/Nelder-Mead\_method <http://en.wikipedia.org/wiki/Nelder-Mead_method>`_). It should be noted, that
this method, although deterministic, is rather a heuristic and therefore may converge to a local minima, not necessary a global one.
It is iterative optimization technique, which at each step uses an information about the values of a function evaluated only at
*n+1* points, arranged as a *simplex* in *n*-dimensional space (hence the second name of the method). At each step new point is
chosen to evaluate function at, obtained value is compared with previous ones and based on this information simplex changes it's shape
, slowly moving to the local minimum. Thus this method is using *only* function values to make decision, on contrary to, say, Nonlinear
Conjugate Gradient method (which is also implemented in ``optim``).
Algorithm stops when the number of function evaluations done exceeds ``termcrit.maxCount``, when the function values at the
vertices of simplex are within ``termcrit.epsilon`` range or simplex becomes so small that it
can enclosed in a box with ``termcrit.epsilon`` sides, whatever comes first, for some defined by user
positive integer ``termcrit.maxCount`` and positive non-integer ``termcrit.epsilon``.
::
class CV_EXPORTS Solver : public Algorithm
{
public:
class CV_EXPORTS Function
{
public:
virtual ~Function() {}
virtual double calc(const double* x) const = 0;
virtual void getGradient(const double* /*x*/,double* /*grad*/) {}
};
virtual Ptr<Function> getFunction() const = 0;
virtual void setFunction(const Ptr<Function>& f) = 0;
virtual TermCriteria getTermCriteria() const = 0;
virtual void setTermCriteria(const TermCriteria& termcrit) = 0;
// x contain the initial point before the call and the minima position (if algorithm converged) after. x is assumed to be (something that
// after getMat() will return) row-vector or column-vector. *It's size and should
// be consisted with previous dimensionality data given, if any (otherwise, it determines dimensionality)*
virtual double minimize(InputOutputArray x) = 0;
};
class CV_EXPORTS DownhillSolver : public Solver
{
public:
//! returns row-vector, even if the column-vector was given
virtual void getInitStep(OutputArray step) const=0;
//!This should be called at least once before the first call to minimize() and step is assumed to be (something that
//! after getMat() will return) row-vector or column-vector. *It's dimensionality determines the dimensionality of a problem.*
virtual void setInitStep(InputArray step)=0;
};
It should be noted, that ``DownhillSolver`` is a derivative of the abstract interface ``Solver``, which in
turn is derived from the ``Algorithm`` interface and is used to encapsulate the functionality, common to all non-linear optimization
algorithms in the ``optim`` module.
DownhillSolver::getFunction
--------------------------------------------
Getter for the optimized function. The optimized function is represented by ``Solver::Function`` interface, which requires
derivatives to implement the sole method ``calc(double*)`` to evaluate the function.
.. ocv:function:: Ptr<Solver::Function> DownhillSolver::getFunction()
:return: Smart-pointer to an object that implements ``Solver::Function`` interface - it represents the function that is being optimized. It can be empty, if no function was given so far.
DownhillSolver::setFunction
-----------------------------------------------
Setter for the optimized function. *It should be called at least once before the call to* ``DownhillSolver::minimize()``, as
default value is not usable.
.. ocv:function:: void DownhillSolver::setFunction(const Ptr<Solver::Function>& f)
:param f: The new function to optimize.
DownhillSolver::getTermCriteria
----------------------------------------------------
Getter for the previously set terminal criteria for this algorithm.
.. ocv:function:: TermCriteria DownhillSolver::getTermCriteria()
:return: Deep copy of the terminal criteria used at the moment.
DownhillSolver::setTermCriteria
------------------------------------------
Set terminal criteria for downhill simplex method. Two things should be noted. First, this method *is not necessary* to be called
before the first call to ``DownhillSolver::minimize()``, as the default value is sensible. Second, the method will raise an error
if ``termcrit.type!=(TermCriteria::MAX_ITER+TermCriteria::EPS)``, ``termcrit.epsilon<=0`` or ``termcrit.maxCount<=0``. That is,
both ``epsilon`` and ``maxCount`` should be set to positive values (non-integer and integer respectively) and they represent
tolerance and maximal number of function evaluations that is allowed.
Algorithm stops when the number of function evaluations done exceeds ``termcrit.maxCount``, when the function values at the
vertices of simplex are within ``termcrit.epsilon`` range or simplex becomes so small that it
can enclosed in a box with ``termcrit.epsilon`` sides, whatever comes first.
.. ocv:function:: void DownhillSolver::setTermCriteria(const TermCriteria& termcrit)
:param termcrit: Terminal criteria to be used, represented as ``TermCriteria`` structure (defined elsewhere in openCV). Mind you, that it should meet ``(termcrit.type==(TermCriteria::MAX_ITER+TermCriteria::EPS) && termcrit.epsilon>0 && termcrit.maxCount>0)``, otherwise the error will be raised.
DownhillSolver::getInitStep
-----------------------------------
Returns the initial step that will be used in downhill simplex algorithm. See the description
of corresponding setter (follows next) for the meaning of this parameter.
.. ocv:function:: void getInitStep(OutputArray step)
:param step: Initial step that will be used in algorithm. Note, that although corresponding setter accepts column-vectors as well as row-vectors, this method will return a row-vector.
DownhillSolver::setInitStep
----------------------------------
Sets the initial step that will be used in downhill simplex algorithm. Step, together with initial point (givin in ``DownhillSolver::minimize``)
are two *n*-dimensional vectors that are used to determine the shape of initial simplex. Roughly said, initial point determines the position
of a simplex (it will become simplex's centroid), while step determines the spread (size in each dimension) of a simplex. To be more precise,
if :math:`s,x_0\in\mathbb{R}^n` are the initial step and initial point respectively, the vertices of a simplex will be: :math:`v_0:=x_0-\frac{1}{2}
s` and :math:`v_i:=x_0+s_i` for :math:`i=1,2,\dots,n` where :math:`s_i` denotes projections of the initial step of *n*-th coordinate (the result
of projection is treated to be vector given by :math:`s_i:=e_i\cdot\left<e_i\cdot s\right>`, where :math:`e_i` form canonical basis)
.. ocv:function:: void setInitStep(InputArray step)
:param step: Initial step that will be used in algorithm. Roughly said, it determines the spread (size in each dimension) of an initial simplex.
DownhillSolver::minimize
-----------------------------------
The main method of the ``DownhillSolver``. It actually runs the algorithm and performs the minimization. The sole input parameter determines the
centroid of the starting simplex (roughly, it tells where to start), all the others (terminal criteria, initial step, function to be minimized)
are supposed to be set via the setters before the call to this method or the default values (not always sensible) will be used.
.. ocv:function:: double DownhillSolver::minimize(InputOutputArray x)
:param x: The initial point, that will become a centroid of an initial simplex. After the algorithm will terminate, it will be setted to the point where the algorithm stops, the point of possible minimum.
:return: The value of a function at the point found.
createDownhillSolver
------------------------------------
This function returns the reference to the ready-to-use ``DownhillSolver`` object. All the parameters are optional, so this procedure can be called
even without parameters at all. In this case, the default values will be used. As default value for terminal criteria are the only sensible ones,
``DownhillSolver::setFunction()`` and ``DownhillSolver::setInitStep()`` should be called upon the obtained object, if the respective parameters
were not given to ``createDownhillSolver()``. Otherwise, the two ways (give parameters to ``createDownhillSolver()`` or miss them out and call the
``DownhillSolver::setFunction()`` and ``DownhillSolver::setInitStep()``) are absolutely equivalent (and will drop the same errors in the same way,
should invalid input be detected).
.. ocv:function:: Ptr<DownhillSolver> createDownhillSolver(const Ptr<Solver::Function>& f,InputArray initStep, TermCriteria termcrit)
:param f: Pointer to the function that will be minimized, similarly to the one you submit via ``DownhillSolver::setFunction``.
:param step: Initial step, that will be used to construct the initial simplex, similarly to the one you submit via ``DownhillSolver::setInitStep``.
:param termcrit: Terminal criteria to the algorithm, similarly to the one you submit via ``DownhillSolver::setTermCriteria``.
ConjGradSolver
---------------------------------
.. ocv:class:: ConjGradSolver
This class is used to perform the non-linear non-constrained *minimization* of a function with *known gradient*
, defined on an *n*-dimensional Euclidean space,
using the **Nonlinear Conjugate Gradient method**. The implementation was done based on the beautifully clear explanatory article `An Introduction to the Conjugate Gradient Method Without the Agonizing Pain <http://www.cs.cmu.edu/~quake-papers/painless-conjugate-gradient.pdf>`_
by Jonathan Richard Shewchuk. The method can be seen as an adaptation of a standard Conjugate Gradient method (see, for example
`http://en.wikipedia.org/wiki/Conjugate_gradient_method <http://en.wikipedia.org/wiki/Conjugate_gradient_method>`_) for numerically solving the
systems of linear equations.
It should be noted, that
this method, although deterministic, is rather a heuristic method and therefore may converge to a local minima, not necessary a global one. What
is even more disastrous, most of its behaviour is ruled by gradient, therefore it essentially cannot distinguish between local minima and maxima.
Therefore, if it starts sufficiently near to the local maximum, it may converge to it. Another obvious restriction is that it should be possible
to compute the gradient of a function at any point, thus it is preferable to have analytic expression for gradient and computational burden
should be born by the user.
The latter responsibility is accompilished via the ``getGradient(const double* x,double* grad)`` method of a
``Solver::Function`` interface (which represents function that is being optimized). This method takes point a point in *n*-dimensional space
(first argument represents the array of coordinates of that point) and comput its gradient (it should be stored in the second argument as an array).
::
class CV_EXPORTS Solver : public Algorithm
{
public:
class CV_EXPORTS Function
{
public:
virtual ~Function() {}
virtual double calc(const double* x) const = 0;
virtual void getGradient(const double* /*x*/,double* /*grad*/) {}
};
virtual Ptr<Function> getFunction() const = 0;
virtual void setFunction(const Ptr<Function>& f) = 0;
virtual TermCriteria getTermCriteria() const = 0;
virtual void setTermCriteria(const TermCriteria& termcrit) = 0;
// x contain the initial point before the call and the minima position (if algorithm converged) after. x is assumed to be (something that
// after getMat() will return) row-vector or column-vector. *It's size and should
// be consisted with previous dimensionality data given, if any (otherwise, it determines dimensionality)*
virtual double minimize(InputOutputArray x) = 0;
};
class CV_EXPORTS ConjGradSolver : public Solver{
};
Note, that class ``ConjGradSolver`` thus does not add any new methods to the basic ``Solver`` interface.
ConjGradSolver::getFunction
--------------------------------------------
Getter for the optimized function. The optimized function is represented by ``Solver::Function`` interface, which requires
derivatives to implement the method ``calc(double*)`` to evaluate the function. It should be emphasized once more, that since Nonlinear
Conjugate Gradient method requires gradient to be computable in addition to the function values,
``getGradient(const double* x,double* grad)`` method of a ``Solver::Function`` interface should be also implemented meaningfully.
.. ocv:function:: Ptr<Solver::Function> ConjGradSolver::getFunction()
:return: Smart-pointer to an object that implements ``Solver::Function`` interface - it represents the function that is being optimized. It can be empty, if no function was given so far.
ConjGradSolver::setFunction
-----------------------------------------------
Setter for the optimized function. *It should be called at least once before the call to* ``ConjGradSolver::minimize()``, as
default value is not usable.
.. ocv:function:: void ConjGradSolver::setFunction(const Ptr<Solver::Function>& f)
:param f: The new function to optimize.
ConjGradSolver::getTermCriteria
----------------------------------------------------
Getter for the previously set terminal criteria for this algorithm.
.. ocv:function:: TermCriteria ConjGradSolver::getTermCriteria()
:return: Deep copy of the terminal criteria used at the moment.
ConjGradSolver::setTermCriteria
------------------------------------------
Set terminal criteria for downhill simplex method. Two things should be noted. First, this method *is not necessary* to be called
before the first call to ``ConjGradSolver::minimize()``, as the default value is sensible. Second, the method will raise an error
if ``termcrit.type!=(TermCriteria::MAX_ITER+TermCriteria::EPS)`` and ``termcrit.type!=TermCriteria::MAX_ITER``. This means that termination criteria
has to restrict maximum number of iterations to be done and may optionally allow algorithm to stop earlier if certain tolerance
is achieved (what we mean by "tolerance is achieved" will be clarified below). If ``termcrit`` restricts both tolerance and maximum iteration
number, both ``termcrit.epsilon`` and ``termcrit.maxCount`` should be positive. In case, if ``termcrit.type==TermCriteria::MAX_ITER``,
only member ``termcrit.maxCount`` is required to be positive and in this case algorithm will just work for required number of iterations.
In current implementation, "tolerance is achieved" means that we have arrived at the point where the :math:`L_2`-norm of the gradient is less
than the tolerance value.
.. ocv:function:: void ConjGradSolver::setTermCriteria(const TermCriteria& termcrit)
:param termcrit: Terminal criteria to be used, represented as ``TermCriteria`` structure (defined elsewhere in openCV). Mind you, that it should meet ``termcrit.type==(TermCriteria::MAX_ITER+TermCriteria::EPS) && termcrit.epsilon>0 && termcrit.maxCount>0`` or ``termcrit.type==TermCriteria::MAX_ITER) && termcrit.maxCount>0``, otherwise the error will be raised.
ConjGradSolver::minimize
-----------------------------------
The main method of the ``ConjGradSolver``. It actually runs the algorithm and performs the minimization. The sole input parameter determines the
centroid of the starting simplex (roughly, it tells where to start), all the others (terminal criteria and function to be minimized)
are supposed to be set via the setters before the call to this method or the default values (not always sensible) will be used. Sometimes it may
throw an error, if these default values cannot be used (say, you forgot to set the function to minimize and default value, that is, empty function,
cannot be used).
.. ocv:function:: double ConjGradSolver::minimize(InputOutputArray x)
:param x: The initial point. It is hard to overemphasize how important the choise of initial point is when you are using the heuristic algorithm like this one. Badly chosen initial point can make algorithm converge to (local) maximum instead of minimum, do not converge at all, converge to local minimum instead of global one.
:return: The value of a function at the point found.
createConjGradSolver
------------------------------------
This function returns the reference to the ready-to-use ``ConjGradSolver`` object. All the parameters are optional, so this procedure can be called
even without parameters at all. In this case, the default values will be used. As default value for terminal criteria are the only sensible ones,
``ConjGradSolver::setFunction()`` should be called upon the obtained object, if the function
was not given to ``createConjGradSolver()``. Otherwise, the two ways (submit it to ``createConjGradSolver()`` or miss it out and call the
``ConjGradSolver::setFunction()``) are absolutely equivalent (and will drop the same errors in the same way,
should invalid input be detected).
.. ocv:function:: Ptr<ConjGradSolver> createConjGradSolver(const Ptr<Solver::Function>& f, TermCriteria termcrit)
:param f: Pointer to the function that will be minimized, similarly to the one you submit via ``ConjGradSolver::setFunction``.
:param termcrit: Terminal criteria to the algorithm, similarly to the one you submit via ``ConjGradSolver::setTermCriteria``.

View File

@ -506,96 +506,6 @@ CV_EXPORTS_W void randn(InputOutputArray dst, InputArray mean, InputArray stddev
//! shuffles the input array elements
CV_EXPORTS_W void randShuffle(InputOutputArray dst, double iterFactor = 1., RNG* rng = 0);
//! draws the line segment (pt1, pt2) in the image
CV_EXPORTS_W void line(InputOutputArray img, Point pt1, Point pt2, const Scalar& color,
int thickness = 1, int lineType = LINE_8, int shift = 0);
//! draws an arrow from pt1 to pt2 in the image
CV_EXPORTS_W void arrowedLine(InputOutputArray img, Point pt1, Point pt2, const Scalar& color,
int thickness=1, int line_type=8, int shift=0, double tipLength=0.1);
//! draws the rectangle outline or a solid rectangle with the opposite corners pt1 and pt2 in the image
CV_EXPORTS_W void rectangle(InputOutputArray img, Point pt1, Point pt2,
const Scalar& color, int thickness = 1,
int lineType = LINE_8, int shift = 0);
//! draws the rectangle outline or a solid rectangle covering rec in the image
CV_EXPORTS void rectangle(CV_IN_OUT Mat& img, Rect rec,
const Scalar& color, int thickness = 1,
int lineType = LINE_8, int shift = 0);
//! draws the circle outline or a solid circle in the image
CV_EXPORTS_W void circle(InputOutputArray img, Point center, int radius,
const Scalar& color, int thickness = 1,
int lineType = LINE_8, int shift = 0);
//! draws an elliptic arc, ellipse sector or a rotated ellipse in the image
CV_EXPORTS_W void ellipse(InputOutputArray img, Point center, Size axes,
double angle, double startAngle, double endAngle,
const Scalar& color, int thickness = 1,
int lineType = LINE_8, int shift = 0);
//! draws a rotated ellipse in the image
CV_EXPORTS_W void ellipse(InputOutputArray img, const RotatedRect& box, const Scalar& color,
int thickness = 1, int lineType = LINE_8);
//! draws a filled convex polygon in the image
CV_EXPORTS void fillConvexPoly(Mat& img, const Point* pts, int npts,
const Scalar& color, int lineType = LINE_8,
int shift = 0);
CV_EXPORTS_W void fillConvexPoly(InputOutputArray img, InputArray points,
const Scalar& color, int lineType = LINE_8,
int shift = 0);
//! fills an area bounded by one or more polygons
CV_EXPORTS void fillPoly(Mat& img, const Point** pts,
const int* npts, int ncontours,
const Scalar& color, int lineType = LINE_8, int shift = 0,
Point offset = Point() );
CV_EXPORTS_W void fillPoly(InputOutputArray img, InputArrayOfArrays pts,
const Scalar& color, int lineType = LINE_8, int shift = 0,
Point offset = Point() );
//! draws one or more polygonal curves
CV_EXPORTS void polylines(Mat& img, const Point* const* pts, const int* npts,
int ncontours, bool isClosed, const Scalar& color,
int thickness = 1, int lineType = LINE_8, int shift = 0 );
CV_EXPORTS_W void polylines(InputOutputArray img, InputArrayOfArrays pts,
bool isClosed, const Scalar& color,
int thickness = 1, int lineType = LINE_8, int shift = 0 );
//! draws contours in the image
CV_EXPORTS_W void drawContours( InputOutputArray image, InputArrayOfArrays contours,
int contourIdx, const Scalar& color,
int thickness = 1, int lineType = LINE_8,
InputArray hierarchy = noArray(),
int maxLevel = INT_MAX, Point offset = Point() );
//! clips the line segment by the rectangle Rect(0, 0, imgSize.width, imgSize.height)
CV_EXPORTS bool clipLine(Size imgSize, CV_IN_OUT Point& pt1, CV_IN_OUT Point& pt2);
//! clips the line segment by the rectangle imgRect
CV_EXPORTS_W bool clipLine(Rect imgRect, CV_OUT CV_IN_OUT Point& pt1, CV_OUT CV_IN_OUT Point& pt2);
//! converts elliptic arc to a polygonal curve
CV_EXPORTS_W void ellipse2Poly( Point center, Size axes, int angle,
int arcStart, int arcEnd, int delta,
CV_OUT std::vector<Point>& pts );
//! renders text string in the image
CV_EXPORTS_W void putText( InputOutputArray img, const String& text, Point org,
int fontFace, double fontScale, Scalar color,
int thickness = 1, int lineType = LINE_8,
bool bottomLeftOrigin = false );
//! returns bounding box of the text string
CV_EXPORTS_W Size getTextSize(const String& text, int fontFace,
double fontScale, int thickness,
CV_OUT int* baseLine);
/*!
Principal Component Analysis
@ -690,7 +600,61 @@ public:
Mat mean; //!< mean value subtracted before the projection and added after the back projection
};
// Linear Discriminant Analysis
class CV_EXPORTS LDA
{
public:
// Initializes a LDA with num_components (default 0) and specifies how
// samples are aligned (default dataAsRow=true).
explicit LDA(int num_components = 0);
// Initializes and performs a Discriminant Analysis with Fisher's
// Optimization Criterion on given data in src and corresponding labels
// in labels. If 0 (or less) number of components are given, they are
// automatically determined for given data in computation.
LDA(InputArrayOfArrays src, InputArray labels, int num_components = 0);
// Serializes this object to a given filename.
void save(const String& filename) const;
// Deserializes this object from a given filename.
void load(const String& filename);
// Serializes this object to a given cv::FileStorage.
void save(FileStorage& fs) const;
// Deserializes this object from a given cv::FileStorage.
void load(const FileStorage& node);
// Destructor.
~LDA();
//! Compute the discriminants for data in src and labels.
void compute(InputArrayOfArrays src, InputArray labels);
// Projects samples into the LDA subspace.
Mat project(InputArray src);
// Reconstructs projections from the LDA subspace.
Mat reconstruct(InputArray src);
// Returns the eigenvectors of this LDA.
Mat eigenvectors() const { return _eigenvectors; }
// Returns the eigenvalues of this LDA.
Mat eigenvalues() const { return _eigenvalues; }
static Mat subspaceProject(InputArray W, InputArray mean, InputArray src);
static Mat subspaceReconstruct(InputArray W, InputArray mean, InputArray src);
protected:
bool _dataAsRow;
int _num_components;
Mat _eigenvectors;
Mat _eigenvalues;
void lda(InputArrayOfArrays src, InputArray labels);
};
/*!
Singular Value Decomposition class
@ -1265,5 +1229,7 @@ template<> struct ParamType<uchar>
#include "opencv2/core/operations.hpp"
#include "opencv2/core/cvstd.inl.hpp"
#include "opencv2/core/utility.hpp"
#include "opencv2/core/optim.hpp"
#endif /*__OPENCV_CORE_HPP__*/

View File

@ -1122,7 +1122,7 @@ CV_INLINE CvSetElem* cvSetNew( CvSet* set_header )
set_header->active_count++;
}
else
cvSetAdd( set_header, NULL, (CvSetElem**)&elem );
cvSetAdd( set_header, NULL, &elem );
return elem;
}
@ -1262,192 +1262,6 @@ CVAPI(int) cvNextGraphItem( CvGraphScanner* scanner );
/* Creates a copy of graph */
CVAPI(CvGraph*) cvCloneGraph( const CvGraph* graph, CvMemStorage* storage );
/****************************************************************************************\
* Drawing *
\****************************************************************************************/
/****************************************************************************************\
* Drawing functions work with images/matrices of arbitrary type. *
* For color images the channel order is BGR[A] *
* Antialiasing is supported only for 8-bit image now. *
* All the functions include parameter color that means rgb value (that may be *
* constructed with CV_RGB macro) for color images and brightness *
* for grayscale images. *
* If a drawn figure is partially or completely outside of the image, it is clipped.*
\****************************************************************************************/
#define CV_RGB( r, g, b ) cvScalar( (b), (g), (r), 0 )
#define CV_FILLED -1
#define CV_AA 16
/* Draws 4-connected, 8-connected or antialiased line segment connecting two points */
CVAPI(void) cvLine( CvArr* img, CvPoint pt1, CvPoint pt2,
CvScalar color, int thickness CV_DEFAULT(1),
int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0) );
/* Draws a rectangle given two opposite corners of the rectangle (pt1 & pt2),
if thickness<0 (e.g. thickness == CV_FILLED), the filled box is drawn */
CVAPI(void) cvRectangle( CvArr* img, CvPoint pt1, CvPoint pt2,
CvScalar color, int thickness CV_DEFAULT(1),
int line_type CV_DEFAULT(8),
int shift CV_DEFAULT(0));
/* Draws a rectangle specified by a CvRect structure */
CVAPI(void) cvRectangleR( CvArr* img, CvRect r,
CvScalar color, int thickness CV_DEFAULT(1),
int line_type CV_DEFAULT(8),
int shift CV_DEFAULT(0));
/* Draws a circle with specified center and radius.
Thickness works in the same way as with cvRectangle */
CVAPI(void) cvCircle( CvArr* img, CvPoint center, int radius,
CvScalar color, int thickness CV_DEFAULT(1),
int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0));
/* Draws ellipse outline, filled ellipse, elliptic arc or filled elliptic sector,
depending on <thickness>, <start_angle> and <end_angle> parameters. The resultant figure
is rotated by <angle>. All the angles are in degrees */
CVAPI(void) cvEllipse( CvArr* img, CvPoint center, CvSize axes,
double angle, double start_angle, double end_angle,
CvScalar color, int thickness CV_DEFAULT(1),
int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0));
CV_INLINE void cvEllipseBox( CvArr* img, CvBox2D box, CvScalar color,
int thickness CV_DEFAULT(1),
int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0) )
{
CvSize axes;
axes.width = cvRound(box.size.width*0.5);
axes.height = cvRound(box.size.height*0.5);
cvEllipse( img, cvPointFrom32f( box.center ), axes, box.angle,
0, 360, color, thickness, line_type, shift );
}
/* Fills convex or monotonous polygon. */
CVAPI(void) cvFillConvexPoly( CvArr* img, const CvPoint* pts, int npts, CvScalar color,
int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0));
/* Fills an area bounded by one or more arbitrary polygons */
CVAPI(void) cvFillPoly( CvArr* img, CvPoint** pts, const int* npts,
int contours, CvScalar color,
int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0) );
/* Draws one or more polygonal curves */
CVAPI(void) cvPolyLine( CvArr* img, CvPoint** pts, const int* npts, int contours,
int is_closed, CvScalar color, int thickness CV_DEFAULT(1),
int line_type CV_DEFAULT(8), int shift CV_DEFAULT(0) );
#define cvDrawRect cvRectangle
#define cvDrawLine cvLine
#define cvDrawCircle cvCircle
#define cvDrawEllipse cvEllipse
#define cvDrawPolyLine cvPolyLine
/* Clips the line segment connecting *pt1 and *pt2
by the rectangular window
(0<=x<img_size.width, 0<=y<img_size.height). */
CVAPI(int) cvClipLine( CvSize img_size, CvPoint* pt1, CvPoint* pt2 );
/* Initializes line iterator. Initially, line_iterator->ptr will point
to pt1 (or pt2, see left_to_right description) location in the image.
Returns the number of pixels on the line between the ending points. */
CVAPI(int) cvInitLineIterator( const CvArr* image, CvPoint pt1, CvPoint pt2,
CvLineIterator* line_iterator,
int connectivity CV_DEFAULT(8),
int left_to_right CV_DEFAULT(0));
/* Moves iterator to the next line point */
#define CV_NEXT_LINE_POINT( line_iterator ) \
{ \
int _line_iterator_mask = (line_iterator).err < 0 ? -1 : 0; \
(line_iterator).err += (line_iterator).minus_delta + \
((line_iterator).plus_delta & _line_iterator_mask); \
(line_iterator).ptr += (line_iterator).minus_step + \
((line_iterator).plus_step & _line_iterator_mask); \
}
/* basic font types */
#define CV_FONT_HERSHEY_SIMPLEX 0
#define CV_FONT_HERSHEY_PLAIN 1
#define CV_FONT_HERSHEY_DUPLEX 2
#define CV_FONT_HERSHEY_COMPLEX 3
#define CV_FONT_HERSHEY_TRIPLEX 4
#define CV_FONT_HERSHEY_COMPLEX_SMALL 5
#define CV_FONT_HERSHEY_SCRIPT_SIMPLEX 6
#define CV_FONT_HERSHEY_SCRIPT_COMPLEX 7
/* font flags */
#define CV_FONT_ITALIC 16
#define CV_FONT_VECTOR0 CV_FONT_HERSHEY_SIMPLEX
/* Font structure */
typedef struct CvFont
{
const char* nameFont; //Qt:nameFont
CvScalar color; //Qt:ColorFont -> cvScalar(blue_component, green_component, red\_component[, alpha_component])
int font_face; //Qt: bool italic /* =CV_FONT_* */
const int* ascii; /* font data and metrics */
const int* greek;
const int* cyrillic;
float hscale, vscale;
float shear; /* slope coefficient: 0 - normal, >0 - italic */
int thickness; //Qt: weight /* letters thickness */
float dx; /* horizontal interval between letters */
int line_type; //Qt: PointSize
}
CvFont;
/* Initializes font structure used further in cvPutText */
CVAPI(void) cvInitFont( CvFont* font, int font_face,
double hscale, double vscale,
double shear CV_DEFAULT(0),
int thickness CV_DEFAULT(1),
int line_type CV_DEFAULT(8));
CV_INLINE CvFont cvFont( double scale, int thickness CV_DEFAULT(1) )
{
CvFont font;
cvInitFont( &font, CV_FONT_HERSHEY_PLAIN, scale, scale, 0, thickness, CV_AA );
return font;
}
/* Renders text stroke with specified font and color at specified location.
CvFont should be initialized with cvInitFont */
CVAPI(void) cvPutText( CvArr* img, const char* text, CvPoint org,
const CvFont* font, CvScalar color );
/* Calculates bounding box of text stroke (useful for alignment) */
CVAPI(void) cvGetTextSize( const char* text_string, const CvFont* font,
CvSize* text_size, int* baseline );
/* Unpacks color value, if arrtype is CV_8UC?, <color> is treated as
packed color value, otherwise the first channels (depending on arrtype)
of destination scalar are set to the same value = <color> */
CVAPI(CvScalar) cvColorToScalar( double packed_color, int arrtype );
/* Returns the polygon points which make up the given ellipse. The ellipse is define by
the box of size 'axes' rotated 'angle' around the 'center'. A partial sweep
of the ellipse arc can be done by spcifying arc_start and arc_end to be something
other than 0 and 360, respectively. The input array 'pts' must be large enough to
hold the result. The total number of points stored into 'pts' is returned by this
function. */
CVAPI(int) cvEllipse2Poly( CvPoint center, CvSize axes,
int angle, int arc_start, int arc_end, CvPoint * pts, int delta );
/* Draws contour outlines or filled interiors on the image */
CVAPI(void) cvDrawContours( CvArr *img, CvSeq* contour,
CvScalar external_color, CvScalar hole_color,
int max_level, int thickness CV_DEFAULT(1),
int line_type CV_DEFAULT(8),
CvPoint offset CV_DEFAULT(cvPoint(0,0)));
/* Does look-up transformation. Elements of the source array
(that should be 8uC1 or 8sC1) are used as indexes in lutarr 256-element table */

View File

@ -262,7 +262,7 @@ public:
//! helper fields used in locateROI and adjustROI
uchar* datastart;
uchar* dataend;
const uchar* dataend;
//! allocator
Allocator* allocator;
@ -350,7 +350,7 @@ public:
int* refcount;
uchar* datastart;
uchar* dataend;
const uchar* dataend;
AllocType alloc_type;
};

View File

@ -219,8 +219,14 @@ template<typename _Tp, int n> static inline
std::ostream& operator << (std::ostream& out, const Vec<_Tp, n>& vec)
{
out << "[";
#ifdef _MSC_VER
#pragma warning( push )
#pragma warning( disable: 4127 )
#endif
if(Vec<_Tp, n>::depth < CV_32F)
#ifdef _MSC_VER
#pragma warning( pop )
#endif
{
for (int i = 0; i < n - 1; ++i) {
out << (int)vec[i] << ", ";

View File

@ -395,7 +395,7 @@ struct CV_EXPORTS UMatData
struct CV_EXPORTS UMatDataAutoLock
{
UMatDataAutoLock(UMatData* u);
explicit UMatDataAutoLock(UMatData* u);
~UMatDataAutoLock();
UMatData* u;
};
@ -403,7 +403,7 @@ struct CV_EXPORTS UMatDataAutoLock
struct CV_EXPORTS MatSize
{
MatSize(int* _p);
explicit MatSize(int* _p);
Size operator()() const;
const int& operator[](int i) const;
int& operator[](int i);
@ -417,7 +417,7 @@ struct CV_EXPORTS MatSize
struct CV_EXPORTS MatStep
{
MatStep();
MatStep(size_t s);
explicit MatStep(size_t s);
const size_t& operator[](int i) const;
size_t& operator[](int i);
operator size_t() const;
@ -900,6 +900,11 @@ public:
template<typename _Tp> MatConstIterator_<_Tp> begin() const;
template<typename _Tp> MatConstIterator_<_Tp> end() const;
//! template methods for for operation over all matrix elements.
// the operations take care of skipping gaps in the end of rows (if any)
template<typename _Tp, typename Functor> void forEach(const Functor& operation);
template<typename _Tp, typename Functor> void forEach(const Functor& operation) const;
enum { MAGIC_VAL = 0x42FF0000, AUTO_STEP = 0, CONTINUOUS_FLAG = CV_MAT_CONT_FLAG, SUBMATRIX_FLAG = CV_SUBMAT_FLAG };
enum { MAGIC_MASK = 0xFFFF0000, TYPE_MASK = 0x00000FFF, DEPTH_MASK = 7 };
@ -918,9 +923,9 @@ public:
uchar* data;
//! helper fields used in locateROI and adjustROI
uchar* datastart;
uchar* dataend;
uchar* datalimit;
const uchar* datastart;
const uchar* dataend;
const uchar* datalimit;
//! custom allocator
MatAllocator* allocator;
@ -934,6 +939,7 @@ public:
MatStep step;
protected:
template<typename _Tp, typename Functor> void forEach_impl(const Functor& operation);
};
@ -1043,6 +1049,11 @@ public:
const_iterator begin() const;
const_iterator end() const;
//! template methods for for operation over all matrix elements.
// the operations take care of skipping gaps in the end of rows (if any)
template<typename Functor> void forEach(const Functor& operation);
template<typename Functor> void forEach(const Functor& operation) const;
//! equivalent to Mat::create(_rows, _cols, DataType<_Tp>::type)
void create(int _rows, int _cols);
//! equivalent to Mat::create(_size, DataType<_Tp>::type)
@ -1804,9 +1815,9 @@ public:
//! copy operator
MatConstIterator& operator = (const MatConstIterator& it);
//! returns the current matrix element
uchar* operator *() const;
const uchar* operator *() const;
//! returns the i-th matrix element, relative to the current
uchar* operator [](ptrdiff_t i) const;
const uchar* operator [](ptrdiff_t i) const;
//! shifts the iterator forward by the specified number of elements
MatConstIterator& operator += (ptrdiff_t ofs);
@ -1831,9 +1842,9 @@ public:
const Mat* m;
size_t elemSize;
uchar* ptr;
uchar* sliceStart;
uchar* sliceEnd;
const uchar* ptr;
const uchar* sliceStart;
const uchar* sliceEnd;
};
@ -1917,9 +1928,9 @@ public:
//! constructor that sets the iterator to the specified element of the matrix
MatIterator_(Mat_<_Tp>* _m, int _row, int _col=0);
//! constructor that sets the iterator to the specified element of the matrix
MatIterator_(const Mat_<_Tp>* _m, Point _pt);
MatIterator_(Mat_<_Tp>* _m, Point _pt);
//! constructor that sets the iterator to the specified element of the matrix
MatIterator_(const Mat_<_Tp>* _m, const int* _idx);
MatIterator_(Mat_<_Tp>* _m, const int* _idx);
//! copy constructor
MatIterator_(const MatIterator_& it);
//! copy operator

View File

@ -438,7 +438,7 @@ Mat::Mat(const std::vector<_Tp>& vec, bool copyData)
if( !copyData )
{
step[0] = step[1] = sizeof(_Tp);
data = datastart = (uchar*)&vec[0];
datastart = data = (uchar*)&vec[0];
datalimit = dataend = datastart + rows * step[0];
}
else
@ -453,7 +453,7 @@ Mat::Mat(const Vec<_Tp, n>& vec, bool copyData)
if( !copyData )
{
step[0] = step[1] = sizeof(_Tp);
data = datastart = (uchar*)vec.val;
datastart = data = (uchar*)vec.val;
datalimit = dataend = datastart + rows * step[0];
}
else
@ -470,7 +470,7 @@ Mat::Mat(const Matx<_Tp,m,n>& M, bool copyData)
{
step[0] = cols * sizeof(_Tp);
step[1] = sizeof(_Tp);
data = datastart = (uchar*)M.val;
datastart = data = (uchar*)M.val;
datalimit = dataend = datastart + rows * step[0];
}
else
@ -485,7 +485,7 @@ Mat::Mat(const Point_<_Tp>& pt, bool copyData)
if( !copyData )
{
step[0] = step[1] = sizeof(_Tp);
data = datastart = (uchar*)&pt.x;
datastart = data = (uchar*)&pt.x;
datalimit = dataend = datastart + rows * step[0];
}
else
@ -504,7 +504,7 @@ Mat::Mat(const Point3_<_Tp>& pt, bool copyData)
if( !copyData )
{
step[0] = step[1] = sizeof(_Tp);
data = datastart = (uchar*)&pt.x;
datastart = data = (uchar*)&pt.x;
datalimit = dataend = datastart + rows * step[0];
}
else
@ -642,8 +642,9 @@ inline void Mat::release()
if( u && CV_XADD(&u->refcount, -1) == 1 )
deallocate();
u = NULL;
data = datastart = dataend = datalimit = 0;
size.p[0] = 0;
datastart = dataend = datalimit = data = 0;
for(int i = 0; i < dims; i++)
size.p[i] = 0;
}
inline
@ -999,6 +1000,17 @@ MatIterator_<_Tp> Mat::end()
return it;
}
template<typename _Tp, typename Functor> inline
void Mat::forEach(const Functor& operation) {
this->forEach_impl<_Tp>(operation);
};
template<typename _Tp, typename Functor> inline
void Mat::forEach(const Functor& operation) const {
// call as not const
(const_cast<Mat*>(this))->forEach<const _Tp>(operation);
};
template<typename _Tp> inline
Mat::operator std::vector<_Tp>() const
{
@ -1044,7 +1056,7 @@ void Mat::push_back(const _Tp& elem)
}
CV_Assert(DataType<_Tp>::type == type() && cols == 1
/* && dims == 2 (cols == 1 implies dims == 2) */);
uchar* tmp = dataend + step[0];
const uchar* tmp = dataend + step[0];
if( !isSubmatrix() && isContinuous() && tmp <= datalimit )
{
*(_Tp*)(data + (size.p[0]++) * step.p[0]) = elem;
@ -1584,6 +1596,15 @@ MatIterator_<_Tp> Mat_<_Tp>::end()
return Mat::end<_Tp>();
}
template<typename _Tp> template<typename Functor> inline
void Mat_<_Tp>::forEach(const Functor& operation) {
Mat::forEach<_Tp, Functor>(operation);
}
template<typename _Tp> template<typename Functor> inline
void Mat_<_Tp>::forEach(const Functor& operation) const {
Mat::forEach<_Tp, Functor>(operation);
}
///////////////////////////// SparseMat /////////////////////////////
@ -2100,7 +2121,7 @@ MatConstIterator::MatConstIterator(const Mat* _m)
{
if( m && m->isContinuous() )
{
sliceStart = m->data;
sliceStart = m->ptr();
sliceEnd = sliceStart + m->total()*elemSize;
}
seek((const int*)0);
@ -2113,7 +2134,7 @@ MatConstIterator::MatConstIterator(const Mat* _m, int _row, int _col)
CV_Assert(m && m->dims <= 2);
if( m->isContinuous() )
{
sliceStart = m->data;
sliceStart = m->ptr();
sliceEnd = sliceStart + m->total()*elemSize;
}
int idx[] = {_row, _col};
@ -2127,7 +2148,7 @@ MatConstIterator::MatConstIterator(const Mat* _m, Point _pt)
CV_Assert(m && m->dims <= 2);
if( m->isContinuous() )
{
sliceStart = m->data;
sliceStart = m->ptr();
sliceEnd = sliceStart + m->total()*elemSize;
}
int idx[] = {_pt.y, _pt.x};
@ -2148,7 +2169,7 @@ MatConstIterator& MatConstIterator::operator = (const MatConstIterator& it )
}
inline
uchar* MatConstIterator::operator *() const
const uchar* MatConstIterator::operator *() const
{
return ptr;
}
@ -2281,7 +2302,7 @@ MatConstIterator operator - (const MatConstIterator& a, ptrdiff_t ofs)
inline
uchar* MatConstIterator::operator [](ptrdiff_t i) const
const uchar* MatConstIterator::operator [](ptrdiff_t i) const
{
return *(*this + i);
}
@ -2453,12 +2474,12 @@ MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m, int _row, int _col)
{}
template<typename _Tp> inline
MatIterator_<_Tp>::MatIterator_(const Mat_<_Tp>* _m, Point _pt)
MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m, Point _pt)
: MatConstIterator_<_Tp>(_m, _pt)
{}
template<typename _Tp> inline
MatIterator_<_Tp>::MatIterator_(const Mat_<_Tp>* _m, const int* _idx)
MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m, const int* _idx)
: MatConstIterator_<_Tp>(_m, _idx)
{}
@ -2592,7 +2613,7 @@ inline SparseMatConstIterator& SparseMatConstIterator::operator = (const SparseM
template<typename _Tp> inline
const _Tp& SparseMatConstIterator::value() const
{
return *(_Tp*)ptr;
return *(const _Tp*)ptr;
}
inline
@ -2733,7 +2754,7 @@ SparseMatConstIterator_<_Tp>& SparseMatConstIterator_<_Tp>::operator ++()
template<typename _Tp> inline
SparseMatConstIterator_<_Tp> SparseMatConstIterator_<_Tp>::operator ++(int)
{
SparseMatConstIterator it = *this;
SparseMatConstIterator_<_Tp> it = *this;
SparseMatConstIterator::operator ++();
return it;
}
@ -2785,7 +2806,7 @@ SparseMatIterator_<_Tp>& SparseMatIterator_<_Tp>::operator ++()
template<typename _Tp> inline
SparseMatIterator_<_Tp> SparseMatIterator_<_Tp>::operator ++(int)
{
SparseMatIterator it = *this;
SparseMatIterator_<_Tp> it = *this;
SparseMatConstIterator::operator ++();
return it;
}

View File

@ -636,6 +636,9 @@ protected:
CV_EXPORTS MatAllocator* getOpenCLAllocator();
CV_EXPORTS_W bool isPerformanceCheckBypassed();
#define OCL_PERFORMANCE_CHECK(condition) (cv::ocl::isPerformanceCheckBypassed() || (condition))
}}
#endif

View File

@ -44,9 +44,10 @@
#include "opencv2/core.hpp"
namespace cv{namespace optim
namespace cv
{
class CV_EXPORTS Solver : public Algorithm
class CV_EXPORTS MinProblemSolver : public Algorithm
{
public:
class CV_EXPORTS Function
@ -70,7 +71,7 @@ public:
};
//! downhill simplex class
class CV_EXPORTS DownhillSolver : public Solver
class CV_EXPORTS DownhillSolver : public MinProblemSolver
{
public:
//! returns row-vector, even if the column-vector was given
@ -78,20 +79,22 @@ public:
//!This should be called at least once before the first call to minimize() and step is assumed to be (something that
//! after getMat() will return) row-vector or column-vector. *It's dimensionality determines the dimensionality of a problem.*
virtual void setInitStep(InputArray step)=0;
};
// both minRange & minError are specified by termcrit.epsilon; In addition, user may specify the number of iterations that the algorithm does.
CV_EXPORTS_W Ptr<DownhillSolver> createDownhillSolver(const Ptr<Solver::Function>& f=Ptr<Solver::Function>(),
InputArray initStep=Mat_<double>(1,1,0.0),
TermCriteria termcrit=TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS,5000,0.000001));
// both minRange & minError are specified by termcrit.epsilon;
// In addition, user may specify the number of iterations that the algorithm does.
static Ptr<DownhillSolver> create(const Ptr<MinProblemSolver::Function>& f=Ptr<MinProblemSolver::Function>(),
InputArray initStep=Mat_<double>(1,1,0.0),
TermCriteria termcrit=TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS,5000,0.000001));
};
//! conjugate gradient method
class CV_EXPORTS ConjGradSolver : public Solver{
class CV_EXPORTS ConjGradSolver : public MinProblemSolver
{
public:
static Ptr<ConjGradSolver> create(const Ptr<MinProblemSolver::Function>& f=Ptr<ConjGradSolver::Function>(),
TermCriteria termcrit=TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS,5000,0.000001));
};
CV_EXPORTS_W Ptr<ConjGradSolver> createConjGradSolver(const Ptr<Solver::Function>& f=Ptr<ConjGradSolver::Function>(),
TermCriteria termcrit=TermCriteria(TermCriteria::MAX_ITER+TermCriteria::EPS,5000,0.000001));
//!the return codes for solveLP() function
enum
{
@ -102,7 +105,7 @@ enum
};
CV_EXPORTS_W int solveLP(const Mat& Func, const Mat& Constr, Mat& z);
CV_EXPORTS_W void denoise_TVL1(const std::vector<Mat>& observations,Mat& result, double lambda=1.0, int niters=30);
}}// cv
}// cv
#endif

View File

@ -548,7 +548,7 @@ CV_INLINE void cvmSet( CvMat* mat, int row, int col, double value )
else
{
assert( type == CV_64FC1 );
((double*)(void*)(mat->data.ptr + (size_t)mat->step*row))[col] = (double)value;
((double*)(void*)(mat->data.ptr + (size_t)mat->step*row))[col] = value;
}
}

View File

@ -274,6 +274,102 @@ public:
CV_EXPORTS void parallel_for_(const Range& range, const ParallelLoopBody& body, double nstripes=-1.);
/////////////////////////////// forEach method of cv::Mat ////////////////////////////
template<typename _Tp, typename Functor> inline
void Mat::forEach_impl(const Functor& operation) {
if (false) {
operation(*reinterpret_cast<_Tp*>(0), reinterpret_cast<int*>(NULL));
// If your compiler fail in this line.
// Please check that your functor signature is
// (_Tp&, const int*) <- multidimential
// or (_Tp&, void*) <- in case of you don't need current idx.
}
CV_Assert(this->total() / this->size[this->dims - 1] <= INT_MAX);
const int LINES = static_cast<int>(this->total() / this->size[this->dims - 1]);
class PixelOperationWrapper :public ParallelLoopBody
{
public:
PixelOperationWrapper(Mat_<_Tp>* const frame, const Functor& _operation)
: mat(frame), op(_operation) {};
virtual ~PixelOperationWrapper(){};
// ! Overloaded virtual operator
// convert range call to row call.
virtual void operator()(const Range &range) const {
const int DIMS = mat->dims;
const int COLS = mat->size[DIMS - 1];
if (DIMS <= 2) {
for (int row = range.start; row < range.end; ++row) {
this->rowCall2(row, COLS);
}
} else {
std::vector<int> idx(COLS); /// idx is modified in this->rowCall
idx[DIMS - 2] = range.start - 1;
for (int line_num = range.start; line_num < range.end; ++line_num) {
idx[DIMS - 2]++;
for (int i = DIMS - 2; i >= 0; --i) {
if (idx[i] >= mat->size[i]) {
idx[i - 1] += idx[i] / mat->size[i];
idx[i] %= mat->size[i];
continue; // carry-over;
}
else {
break;
}
}
this->rowCall(&idx[0], COLS, DIMS);
}
}
};
private:
Mat_<_Tp>* const mat;
const Functor op;
// ! Call operator for each elements in this row.
inline void rowCall(int* const idx, const int COLS, const int DIMS) const {
int &col = idx[DIMS - 1];
col = 0;
_Tp* pixel = &(mat->template at<_Tp>(idx));
while (col < COLS) {
op(*pixel, const_cast<const int*>(idx));
pixel++; col++;
}
col = 0;
}
// ! Call operator for each elements in this row. 2d mat special version.
inline void rowCall2(const int row, const int COLS) const {
union Index{
int body[2];
operator const int*() const {
return reinterpret_cast<const int*>(this);
}
int& operator[](const int i) {
return body[i];
}
} idx = {{row, 0}};
// Special union is needed to avoid
// "error: array subscript is above array bounds [-Werror=array-bounds]"
// when call the functor `op` such that access idx[3].
_Tp* pixel = &(mat->template at<_Tp>(idx));
const _Tp* const pixel_end = pixel + COLS;
while(pixel < pixel_end) {
op(*pixel++, static_cast<const int*>(idx));
idx[1]++;
}
};
PixelOperationWrapper& operator=(const PixelOperationWrapper &) {
CV_Assert(false);
// We can not remove this implementation because Visual Studio warning C4822.
return *this;
};
};
parallel_for_(cv::Range(0, LINES), PixelOperationWrapper(reinterpret_cast<Mat_<_Tp>*>(this), operation));
};
/////////////////////////// Synchronization Primitives ///////////////////////////////
class CV_EXPORTS Mutex

View File

@ -39,7 +39,7 @@
//
//M*/
#include "perf_precomp.hpp"
#include "../perf_precomp.hpp"
#include "opencv2/ts/ocl_perf.hpp"
#ifdef HAVE_OPENCL

View File

@ -4,7 +4,7 @@
//
// Copyright (C) 2014, Advanced Micro Devices, Inc., all rights reserved.
#include "perf_precomp.hpp"
#include "../perf_precomp.hpp"
#include "opencv2/ts/ocl_perf.hpp"
#ifdef HAVE_OPENCL

View File

@ -44,7 +44,7 @@
//
//M*/
#include "perf_precomp.hpp"
#include "../perf_precomp.hpp"
#include "opencv2/ts/ocl_perf.hpp"
#ifdef HAVE_OPENCL

View File

@ -44,7 +44,7 @@
//
//M*/
#include "perf_precomp.hpp"
#include "../perf_precomp.hpp"
#include "opencv2/ts/ocl_perf.hpp"
#ifdef HAVE_OPENCL
@ -75,7 +75,7 @@ OCL_PERF_TEST_P(DftFixture, Dft, ::testing::Combine(Values(C2C, R2R, C2R, R2C),
const Size srcSize = get<1>(params);
int flags = get<2>(params);
int in_cn, out_cn;
int in_cn = 0, out_cn = 0;
switch (dft_type)
{
case R2R: flags |= cv::DFT_REAL_OUTPUT; in_cn = 1; out_cn = 1; break;

View File

@ -44,7 +44,7 @@
//
//M*/
#include "perf_precomp.hpp"
#include "../perf_precomp.hpp"
#include "opencv2/ts/ocl_perf.hpp"
#ifdef HAVE_OPENCL

View File

@ -5,7 +5,7 @@
// Copyright (C) 2014, Advanced Micro Devices, Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
#include "perf_precomp.hpp"
#include "../perf_precomp.hpp"
#include "opencv2/ts/ocl_perf.hpp"
#ifdef HAVE_OPENCL

Some files were not shown because too many files have changed in this diff Show More