Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4d34934d25 | |||
| 1b5c2bb363 | |||
| 45263d7642 |
@@ -24,4 +24,3 @@ bin/
|
||||
build
|
||||
node_modules
|
||||
CMakeSettings.json
|
||||
xcuserdata/
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Binaries branch name: ffmpeg/master_20200609
|
||||
# Binaries were created for OpenCV: 5f3012fc9afbffbf53a38f1468523d3454b3e2f6
|
||||
ocv_update(FFMPEG_BINARIES_COMMIT "1df9bf0c0c6c2cf225bd3d8e4cf5985198352454")
|
||||
ocv_update(FFMPEG_FILE_HASH_BIN32 "854b3460c435d04277e1f1ecc06cb809")
|
||||
ocv_update(FFMPEG_FILE_HASH_BIN64 "3a46d6356220796e044817ae3a21cc31")
|
||||
# Binaries branch name: ffmpeg/master_20200311
|
||||
# Binaries were created for OpenCV: 850414a501d5e6dba111c92d73fdd05794c7061d
|
||||
ocv_update(FFMPEG_BINARIES_COMMIT "3d2e97081683265950316c65a52c2e8858ffba1b")
|
||||
ocv_update(FFMPEG_FILE_HASH_BIN32 "3b094c37d270a30f0b20a0bc8d3ecafb")
|
||||
ocv_update(FFMPEG_FILE_HASH_BIN64 "388ee23a7ca44eef2344e265fafd5940")
|
||||
ocv_update(FFMPEG_FILE_HASH_CMAKE "ad57c038ba34b868277ccbe6dd0f9602")
|
||||
|
||||
function(download_win_ffmpeg script_var)
|
||||
|
||||
@@ -63,7 +63,7 @@ Attribute::~Attribute () {}
|
||||
|
||||
namespace {
|
||||
|
||||
struct NameCompare
|
||||
struct NameCompare: std::binary_function <const char *, const char *, bool>
|
||||
{
|
||||
bool
|
||||
operator () (const char *x, const char *y) const
|
||||
|
||||
@@ -225,9 +225,7 @@ class TextFormat::Parser::ParserImpl {
|
||||
bool allow_unknown_enum,
|
||||
bool allow_field_number,
|
||||
bool allow_relaxed_whitespace,
|
||||
bool allow_partial,
|
||||
int recursion_limit // backported from 3.8.0
|
||||
)
|
||||
bool allow_partial)
|
||||
: error_collector_(error_collector),
|
||||
finder_(finder),
|
||||
parse_info_tree_(parse_info_tree),
|
||||
@@ -240,9 +238,7 @@ class TextFormat::Parser::ParserImpl {
|
||||
allow_unknown_enum_(allow_unknown_enum),
|
||||
allow_field_number_(allow_field_number),
|
||||
allow_partial_(allow_partial),
|
||||
had_errors_(false),
|
||||
recursion_limit_(recursion_limit) // backported from 3.8.0
|
||||
{
|
||||
had_errors_(false) {
|
||||
// For backwards-compatibility with proto1, we need to allow the 'f' suffix
|
||||
// for floats.
|
||||
tokenizer_.set_allow_f_after_float(true);
|
||||
@@ -494,9 +490,9 @@ class TextFormat::Parser::ParserImpl {
|
||||
if (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) {
|
||||
UnknownFieldSet* unknown_field = unknown_fields->AddGroup(unknown_fields->field_count());
|
||||
unknown_field->AddLengthDelimited(0, field_name); // Add a field's name.
|
||||
return SkipFieldValue(unknown_field, recursion_limit_);
|
||||
return SkipFieldValue(unknown_field);
|
||||
} else {
|
||||
return SkipFieldMessage(unknown_fields, recursion_limit_);
|
||||
return SkipFieldMessage(unknown_fields);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -579,14 +575,7 @@ label_skip_parsing:
|
||||
}
|
||||
|
||||
// Skips the next field including the field's name and value.
|
||||
bool SkipField(UnknownFieldSet* unknown_fields, int recursion_limit) {
|
||||
|
||||
// OpenCV specific
|
||||
if (--recursion_limit < 0) {
|
||||
ReportError("Message is too deep (SkipField)");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SkipField(UnknownFieldSet* unknown_fields) {
|
||||
string field_name;
|
||||
if (TryConsume("[")) {
|
||||
// Extension name.
|
||||
@@ -605,9 +594,9 @@ label_skip_parsing:
|
||||
if (TryConsume(":") && !LookingAt("{") && !LookingAt("<")) {
|
||||
UnknownFieldSet* unknown_field = unknown_fields->AddGroup(unknown_fields->field_count());
|
||||
unknown_field->AddLengthDelimited(0, field_name); // Add a field's name.
|
||||
DO(SkipFieldValue(unknown_field, recursion_limit));
|
||||
DO(SkipFieldValue(unknown_field));
|
||||
} else {
|
||||
DO(SkipFieldMessage(unknown_fields, recursion_limit));
|
||||
DO(SkipFieldMessage(unknown_fields));
|
||||
}
|
||||
// For historical reasons, fields may optionally be separated by commas or
|
||||
// semicolons.
|
||||
@@ -619,12 +608,6 @@ label_skip_parsing:
|
||||
const Reflection* reflection,
|
||||
const FieldDescriptor* field) {
|
||||
|
||||
// backported from 3.8.0
|
||||
if (--recursion_limit_ < 0) {
|
||||
ReportError("Message is too deep");
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the parse information tree is not NULL, create a nested one
|
||||
// for the nested message.
|
||||
ParseInfoTree* parent = parse_info_tree_;
|
||||
@@ -641,9 +624,6 @@ label_skip_parsing:
|
||||
delimiter));
|
||||
}
|
||||
|
||||
// backported from 3.8.0
|
||||
++recursion_limit_;
|
||||
|
||||
// Reset the parse information tree.
|
||||
parse_info_tree_ = parent;
|
||||
return true;
|
||||
@@ -651,17 +631,11 @@ label_skip_parsing:
|
||||
|
||||
// Skips the whole body of a message including the beginning delimiter and
|
||||
// the ending delimiter.
|
||||
bool SkipFieldMessage(UnknownFieldSet* unknown_fields, int recursion_limit) {
|
||||
// OpenCV specific
|
||||
if (--recursion_limit < 0) {
|
||||
ReportError("Message is too deep (SkipFieldMessage)");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SkipFieldMessage(UnknownFieldSet* unknown_fields) {
|
||||
string delimiter;
|
||||
DO(ConsumeMessageDelimiter(&delimiter));
|
||||
while (!LookingAt(">") && !LookingAt("}")) {
|
||||
DO(SkipField(unknown_fields, recursion_limit));
|
||||
DO(SkipField(unknown_fields));
|
||||
}
|
||||
DO(Consume(delimiter));
|
||||
return true;
|
||||
@@ -801,14 +775,7 @@ label_skip_parsing:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SkipFieldValue(UnknownFieldSet* unknown_field, int recursion_limit) {
|
||||
|
||||
// OpenCV specific
|
||||
if (--recursion_limit < 0) {
|
||||
ReportError("Message is too deep (SkipFieldValue)");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SkipFieldValue(UnknownFieldSet* unknown_field) {
|
||||
if (LookingAtType(io::Tokenizer::TYPE_STRING)) {
|
||||
while (LookingAtType(io::Tokenizer::TYPE_STRING)) {
|
||||
tokenizer_.Next();
|
||||
@@ -818,9 +785,9 @@ label_skip_parsing:
|
||||
if (TryConsume("[")) {
|
||||
while (true) {
|
||||
if (!LookingAt("{") && !LookingAt("<")) {
|
||||
DO(SkipFieldValue(unknown_field, recursion_limit));
|
||||
DO(SkipFieldValue(unknown_field));
|
||||
} else {
|
||||
DO(SkipFieldMessage(unknown_field, recursion_limit));
|
||||
DO(SkipFieldMessage(unknown_field));
|
||||
}
|
||||
if (TryConsume("]")) {
|
||||
break;
|
||||
@@ -1189,7 +1156,6 @@ label_skip_parsing:
|
||||
const bool allow_field_number_;
|
||||
const bool allow_partial_;
|
||||
bool had_errors_;
|
||||
int recursion_limit_; // backported from 3.8.0
|
||||
};
|
||||
|
||||
#undef DO
|
||||
@@ -1340,19 +1306,17 @@ class TextFormat::Printer::TextGenerator
|
||||
TextFormat::Finder::~Finder() {
|
||||
}
|
||||
|
||||
TextFormat::Parser::Parser()
|
||||
TextFormat::Parser::Parser(bool allow_unknown_field)
|
||||
: error_collector_(NULL),
|
||||
finder_(NULL),
|
||||
parse_info_tree_(NULL),
|
||||
allow_partial_(false),
|
||||
allow_case_insensitive_field_(false),
|
||||
allow_unknown_field_(false),
|
||||
allow_unknown_field_(allow_unknown_field),
|
||||
allow_unknown_enum_(false),
|
||||
allow_field_number_(false),
|
||||
allow_relaxed_whitespace_(false),
|
||||
allow_singular_overwrites_(false),
|
||||
recursion_limit_(std::numeric_limits<int>::max())
|
||||
{
|
||||
allow_singular_overwrites_(false) {
|
||||
}
|
||||
|
||||
TextFormat::Parser::~Parser() {}
|
||||
@@ -1371,7 +1335,7 @@ bool TextFormat::Parser::Parse(io::ZeroCopyInputStream* input,
|
||||
overwrites_policy,
|
||||
allow_case_insensitive_field_, allow_unknown_field_,
|
||||
allow_unknown_enum_, allow_field_number_,
|
||||
allow_relaxed_whitespace_, allow_partial_, recursion_limit_);
|
||||
allow_relaxed_whitespace_, allow_partial_);
|
||||
return MergeUsingImpl(input, output, &parser);
|
||||
}
|
||||
|
||||
@@ -1389,7 +1353,7 @@ bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input,
|
||||
ParserImpl::ALLOW_SINGULAR_OVERWRITES,
|
||||
allow_case_insensitive_field_, allow_unknown_field_,
|
||||
allow_unknown_enum_, allow_field_number_,
|
||||
allow_relaxed_whitespace_, allow_partial_, recursion_limit_);
|
||||
allow_relaxed_whitespace_, allow_partial_);
|
||||
return MergeUsingImpl(input, output, &parser);
|
||||
}
|
||||
|
||||
@@ -1424,7 +1388,7 @@ bool TextFormat::Parser::ParseFieldValueFromString(
|
||||
ParserImpl::ALLOW_SINGULAR_OVERWRITES,
|
||||
allow_case_insensitive_field_, allow_unknown_field_,
|
||||
allow_unknown_enum_, allow_field_number_,
|
||||
allow_relaxed_whitespace_, allow_partial_, recursion_limit_);
|
||||
allow_relaxed_whitespace_, allow_partial_);
|
||||
return parser.ParseField(field, output);
|
||||
}
|
||||
|
||||
|
||||
@@ -457,7 +457,7 @@ class LIBPROTOBUF_EXPORT TextFormat {
|
||||
// For more control over parsing, use this class.
|
||||
class LIBPROTOBUF_EXPORT Parser {
|
||||
public:
|
||||
Parser();
|
||||
Parser(bool allow_unknown_field = false);
|
||||
~Parser();
|
||||
|
||||
// Like TextFormat::Parse().
|
||||
@@ -508,24 +508,10 @@ class LIBPROTOBUF_EXPORT TextFormat {
|
||||
Message* output);
|
||||
|
||||
|
||||
// backported from 3.8.0
|
||||
// When an unknown field is met, parsing will fail if this option is set
|
||||
// to false(the default). If true, unknown fields will be ignored and
|
||||
// a warning message will be generated.
|
||||
// Please aware that set this option true may hide some errors (e.g.
|
||||
// spelling error on field name). Avoid to use this option if possible.
|
||||
void AllowUnknownField(bool allow) { allow_unknown_field_ = allow; }
|
||||
|
||||
|
||||
void AllowFieldNumber(bool allow) {
|
||||
allow_field_number_ = allow;
|
||||
}
|
||||
|
||||
// backported from 3.8.0
|
||||
// Sets maximum recursion depth which parser can use. This is effectively
|
||||
// the maximum allowed nesting of proto messages.
|
||||
void SetRecursionLimit(int limit) { recursion_limit_ = limit; }
|
||||
|
||||
private:
|
||||
// Forward declaration of an internal class used to parse text
|
||||
// representations (see text_format.cc for implementation).
|
||||
@@ -547,7 +533,6 @@ class LIBPROTOBUF_EXPORT TextFormat {
|
||||
bool allow_field_number_;
|
||||
bool allow_relaxed_whitespace_;
|
||||
bool allow_singular_overwrites_;
|
||||
int recursion_limit_; // backported from 3.8.0
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -32,10 +32,8 @@
|
||||
#define QUIRC_PERSPECTIVE_PARAMS 8
|
||||
|
||||
#if QUIRC_MAX_REGIONS < UINT8_MAX
|
||||
#define QUIRC_PIXEL_ALIAS_IMAGE 1
|
||||
typedef uint8_t quirc_pixel_t;
|
||||
#elif QUIRC_MAX_REGIONS < UINT16_MAX
|
||||
#define QUIRC_PIXEL_ALIAS_IMAGE 0
|
||||
typedef uint16_t quirc_pixel_t;
|
||||
#else
|
||||
#error "QUIRC_MAX_REGIONS > 65534 is not supported"
|
||||
@@ -79,6 +77,7 @@ struct quirc_grid {
|
||||
struct quirc {
|
||||
uint8_t *image;
|
||||
quirc_pixel_t *pixels;
|
||||
int *row_average; /* used by threshold() */
|
||||
int w;
|
||||
int h;
|
||||
|
||||
|
||||
@@ -874,7 +874,7 @@ static quirc_decode_error_t decode_payload(struct quirc_data *data,
|
||||
done:
|
||||
|
||||
/* Add nul terminator to all payloads */
|
||||
if (data->payload_len >= (int) sizeof(data->payload))
|
||||
if ((unsigned)data->payload_len >= sizeof(data->payload))
|
||||
data->payload_len--;
|
||||
data->payload[data->payload_len] = 0;
|
||||
|
||||
|
||||
@@ -27,7 +27,10 @@ struct quirc *quirc_new(void)
|
||||
{
|
||||
struct quirc *q = malloc(sizeof(*q));
|
||||
|
||||
memset(q, 0, sizeof(*q));
|
||||
if (!q)
|
||||
return NULL;
|
||||
|
||||
memset(q, 0, sizeof(*q));
|
||||
return q;
|
||||
}
|
||||
|
||||
@@ -36,8 +39,9 @@ void quirc_destroy(struct quirc *q)
|
||||
free(q->image);
|
||||
/* q->pixels may alias q->image when their type representation is of the
|
||||
same size, so we need to be careful here to avoid a double free */
|
||||
if (!QUIRC_PIXEL_ALIAS_IMAGE)
|
||||
if (sizeof(*q->image) != sizeof(*q->pixels))
|
||||
free(q->pixels);
|
||||
free(q->row_average);
|
||||
free(q);
|
||||
}
|
||||
|
||||
@@ -45,6 +49,7 @@ int quirc_resize(struct quirc *q, int w, int h)
|
||||
{
|
||||
uint8_t *image = NULL;
|
||||
quirc_pixel_t *pixels = NULL;
|
||||
int *row_average = NULL;
|
||||
|
||||
/*
|
||||
* XXX: w and h should be size_t (or at least unsigned) as negatives
|
||||
@@ -77,27 +82,35 @@ int quirc_resize(struct quirc *q, int w, int h)
|
||||
(void)memcpy(image, q->image, min);
|
||||
|
||||
/* alloc a new buffer for q->pixels if needed */
|
||||
if (!QUIRC_PIXEL_ALIAS_IMAGE) {
|
||||
if (sizeof(*q->image) != sizeof(*q->pixels)) {
|
||||
pixels = calloc(newdim, sizeof(quirc_pixel_t));
|
||||
if (!pixels)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* alloc a new buffer for q->row_average */
|
||||
row_average = calloc(w, sizeof(int));
|
||||
if (!row_average)
|
||||
goto fail;
|
||||
|
||||
/* alloc succeeded, update `q` with the new size and buffers */
|
||||
q->w = w;
|
||||
q->h = h;
|
||||
free(q->image);
|
||||
q->image = image;
|
||||
if (!QUIRC_PIXEL_ALIAS_IMAGE) {
|
||||
if (sizeof(*q->image) != sizeof(*q->pixels)) {
|
||||
free(q->pixels);
|
||||
q->pixels = pixels;
|
||||
}
|
||||
free(q->row_average);
|
||||
q->row_average = row_average;
|
||||
|
||||
return 0;
|
||||
/* NOTREACHED */
|
||||
fail:
|
||||
free(image);
|
||||
free(pixels);
|
||||
free(row_average);
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -120,10 +133,6 @@ static const char *const error_table[] = {
|
||||
|
||||
const char *quirc_strerror(quirc_decode_error_t err)
|
||||
{
|
||||
if ((int) err >= 0) {
|
||||
if ((unsigned long) err < (unsigned long) (sizeof(error_table) / sizeof(error_table[0])))
|
||||
return error_table[err];
|
||||
}
|
||||
|
||||
return "Unknown error";
|
||||
if ((int)err < 8) { return error_table[err]; }
|
||||
else { return "Unknown error"; }
|
||||
}
|
||||
|
||||
@@ -17,7 +17,16 @@
|
||||
#include <quirc_internal.h>
|
||||
|
||||
const struct quirc_version_info quirc_version_db[QUIRC_MAX_VERSION + 1] = {
|
||||
{0},
|
||||
{ /* 0 */
|
||||
.data_bytes = 0,
|
||||
.apat = {0},
|
||||
.ecc = {
|
||||
{.bs = 0, .dw = 0, .ns = 0},
|
||||
{.bs = 0, .dw = 0, .ns = 0},
|
||||
{.bs = 0, .dw = 0, .ns = 0},
|
||||
{.bs = 0, .dw = 0, .ns = 0}
|
||||
}
|
||||
},
|
||||
{ /* Version 1 */
|
||||
.data_bytes = 26,
|
||||
.apat = {0},
|
||||
|
||||
@@ -5,8 +5,8 @@ if (WIN32 AND NOT ARM)
|
||||
message(FATAL_ERROR "BUILD_TBB option supports Windows on ARM only!\nUse regular official TBB build instead of the BUILD_TBB option!")
|
||||
endif()
|
||||
|
||||
ocv_update(OPENCV_TBB_RELEASE "v2020.2")
|
||||
ocv_update(OPENCV_TBB_RELEASE_MD5 "5af6f6c2a24c2043e62e47205e273b1f")
|
||||
ocv_update(OPENCV_TBB_RELEASE "v2020.1")
|
||||
ocv_update(OPENCV_TBB_RELEASE_MD5 "734f335d06ee80a7d4a20cc0da734c59")
|
||||
ocv_update(OPENCV_TBB_FILENAME "${OPENCV_TBB_RELEASE}.tar.gz")
|
||||
string(REGEX REPLACE "^v" "" OPENCV_TBB_RELEASE_ "${OPENCV_TBB_RELEASE}")
|
||||
#ocv_update(OPENCV_TBB_SUBDIR ...)
|
||||
|
||||
@@ -285,12 +285,9 @@ OCV_OPTION(WITH_INF_ENGINE "Include Intel Inference Engine support" OFF
|
||||
OCV_OPTION(WITH_NGRAPH "Include nGraph support" WITH_INF_ENGINE
|
||||
VISIBLE_IF TRUE
|
||||
VERIFY TARGET ngraph::ngraph)
|
||||
OCV_OPTION(WITH_JASPER "Include JPEG2K support (Jasper)" ON
|
||||
OCV_OPTION(WITH_JASPER "Include JPEG2K support" ON
|
||||
VISIBLE_IF NOT IOS
|
||||
VERIFY HAVE_JASPER)
|
||||
OCV_OPTION(WITH_OPENJPEG "Include JPEG2K support (OpenJPEG)" ON
|
||||
VISIBLE_IF NOT IOS
|
||||
VERIFY HAVE_OPENJPEG)
|
||||
OCV_OPTION(WITH_JPEG "Include JPEG support" ON
|
||||
VISIBLE_IF TRUE
|
||||
VERIFY HAVE_JPEG)
|
||||
@@ -452,7 +449,6 @@ OCV_OPTION(BUILD_FAT_JAVA_LIB "Create Java wrapper exporting all functions
|
||||
OCV_OPTION(BUILD_ANDROID_SERVICE "Build OpenCV Manager for Google Play" OFF IF ANDROID )
|
||||
OCV_OPTION(BUILD_CUDA_STUBS "Build CUDA modules stubs when no CUDA SDK" OFF IF (NOT APPLE_FRAMEWORK) )
|
||||
OCV_OPTION(BUILD_JAVA "Enable Java support" (ANDROID OR NOT CMAKE_CROSSCOMPILING) IF (ANDROID OR (NOT APPLE_FRAMEWORK AND NOT WINRT)) )
|
||||
OCV_OPTION(BUILD_OBJC "Enable Objective-C support" ON IF APPLE_FRAMEWORK )
|
||||
|
||||
# OpenCV installation options
|
||||
# ===================================================
|
||||
@@ -947,11 +943,11 @@ endif()
|
||||
# for UNIX it does not make sense as LICENSE and readme will be part of the package automatically
|
||||
if(ANDROID OR NOT UNIX)
|
||||
install(FILES ${OPENCV_LICENSE_FILE}
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
|
||||
PERMISSIONS OWNER_READ GROUP_READ WORLD_READ
|
||||
DESTINATION ./ COMPONENT libs)
|
||||
if(OPENCV_README_FILE)
|
||||
install(FILES ${OPENCV_README_FILE}
|
||||
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
|
||||
PERMISSIONS OWNER_READ GROUP_READ WORLD_READ
|
||||
DESTINATION ./ COMPONENT libs)
|
||||
endif()
|
||||
endif()
|
||||
@@ -1253,12 +1249,8 @@ if(WITH_TIFF OR HAVE_TIFF)
|
||||
status(" TIFF:" TIFF_FOUND THEN "${TIFF_LIBRARY} (ver ${TIFF_VERSION} / ${TIFF_VERSION_STRING})" ELSE "build (ver ${TIFF_VERSION} - ${TIFF_VERSION_STRING})")
|
||||
endif()
|
||||
|
||||
if(HAVE_OPENJPEG)
|
||||
status(" JPEG 2000:" "OpenJPEG (ver ${OPENJPEG_MAJOR_VERSION}.${OPENJPEG_MINOR_VERSION}.${OPENJPEG_BUILD_VERSION})")
|
||||
elseif(HAVE_JASPER)
|
||||
status(" JPEG 2000:" JASPER_FOUND THEN "${JASPER_LIBRARY} (ver ${JASPER_VERSION_STRING})" ELSE "build Jasper (ver ${JASPER_VERSION_STRING})")
|
||||
elseif(WITH_OPENJPEG OR WITH_JASPER)
|
||||
status(" JPEG 2000:" "NO")
|
||||
if(WITH_JASPER OR HAVE_JASPER)
|
||||
status(" JPEG 2000:" JASPER_FOUND THEN "${JASPER_LIBRARY} (ver ${JASPER_VERSION_STRING})" ELSE "build (ver ${JASPER_VERSION_STRING})")
|
||||
endif()
|
||||
|
||||
if(WITH_OPENEXR OR HAVE_OPENEXR)
|
||||
@@ -1596,12 +1588,6 @@ if(BUILD_JAVA)
|
||||
status(" Java tests:" BUILD_TESTS AND opencv_test_java_BINARY_DIR THEN YES ELSE NO)
|
||||
endif()
|
||||
|
||||
# ========================== Objective-C =======================
|
||||
if(BUILD_OBJC)
|
||||
status("")
|
||||
status(" Objective-C wrappers:" HAVE_opencv_objc THEN YES ELSE NO)
|
||||
endif()
|
||||
|
||||
ocv_cmake_hook(STATUS_DUMP_EXTRA)
|
||||
|
||||
# ========================== auxiliary ==========================
|
||||
|
||||
@@ -3,12 +3,10 @@
|
||||
### Resources
|
||||
|
||||
* Homepage: <https://opencv.org>
|
||||
* Courses: <https://opencv.org/courses>
|
||||
* Docs: <https://docs.opencv.org/master/>
|
||||
* Q&A forum: <http://answers.opencv.org>
|
||||
* Issue tracking: <https://github.com/opencv/opencv/issues>
|
||||
|
||||
|
||||
### Contributing
|
||||
|
||||
Please read the [contribution guidelines](https://github.com/opencv/opencv/wiki/How_to_contribute) before starting work on a pull request.
|
||||
|
||||
@@ -63,12 +63,6 @@ if(CUDA_FOUND)
|
||||
message(STATUS "CUDA detected: " ${CUDA_VERSION})
|
||||
|
||||
set(_generations "Fermi" "Kepler" "Maxwell" "Pascal" "Volta" "Turing")
|
||||
set(_arch_fermi "2.0")
|
||||
set(_arch_kepler "3.0;3.5;3.7")
|
||||
set(_arch_maxwell "5.0;5.2")
|
||||
set(_arch_pascal "6.0;6.1")
|
||||
set(_arch_volta "7.0")
|
||||
set(_arch_turing "7.5")
|
||||
if(NOT CMAKE_CROSSCOMPILING)
|
||||
list(APPEND _generations "Auto")
|
||||
endif()
|
||||
@@ -92,58 +86,30 @@ if(CUDA_FOUND)
|
||||
SET(DETECT_ARCHS_COMMAND ${DETECT_ARCHS_COMMAND} "-ccbin" "${host_compiler_bindir}")
|
||||
endif()
|
||||
|
||||
macro(ocv_filter_available_architecture result_list)
|
||||
if(DEFINED CUDA_SUPPORTED_CC)
|
||||
set(${result_list} "${CUDA_SUPPORTED_CC}")
|
||||
else()
|
||||
set(CC_LIST ${ARGN})
|
||||
foreach(target_arch ${CC_LIST})
|
||||
string(REPLACE "." "" target_arch_short ${target_arch})
|
||||
set(NVCC_OPTION "-gencode;arch=compute_${target_arch_short},code=sm_${target_arch_short}")
|
||||
execute_process( COMMAND "${CUDA_NVCC_EXECUTABLE}" ${NVCC_OPTION} "${OpenCV_SOURCE_DIR}/cmake/checks/OpenCVDetectCudaArch.cu"
|
||||
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/"
|
||||
RESULT_VARIABLE _nvcc_res OUTPUT_VARIABLE _nvcc_out
|
||||
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if(_nvcc_res EQUAL 0)
|
||||
set(${result_list} "${${result_list}} ${target_arch}")
|
||||
endif()
|
||||
endforeach()
|
||||
string(STRIP ${${result_list}} ${result_list})
|
||||
set(CUDA_SUPPORTED_CC ${${result_list}} CACHE INTERNAL "List of supported compute capability")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(ocv_detect_native_cuda_arch status output)
|
||||
execute_process( COMMAND ${DETECT_ARCHS_COMMAND}
|
||||
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/"
|
||||
RESULT_VARIABLE ${status} OUTPUT_VARIABLE _nvcc_out
|
||||
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
string(REGEX REPLACE ".*\n" "" ${output} "${_nvcc_out}") #Strip leading warning messages, if any
|
||||
endmacro()
|
||||
|
||||
macro(ocv_wipeout_deprecated _arch_bin_list)
|
||||
string(REPLACE "2.1" "2.1(2.0)" ${_arch_bin_list} ${${_arch_bin_list}})
|
||||
endmacro()
|
||||
|
||||
set(__cuda_arch_ptx "")
|
||||
if(CUDA_GENERATION STREQUAL "Fermi")
|
||||
set(__cuda_arch_bin ${_arch_fermi})
|
||||
set(__cuda_arch_bin "2.0")
|
||||
elseif(CUDA_GENERATION STREQUAL "Kepler")
|
||||
set(__cuda_arch_bin ${_arch_kepler})
|
||||
set(__cuda_arch_bin "3.0 3.5 3.7")
|
||||
elseif(CUDA_GENERATION STREQUAL "Maxwell")
|
||||
set(__cuda_arch_bin ${_arch_maxwell})
|
||||
set(__cuda_arch_bin "5.0 5.2")
|
||||
elseif(CUDA_GENERATION STREQUAL "Pascal")
|
||||
set(__cuda_arch_bin ${_arch_pascal})
|
||||
set(__cuda_arch_bin "6.0 6.1")
|
||||
elseif(CUDA_GENERATION STREQUAL "Volta")
|
||||
set(__cuda_arch_bin ${_arch_volta})
|
||||
set(__cuda_arch_bin "7.0")
|
||||
elseif(CUDA_GENERATION STREQUAL "Turing")
|
||||
set(__cuda_arch_bin ${_arch_turing})
|
||||
set(__cuda_arch_bin "7.5")
|
||||
elseif(CUDA_GENERATION STREQUAL "Auto")
|
||||
ocv_detect_native_cuda_arch(_nvcc_res _nvcc_out)
|
||||
execute_process( COMMAND ${DETECT_ARCHS_COMMAND}
|
||||
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/"
|
||||
RESULT_VARIABLE _nvcc_res OUTPUT_VARIABLE _nvcc_out
|
||||
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
string(REGEX REPLACE ".*\n" "" _nvcc_out "${_nvcc_out}") #Strip leading warning messages, if any
|
||||
if(NOT _nvcc_res EQUAL 0)
|
||||
message(STATUS "Automatic detection of CUDA generation failed. Going to build for all known architectures.")
|
||||
else()
|
||||
string(REGEX MATCHALL "[0-9]+\\.[0-9]" __cuda_arch_bin "${_nvcc_out}")
|
||||
set(__cuda_arch_bin "${_nvcc_out}")
|
||||
string(REPLACE "2.1" "2.1(2.0)" __cuda_arch_bin "${__cuda_arch_bin}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -152,26 +118,29 @@ if(CUDA_FOUND)
|
||||
set(__cuda_arch_bin "3.2")
|
||||
set(__cuda_arch_ptx "")
|
||||
elseif(AARCH64)
|
||||
ocv_detect_native_cuda_arch(_nvcc_res _nvcc_out)
|
||||
execute_process( COMMAND ${DETECT_ARCHS_COMMAND}
|
||||
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/"
|
||||
RESULT_VARIABLE _nvcc_res OUTPUT_VARIABLE _nvcc_out
|
||||
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
string(REGEX REPLACE ".*\n" "" _nvcc_out "${_nvcc_out}") #Strip leading warning messages, if any
|
||||
if(NOT _nvcc_res EQUAL 0)
|
||||
message(STATUS "Automatic detection of CUDA generation failed. Going to build for all known architectures.")
|
||||
set(__cuda_arch_bin "5.3 6.2 7.2")
|
||||
else()
|
||||
set(__cuda_arch_bin "${_nvcc_out}")
|
||||
string(REPLACE "2.1" "2.1(2.0)" __cuda_arch_bin "${__cuda_arch_bin}")
|
||||
endif()
|
||||
set(__cuda_arch_ptx "")
|
||||
else()
|
||||
ocv_filter_available_architecture(__cuda_arch_bin
|
||||
${_arch_fermi}
|
||||
${_arch_kepler}
|
||||
${_arch_maxwell}
|
||||
${_arch_pascal}
|
||||
${_arch_volta}
|
||||
${_arch_turing}
|
||||
)
|
||||
if(CUDA_VERSION VERSION_LESS "9.0")
|
||||
set(__cuda_arch_bin "2.0 3.0 3.5 3.7 5.0 5.2 6.0 6.1")
|
||||
elseif(CUDA_VERSION VERSION_LESS "10.0")
|
||||
set(__cuda_arch_bin "3.0 3.5 3.7 5.0 5.2 6.0 6.1 7.0")
|
||||
else()
|
||||
set(__cuda_arch_bin "3.0 3.5 3.7 5.0 5.2 6.0 6.1 7.0 7.5")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
ocv_wipeout_deprecated(__cuda_arch_bin)
|
||||
|
||||
set(CUDA_ARCH_BIN ${__cuda_arch_bin} CACHE STRING "Specify 'real' GPU architectures to build binaries for, BIN(PTX) format is supported")
|
||||
set(CUDA_ARCH_PTX ${__cuda_arch_ptx} CACHE STRING "Specify 'virtual' PTX architectures to build PTX intermediate code for")
|
||||
|
||||
@@ -98,8 +98,6 @@ elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64")
|
||||
set(PPC64 1)
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(mips.*|MIPS.*)")
|
||||
set(MIPS 1)
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(riscv.*|RISCV.*)")
|
||||
set(RISCV 1)
|
||||
else()
|
||||
if(NOT OPENCV_SUPPRESS_MESSAGE_UNRECOGNIZED_SYSTEM_PROCESSOR)
|
||||
message(WARNING "OpenCV: unrecognized target processor configuration")
|
||||
|
||||
@@ -17,34 +17,10 @@
|
||||
# INF_ENGINE_TARGET - set to name of imported library target representing InferenceEngine
|
||||
#
|
||||
|
||||
|
||||
macro(ocv_ie_find_extra_libraries find_prefix find_suffix)
|
||||
file(GLOB libraries "${INF_ENGINE_LIB_DIRS}/${find_prefix}inference_engine*${find_suffix}")
|
||||
foreach(full_path IN LISTS libraries)
|
||||
get_filename_component(library "${full_path}" NAME_WE)
|
||||
string(REPLACE "${find_prefix}" "" library "${library}")
|
||||
if(library STREQUAL "inference_engine" OR library STREQUAL "inference_engined")
|
||||
# skip
|
||||
else()
|
||||
add_library(${library} UNKNOWN IMPORTED)
|
||||
set_target_properties(${library} PROPERTIES
|
||||
IMPORTED_LOCATION "${full_path}")
|
||||
list(APPEND custom_libraries ${library})
|
||||
endif()
|
||||
endforeach()
|
||||
endmacro()
|
||||
|
||||
function(add_custom_ie_build _inc _lib _lib_rel _lib_dbg _msg)
|
||||
if(NOT _inc OR NOT (_lib OR _lib_rel OR _lib_dbg))
|
||||
return()
|
||||
endif()
|
||||
if(NOT _lib)
|
||||
if(_lib_rel)
|
||||
set(_lib "${_lib_rel}")
|
||||
else()
|
||||
set(_lib "${_lib_dbg}")
|
||||
endif()
|
||||
endif()
|
||||
add_library(inference_engine UNKNOWN IMPORTED)
|
||||
set_target_properties(inference_engine PROPERTIES
|
||||
IMPORTED_LOCATION "${_lib}"
|
||||
@@ -54,31 +30,24 @@ function(add_custom_ie_build _inc _lib _lib_rel _lib_dbg _msg)
|
||||
)
|
||||
|
||||
set(custom_libraries "")
|
||||
set(__prefixes "${CMAKE_FIND_LIBRARY_PREFIXES}")
|
||||
if(NOT __prefixes)
|
||||
set(__prefixes "_empty_")
|
||||
endif()
|
||||
foreach(find_prefix ${__prefixes})
|
||||
if(find_prefix STREQUAL "_empty_") # foreach doesn't iterate over empty elements
|
||||
set(find_prefix "")
|
||||
endif()
|
||||
foreach(find_suffix ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
ocv_ie_find_extra_libraries("${find_prefix}" "${find_suffix}")
|
||||
endforeach()
|
||||
if(NOT CMAKE_FIND_LIBRARY_SUFFIXES)
|
||||
ocv_ie_find_extra_libraries("${find_prefix}" "")
|
||||
endif()
|
||||
file(GLOB libraries "${INF_ENGINE_LIB_DIRS}/${CMAKE_SHARED_LIBRARY_PREFIX}inference_engine_*${CMAKE_SHARED_LIBRARY_SUFFIX}")
|
||||
foreach(full_path IN LISTS libraries)
|
||||
get_filename_component(library "${full_path}" NAME_WE)
|
||||
string(REPLACE "${CMAKE_SHARED_LIBRARY_PREFIX}" "" library "${library}")
|
||||
add_library(${library} UNKNOWN IMPORTED)
|
||||
set_target_properties(${library} PROPERTIES
|
||||
IMPORTED_LOCATION "${full_path}")
|
||||
list(APPEND custom_libraries ${library})
|
||||
endforeach()
|
||||
|
||||
if(NOT INF_ENGINE_RELEASE VERSION_GREATER "2018050000")
|
||||
find_library(INF_ENGINE_OMP_LIBRARY iomp5 PATHS "${INF_ENGINE_OMP_DIR}" NO_DEFAULT_PATH)
|
||||
if(NOT INF_ENGINE_OMP_LIBRARY)
|
||||
message(WARNING "OpenMP for IE have not been found. Set INF_ENGINE_OMP_DIR variable if you experience build errors.")
|
||||
else()
|
||||
set_target_properties(inference_engine PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES "${INF_ENGINE_OMP_LIBRARY}")
|
||||
endif()
|
||||
endif()
|
||||
if(EXISTS "${INF_ENGINE_OMP_LIBRARY}")
|
||||
set_target_properties(inference_engine PROPERTIES IMPORTED_LINK_INTERFACE_LIBRARIES "${INF_ENGINE_OMP_LIBRARY}")
|
||||
endif()
|
||||
set(INF_ENGINE_VERSION "Unknown" CACHE STRING "")
|
||||
set(INF_ENGINE_TARGET "inference_engine;${custom_libraries}" PARENT_SCOPE)
|
||||
message(STATUS "Detected InferenceEngine: ${_msg}")
|
||||
@@ -95,9 +64,6 @@ endif()
|
||||
|
||||
if(NOT INF_ENGINE_TARGET AND INF_ENGINE_LIB_DIRS AND INF_ENGINE_INCLUDE_DIRS)
|
||||
find_path(ie_custom_inc "inference_engine.hpp" PATHS "${INF_ENGINE_INCLUDE_DIRS}" NO_DEFAULT_PATH)
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
find_library(ie_custom_lib_dbg "inference_engined" PATHS "${INF_ENGINE_LIB_DIRS}" NO_DEFAULT_PATH) # Win32 and MacOSX
|
||||
endif()
|
||||
find_library(ie_custom_lib "inference_engine" PATHS "${INF_ENGINE_LIB_DIRS}" NO_DEFAULT_PATH)
|
||||
find_library(ie_custom_lib_rel "inference_engine" PATHS "${INF_ENGINE_LIB_DIRS}/Release" NO_DEFAULT_PATH)
|
||||
find_library(ie_custom_lib_dbg "inference_engine" PATHS "${INF_ENGINE_LIB_DIRS}/Debug" NO_DEFAULT_PATH)
|
||||
@@ -116,9 +82,6 @@ if(NOT INF_ENGINE_TARGET AND _loc)
|
||||
endif()
|
||||
set(INF_ENGINE_PLATFORM "${INF_ENGINE_PLATFORM_DEFAULT}" CACHE STRING "InferenceEngine platform (library dir)")
|
||||
find_path(ie_custom_env_inc "inference_engine.hpp" PATHS "${_loc}/deployment_tools/inference_engine/include" NO_DEFAULT_PATH)
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
find_library(ie_custom_env_lib_dbg "inference_engined" PATHS "${_loc}/deployment_tools/inference_engine/lib/${INF_ENGINE_PLATFORM}/intel64" NO_DEFAULT_PATH)
|
||||
endif()
|
||||
find_library(ie_custom_env_lib "inference_engine" PATHS "${_loc}/deployment_tools/inference_engine/lib/${INF_ENGINE_PLATFORM}/intel64" NO_DEFAULT_PATH)
|
||||
find_library(ie_custom_env_lib_rel "inference_engine" PATHS "${_loc}/deployment_tools/inference_engine/lib/intel64/Release" NO_DEFAULT_PATH)
|
||||
find_library(ie_custom_env_lib_dbg "inference_engine" PATHS "${_loc}/deployment_tools/inference_engine/lib/intel64/Debug" NO_DEFAULT_PATH)
|
||||
@@ -129,9 +92,9 @@ endif()
|
||||
|
||||
if(INF_ENGINE_TARGET)
|
||||
if(NOT INF_ENGINE_RELEASE)
|
||||
message(WARNING "InferenceEngine version has not been set, 2020.4 will be used by default. Set INF_ENGINE_RELEASE variable if you experience build errors.")
|
||||
message(WARNING "InferenceEngine version has not been set, 2020.2 will be used by default. Set INF_ENGINE_RELEASE variable if you experience build errors.")
|
||||
endif()
|
||||
set(INF_ENGINE_RELEASE "2020040000" CACHE STRING "Force IE version, should be in form YYYYAABBCC (e.g. 2020.1.0.2 -> 2020010002)")
|
||||
set(INF_ENGINE_RELEASE "2020020000" CACHE STRING "Force IE version, should be in form YYYYAABBCC (e.g. 2020.1.0.2 -> 2020010002)")
|
||||
set_target_properties(${INF_ENGINE_TARGET} PROPERTIES
|
||||
INTERFACE_COMPILE_DEFINITIONS "HAVE_INF_ENGINE=1;INF_ENGINE_RELEASE=${INF_ENGINE_RELEASE}"
|
||||
)
|
||||
|
||||
@@ -1,30 +1,12 @@
|
||||
# VTK 9.0
|
||||
if(NOT VTK_FOUND)
|
||||
find_package(VTK 9 QUIET NAMES vtk COMPONENTS
|
||||
FiltersExtraction
|
||||
FiltersSources
|
||||
FiltersTexture
|
||||
IOExport
|
||||
IOGeometry
|
||||
IOPLY
|
||||
InteractionStyle
|
||||
RenderingCore
|
||||
RenderingLOD
|
||||
RenderingOpenGL2
|
||||
NO_MODULE)
|
||||
endif()
|
||||
|
||||
# VTK 6.x components
|
||||
if(NOT VTK_FOUND)
|
||||
find_package(VTK QUIET COMPONENTS vtkInteractionStyle vtkRenderingLOD vtkIOPLY vtkFiltersTexture vtkRenderingFreeType vtkIOExport NO_MODULE)
|
||||
IF(VTK_FOUND)
|
||||
IF(VTK_RENDERING_BACKEND) #in vtk 7, the rendering backend is exported as a var.
|
||||
find_package(VTK QUIET COMPONENTS vtkInteractionStyle vtkRenderingLOD vtkIOPLY vtkFiltersTexture vtkRenderingFreeType vtkIOExport NO_MODULE)
|
||||
IF(VTK_FOUND)
|
||||
IF(VTK_RENDERING_BACKEND) #in vtk 7, the rendering backend is exported as a var.
|
||||
find_package(VTK QUIET COMPONENTS vtkRendering${VTK_RENDERING_BACKEND} vtkInteractionStyle vtkRenderingLOD vtkIOPLY vtkFiltersTexture vtkRenderingFreeType vtkIOExport vtkIOGeometry NO_MODULE)
|
||||
ELSE(VTK_RENDERING_BACKEND)
|
||||
ELSE(VTK_RENDERING_BACKEND)
|
||||
find_package(VTK QUIET COMPONENTS vtkRenderingOpenGL vtkInteractionStyle vtkRenderingLOD vtkIOPLY vtkFiltersTexture vtkRenderingFreeType vtkIOExport NO_MODULE)
|
||||
ENDIF(VTK_RENDERING_BACKEND)
|
||||
ENDIF(VTK_FOUND)
|
||||
endif()
|
||||
ENDIF(VTK_RENDERING_BACKEND)
|
||||
ENDIF(VTK_FOUND)
|
||||
|
||||
# VTK 5.x components
|
||||
if(NOT VTK_FOUND)
|
||||
|
||||
@@ -1,22 +1,17 @@
|
||||
# ----------------------------------------------------------------------------
|
||||
# Uninstall target, for "make uninstall"
|
||||
# ----------------------------------------------------------------------------
|
||||
if(NOT TARGET uninstall) # avoid conflicts with parent projects
|
||||
configure_file(
|
||||
"${OpenCV_SOURCE_DIR}/cmake/templates/cmake_uninstall.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
|
||||
@ONLY
|
||||
)
|
||||
CONFIGURE_FILE(
|
||||
"${OpenCV_SOURCE_DIR}/cmake/templates/cmake_uninstall.cmake.in"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
|
||||
@ONLY)
|
||||
|
||||
add_custom_target(uninstall
|
||||
COMMAND "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
|
||||
)
|
||||
|
||||
if(ENABLE_SOLUTION_FOLDERS)
|
||||
set_target_properties(uninstall PROPERTIES FOLDER "CMakeTargets")
|
||||
endif()
|
||||
ADD_CUSTOM_TARGET(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
|
||||
if(ENABLE_SOLUTION_FOLDERS)
|
||||
set_target_properties(uninstall PROPERTIES FOLDER "CMakeTargets")
|
||||
endif()
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# target building all OpenCV modules
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
@@ -148,7 +148,7 @@ macro(ipp_detect_version)
|
||||
IMPORTED_LOCATION ${IPP_LIBRARY_DIR}/${IPP_LIB_PREFIX}${IPP_PREFIX}${name}${IPP_SUFFIX}${IPP_LIB_SUFFIX}
|
||||
)
|
||||
list(APPEND IPP_LIBRARIES ipp${name})
|
||||
if (NOT BUILD_SHARED_LIBS AND (HAVE_IPP_ICV OR ";${OPENCV_INSTALL_EXTERNAL_DEPENDENCIES};" MATCHES ";ipp;"))
|
||||
if (NOT BUILD_SHARED_LIBS)
|
||||
# CMake doesn't support "install(TARGETS ${IPP_PREFIX}${name} " command with imported targets
|
||||
install(FILES ${IPP_LIBRARY_DIR}/${IPP_LIB_PREFIX}${IPP_PREFIX}${name}${IPP_SUFFIX}${IPP_LIB_SUFFIX}
|
||||
DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev)
|
||||
|
||||
@@ -108,13 +108,12 @@ macro(ippiw_setup PATH BUILD)
|
||||
message(STATUS "found Intel IPP Integration Wrappers binaries: ${IW_VERSION_MAJOR}.${IW_VERSION_MINOR}.${IW_VERSION_UPDATE}")
|
||||
message(STATUS "at: ${IPP_IW_PATH}")
|
||||
|
||||
add_library(ipp_iw STATIC IMPORTED)
|
||||
set_target_properties(ipp_iw PROPERTIES
|
||||
add_library(ippiw STATIC IMPORTED)
|
||||
set_target_properties(ippiw PROPERTIES
|
||||
IMPORTED_LINK_INTERFACE_LIBRARIES ""
|
||||
IMPORTED_LOCATION "${FILE}"
|
||||
)
|
||||
|
||||
if (NOT BUILD_SHARED_LIBS AND ";${OPENCV_INSTALL_EXTERNAL_DEPENDENCIES};" MATCHES ";ipp;")
|
||||
if (NOT BUILD_SHARED_LIBS)
|
||||
# CMake doesn't support "install(TARGETS ${name} ...)" command with imported targets
|
||||
install(FILES "${FILE}"
|
||||
DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev)
|
||||
@@ -123,7 +122,7 @@ macro(ippiw_setup PATH BUILD)
|
||||
endif()
|
||||
|
||||
set(IPP_IW_INCLUDES "${IPP_IW_PATH}/include")
|
||||
set(IPP_IW_LIBRARIES ipp_iw)
|
||||
set(IPP_IW_LIBRARIES ippiw)
|
||||
|
||||
set(HAVE_IPP_IW 1)
|
||||
set(BUILD_IPP_IW 0)
|
||||
|
||||
@@ -153,23 +153,8 @@ if(NOT WEBP_VERSION AND WEBP_INCLUDE_DIR)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# --- libopenjp2 (optional, check before libjasper) ---
|
||||
if(WITH_OPENJPEG)
|
||||
find_package(OpenJPEG QUIET)
|
||||
|
||||
if(NOT OpenJPEG_FOUND OR OPENJPEG_MAJOR_VERSION LESS 2)
|
||||
set(HAVE_OPENJPEG NO)
|
||||
ocv_clear_vars(OPENJPEG_MAJOR_VERSION OPENJPEG_MINOR_VERSION OPENJPEG_BUILD_VERSION OPENJPEG_LIBRARIES OPENJPEG_INCLUDE_DIRS)
|
||||
message(STATUS "Could NOT find OpenJPEG (minimal suitable version: 2.0, recommended version >= 2.3.1)")
|
||||
else()
|
||||
set(HAVE_OPENJPEG YES)
|
||||
message(STATUS "Found OpenJPEG: ${OPENJPEG_LIBRARIES} "
|
||||
"(found version \"${OPENJPEG_MAJOR_VERSION}.${OPENJPEG_MINOR_VERSION}.${OPENJPEG_BUILD_VERSION}\")")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# --- libjasper (optional, should be searched after libjpeg) ---
|
||||
if(WITH_JASPER AND NOT HAVE_OPENJPEG)
|
||||
if(WITH_JASPER)
|
||||
if(BUILD_JASPER)
|
||||
ocv_clear_vars(JASPER_FOUND)
|
||||
else()
|
||||
@@ -288,4 +273,4 @@ if(WITH_IMGCODEC_PFM)
|
||||
set(HAVE_IMGCODEC_PFM ON)
|
||||
elseif(DEFINED WITH_IMGCODEC_PFM)
|
||||
set(HAVE_IMGCODEC_PFM OFF)
|
||||
endif()
|
||||
endif()
|
||||
@@ -6,15 +6,9 @@ if(NOT WITH_PROTOBUF)
|
||||
return()
|
||||
endif()
|
||||
|
||||
ocv_option(BUILD_PROTOBUF "Force to build libprotobuf runtime from sources" ON)
|
||||
ocv_option(BUILD_PROTOBUF "Force to build libprotobuf from sources" ON)
|
||||
ocv_option(PROTOBUF_UPDATE_FILES "Force rebuilding .proto files (protoc should be available)" OFF)
|
||||
|
||||
# BUILD_PROTOBUF=OFF: Custom manual protobuf configuration (see find_package(Protobuf) for details):
|
||||
# - Protobuf_INCLUDE_DIR
|
||||
# - Protobuf_LIBRARY
|
||||
# - Protobuf_PROTOC_EXECUTABLE
|
||||
|
||||
|
||||
function(get_protobuf_version version include)
|
||||
file(STRINGS "${include}/google/protobuf/stubs/common.h" ver REGEX "#define GOOGLE_PROTOBUF_VERSION [0-9]+")
|
||||
string(REGEX MATCHALL "[0-9]+" ver ${ver})
|
||||
@@ -25,9 +19,7 @@ function(get_protobuf_version version include)
|
||||
endfunction()
|
||||
|
||||
if(BUILD_PROTOBUF)
|
||||
ocv_assert(NOT PROTOBUF_UPDATE_FILES)
|
||||
add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/protobuf")
|
||||
set(Protobuf_LIBRARIES "libprotobuf")
|
||||
set(HAVE_PROTOBUF TRUE)
|
||||
else()
|
||||
unset(Protobuf_VERSION CACHE)
|
||||
@@ -52,7 +44,10 @@ else()
|
||||
|
||||
if(Protobuf_FOUND)
|
||||
if(TARGET protobuf::libprotobuf)
|
||||
set(Protobuf_LIBRARIES "protobuf::libprotobuf")
|
||||
add_library(libprotobuf INTERFACE IMPORTED)
|
||||
set_target_properties(libprotobuf PROPERTIES
|
||||
INTERFACE_LINK_LIBRARIES protobuf::libprotobuf
|
||||
)
|
||||
else()
|
||||
add_library(libprotobuf UNKNOWN IMPORTED)
|
||||
set_target_properties(libprotobuf PROPERTIES
|
||||
@@ -61,31 +56,21 @@ else()
|
||||
INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${Protobuf_INCLUDE_DIR}"
|
||||
)
|
||||
get_protobuf_version(Protobuf_VERSION "${Protobuf_INCLUDE_DIR}")
|
||||
set(Protobuf_LIBRARIES "libprotobuf")
|
||||
endif()
|
||||
set(HAVE_PROTOBUF TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(HAVE_PROTOBUF AND PROTOBUF_UPDATE_FILES AND NOT COMMAND PROTOBUF_GENERATE_CPP)
|
||||
message(FATAL_ERROR "Can't configure protobuf dependency (BUILD_PROTOBUF=${BUILD_PROTOBUF} PROTOBUF_UPDATE_FILES=${PROTOBUF_UPDATE_FILES})")
|
||||
find_package(Protobuf QUIET)
|
||||
if(NOT COMMAND PROTOBUF_GENERATE_CPP)
|
||||
message(FATAL_ERROR "PROTOBUF_GENERATE_CPP command is not available")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(HAVE_PROTOBUF)
|
||||
list(APPEND CUSTOM_STATUS protobuf)
|
||||
if(NOT BUILD_PROTOBUF)
|
||||
if(TARGET "${Protobuf_LIBRARIES}")
|
||||
get_target_property(__location "${Protobuf_LIBRARIES}" IMPORTED_LOCATION_RELEASE)
|
||||
if(NOT __location)
|
||||
get_target_property(__location "${Protobuf_LIBRARIES}" IMPORTED_LOCATION)
|
||||
endif()
|
||||
elseif(Protobuf_LIBRARY)
|
||||
set(__location "${Protobuf_LIBRARY}")
|
||||
else()
|
||||
set(__location "${Protobuf_LIBRARIES}")
|
||||
endif()
|
||||
endif()
|
||||
list(APPEND CUSTOM_STATUS_protobuf " Protobuf:"
|
||||
BUILD_PROTOBUF THEN "build (${Protobuf_VERSION})"
|
||||
ELSE "${__location} (${Protobuf_VERSION})")
|
||||
ELSE "${Protobuf_LIBRARY} (${Protobuf_VERSION})")
|
||||
endif()
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
# VA_INTEL_IOCL_ROOT - root of Intel OCL installation
|
||||
|
||||
if(UNIX AND NOT ANDROID)
|
||||
ocv_check_environment_variables(VA_INTEL_IOCL_ROOT)
|
||||
if(NOT DEFINED VA_INTEL_IOCL_ROOT)
|
||||
set(VA_INTEL_IOCL_ROOT "/opt/intel/opencl")
|
||||
if($ENV{VA_INTEL_IOCL_ROOT})
|
||||
set(VA_INTEL_IOCL_ROOT $ENV{VA_INTEL_IOCL_ROOT})
|
||||
else()
|
||||
set(VA_INTEL_IOCL_ROOT "/opt/intel/opencl")
|
||||
endif()
|
||||
|
||||
find_path(
|
||||
|
||||
@@ -30,11 +30,6 @@ if(BUILD_FAT_JAVA_LIB AND HAVE_opencv_java)
|
||||
list(APPEND OPENCV_MODULES_CONFIGCMAKE opencv_java)
|
||||
endif()
|
||||
|
||||
if(BUILD_OBJC AND HAVE_opencv_objc)
|
||||
list(APPEND OPENCV_MODULES_CONFIGCMAKE opencv_objc)
|
||||
endif()
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------------------------
|
||||
# Part 1/3: ${BIN_DIR}/OpenCVConfig.cmake -> For use *without* "make install"
|
||||
# -------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -788,7 +788,6 @@ macro(ocv_glob_module_sources)
|
||||
if (APPLE)
|
||||
file(GLOB_RECURSE lib_srcs_apple
|
||||
"${CMAKE_CURRENT_LIST_DIR}/src/*.mm"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/src/*.swift"
|
||||
)
|
||||
list(APPEND lib_srcs ${lib_srcs_apple})
|
||||
endif()
|
||||
@@ -1088,17 +1087,6 @@ macro(ocv_check_dependencies)
|
||||
endforeach()
|
||||
endmacro()
|
||||
|
||||
################################################################################
|
||||
# OpenCV tests
|
||||
################################################################################
|
||||
|
||||
if(DEFINED OPENCV_BUILD_TEST_MODULES_LIST)
|
||||
string(REPLACE "," ";" OPENCV_BUILD_TEST_MODULES_LIST "${OPENCV_BUILD_TEST_MODULES_LIST}") # support comma-separated list (,) too
|
||||
endif()
|
||||
if(DEFINED OPENCV_BUILD_PERF_TEST_MODULES_LIST)
|
||||
string(REPLACE "," ";" OPENCV_BUILD_PERF_TEST_MODULES_LIST "${OPENCV_BUILD_PERF_TEST_MODULES_LIST}") # support comma-separated list (,) too
|
||||
endif()
|
||||
|
||||
# auxiliary macro to parse arguments of ocv_add_accuracy_tests and ocv_add_perf_tests commands
|
||||
macro(__ocv_parse_test_sources tests_type)
|
||||
set(OPENCV_${tests_type}_${the_module}_SOURCES "")
|
||||
@@ -1139,12 +1127,7 @@ function(ocv_add_perf_tests)
|
||||
endif()
|
||||
|
||||
set(perf_path "${CMAKE_CURRENT_LIST_DIR}/perf")
|
||||
if(BUILD_PERF_TESTS AND EXISTS "${perf_path}"
|
||||
AND (NOT DEFINED OPENCV_BUILD_PERF_TEST_MODULES_LIST
|
||||
OR OPENCV_BUILD_PERF_TEST_MODULES_LIST STREQUAL "all"
|
||||
OR ";${OPENCV_BUILD_PERF_TEST_MODULES_LIST};" MATCHES ";${name};"
|
||||
)
|
||||
)
|
||||
if(BUILD_PERF_TESTS AND EXISTS "${perf_path}")
|
||||
__ocv_parse_test_sources(PERF ${ARGN})
|
||||
|
||||
# opencv_imgcodecs is required for imread/imwrite
|
||||
@@ -1229,12 +1212,7 @@ function(ocv_add_accuracy_tests)
|
||||
ocv_debug_message("ocv_add_accuracy_tests(" ${ARGN} ")")
|
||||
|
||||
set(test_path "${CMAKE_CURRENT_LIST_DIR}/test")
|
||||
if(BUILD_TESTS AND EXISTS "${test_path}"
|
||||
AND (NOT DEFINED OPENCV_BUILD_TEST_MODULES_LIST
|
||||
OR OPENCV_BUILD_TEST_MODULES_LIST STREQUAL "all"
|
||||
OR ";${OPENCV_BUILD_TEST_MODULES_LIST};" MATCHES ";${name};"
|
||||
)
|
||||
)
|
||||
if(BUILD_TESTS AND EXISTS "${test_path}")
|
||||
__ocv_parse_test_sources(TEST ${ARGN})
|
||||
|
||||
# opencv_imgcodecs is required for imread/imwrite
|
||||
|
||||
@@ -1,28 +1,25 @@
|
||||
# -----------------------------------------------
|
||||
# File that provides "make uninstall" target
|
||||
# We use the file 'install_manifest.txt'
|
||||
#
|
||||
# Details: https://gitlab.kitware.com/cmake/community/-/wikis/FAQ#can-i-do-make-uninstall-with-cmake
|
||||
# -----------------------------------------------
|
||||
IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||
MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
|
||||
ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||
|
||||
if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
|
||||
message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_BINARY_DIR@/install_manifest.txt\"")
|
||||
endif()
|
||||
|
||||
file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files)
|
||||
string(REGEX REPLACE "\n" ";" files "${files}")
|
||||
foreach(file ${files})
|
||||
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
|
||||
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
exec_program(
|
||||
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
|
||||
OUTPUT_VARIABLE rm_out
|
||||
RETURN_VALUE rm_retval
|
||||
)
|
||||
if(NOT "${rm_retval}" STREQUAL 0)
|
||||
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
|
||||
endif()
|
||||
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
|
||||
endif()
|
||||
endforeach()
|
||||
FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
|
||||
STRING(REGEX REPLACE "\n" ";" files "${files}")
|
||||
FOREACH(file ${files})
|
||||
MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
|
||||
IF(EXISTS "$ENV{DESTDIR}${file}")
|
||||
EXEC_PROGRAM(
|
||||
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
|
||||
OUTPUT_VARIABLE rm_out
|
||||
RETURN_VALUE rm_retval
|
||||
)
|
||||
IF(NOT "${rm_retval}" STREQUAL 0)
|
||||
MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
|
||||
ENDIF(NOT "${rm_retval}" STREQUAL 0)
|
||||
ELSE(EXISTS "$ENV{DESTDIR}${file}")
|
||||
MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
|
||||
ENDIF(EXISTS "$ENV{DESTDIR}${file}")
|
||||
ENDFOREACH(file)
|
||||
|
||||
@@ -81,7 +81,6 @@
|
||||
#cmakedefine HAVE_IPP_IW_LL
|
||||
|
||||
/* JPEG-2000 codec */
|
||||
#cmakedefine HAVE_OPENJPEG
|
||||
#cmakedefine HAVE_JASPER
|
||||
|
||||
/* IJG JPEG codec */
|
||||
|
||||
@@ -3,11 +3,12 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
includedir_old=@includedir@/opencv
|
||||
includedir_new=@includedir@
|
||||
|
||||
Name: OpenCV
|
||||
Description: Open Source Computer Vision Library
|
||||
Version: @OPENCV_VERSION_PLAIN@
|
||||
Libs: @OPENCV_PC_LIBS@
|
||||
Libs.private: @OPENCV_PC_LIBS_PRIVATE@
|
||||
Cflags: -I${includedir}
|
||||
Cflags: -I${includedir_old} -I${includedir_new}
|
||||
|
||||
@@ -246,7 +246,7 @@ PREDEFINED = __cplusplus=1 \
|
||||
CV_WRAP_PHANTOM(x)= \
|
||||
CV_WRAP_DEFAULT(x)= \
|
||||
CV_CDECL= \
|
||||
CV_Func= \
|
||||
CV_Func = \
|
||||
CV_DO_PRAGMA(x)= \
|
||||
CV_SUPPRESS_DEPRECATED_START= \
|
||||
CV_SUPPRESS_DEPRECATED_END= \
|
||||
|
||||
@@ -1,4 +1,23 @@
|
||||
Frequently Asked Questions {#faq}
|
||||
==========================
|
||||
|
||||
Compatibility page. FAQ migrated to the project [wiki](https://github.com/opencv/opencv/wiki/FAQ).
|
||||
- **What is InputArray?**
|
||||
|
||||
It can be seen that almost all OpenCV functions receive InputArray type.
|
||||
What is it, and how can I understand the actual input types of parameters?
|
||||
|
||||
|
||||
This is the proxy class for passing read-only input arrays into OpenCV functions.
|
||||
|
||||
Inside a function you should use cv::_InputArray::getMat() method to construct
|
||||
a matrix header for the array (without copying data). cv::_InputArray::kind() can be used to distinguish Mat from vector<> etc.
|
||||
but normally it is not needed.
|
||||
|
||||
for more information see cv::_InputArray
|
||||
|
||||
- **Which is more efficient, use contourArea() or count number of ROI non-zero pixels?**
|
||||
|
||||
In a case where you only want relative areas, which one is faster to compute:
|
||||
calculate a contour area or count the number of ROI non-zero pixels?
|
||||
|
||||
cv::contourArea() uses Green formula (http://en.wikipedia.org/wiki/Green's_theorem) to compute the area, therefore its complexity is O(contour_number_of_vertices). Counting non-zero pixels in the ROI is O(roi_width*roi_height) algorithm, i.e. much slower. Note, however, that because of finite, and quite low, resolution of the raster grid, the two algorithms will give noticeably different results. For large and square-like contours the error will be minimal. For small and/or oblong contours the error can be quite large.
|
||||
|
||||
@@ -146,7 +146,7 @@ npm install canvas jsdom
|
||||
@code{.js}
|
||||
const { Canvas, createCanvas, Image, ImageData, loadImage } = require('canvas');
|
||||
const { JSDOM } = require('jsdom');
|
||||
const { writeFileSync, existsSync, mkdirSync } = require("fs");
|
||||
const { writeFileSync } = require('fs');
|
||||
|
||||
// This is our program. This time we use JavaScript async / await and promises to handle asynchronicity.
|
||||
(async () => {
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
Build OpenCV.js {#tutorial_js_setup}
|
||||
===============================
|
||||
|
||||
@note
|
||||
You don't have to build your own copy if you simply want to start using it. Refer the Using Opencv.js tutorial for steps on getting a prebuilt copy from our releases or online documentation.
|
||||
|
||||
Installing Emscripten
|
||||
-----------------------------
|
||||
|
||||
@@ -4,7 +4,7 @@ Using OpenCV.js {#tutorial_js_usage}
|
||||
Steps
|
||||
-----
|
||||
|
||||
In this tutorial, you will learn how to include and start to use `opencv.js` inside a web page. You can get a copy of `opencv.js` from `opencv-{VERSION_NUMBER}-docs.zip` in each [release](https://github.com/opencv/opencv/releases), or simply download the prebuilt script from the online documentations at "https://docs.opencv.org/{VERISON_NUMBER}/opencv.js" (For example, [https://docs.opencv.org/3.4.0/opencv.js](https://docs.opencv.org/3.4.0/opencv.js). Use `master` if you want the latest build). You can also build your own copy by following the tutorial on Build Opencv.js.
|
||||
In this tutorial, you will learn how to include and start to use `opencv.js` inside a web page.
|
||||
|
||||
### Create a web page
|
||||
|
||||
@@ -44,7 +44,7 @@ To run this web page, copy the content above and save to a local index.html file
|
||||
|
||||
Set the URL of `opencv.js` to `src` attribute of \<script\> tag.
|
||||
|
||||
@note For this tutorial, we host `opencv.js` at same folder as index.html. You can also choose to use the URL of the prebuilt `opencv.js` in our online documentation.
|
||||
@note For this tutorial, we host `opencv.js` at same folder as index.html.
|
||||
|
||||
Example for synchronous loading:
|
||||
@code{.js}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#3 & \mbox{#4}\\
|
||||
#5 & \mbox{#6}\\
|
||||
\end{array} \right.}
|
||||
\newcommand{\forkfour}[8]{
|
||||
\newcommand{\forkthree}[8]{
|
||||
\left\{
|
||||
\begin{array}{l l}
|
||||
#1 & \mbox{#2}\\
|
||||
|
||||
@@ -620,7 +620,7 @@
|
||||
volume = {1},
|
||||
publisher = {IEEE}
|
||||
}
|
||||
@article{Lowe04,
|
||||
@article{Lowe:2004:DIF:993451.996342,
|
||||
author = {Lowe, David G.},
|
||||
title = {Distinctive Image Features from Scale-Invariant Keypoints},
|
||||
journal = {Int. J. Comput. Vision},
|
||||
|
||||
@@ -16,106 +16,110 @@ python gen_pattern.py -o out.svg -r 11 -c 8 -T circles -s 20.0 -R 5.0 -u mm -w 2
|
||||
-H, --help - show help
|
||||
"""
|
||||
|
||||
import argparse
|
||||
|
||||
from svgfig import *
|
||||
|
||||
import sys
|
||||
import getopt
|
||||
|
||||
class PatternMaker:
|
||||
def __init__(self, cols, rows, output, units, square_size, radius_rate, page_width, page_height):
|
||||
self.cols = cols
|
||||
self.rows = rows
|
||||
self.output = output
|
||||
self.units = units
|
||||
self.square_size = square_size
|
||||
self.radius_rate = radius_rate
|
||||
self.width = page_width
|
||||
self.height = page_height
|
||||
self.g = SVG("g") # the svg group container
|
||||
def __init__(self, cols,rows,output,units,square_size,radius_rate,page_width,page_height):
|
||||
self.cols = cols
|
||||
self.rows = rows
|
||||
self.output = output
|
||||
self.units = units
|
||||
self.square_size = square_size
|
||||
self.radius_rate = radius_rate
|
||||
self.width = page_width
|
||||
self.height = page_height
|
||||
self.g = SVG("g") # the svg group container
|
||||
|
||||
def make_circles_pattern(self):
|
||||
spacing = self.square_size
|
||||
r = spacing / self.radius_rate
|
||||
for x in range(1, self.cols + 1):
|
||||
for y in range(1, self.rows + 1):
|
||||
dot = SVG("circle", cx=x * spacing, cy=y * spacing, r=r, fill="black", stroke="none")
|
||||
self.g.append(dot)
|
||||
def makeCirclesPattern(self):
|
||||
spacing = self.square_size
|
||||
r = spacing / self.radius_rate
|
||||
for x in range(1,self.cols+1):
|
||||
for y in range(1,self.rows+1):
|
||||
dot = SVG("circle", cx=x * spacing, cy=y * spacing, r=r, fill="black", stroke="none")
|
||||
self.g.append(dot)
|
||||
|
||||
def make_acircles_pattern(self):
|
||||
spacing = self.square_size
|
||||
r = spacing / self.radius_rate
|
||||
for i in range(0, self.rows):
|
||||
for j in range(0, self.cols):
|
||||
dot = SVG("circle", cx=((j * 2 + i % 2) * spacing) + spacing, cy=self.height - (i * spacing + spacing),
|
||||
r=r, fill="black", stroke="none")
|
||||
self.g.append(dot)
|
||||
def makeACirclesPattern(self):
|
||||
spacing = self.square_size
|
||||
r = spacing / self.radius_rate
|
||||
for i in range(0,self.rows):
|
||||
for j in range(0,self.cols):
|
||||
dot = SVG("circle", cx= ((j*2 + i%2)*spacing) + spacing, cy=self.height - (i * spacing + spacing), r=r, fill="black", stroke="none")
|
||||
self.g.append(dot)
|
||||
|
||||
def make_checkerboard_pattern(self):
|
||||
spacing = self.square_size
|
||||
xspacing = (self.width - self.cols * self.square_size) / 2.0
|
||||
yspacing = (self.height - self.rows * self.square_size) / 2.0
|
||||
for x in range(0, self.cols):
|
||||
for y in range(0, self.rows):
|
||||
if x % 2 == y % 2:
|
||||
square = SVG("rect", x=x * spacing + xspacing, y=y * spacing + yspacing, width=spacing,
|
||||
height=spacing, fill="black", stroke="none")
|
||||
self.g.append(square)
|
||||
def makeCheckerboardPattern(self):
|
||||
spacing = self.square_size
|
||||
xspacing = (self.width - self.cols * self.square_size) / 2.0
|
||||
yspacing = (self.height - self.rows * self.square_size) / 2.0
|
||||
for x in range(0,self.cols):
|
||||
for y in range(0,self.rows):
|
||||
if x%2 == y%2:
|
||||
square = SVG("rect", x=x * spacing + xspacing, y=y * spacing + yspacing, width=spacing, height=spacing, fill="black", stroke="none")
|
||||
self.g.append(square)
|
||||
|
||||
def save(self):
|
||||
c = canvas(self.g, width="%d%s" % (self.width, self.units), height="%d%s" % (self.height, self.units),
|
||||
viewBox="0 0 %d %d" % (self.width, self.height))
|
||||
c.save(self.output)
|
||||
def save(self):
|
||||
c = canvas(self.g,width="%d%s"%(self.width,self.units),height="%d%s"%(self.height,self.units),viewBox="0 0 %d %d"%(self.width,self.height))
|
||||
c.save(self.output)
|
||||
|
||||
|
||||
def main():
|
||||
# parse command line options
|
||||
parser = argparse.ArgumentParser(description="generate camera-calibration pattern", add_help=False)
|
||||
parser.add_argument("-H", "--help", help="show help", action="store_true", dest="show_help")
|
||||
parser.add_argument("-o", "--output", help="output file", default="out.svg", action="store", dest="output")
|
||||
parser.add_argument("-c", "--columns", help="pattern columns", default="8", action="store", dest="columns",
|
||||
type=int)
|
||||
parser.add_argument("-r", "--rows", help="pattern rows", default="11", action="store", dest="rows", type=int)
|
||||
parser.add_argument("-T", "--type", help="type of pattern", default="circles", action="store", dest="p_type",
|
||||
choices=["circles", "acircles", "checkerboard"])
|
||||
parser.add_argument("-u", "--units", help="length unit", default="mm", action="store", dest="units",
|
||||
choices=["mm", "inches", "px", "m"])
|
||||
parser.add_argument("-s", "--square_size", help="size of squares in pattern", default="20.0", action="store",
|
||||
dest="square_size", type=float)
|
||||
parser.add_argument("-R", "--radius_rate", help="circles_radius = square_size/radius_rate", default="5.0",
|
||||
action="store", dest="radius_rate", type=float)
|
||||
parser.add_argument("-w", "--page_width", help="page width in units", default="216", action="store",
|
||||
dest="page_width", type=int)
|
||||
parser.add_argument("-h", "--page_height", help="page height in units", default="279", action="store",
|
||||
dest="page_width", type=int)
|
||||
parser.add_argument("-a", "--page_size", help="page size, supersedes -h -w arguments", default="A4", action="store",
|
||||
dest="page_size", choices=["A0", "A1", "A2", "A3", "A4", "A5"])
|
||||
args = parser.parse_args()
|
||||
|
||||
show_help = args.show_help
|
||||
if show_help:
|
||||
parser.print_help()
|
||||
return
|
||||
output = args.output
|
||||
columns = args.columns
|
||||
rows = args.rows
|
||||
p_type = args.p_type
|
||||
units = args.units
|
||||
square_size = args.square_size
|
||||
radius_rate = args.radius_rate
|
||||
page_size = args.page_size
|
||||
# parse command line options, TODO use argparse for better doc
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "Ho:c:r:T:u:s:R:w:h:a:", ["help","output=","columns=","rows=",
|
||||
"type=","units=","square_size=","radius_rate=",
|
||||
"page_width=","page_height=", "page_size="])
|
||||
except getopt.error as msg:
|
||||
print(msg)
|
||||
print("for help use --help")
|
||||
sys.exit(2)
|
||||
output = "out.svg"
|
||||
columns = 8
|
||||
rows = 11
|
||||
p_type = "circles"
|
||||
units = "mm"
|
||||
square_size = 20.0
|
||||
radius_rate = 5.0
|
||||
page_size = "A4"
|
||||
# page size dict (ISO standard, mm) for easy lookup. format - size: [width, height]
|
||||
page_sizes = {"A0": [840, 1188], "A1": [594, 840], "A2": [420, 594], "A3": [297, 420], "A4": [210, 297],
|
||||
"A5": [148, 210]}
|
||||
page_sizes = {"A0": [840, 1188], "A1": [594, 840], "A2": [420, 594], "A3": [297, 420], "A4": [210, 297], "A5": [148, 210]}
|
||||
page_width = page_sizes[page_size.upper()][0]
|
||||
page_height = page_sizes[page_size.upper()][1]
|
||||
pm = PatternMaker(columns, rows, output, units, square_size, radius_rate, page_width, page_height)
|
||||
# dict for easy lookup of pattern type
|
||||
mp = {"circles": pm.make_circles_pattern, "acircles": pm.make_acircles_pattern,
|
||||
"checkerboard": pm.make_checkerboard_pattern}
|
||||
# process options
|
||||
for o, a in opts:
|
||||
if o in ("-H", "--help"):
|
||||
print(__doc__)
|
||||
sys.exit(0)
|
||||
elif o in ("-r", "--rows"):
|
||||
rows = int(a)
|
||||
elif o in ("-c", "--columns"):
|
||||
columns = int(a)
|
||||
elif o in ("-o", "--output"):
|
||||
output = a
|
||||
elif o in ("-T", "--type"):
|
||||
p_type = a
|
||||
elif o in ("-u", "--units"):
|
||||
units = a
|
||||
elif o in ("-s", "--square_size"):
|
||||
square_size = float(a)
|
||||
elif o in ("-R", "--radius_rate"):
|
||||
radius_rate = float(a)
|
||||
elif o in ("-w", "--page_width"):
|
||||
page_width = float(a)
|
||||
elif o in ("-h", "--page_height"):
|
||||
page_height = float(a)
|
||||
elif o in ("-a", "--page_size"):
|
||||
units = "mm"
|
||||
page_size = a.upper()
|
||||
page_width = page_sizes[page_size][0]
|
||||
page_height = page_sizes[page_size][1]
|
||||
pm = PatternMaker(columns,rows,output,units,square_size,radius_rate,page_width,page_height)
|
||||
#dict for easy lookup of pattern type
|
||||
mp = {"circles":pm.makeCirclesPattern,"acircles":pm.makeACirclesPattern,"checkerboard":pm.makeCheckerboardPattern}
|
||||
mp[p_type]()
|
||||
# this should save pattern to output
|
||||
#this should save pattern to output
|
||||
pm.save()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -44,7 +44,7 @@ img1 = cv.imread('box.png',0) # queryImage
|
||||
img2 = cv.imread('box_in_scene.png',0) # trainImage
|
||||
|
||||
# Initiate SIFT detector
|
||||
sift = cv.SIFT_create()
|
||||
sift = cv.xfeatures2d.SIFT_create()
|
||||
|
||||
# find the keypoints and descriptors with SIFT
|
||||
kp1, des1 = sift.detectAndCompute(img1,None)
|
||||
|
||||
@@ -110,7 +110,7 @@ img1 = cv.imread('box.png',cv.IMREAD_GRAYSCALE) # queryImage
|
||||
img2 = cv.imread('box_in_scene.png',cv.IMREAD_GRAYSCALE) # trainImage
|
||||
|
||||
# Initiate SIFT detector
|
||||
sift = cv.SIFT_create()
|
||||
sift = cv.xfeatures2d.SIFT_create()
|
||||
|
||||
# find the keypoints and descriptors with SIFT
|
||||
kp1, des1 = sift.detectAndCompute(img1,None)
|
||||
@@ -174,7 +174,7 @@ img1 = cv.imread('box.png',cv.IMREAD_GRAYSCALE) # queryImage
|
||||
img2 = cv.imread('box_in_scene.png',cv.IMREAD_GRAYSCALE) # trainImage
|
||||
|
||||
# Initiate SIFT detector
|
||||
sift = cv.SIFT_create()
|
||||
sift = cv.xfeatures2d.SIFT_create()
|
||||
|
||||
# find the keypoints and descriptors with SIFT
|
||||
kp1, des1 = sift.detectAndCompute(img1,None)
|
||||
|
||||
@@ -119,7 +119,7 @@ import cv2 as cv
|
||||
img = cv.imread('home.jpg')
|
||||
gray= cv.cvtColor(img,cv.COLOR_BGR2GRAY)
|
||||
|
||||
sift = cv.SIFT_create()
|
||||
sift = cv.xfeatures2d.SIFT_create()
|
||||
kp = sift.detect(gray,None)
|
||||
|
||||
img=cv.drawKeypoints(gray,kp,img)
|
||||
@@ -151,7 +151,7 @@ Now to calculate the descriptor, OpenCV provides two methods.
|
||||
|
||||
We will see the second method:
|
||||
@code{.py}
|
||||
sift = cv.SIFT_create()
|
||||
sift = cv.xfeatures2d.SIFT_create()
|
||||
kp, des = sift.detectAndCompute(gray,None)
|
||||
@endcode
|
||||
Here kp will be a list of keypoints and des is a numpy array of shape
|
||||
|
||||
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 25 KiB |
@@ -1,4 +1,153 @@
|
||||
Getting Started with Images {#tutorial_py_image_display}
|
||||
===========================
|
||||
|
||||
Tutorial content has been moved: @ref tutorial_display_image
|
||||
Goals
|
||||
-----
|
||||
|
||||
- Here, you will learn how to read an image, how to display it, and how to save it back
|
||||
- You will learn these functions : **cv.imread()**, **cv.imshow()** , **cv.imwrite()**
|
||||
- Optionally, you will learn how to display images with Matplotlib
|
||||
|
||||
Using OpenCV
|
||||
------------
|
||||
|
||||
### Read an image
|
||||
|
||||
Use the function **cv.imread()** to read an image. The image should be in the working directory or
|
||||
a full path of image should be given.
|
||||
|
||||
Second argument is a flag which specifies the way image should be read.
|
||||
|
||||
- cv.IMREAD_COLOR : Loads a color image. Any transparency of image will be neglected. It is the
|
||||
default flag.
|
||||
- cv.IMREAD_GRAYSCALE : Loads image in grayscale mode
|
||||
- cv.IMREAD_UNCHANGED : Loads image as such including alpha channel
|
||||
|
||||
@note Instead of these three flags, you can simply pass integers 1, 0 or -1 respectively.
|
||||
|
||||
See the code below:
|
||||
@code{.py}
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
|
||||
# Load a color image in grayscale
|
||||
img = cv.imread('messi5.jpg',0)
|
||||
@endcode
|
||||
|
||||
**warning**
|
||||
|
||||
Even if the image path is wrong, it won't throw any error, but `print img` will give you `None`
|
||||
|
||||
### Display an image
|
||||
|
||||
Use the function **cv.imshow()** to display an image in a window. The window automatically fits to
|
||||
the image size.
|
||||
|
||||
First argument is a window name which is a string. Second argument is our image. You can create as
|
||||
many windows as you wish, but with different window names.
|
||||
@code{.py}
|
||||
cv.imshow('image',img)
|
||||
cv.waitKey(0)
|
||||
cv.destroyAllWindows()
|
||||
@endcode
|
||||
A screenshot of the window will look like this (in Fedora-Gnome machine):
|
||||
|
||||

|
||||
|
||||
**cv.waitKey()** is a keyboard binding function. Its argument is the time in milliseconds. The
|
||||
function waits for specified milliseconds for any keyboard event. If you press any key in that time,
|
||||
the program continues. If **0** is passed, it waits indefinitely for a key stroke. It can also be
|
||||
set to detect specific key strokes like, if key a is pressed etc which we will discuss below.
|
||||
|
||||
@note Besides binding keyboard events this function also processes many other GUI events, so you
|
||||
MUST use it to actually display the image.
|
||||
|
||||
**cv.destroyAllWindows()** simply destroys all the windows we created. If you want to destroy any
|
||||
specific window, use the function **cv.destroyWindow()** where you pass the exact window name as
|
||||
the argument.
|
||||
|
||||
@note There is a special case where you can create an empty window and load an image to it later. In
|
||||
that case, you can specify whether the window is resizable or not. It is done with the function
|
||||
**cv.namedWindow()**. By default, the flag is cv.WINDOW_AUTOSIZE. But if you specify the flag to be
|
||||
cv.WINDOW_NORMAL, you can resize window. It will be helpful when an image is too large in dimension
|
||||
and when adding track bars to windows.
|
||||
|
||||
See the code below:
|
||||
@code{.py}
|
||||
cv.namedWindow('image', cv.WINDOW_NORMAL)
|
||||
cv.imshow('image',img)
|
||||
cv.waitKey(0)
|
||||
cv.destroyAllWindows()
|
||||
@endcode
|
||||
### Write an image
|
||||
|
||||
Use the function **cv.imwrite()** to save an image.
|
||||
|
||||
First argument is the file name, second argument is the image you want to save.
|
||||
@code{.py}
|
||||
cv.imwrite('messigray.png',img)
|
||||
@endcode
|
||||
This will save the image in PNG format in the working directory.
|
||||
|
||||
### Sum it up
|
||||
|
||||
Below program loads an image in grayscale, displays it, saves the image if you press 's' and exit, or
|
||||
simply exits without saving if you press ESC key.
|
||||
@code{.py}
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
|
||||
img = cv.imread('messi5.jpg',0)
|
||||
cv.imshow('image',img)
|
||||
k = cv.waitKey(0)
|
||||
if k == 27: # wait for ESC key to exit
|
||||
cv.destroyAllWindows()
|
||||
elif k == ord('s'): # wait for 's' key to save and exit
|
||||
cv.imwrite('messigray.png',img)
|
||||
cv.destroyAllWindows()
|
||||
@endcode
|
||||
|
||||
**warning**
|
||||
|
||||
If you are using a 64-bit machine, you will have to modify `k = cv.waitKey(0)` line as follows :
|
||||
`k = cv.waitKey(0) & 0xFF`
|
||||
|
||||
Using Matplotlib
|
||||
----------------
|
||||
|
||||
Matplotlib is a plotting library for Python which gives you wide variety of plotting methods. You
|
||||
will see them in coming articles. Here, you will learn how to display image with Matplotlib. You can
|
||||
zoom images, save them, etc, using Matplotlib.
|
||||
@code{.py}
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
img = cv.imread('messi5.jpg',0)
|
||||
plt.imshow(img, cmap = 'gray', interpolation = 'bicubic')
|
||||
plt.xticks([]), plt.yticks([]) # to hide tick values on X and Y axis
|
||||
plt.show()
|
||||
@endcode
|
||||
A screen-shot of the window will look like this :
|
||||
|
||||

|
||||
|
||||
@note Plenty of plotting options are available in Matplotlib. Please refer to Matplotlib docs for more
|
||||
details. Some, we will see on the way.
|
||||
|
||||
__warning__
|
||||
|
||||
Color image loaded by OpenCV is in BGR mode. But Matplotlib displays in RGB mode. So color images
|
||||
will not be displayed correctly in Matplotlib if image is read with OpenCV. Please see the exercises
|
||||
for more details.
|
||||
|
||||
Additional Resources
|
||||
--------------------
|
||||
|
||||
-# [Matplotlib Plotting Styles and Features](http://matplotlib.org/api/pyplot_api.html)
|
||||
|
||||
Exercises
|
||||
---------
|
||||
|
||||
-# There is some problem when you try to load color image in OpenCV and display it in Matplotlib.
|
||||
Read [this discussion](http://stackoverflow.com/a/15074748/1134940) and understand it.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Gui Features in OpenCV {#tutorial_py_table_of_contents_gui}
|
||||
======================
|
||||
|
||||
- @ref tutorial_display_image
|
||||
- @subpage tutorial_py_image_display
|
||||
|
||||
Learn to load an
|
||||
image, display it, and save it back
|
||||
|
||||
@@ -80,7 +80,7 @@ Probabilistic Hough Transform
|
||||
In the hough transform, you can see that even for a line with two arguments, it takes a lot of
|
||||
computation. Probabilistic Hough Transform is an optimization of the Hough Transform we saw. It doesn't
|
||||
take all the points into consideration. Instead, it takes only a random subset of points which is
|
||||
sufficient for line detection. We just have to decrease the threshold. See image below which compares
|
||||
sufficient for line detection. Just we have to decrease the threshold. See image below which compares
|
||||
Hough Transform and Probabilistic Hough Transform in Hough space. (Image Courtesy :
|
||||
[Franck Bettinger's home page](http://phdfb1.free.fr/robot/mscthesis/node14.html) )
|
||||
|
||||
|
||||
@@ -4,20 +4,20 @@ OCR of Hand-written Data using kNN {#tutorial_py_knn_opencv}
|
||||
Goal
|
||||
----
|
||||
|
||||
In this chapter:
|
||||
- We will use our knowledge on kNN to build a basic OCR (Optical Character Recognition) application.
|
||||
- We will try our application on Digits and Alphabets data that comes with OpenCV.
|
||||
In this chapter
|
||||
- We will use our knowledge on kNN to build a basic OCR application.
|
||||
- We will try with Digits and Alphabets data available that comes with OpenCV.
|
||||
|
||||
OCR of Hand-written Digits
|
||||
--------------------------
|
||||
|
||||
Our goal is to build an application which can read handwritten digits. For this we need some
|
||||
training data and some test data. OpenCV comes with an image digits.png (in the folder
|
||||
Our goal is to build an application which can read the handwritten digits. For this we need some
|
||||
train_data and test_data. OpenCV comes with an image digits.png (in the folder
|
||||
opencv/samples/data/) which has 5000 handwritten digits (500 for each digit). Each digit is
|
||||
a 20x20 image. So our first step is to split this image into 5000 different digit images. Then for each digit (20x20 image),
|
||||
we flatten it into a single row with 400 pixels. That is our feature set, i.e. intensity values of all
|
||||
pixels. It is the simplest feature set we can create. We use the first 250 samples of each digit as
|
||||
training data, and the other 250 samples as test data. So let's prepare them first.
|
||||
a 20x20 image. So our first step is to split this image into 5000 different digits. For each digit,
|
||||
we flatten it into a single row with 400 pixels. That is our feature set, ie intensity values of all
|
||||
pixels. It is the simplest feature set we can create. We use first 250 samples of each digit as
|
||||
train_data, and next 250 samples as test_data. So let's prepare them first.
|
||||
@code{.py}
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
@@ -28,10 +28,10 @@ gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
|
||||
# Now we split the image to 5000 cells, each 20x20 size
|
||||
cells = [np.hsplit(row,100) for row in np.vsplit(gray,50)]
|
||||
|
||||
# Make it into a Numpy array: its size will be (50,100,20,20)
|
||||
# Make it into a Numpy array. It size will be (50,100,20,20)
|
||||
x = np.array(cells)
|
||||
|
||||
# Now we prepare the training data and test data
|
||||
# Now we prepare train_data and test_data.
|
||||
train = x[:,:50].reshape(-1,400).astype(np.float32) # Size = (2500,400)
|
||||
test = x[:,50:100].reshape(-1,400).astype(np.float32) # Size = (2500,400)
|
||||
|
||||
@@ -40,7 +40,7 @@ k = np.arange(10)
|
||||
train_labels = np.repeat(k,250)[:,np.newaxis]
|
||||
test_labels = train_labels.copy()
|
||||
|
||||
# Initiate kNN, train it on the training data, then test it with the test data with k=1
|
||||
# Initiate kNN, train the data, then test it with test data for k=1
|
||||
knn = cv.ml.KNearest_create()
|
||||
knn.train(train, cv.ml.ROW_SAMPLE, train_labels)
|
||||
ret,result,neighbours,dist = knn.findNearest(test,k=5)
|
||||
@@ -52,15 +52,13 @@ correct = np.count_nonzero(matches)
|
||||
accuracy = correct*100.0/result.size
|
||||
print( accuracy )
|
||||
@endcode
|
||||
So our basic OCR app is ready. This particular example gave me an accuracy of 91%. One option to
|
||||
improve accuracy is to add more data for training, especially for the digits where we had more errors.
|
||||
|
||||
Instead of finding
|
||||
this training data every time I start the application, I better save it, so that the next time, I can directly
|
||||
read this data from a file and start classification. This can be done with the help of some Numpy
|
||||
functions like np.savetxt, np.savez, np.load, etc. Please check the NumPy docs for more details.
|
||||
So our basic OCR app is ready. This particular example gave me an accuracy of 91%. One option
|
||||
improve accuracy is to add more data for training, especially the wrong ones. So instead of finding
|
||||
this training data every time I start application, I better save it, so that next time, I directly
|
||||
read this data from a file and start classification. You can do it with the help of some Numpy
|
||||
functions like np.savetxt, np.savez, np.load etc. Please check their docs for more details.
|
||||
@code{.py}
|
||||
# Save the data
|
||||
# save the data
|
||||
np.savez('knn_data.npz',train=train, train_labels=train_labels)
|
||||
|
||||
# Now load the data
|
||||
@@ -73,36 +71,36 @@ In my system, it takes around 4.4 MB of memory. Since we are using intensity val
|
||||
features, it would be better to convert the data to np.uint8 first and then save it. It takes only
|
||||
1.1 MB in this case. Then while loading, you can convert back into float32.
|
||||
|
||||
OCR of the English Alphabet
|
||||
OCR of English Alphabets
|
||||
------------------------
|
||||
|
||||
Next we will do the same for the English alphabet, but there is a slight change in data and feature
|
||||
Next we will do the same for English alphabets, but there is a slight change in data and feature
|
||||
set. Here, instead of images, OpenCV comes with a data file, letter-recognition.data in
|
||||
opencv/samples/cpp/ folder. If you open it, you will see 20000 lines which may, on first sight, look
|
||||
like garbage. Actually, in each row, the first column is a letter which is our label. The next 16 numbers
|
||||
following it are the different features. These features are obtained from the [UCI Machine Learning
|
||||
like garbage. Actually, in each row, first column is an alphabet which is our label. Next 16 numbers
|
||||
following it are its different features. These features are obtained from [UCI Machine Learning
|
||||
Repository](http://archive.ics.uci.edu/ml/). You can find the details of these features in [this
|
||||
page](http://archive.ics.uci.edu/ml/datasets/Letter+Recognition).
|
||||
|
||||
There are 20000 samples available, so we take the first 10000 as training samples and the remaining
|
||||
10000 as test samples. We should change the letters to ascii characters because we can't work with
|
||||
letters directly.
|
||||
There are 20000 samples available, so we take first 10000 data as training samples and remaining
|
||||
10000 as test samples. We should change the alphabets to ascii characters because we can't work with
|
||||
alphabets directly.
|
||||
@code{.py}
|
||||
import cv2 as cv
|
||||
import numpy as np
|
||||
|
||||
# Load the data and convert the letters to numbers
|
||||
# Load the data, converters convert the letter to a number
|
||||
data= np.loadtxt('letter-recognition.data', dtype= 'float32', delimiter = ',',
|
||||
converters= {0: lambda ch: ord(ch)-ord('A')})
|
||||
|
||||
# Split the dataset in two, with 10000 samples each for training and test sets
|
||||
# split the data to two, 10000 each for train and test
|
||||
train, test = np.vsplit(data,2)
|
||||
|
||||
# Split trainData and testData into features and responses
|
||||
# split trainData and testData to features and responses
|
||||
responses, trainData = np.hsplit(train,[1])
|
||||
labels, testData = np.hsplit(test,[1])
|
||||
|
||||
# Initiate the kNN, classify, measure accuracy
|
||||
# Initiate the kNN, classify, measure accuracy.
|
||||
knn = cv.ml.KNearest_create()
|
||||
knn.train(trainData, cv.ml.ROW_SAMPLE, responses)
|
||||
ret, result, neighbours, dist = knn.findNearest(testData, k=5)
|
||||
@@ -112,12 +110,10 @@ accuracy = correct*100.0/10000
|
||||
print( accuracy )
|
||||
@endcode
|
||||
It gives me an accuracy of 93.22%. Again, if you want to increase accuracy, you can iteratively add
|
||||
more data.
|
||||
error data in each level.
|
||||
|
||||
Additional Resources
|
||||
--------------------
|
||||
1. [Wikipedia article on Optical character recognition](https://en.wikipedia.org/wiki/Optical_character_recognition)
|
||||
|
||||
Exercises
|
||||
---------
|
||||
1. Here we used k=5. What happens if you try other values of k? Can you find a value that maximizes accuracy (minimizes the number of errors)?
|
||||
@@ -4,55 +4,61 @@ Understanding k-Nearest Neighbour {#tutorial_py_knn_understanding}
|
||||
Goal
|
||||
----
|
||||
|
||||
In this chapter, we will understand the concepts of the k-Nearest Neighbour (kNN) algorithm.
|
||||
In this chapter, we will understand the concepts of k-Nearest Neighbour (kNN) algorithm.
|
||||
|
||||
Theory
|
||||
------
|
||||
|
||||
kNN is one of the simplest classification algorithms available for supervised learning. The idea
|
||||
is to search for the closest match(es) of the test data in the feature space. We will look into it with the below
|
||||
kNN is one of the simplest of classification algorithms available for supervised learning. The idea
|
||||
is to search for closest match of the test data in feature space. We will look into it with below
|
||||
image.
|
||||
|
||||

|
||||
|
||||
In the image, there are two families: Blue Squares and Red Triangles. We refer to each family as
|
||||
a **Class**. Their houses are shown in their town map which we call the **Feature Space**. You can consider
|
||||
a feature space as a space where all data are projected. For example, consider a 2D coordinate
|
||||
space. Each datum has two features, a x coordinate and a y coordinate. You can represent this datum in your 2D
|
||||
coordinate space, right? Now imagine that there are three features, you will need 3D space. Now consider N
|
||||
features: you need N-dimensional space, right? This N-dimensional space is its feature space.
|
||||
In our image, you can consider it as a 2D case with two features.
|
||||
In the image, there are two families, Blue Squares and Red Triangles. We call each family as
|
||||
**Class**. Their houses are shown in their town map which we call feature space. *(You can consider
|
||||
a feature space as a space where all datas are projected. For example, consider a 2D coordinate
|
||||
space. Each data has two features, x and y coordinates. You can represent this data in your 2D
|
||||
coordinate space, right? Now imagine if there are three features, you need 3D space. Now consider N
|
||||
features, where you need N-dimensional space, right? This N-dimensional space is its feature space.
|
||||
In our image, you can consider it as a 2D case with two features)*.
|
||||
|
||||
Now consider what happens if a new member comes into the town and creates a new home, which is shown as the green circle. He
|
||||
should be added to one of these Blue or Red families (or *classes*). We call that process, **Classification**. How exactly should this new member be classified? Since we are dealing with kNN, let us apply the algorithm.
|
||||
Now a new member comes into the town and creates a new home, which is shown as green circle. He
|
||||
should be added to one of these Blue/Red families. We call that process, **Classification**. What we
|
||||
do? Since we are dealing with kNN, let us apply this algorithm.
|
||||
|
||||
One simple method is to check who is his nearest neighbour. From the image, it is clear that it is a member of the Red
|
||||
Triangle family. So he is classified as a Red Triangle. This method is called simply **Nearest Neighbour** classification, because classification depends only on the *nearest neighbour*.
|
||||
One method is to check who is his nearest neighbour. From the image, it is clear it is the Red
|
||||
Triangle family. So he is also added into Red Triangle. This method is called simply **Nearest
|
||||
Neighbour**, because classification depends only on the nearest neighbour.
|
||||
|
||||
But there is a problem with this approach! Red Triangle may be the nearest neighbour, but what if there are also a lot of Blue
|
||||
Squares nearby? Then Blue Squares have more strength in that locality than Red Triangles, so
|
||||
just checking the nearest one is not sufficient. Instead we may want to check some **k** nearest families. Then whichever family is the majority amongst them, the new guy should belong to that family. In our image, let's take k=3, i.e. consider the 3 nearest
|
||||
neighbours. The new member has two Red neighbours and one Blue neighbour (there are two Blues equidistant, but since k=3, we can take only
|
||||
But there is a problem with that. Red Triangle may be the nearest. But what if there are lot of Blue
|
||||
Squares near to him? Then Blue Squares have more strength in that locality than Red Triangle. So
|
||||
just checking nearest one is not sufficient. Instead we check some k nearest families. Then whoever
|
||||
is majority in them, the new guy belongs to that family. In our image, let's take k=3, ie 3 nearest
|
||||
families. He has two Red and one Blue (there are two Blues equidistant, but since k=3, we take only
|
||||
one of them), so again he should be added to Red family. But what if we take k=7? Then he has 5 Blue
|
||||
neighbours and 2 Red neighbours and should be added to the Blue family. The result will vary with the selected
|
||||
value of k. Note that if k is not an odd number, we can get a tie, as would happen in the above case with k=4. We would see that our new member has 2 Red and 2 Blue neighbours as his four nearest neighbours and we would need to choose a method for breaking the tie to perform classification. So to reiterate, this method is called **k-Nearest Neighbour** since
|
||||
classification depends on the *k nearest neighbours*.
|
||||
families and 2 Red families. Great!! Now he should be added to Blue family. So it all changes with
|
||||
value of k. More funny thing is, what if k = 4? He has 2 Red and 2 Blue neighbours. It is a tie !!!
|
||||
So better take k as an odd number. So this method is called **k-Nearest Neighbour** since
|
||||
classification depends on k nearest neighbours.
|
||||
|
||||
Again, in kNN, it is true we are considering k neighbours, but we are giving equal importance to
|
||||
all, right? Is this justified? For example, take the tied case of k=4. As we can see, the 2
|
||||
Red neighbours are actually closer to the new member than the other 2 Blue neighbours, so he is more eligible to be
|
||||
added to the Red family. How do we mathematically explain that? We give some weights to each neighbour
|
||||
depending on their distance to the new-comer: those who are nearer to him get higher weights, while
|
||||
those that are farther away get lower weights. Then we add the total weights of each family separately and classify the new-comer as part of whichever family
|
||||
received higher total weights. This is called **modified kNN** or **weighted kNN**.
|
||||
all, right? Is it justice? For example, take the case of k=4. We told it is a tie. But see, the 2
|
||||
Red families are more closer to him than the other 2 Blue families. So he is more eligible to be
|
||||
added to Red. So how do we mathematically explain that? We give some weights to each family
|
||||
depending on their distance to the new-comer. For those who are near to him get higher weights while
|
||||
those are far away get lower weights. Then we add total weights of each family separately. Whoever
|
||||
gets highest total weights, new-comer goes to that family. This is called **modified kNN**.
|
||||
|
||||
So what are some important things you see here?
|
||||
|
||||
- Because we have to check
|
||||
the distance from the new-comer to all the existing houses to find the nearest neighbour(s), you need to have information about all of the houses in town, right? If there are plenty of houses and families, it takes a lot of memory, and also more time for calculation.
|
||||
- There is almost zero time for any kind of "training" or preparation. Our "learning" involves only memorizing (storing) the data, before testing and classifying.
|
||||
- You need to have information about all the houses in town, right? Because, we have to check
|
||||
the distance from new-comer to all the existing houses to find the nearest neighbour. If there
|
||||
are plenty of houses and families, it takes lots of memory, and more time for calculation
|
||||
also.
|
||||
- There is almost zero time for any kind of training or preparation.
|
||||
|
||||
Now let's see this algorithm at work in OpenCV.
|
||||
Now let's see it in OpenCV.
|
||||
|
||||
kNN in OpenCV
|
||||
-------------
|
||||
@@ -61,11 +67,11 @@ We will do a simple example here, with two families (classes), just like above.
|
||||
chapter, we will do an even better example.
|
||||
|
||||
So here, we label the Red family as **Class-0** (so denoted by 0) and Blue family as **Class-1**
|
||||
(denoted by 1). We create 25 neighbours or 25 training data, and label each of them as either part of Class-0 or Class-1.
|
||||
We can do this with the help of a Random Number Generator from NumPy.
|
||||
(denoted by 1). We create 25 families or 25 training data, and label them either Class-0 or Class-1.
|
||||
We do all these with the help of Random Number Generator in Numpy.
|
||||
|
||||
Then we can plot it with the help of Matplotlib. Red neighbours are shown as Red Triangles and Blue
|
||||
neighbours are shown as Blue Squares.
|
||||
Then we plot it with the help of Matplotlib. Red families are shown as Red Triangles and Blue
|
||||
families are shown as Blue Squares.
|
||||
@code{.py}
|
||||
import cv2 as cv
|
||||
import numpy as np
|
||||
@@ -74,36 +80,36 @@ import matplotlib.pyplot as plt
|
||||
# Feature set containing (x,y) values of 25 known/training data
|
||||
trainData = np.random.randint(0,100,(25,2)).astype(np.float32)
|
||||
|
||||
# Label each one either Red or Blue with numbers 0 and 1
|
||||
# Labels each one either Red or Blue with numbers 0 and 1
|
||||
responses = np.random.randint(0,2,(25,1)).astype(np.float32)
|
||||
|
||||
# Take Red neighbours and plot them
|
||||
# Take Red families and plot them
|
||||
red = trainData[responses.ravel()==0]
|
||||
plt.scatter(red[:,0],red[:,1],80,'r','^')
|
||||
|
||||
# Take Blue neighbours and plot them
|
||||
# Take Blue families and plot them
|
||||
blue = trainData[responses.ravel()==1]
|
||||
plt.scatter(blue[:,0],blue[:,1],80,'b','s')
|
||||
|
||||
plt.show()
|
||||
@endcode
|
||||
You will get something similar to our first image. Since you are using a random number generator, you
|
||||
will get different data each time you run the code.
|
||||
You will get something similar to our first image. Since you are using random number generator, you
|
||||
will be getting different data each time you run the code.
|
||||
|
||||
Next initiate the kNN algorithm and pass the trainData and responses to train the kNN. (Underneath the hood, it constructs
|
||||
a search tree: see the Additional Resources section below for more information on this.)
|
||||
Next initiate the kNN algorithm and pass the trainData and responses to train the kNN (It constructs
|
||||
a search tree).
|
||||
|
||||
Then we will bring one new-comer and classify him as belonging to a family with the help of kNN in OpenCV. Before
|
||||
running kNN, we need to know something about our test data (data of new comers). Our data should be a
|
||||
Then we will bring one new-comer and classify him to a family with the help of kNN in OpenCV. Before
|
||||
going to kNN, we need to know something on our test data (data of new comers). Our data should be a
|
||||
floating point array with size \f$number \; of \; testdata \times number \; of \; features\f$. Then we
|
||||
find the nearest neighbours of the new-comer. We can specify *k*: how many neighbours we want. (Here we used 3.) It returns:
|
||||
find the nearest neighbours of new-comer. We can specify how many neighbours we want. It returns:
|
||||
|
||||
1. The label given to the new-comer depending upon the kNN theory we saw earlier. If you want the *Nearest
|
||||
Neighbour* algorithm, just specify k=1.
|
||||
2. The labels of the k-Nearest Neighbours.
|
||||
3. The corresponding distances from the new-comer to each nearest neighbour.
|
||||
-# The label given to new-comer depending upon the kNN theory we saw earlier. If you want Nearest
|
||||
Neighbour algorithm, just specify k=1 where k is the number of neighbours.
|
||||
2. The labels of k-Nearest Neighbours.
|
||||
3. Corresponding distances from new-comer to each nearest neighbour.
|
||||
|
||||
So let's see how it works. The new-comer is marked in green.
|
||||
So let's see how it works. New comer is marked in green color.
|
||||
@code{.py}
|
||||
newcomer = np.random.randint(0,100,(1,2)).astype(np.float32)
|
||||
plt.scatter(newcomer[:,0],newcomer[:,1],80,'g','o')
|
||||
@@ -118,21 +124,21 @@ print( "distance: {}\n".format(dist) )
|
||||
|
||||
plt.show()
|
||||
@endcode
|
||||
I got the following results:
|
||||
I got the result as follows:
|
||||
@code{.py}
|
||||
result: [[ 1.]]
|
||||
neighbours: [[ 1. 1. 1.]]
|
||||
distance: [[ 53. 58. 61.]]
|
||||
@endcode
|
||||
It says that our new-comer's 3 nearest neighbours are all from the Blue family. Therefore, he is labelled as part of the Blue
|
||||
family. It is obvious from the plot below:
|
||||
It says our new-comer got 3 neighbours, all from Blue family. Therefore, he is labelled as Blue
|
||||
family. It is obvious from plot below:
|
||||
|
||||

|
||||
|
||||
If you have multiple new-comers (test data), you can just pass them as an array. Corresponding results are also
|
||||
If you have large number of data, you can just pass it as array. Corresponding results are also
|
||||
obtained as arrays.
|
||||
@code{.py}
|
||||
# 10 new-comers
|
||||
# 10 new comers
|
||||
newcomers = np.random.randint(0,100,(10,2)).astype(np.float32)
|
||||
ret, results,neighbours,dist = knn.findNearest(newcomer, 3)
|
||||
# The results also will contain 10 labels.
|
||||
@@ -140,11 +146,8 @@ ret, results,neighbours,dist = knn.findNearest(newcomer, 3)
|
||||
Additional Resources
|
||||
--------------------
|
||||
|
||||
1. [NPTEL notes on Pattern Recognition, Chapter
|
||||
11](https://nptel.ac.in/courses/106/108/106108057/)
|
||||
2. [Wikipedia article on Nearest neighbor search](https://en.wikipedia.org/wiki/Nearest_neighbor_search)
|
||||
3. [Wikipedia article on k-d tree](https://en.wikipedia.org/wiki/K-d_tree)
|
||||
-# [NPTEL notes on Pattern Recognition, Chapter
|
||||
11](http://www.nptel.iitm.ac.in/courses/106108057/12)
|
||||
|
||||
Exercises
|
||||
---------
|
||||
1. Try repeating the above with more classes and different choices of k. Does choosing k become harder with more classes in the same 2D feature space?
|
||||
@@ -83,7 +83,7 @@ Let us define a kernel function \f$K(p,q)\f$ which does a dot product between tw
|
||||
\begin{aligned}
|
||||
K(p,q) = \phi(p).\phi(q) &= \phi(p)^T \phi(q) \\
|
||||
&= (p_{1}^2,p_{2}^2,\sqrt{2} p_1 p_2).(q_{1}^2,q_{2}^2,\sqrt{2} q_1 q_2) \\
|
||||
&= p_{1}^2 q_{1}^2 + p_{2}^2 q_{2}^2 + 2 p_1 q_1 p_2 q_2 \\
|
||||
&= p_1 q_1 + p_2 q_2 + 2 p_1 q_1 p_2 q_2 \\
|
||||
&= (p_1 q_1 + p_2 q_2)^2 \\
|
||||
\phi(p).\phi(q) &= (p.q)^2
|
||||
\end{aligned}
|
||||
|
||||
@@ -80,7 +80,7 @@ Additional Resources
|
||||
--------------------
|
||||
|
||||
-# A Quick guide to Python - [A Byte of Python](http://swaroopch.com/notes/python/)
|
||||
2. [NumPy Quickstart tutorial](https://numpy.org/devdocs/user/quickstart.html)
|
||||
3. [NumPy Reference](https://numpy.org/devdocs/reference/index.html#reference)
|
||||
2. [Basic Numpy Tutorials](http://wiki.scipy.org/Tentative_NumPy_Tutorial)
|
||||
3. [Numpy Examples List](http://wiki.scipy.org/Numpy_Example_List)
|
||||
4. [OpenCV Documentation](http://docs.opencv.org/)
|
||||
5. [OpenCV Forum](http://answers.opencv.org/questions/)
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
Camera calibration With OpenCV {#tutorial_camera_calibration}
|
||||
==============================
|
||||
|
||||
@prev_tutorial{tutorial_camera_calibration_square_chess}
|
||||
@next_tutorial{tutorial_real_time_pose}
|
||||
|
||||
|
||||
Cameras have been around for a long-long time. However, with the introduction of the cheap *pinhole*
|
||||
cameras in the late 20th century, they became a common occurrence in our everyday life.
|
||||
Unfortunately, this cheapness comes with its price: significant distortion. Luckily, these are
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
Create calibration pattern {#tutorial_camera_calibration_pattern}
|
||||
=========================================
|
||||
|
||||
@next_tutorial{tutorial_camera_calibration_square_chess}
|
||||
|
||||
|
||||
The goal of this tutorial is to learn how to create calibration pattern.
|
||||
|
||||
You can find a chessboard pattern in https://github.com/opencv/opencv/blob/master/doc/pattern.png
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
Camera calibration with square chessboard {#tutorial_camera_calibration_square_chess}
|
||||
=========================================
|
||||
|
||||
@prev_tutorial{tutorial_camera_calibration_pattern}
|
||||
@next_tutorial{tutorial_camera_calibration}
|
||||
|
||||
|
||||
The goal of this tutorial is to learn how to calibrate a camera given a set of chessboard images.
|
||||
|
||||
*Test data*: use images in your data/chess folder.
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
Interactive camera calibration application {#tutorial_interactive_calibration}
|
||||
==============================
|
||||
|
||||
@prev_tutorial{tutorial_real_time_pose}
|
||||
|
||||
|
||||
According to classical calibration technique user must collect all data first and when run @ref cv::calibrateCamera function
|
||||
to obtain camera parameters. If average re-projection error is huge or if estimated parameters seems to be wrong, process of
|
||||
selection or collecting data and starting of @ref cv::calibrateCamera repeats.
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
Real Time pose estimation of a textured object {#tutorial_real_time_pose}
|
||||
==============================================
|
||||
|
||||
@prev_tutorial{tutorial_camera_calibration}
|
||||
@next_tutorial{tutorial_interactive_calibration}
|
||||
|
||||
|
||||
Nowadays, augmented reality is one of the top research topic in computer vision and robotics fields.
|
||||
The most elemental problem in augmented reality is the estimation of the camera pose respect of an
|
||||
object in the case of computer vision area to do later some 3D rendering or in the case of robotics
|
||||
|
||||
@@ -5,8 +5,6 @@ Although we get most of our images in a 2D format they do come from a 3D world.
|
||||
|
||||
- @subpage tutorial_camera_calibration_pattern
|
||||
|
||||
*Languages:* Python
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Laurent Berger
|
||||
@@ -15,8 +13,6 @@ Although we get most of our images in a 2D format they do come from a 3D world.
|
||||
|
||||
- @subpage tutorial_camera_calibration_square_chess
|
||||
|
||||
*Languages:* C++
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Victor Eruhimov
|
||||
@@ -25,8 +21,6 @@ Although we get most of our images in a 2D format they do come from a 3D world.
|
||||
|
||||
- @subpage tutorial_camera_calibration
|
||||
|
||||
*Languages:* C++
|
||||
|
||||
*Compatibility:* \> OpenCV 4.0
|
||||
|
||||
*Author:* Bernát Gábor
|
||||
@@ -37,8 +31,6 @@ Although we get most of our images in a 2D format they do come from a 3D world.
|
||||
|
||||
- @subpage tutorial_real_time_pose
|
||||
|
||||
*Languages:* C++
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Edgar Riba
|
||||
|
||||
@@ -107,9 +107,8 @@ you may access it. For sequences you need to go through them to query a specific
|
||||
then we have to specify if our output is either a sequence or map.
|
||||
|
||||
For sequence before the first element print the "[" character and after the last one the "]"
|
||||
character. With Python, call `FileStorage.startWriteStruct(structure_name, struct_type)`,
|
||||
where `struct_type` is `cv2.FileNode_MAP` or `cv2.FileNode_SEQ` to start writing the structure.
|
||||
Call `FileStorage.endWriteStruct()` to finish the structure:
|
||||
character. With Python, the "]" character could be written with the name of the sequence or
|
||||
the last element of the sequence depending on the number of elements:
|
||||
@add_toggle_cpp
|
||||
@snippet cpp/tutorial_code/core/file_input_output/file_input_output.cpp writeStr
|
||||
@end_toggle
|
||||
|
||||
@@ -6,8 +6,6 @@ understanding how to manipulate the images on a pixel level.
|
||||
|
||||
- @subpage tutorial_mat_the_basic_image_container
|
||||
|
||||
*Languages:* C++
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Bernát Gábor
|
||||
@@ -17,8 +15,6 @@ understanding how to manipulate the images on a pixel level.
|
||||
|
||||
- @subpage tutorial_how_to_scan_images
|
||||
|
||||
*Languages:* C++
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Bernát Gábor
|
||||
@@ -79,8 +75,6 @@ understanding how to manipulate the images on a pixel level.
|
||||
|
||||
- @subpage tutorial_file_input_output_with_xml_yml
|
||||
|
||||
*Languages:* C++, Python
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Bernát Gábor
|
||||
@@ -90,8 +84,6 @@ understanding how to manipulate the images on a pixel level.
|
||||
|
||||
- @subpage tutorial_how_to_use_OpenCV_parallel_for_
|
||||
|
||||
*Languages:* C++
|
||||
|
||||
*Compatibility:* \>= OpenCV 2.4.3
|
||||
|
||||
You will see how to use the OpenCV parallel_for_ to easily parallelize your code.
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
# How to run deep networks on Android device {#tutorial_dnn_android}
|
||||
|
||||
@prev_tutorial{tutorial_dnn_halide_scheduling}
|
||||
@next_tutorial{tutorial_dnn_yolo}
|
||||
|
||||
## Introduction
|
||||
In this tutorial you'll know how to run deep learning networks on Android device
|
||||
using OpenCV deep learning module.
|
||||
@@ -15,7 +12,7 @@ Tutorial was written for the following versions of corresponding software:
|
||||
|
||||
- Download and install Android Studio from https://developer.android.com/studio.
|
||||
|
||||
- Get the latest pre-built OpenCV for Android release from https://github.com/opencv/opencv/releases and unpack it (for example, `opencv-4.4.0-android-sdk.zip`).
|
||||
- Get the latest pre-built OpenCV for Android release from https://github.com/opencv/opencv/releases and unpack it (for example, `opencv-4.3.0-android-sdk.zip`).
|
||||
|
||||
- Download MobileNet object detection model from https://github.com/chuanqi305/MobileNet-SSD. We need a configuration file `MobileNetSSD_deploy.prototxt` and weights `MobileNetSSD_deploy.caffemodel`.
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# Custom deep learning layers support {#tutorial_dnn_custom_layers}
|
||||
|
||||
@prev_tutorial{tutorial_dnn_javascript}
|
||||
|
||||
## Introduction
|
||||
Deep learning is a fast growing area. The new approaches to build neural networks
|
||||
usually introduce new types of layers. They could be modifications of existing
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
Load Caffe framework models {#tutorial_dnn_googlenet}
|
||||
===========================
|
||||
|
||||
@next_tutorial{tutorial_dnn_halide}
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
# How to enable Halide backend for improve efficiency {#tutorial_dnn_halide}
|
||||
|
||||
@prev_tutorial{tutorial_dnn_googlenet}
|
||||
@next_tutorial{tutorial_dnn_halide_scheduling}
|
||||
|
||||
## Introduction
|
||||
This tutorial guidelines how to run your models in OpenCV deep learning module
|
||||
using Halide language backend. Halide is an open-source project that let us
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
# How to schedule your network for Halide backend {#tutorial_dnn_halide_scheduling}
|
||||
|
||||
@prev_tutorial{tutorial_dnn_halide}
|
||||
@next_tutorial{tutorial_dnn_android}
|
||||
|
||||
## Introduction
|
||||
Halide code is the same for every device we use. But for achieving the satisfied
|
||||
efficiency we should schedule computations properly. In this tutorial we describe
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
# How to run deep networks in browser {#tutorial_dnn_javascript}
|
||||
|
||||
@prev_tutorial{tutorial_dnn_yolo}
|
||||
@next_tutorial{tutorial_dnn_custom_layers}
|
||||
|
||||
## Introduction
|
||||
This tutorial will show us how to run deep learning models using OpenCV.js right
|
||||
in a browser. Tutorial refers a sample of face detection and face recognition
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
YOLO DNNs {#tutorial_dnn_yolo}
|
||||
===============================
|
||||
|
||||
@prev_tutorial{tutorial_dnn_android}
|
||||
@next_tutorial{tutorial_dnn_javascript}
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@ Deep Neural Networks (dnn module) {#tutorial_table_of_content_dnn}
|
||||
|
||||
- @subpage tutorial_dnn_googlenet
|
||||
|
||||
*Languages:* C++
|
||||
|
||||
*Compatibility:* \> OpenCV 3.3
|
||||
|
||||
*Author:* Vitaliy Lyudvichenko
|
||||
@@ -13,8 +11,6 @@ Deep Neural Networks (dnn module) {#tutorial_table_of_content_dnn}
|
||||
|
||||
- @subpage tutorial_dnn_halide
|
||||
|
||||
*Languages:* Halide
|
||||
|
||||
*Compatibility:* \> OpenCV 3.3
|
||||
|
||||
*Author:* Dmitry Kurtaev
|
||||
@@ -23,8 +19,6 @@ Deep Neural Networks (dnn module) {#tutorial_table_of_content_dnn}
|
||||
|
||||
- @subpage tutorial_dnn_halide_scheduling
|
||||
|
||||
*Languages:* Halide
|
||||
|
||||
*Compatibility:* \> OpenCV 3.3
|
||||
|
||||
*Author:* Dmitry Kurtaev
|
||||
@@ -33,8 +27,6 @@ Deep Neural Networks (dnn module) {#tutorial_table_of_content_dnn}
|
||||
|
||||
- @subpage tutorial_dnn_android
|
||||
|
||||
*Languages:* Java
|
||||
|
||||
*Compatibility:* \> OpenCV 3.3
|
||||
|
||||
*Author:* Dmitry Kurtaev
|
||||
@@ -43,8 +35,6 @@ Deep Neural Networks (dnn module) {#tutorial_table_of_content_dnn}
|
||||
|
||||
- @subpage tutorial_dnn_yolo
|
||||
|
||||
*Languages:* C++, Python
|
||||
|
||||
*Compatibility:* \> OpenCV 3.3.1
|
||||
|
||||
*Author:* Alessandro de Oliveira Faria
|
||||
@@ -53,8 +43,6 @@ Deep Neural Networks (dnn module) {#tutorial_table_of_content_dnn}
|
||||
|
||||
- @subpage tutorial_dnn_javascript
|
||||
|
||||
*Languages:* JavaScript
|
||||
|
||||
*Compatibility:* \> OpenCV 3.3.1
|
||||
|
||||
*Author:* Dmitry Kurtaev
|
||||
@@ -63,8 +51,6 @@ Deep Neural Networks (dnn module) {#tutorial_table_of_content_dnn}
|
||||
|
||||
- @subpage tutorial_dnn_custom_layers
|
||||
|
||||
*Languages:* C++, Python
|
||||
|
||||
*Compatibility:* \> OpenCV 3.4.1
|
||||
|
||||
*Author:* Dmitry Kurtaev
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
AKAZE local features matching {#tutorial_akaze_matching}
|
||||
=============================
|
||||
|
||||
@prev_tutorial{tutorial_detection_of_planar_objects}
|
||||
@next_tutorial{tutorial_akaze_tracking}
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
AKAZE and ORB planar tracking {#tutorial_akaze_tracking}
|
||||
=============================
|
||||
|
||||
@prev_tutorial{tutorial_akaze_matching}
|
||||
@next_tutorial{tutorial_homography}
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
Detection of planar objects {#tutorial_detection_of_planar_objects}
|
||||
===========================
|
||||
|
||||
@prev_tutorial{tutorial_feature_homography}
|
||||
@next_tutorial{tutorial_akaze_matching}
|
||||
|
||||
|
||||
The goal of this tutorial is to learn how to use *features2d* and *calib3d* modules for detecting
|
||||
known planar objects in scenes.
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
Feature Description {#tutorial_feature_description}
|
||||
===================
|
||||
|
||||
@prev_tutorial{tutorial_feature_detection}
|
||||
@next_tutorial{tutorial_feature_flann_matcher}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
Feature Detection {#tutorial_feature_detection}
|
||||
=================
|
||||
|
||||
@prev_tutorial{tutorial_corner_subpixels}
|
||||
@next_tutorial{tutorial_feature_description}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
Feature Matching with FLANN {#tutorial_feature_flann_matcher}
|
||||
===========================
|
||||
|
||||
@prev_tutorial{tutorial_feature_description}
|
||||
@next_tutorial{tutorial_feature_homography}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
@@ -30,7 +27,7 @@ Binary descriptors (ORB, BRISK, ...) are matched using the <a href="https://en.w
|
||||
This distance is equivalent to count the number of different elements for binary strings (population count after applying a XOR operation):
|
||||
\f[ d_{hamming} \left ( a,b \right ) = \sum_{i=0}^{n-1} \left ( a_i \oplus b_i \right ) \f]
|
||||
|
||||
To filter the matches, Lowe proposed in @cite Lowe04 to use a distance ratio test to try to eliminate false matches.
|
||||
To filter the matches, Lowe proposed in @cite Lowe:2004:DIF:993451.996342 to use a distance ratio test to try to eliminate false matches.
|
||||
The distance ratio between the two nearest matches of a considered keypoint is computed and it is a good match when this value is below
|
||||
a threshold. Indeed, this ratio allows helping to discriminate between ambiguous matches (distance ratio between the two nearest neighbors
|
||||
is close to one) and well discriminated matches. The figure below from the SIFT paper illustrates the probability that a match is correct
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
Features2D + Homography to find a known object {#tutorial_feature_homography}
|
||||
==============================================
|
||||
|
||||
@prev_tutorial{tutorial_feature_flann_matcher}
|
||||
@next_tutorial{tutorial_detection_of_planar_objects}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
Basic concepts of the homography explained with code {#tutorial_homography}
|
||||
====================================================
|
||||
|
||||
@prev_tutorial{tutorial_akaze_tracking}
|
||||
|
||||
@tableofcontents
|
||||
|
||||
Introduction {#tutorial_homography_Introduction}
|
||||
|
||||
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 63 KiB |
@@ -89,8 +89,6 @@ OpenCV.
|
||||
|
||||
- @subpage tutorial_detection_of_planar_objects
|
||||
|
||||
*Languages:* C++
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Victor Eruhimov
|
||||
@@ -110,8 +108,6 @@ OpenCV.
|
||||
|
||||
- @subpage tutorial_akaze_tracking
|
||||
|
||||
*Languages:* C++
|
||||
|
||||
*Compatibility:* \> OpenCV 3.0
|
||||
|
||||
*Author:* Fedor Morozov
|
||||
@@ -120,8 +116,6 @@ OpenCV.
|
||||
|
||||
- @subpage tutorial_homography
|
||||
|
||||
*Languages:* C++, Java, Python
|
||||
|
||||
*Compatibility:* \> OpenCV 3.0
|
||||
|
||||
This tutorial will explain the basic concepts of the homography with some
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
Detecting corners location in subpixels {#tutorial_corner_subpixels}
|
||||
=======================================
|
||||
|
||||
@prev_tutorial{tutorial_generic_corner_detector}
|
||||
@next_tutorial{tutorial_feature_detection}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
Creating your own corner detector {#tutorial_generic_corner_detector}
|
||||
=================================
|
||||
|
||||
@prev_tutorial{tutorial_good_features_to_track}
|
||||
@next_tutorial{tutorial_corner_subpixels}
|
||||
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
Shi-Tomasi corner detector {#tutorial_good_features_to_track}
|
||||
==========================
|
||||
|
||||
@prev_tutorial{tutorial_harris_detector}
|
||||
@next_tutorial{tutorial_generic_corner_detector}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
Harris corner detector {#tutorial_harris_detector}
|
||||
======================
|
||||
|
||||
@next_tutorial{tutorial_good_features_to_track}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@ Similarity check (PNSR and SSIM) on the GPU {#tutorial_gpu_basics_similarity}
|
||||
===========================================
|
||||
@todo update this tutorial
|
||||
|
||||
@next_tutorial{tutorial_gpu_thrust_interop}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
Using a cv::cuda::GpuMat with thrust {#tutorial_gpu_thrust_interop}
|
||||
===========================================
|
||||
|
||||
@prev_tutorial{tutorial_gpu_basics_similarity}
|
||||
|
||||
Goal
|
||||
----
|
||||
|
||||
|
||||
@@ -7,8 +7,6 @@ run the OpenCV algorithms.
|
||||
|
||||
- @subpage tutorial_gpu_basics_similarity
|
||||
|
||||
*Languages:* C++
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Bernát Gábor
|
||||
@@ -19,8 +17,6 @@ run the OpenCV algorithms.
|
||||
|
||||
- @subpage tutorial_gpu_thrust_interop
|
||||
|
||||
*Languages:* C++
|
||||
|
||||
*Compatibility:* \>= OpenCV 3.0
|
||||
|
||||
This tutorial will show you how to wrap a GpuMat into a thrust iterator in order to be able to
|
||||
|
||||
@@ -5,8 +5,6 @@ This section contains tutorials about how to read/save your image files.
|
||||
|
||||
- @subpage tutorial_raster_io_gdal
|
||||
|
||||
*Languages:* C++
|
||||
|
||||
*Compatibility:* \> OpenCV 2.0
|
||||
|
||||
*Author:* Marvin Smith
|
||||
|
||||
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 556 B After Width: | Height: | Size: 556 B |