Merge remote-tracking branch 'upstream/3.4' into merge-3.4

This commit is contained in:
Alexander Alekhin 2020-07-06 23:05:04 +00:00
commit 524a2fffe9
28 changed files with 268 additions and 89 deletions

View File

@ -1617,6 +1617,10 @@ if(ENABLE_CONFIG_VERIFICATION)
ocv_verify_config() ocv_verify_config()
endif() endif()
if(HAVE_CUDA AND COMMAND CUDA_BUILD_CLEAN_TARGET)
CUDA_BUILD_CLEAN_TARGET()
endif()
ocv_cmake_hook(POST_FINALIZE) ocv_cmake_hook(POST_FINALIZE)
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------

View File

@ -191,7 +191,6 @@ if(CV_GCC OR CV_CLANG)
# Profiling? # Profiling?
if(ENABLE_PROFILING) if(ENABLE_PROFILING)
add_extra_compiler_option("-pg -g")
# turn off incompatible options # turn off incompatible options
foreach(flags CMAKE_CXX_FLAGS CMAKE_C_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG CMAKE_C_FLAGS_DEBUG foreach(flags CMAKE_CXX_FLAGS CMAKE_C_FLAGS CMAKE_CXX_FLAGS_RELEASE CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS_DEBUG CMAKE_C_FLAGS_DEBUG
OPENCV_EXTRA_FLAGS_RELEASE OPENCV_EXTRA_FLAGS_DEBUG OPENCV_EXTRA_C_FLAGS OPENCV_EXTRA_CXX_FLAGS) OPENCV_EXTRA_FLAGS_RELEASE OPENCV_EXTRA_FLAGS_DEBUG OPENCV_EXTRA_C_FLAGS OPENCV_EXTRA_CXX_FLAGS)
@ -199,6 +198,9 @@ if(CV_GCC OR CV_CLANG)
string(REPLACE "-ffunction-sections" "" ${flags} "${${flags}}") string(REPLACE "-ffunction-sections" "" ${flags} "${${flags}}")
string(REPLACE "-fdata-sections" "" ${flags} "${${flags}}") string(REPLACE "-fdata-sections" "" ${flags} "${${flags}}")
endforeach() endforeach()
# -pg should be placed both in the linker and in the compiler settings
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pg")
add_extra_compiler_option("-pg -g")
else() else()
if(MSVC) if(MSVC)
# TODO: Clang/C2 is not supported # TODO: Clang/C2 is not supported

View File

@ -417,6 +417,13 @@ if(HAVE_CUDA)
set(CUDA_cufft_LIBRARY_ABS ${CUDA_cufft_LIBRARY}) set(CUDA_cufft_LIBRARY_ABS ${CUDA_cufft_LIBRARY})
ocv_convert_to_lib_name(CUDA_cufft_LIBRARY ${CUDA_cufft_LIBRARY}) ocv_convert_to_lib_name(CUDA_cufft_LIBRARY ${CUDA_cufft_LIBRARY})
endif() endif()
if(CMAKE_GENERATOR MATCHES "Visual Studio"
AND NOT OPENCV_SKIP_CUDA_CMAKE_SUPPRESS_REGENERATION
)
message(WARNING "CUDA with MSVS generator is detected. Disabling CMake re-run checks (CMAKE_SUPPRESS_REGENERATION=ON). You need to run CMake manually if updates are required.")
set(CMAKE_SUPPRESS_REGENERATION ON)
endif()
endif() endif()

View File

@ -46,6 +46,7 @@
SET(Open_BLAS_INCLUDE_SEARCH_PATHS SET(Open_BLAS_INCLUDE_SEARCH_PATHS
$ENV{OpenBLAS_HOME} $ENV{OpenBLAS_HOME}
$ENV{OpenBLAS_HOME}/include $ENV{OpenBLAS_HOME}/include
$ENV{OpenBLAS_HOME}/include/openblas
/opt/OpenBLAS/include /opt/OpenBLAS/include
/usr/local/include/openblas /usr/local/include/openblas
/usr/include/openblas /usr/include/openblas

View File

@ -106,8 +106,8 @@ namespace cv
size_t step; size_t step;
__CV_CUDA_HOST_DEVICE__ T* ptr(int y = 0) { return ( T*)( ( char*)DevPtr<T>::data + y * step); } __CV_CUDA_HOST_DEVICE__ T* ptr(int y = 0) { return ( T*)( ( char*)(((DevPtr<T>*)this)->data) + y * step); }
__CV_CUDA_HOST_DEVICE__ const T* ptr(int y = 0) const { return (const T*)( (const char*)DevPtr<T>::data + y * step); } __CV_CUDA_HOST_DEVICE__ const T* ptr(int y = 0) const { return (const T*)( (const char*)(((DevPtr<T>*)this)->data) + y * step); }
__CV_CUDA_HOST_DEVICE__ T& operator ()(int y, int x) { return ptr(y)[x]; } __CV_CUDA_HOST_DEVICE__ T& operator ()(int y, int x) { return ptr(y)[x]; }
__CV_CUDA_HOST_DEVICE__ const T& operator ()(int y, int x) const { return ptr(y)[x]; } __CV_CUDA_HOST_DEVICE__ const T& operator ()(int y, int x) const { return ptr(y)[x]; }

View File

@ -216,6 +216,19 @@ PERF_TEST_P_(DNNTestNetwork, YOLOv4)
processNet("dnn/yolov4.weights", "dnn/yolov4.cfg", "", inp); processNet("dnn/yolov4.weights", "dnn/yolov4.cfg", "", inp);
} }
PERF_TEST_P_(DNNTestNetwork, YOLOv4_tiny)
{
if (backend == DNN_BACKEND_HALIDE)
throw SkipTestException("");
if (target == DNN_TARGET_MYRIAD)
throw SkipTestException("");
Mat sample = imread(findDataFile("dnn/dog416.png"));
cvtColor(sample, sample, COLOR_BGR2RGB);
Mat inp;
sample.convertTo(inp, CV_32FC3, 1.0f / 255, 0);
processNet("dnn/yolov4-tiny.weights", "dnn/yolov4-tiny.cfg", "", inp);
}
PERF_TEST_P_(DNNTestNetwork, EAST_text_detection) PERF_TEST_P_(DNNTestNetwork, EAST_text_detection)
{ {
if (backend == DNN_BACKEND_HALIDE) if (backend == DNN_BACKEND_HALIDE)

View File

@ -363,6 +363,28 @@ namespace cv {
fused_layer_names.push_back(last_layer); fused_layer_names.push_back(last_layer);
} }
void setSlice(int input_index, int split_size, int group_id)
{
int begin[] = {0, split_size * group_id, 0, 0};
cv::dnn::DictValue paramBegin = cv::dnn::DictValue::arrayInt(begin, 4);
int end[] = {-1, begin[1] + split_size, -1, -1};
cv::dnn::DictValue paramEnd = cv::dnn::DictValue::arrayInt(end, 4);
darknet::LayerParameter lp;
lp.layer_name = cv::format("slice_%d", layer_id);
lp.layer_type = "Slice";
lp.layerParams.set("begin", paramBegin);
lp.layerParams.set("end", paramEnd);
lp.bottom_indexes.push_back(fused_layer_names.at(input_index));
net->layers.push_back(lp);
layer_id++;
last_layer = lp.layer_name;
fused_layer_names.push_back(last_layer);
}
void setReorg(int stride) void setReorg(int stride)
{ {
cv::dnn::LayerParams reorg_params; cv::dnn::LayerParams reorg_params;
@ -717,6 +739,7 @@ namespace cv {
{ {
std::string bottom_layers = getParam<std::string>(layer_params, "layers", ""); std::string bottom_layers = getParam<std::string>(layer_params, "layers", "");
CV_Assert(!bottom_layers.empty()); CV_Assert(!bottom_layers.empty());
int groups = getParam<int>(layer_params, "groups", 1);
std::vector<int> layers_vec = getNumbers<int>(bottom_layers); std::vector<int> layers_vec = getNumbers<int>(bottom_layers);
tensor_shape[0] = 0; tensor_shape[0] = 0;
@ -725,11 +748,32 @@ namespace cv {
tensor_shape[0] += net->out_channels_vec[layers_vec[k]]; tensor_shape[0] += net->out_channels_vec[layers_vec[k]];
} }
if (groups > 1)
{
int group_id = getParam<int>(layer_params, "group_id", 0);
tensor_shape[0] /= groups;
int split_size = tensor_shape[0] / layers_vec.size();
for (size_t k = 0; k < layers_vec.size(); ++k)
setParams.setSlice(layers_vec[k], split_size, group_id);
if (layers_vec.size() > 1)
{
// layer ids in layers_vec - inputs of Slice layers
// after adding offset to layers_vec: layer ids - ouputs of Slice layers
for (size_t k = 0; k < layers_vec.size(); ++k)
layers_vec[k] += layers_vec.size();
setParams.setConcat(layers_vec.size(), layers_vec.data());
}
}
else
{
if (layers_vec.size() == 1) if (layers_vec.size() == 1)
setParams.setIdentity(layers_vec.at(0)); setParams.setIdentity(layers_vec.at(0));
else else
setParams.setConcat(layers_vec.size(), layers_vec.data()); setParams.setConcat(layers_vec.size(), layers_vec.data());
} }
}
else if (layer_type == "dropout" || layer_type == "cost") else if (layer_type == "dropout" || layer_type == "cost")
{ {
setParams.setIdentity(layers_counter-1); setParams.setIdentity(layers_counter-1);

View File

@ -41,9 +41,15 @@
//M*/ //M*/
#include "../precomp.hpp" #include "../precomp.hpp"
#include "../op_cuda.hpp"
#include "../op_inf_engine.hpp"
#include <opencv2/dnn/shape_utils.hpp>
#include <opencv2/dnn/all_layers.hpp>
#ifdef HAVE_OPENCL
#include "opencl_kernels_dnn.hpp"
#endif
#include "../op_inf_engine.hpp"
#ifdef HAVE_DNN_NGRAPH #ifdef HAVE_DNN_NGRAPH
#include "../ie_ngraph.hpp" #include "../ie_ngraph.hpp"
#if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2020_4) #if INF_ENGINE_VER_MAJOR_GT(INF_ENGINE_RELEASE_2020_4)
@ -53,13 +59,7 @@
#endif #endif
#endif #endif
#include <opencv2/dnn/shape_utils.hpp> #include "../op_cuda.hpp"
#include <opencv2/dnn/all_layers.hpp>
#ifdef HAVE_OPENCL
#include "opencl_kernels_dnn.hpp"
#endif
#ifdef HAVE_CUDA #ifdef HAVE_CUDA
#include "../cuda4dnn/primitives/reorg.hpp" #include "../cuda4dnn/primitives/reorg.hpp"
using namespace cv::dnn::cuda4dnn; using namespace cv::dnn::cuda4dnn;

View File

@ -209,6 +209,10 @@ public:
#ifdef HAVE_OPENCL #ifdef HAVE_OPENCL
bool forward_ocl(InputArrayOfArrays inputs_, OutputArrayOfArrays outputs_, OutputArrayOfArrays internals_) bool forward_ocl(InputArrayOfArrays inputs_, OutputArrayOfArrays outputs_, OutputArrayOfArrays internals_)
{ {
#if 1
// TODO fix that (brokes YOLOv4-tiny)
return false;
#else
std::vector<UMat> inputs; std::vector<UMat> inputs;
std::vector<UMat> outputs; std::vector<UMat> outputs;
@ -251,6 +255,7 @@ public:
} }
return true; return true;
#endif
} }
#endif #endif

View File

@ -100,9 +100,12 @@ void normAssertDetections(
const char *comment /*= ""*/, double confThreshold /*= 0.0*/, const char *comment /*= ""*/, double confThreshold /*= 0.0*/,
double scores_diff /*= 1e-5*/, double boxes_iou_diff /*= 1e-4*/) double scores_diff /*= 1e-5*/, double boxes_iou_diff /*= 1e-4*/)
{ {
ASSERT_FALSE(testClassIds.empty()) << "No detections";
std::vector<bool> matchedRefBoxes(refBoxes.size(), false); std::vector<bool> matchedRefBoxes(refBoxes.size(), false);
std::vector<double> refBoxesIoUDiff(refBoxes.size(), 1.0);
for (int i = 0; i < testBoxes.size(); ++i) for (int i = 0; i < testBoxes.size(); ++i)
{ {
//cout << "Test[i=" << i << "]: score=" << testScores[i] << " id=" << testClassIds[i] << " box " << testBoxes[i] << endl;
double testScore = testScores[i]; double testScore = testScores[i];
if (testScore < confThreshold) if (testScore < confThreshold)
continue; continue;
@ -119,6 +122,7 @@ void normAssertDetections(
double interArea = (testBox & refBoxes[j]).area(); double interArea = (testBox & refBoxes[j]).area();
double iou = interArea / (testBox.area() + refBoxes[j].area() - interArea); double iou = interArea / (testBox.area() + refBoxes[j].area() - interArea);
topIoU = std::max(topIoU, iou); topIoU = std::max(topIoU, iou);
refBoxesIoUDiff[j] = std::min(refBoxesIoUDiff[j], 1.0f - iou);
if (1.0 - iou < boxes_iou_diff) if (1.0 - iou < boxes_iou_diff)
{ {
matched = true; matched = true;
@ -141,7 +145,9 @@ void normAssertDetections(
if (!matchedRefBoxes[i] && refScores[i] > confThreshold) if (!matchedRefBoxes[i] && refScores[i] > confThreshold)
{ {
std::cout << cv::format("Unmatched reference: class %d score %f box ", std::cout << cv::format("Unmatched reference: class %d score %f box ",
refClassIds[i], refScores[i]) << refBoxes[i] << std::endl; refClassIds[i], refScores[i]) << refBoxes[i]
<< " IoU diff: " << refBoxesIoUDiff[i]
<< std::endl;
EXPECT_LE(refScores[i], confThreshold) << comment; EXPECT_LE(refScores[i], confThreshold) << comment;
} }
} }

View File

@ -254,6 +254,13 @@ public:
} }
if (cvIsNaN(iouDiff))
{
if (b == 0)
std::cout << "Skip accuracy checks" << std::endl;
continue;
}
normAssertDetections(refClassIds[b], refConfidences[b], refBoxes[b], nms_classIds, normAssertDetections(refClassIds[b], refConfidences[b], refBoxes[b], nms_classIds,
nms_confidences, nms_boxes, format("batch size %d, sample %d\n", batch_size, b).c_str(), confThreshold, scoreDiff, iouDiff); nms_confidences, nms_boxes, format("batch size %d, sample %d\n", batch_size, b).c_str(), confThreshold, scoreDiff, iouDiff);
} }
@ -467,7 +474,7 @@ TEST_P(Test_Darknet_nets_async, Accuracy)
} }
INSTANTIATE_TEST_CASE_P(/**/, Test_Darknet_nets_async, Combine( INSTANTIATE_TEST_CASE_P(/**/, Test_Darknet_nets_async, Combine(
Values("yolo-voc", "tiny-yolo-voc", "yolov3", "yolov4"), Values("yolo-voc", "tiny-yolo-voc", "yolov3", "yolov4", "yolov4-tiny"),
dnnBackendsAndTargets() dnnBackendsAndTargets()
)); ));
@ -618,6 +625,63 @@ TEST_P(Test_Darknet_nets, YOLOv4)
} }
} }
TEST_P(Test_Darknet_nets, YOLOv4_tiny)
{
applyTestTag(
target == DNN_TARGET_CPU ? CV_TEST_TAG_MEMORY_512MB : CV_TEST_TAG_MEMORY_1GB
);
const double confThreshold = 0.5;
// batchId, classId, confidence, left, top, right, bottom
const int N0 = 2;
const int N1 = 3;
static const float ref_[/* (N0 + N1) * 7 */] = {
0, 7, 0.85935f, 0.593484f, 0.141211f, 0.920356f, 0.291593f,
0, 16, 0.795188f, 0.169207f, 0.386886f, 0.423753f, 0.933004f,
1, 2, 0.996832f, 0.653802f, 0.464573f, 0.815193f, 0.653292f,
1, 2, 0.963325f, 0.451151f, 0.458915f, 0.496255f, 0.52241f,
1, 0, 0.926244f, 0.194851f, 0.361743f, 0.260277f, 0.632364f,
};
Mat ref(N0 + N1, 7, CV_32FC1, (void*)ref_);
double scoreDiff = 0.01f;
double iouDiff = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD) ? 0.15 : 0.01f;
std::string config_file = "yolov4-tiny.cfg";
std::string weights_file = "yolov4-tiny.weights";
#if defined(INF_ENGINE_RELEASE)
if (target == DNN_TARGET_MYRIAD) // bad accuracy
iouDiff = std::numeric_limits<double>::quiet_NaN();
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_OPENCL)
iouDiff = std::numeric_limits<double>::quiet_NaN();
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 ||
backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) && DNN_TARGET_OPENCL_FP16)
iouDiff = std::numeric_limits<double>::quiet_NaN();
#endif
{
SCOPED_TRACE("batch size 1");
testDarknetModel(config_file, weights_file, ref.rowRange(0, N0), scoreDiff, iouDiff, confThreshold);
}
{
SCOPED_TRACE("batch size 2");
testDarknetModel(config_file, weights_file, ref, scoreDiff, iouDiff, confThreshold);
}
#if defined(INF_ENGINE_RELEASE)
if (target == DNN_TARGET_MYRIAD) // bad accuracy
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_MYRIAD, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
if (backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 && target == DNN_TARGET_OPENCL)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
if ((backend == DNN_BACKEND_INFERENCE_ENGINE_NN_BUILDER_2019 ||
backend == DNN_BACKEND_INFERENCE_ENGINE_NGRAPH) && DNN_TARGET_OPENCL_FP16)
applyTestTag(CV_TEST_TAG_DNN_SKIP_IE_OPENCL_FP16, CV_TEST_TAG_DNN_SKIP_IE_VERSION);
#endif
}
INSTANTIATE_TEST_CASE_P(/**/, Test_Darknet_nets, dnnBackendsAndTargets()); INSTANTIATE_TEST_CASE_P(/**/, Test_Darknet_nets, dnnBackendsAndTargets());
@ -658,6 +722,12 @@ TEST_P(Test_Darknet_layers, reorg)
testDarknetLayer("reorg"); testDarknetLayer("reorg");
} }
TEST_P(Test_Darknet_layers, route)
{
testDarknetLayer("route");
testDarknetLayer("route_multi");
}
TEST_P(Test_Darknet_layers, maxpool) TEST_P(Test_Darknet_layers, maxpool)
{ {
#if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2020020000) #if defined(INF_ENGINE_RELEASE) && INF_ENGINE_VER_MAJOR_GE(2020020000)

View File

@ -497,7 +497,7 @@ private:
const int nn = 1; const int nn = 1;
const size_t SAMPLE_COUNT = 1000; const size_t SAMPLE_COUNT = 1000;
assert(bestIndex_ != NULL); // must have a valid index CV_Assert(bestIndex_ != NULL && "Requires a valid index"); // must have a valid index
float speedup = 0; float speedup = 0;

View File

@ -506,7 +506,7 @@ struct Hamming2
const uint64_t* pa = reinterpret_cast<const uint64_t*>(a); const uint64_t* pa = reinterpret_cast<const uint64_t*>(a);
const uint64_t* pb = reinterpret_cast<const uint64_t*>(b); const uint64_t* pb = reinterpret_cast<const uint64_t*>(b);
ResultType result = 0; ResultType result = 0;
size /= (sizeof(uint64_t)/sizeof(unsigned char)); size /= long_word_size_;
for(size_t i = 0; i < size; ++i ) { for(size_t i = 0; i < size; ++i ) {
result += popcnt64(*pa ^ *pb); result += popcnt64(*pa ^ *pb);
++pa; ++pa;
@ -516,7 +516,7 @@ struct Hamming2
const uint32_t* pa = reinterpret_cast<const uint32_t*>(a); const uint32_t* pa = reinterpret_cast<const uint32_t*>(a);
const uint32_t* pb = reinterpret_cast<const uint32_t*>(b); const uint32_t* pb = reinterpret_cast<const uint32_t*>(b);
ResultType result = 0; ResultType result = 0;
size /= (sizeof(uint32_t)/sizeof(unsigned char)); size /= long_word_size_;
for(size_t i = 0; i < size; ++i ) { for(size_t i = 0; i < size; ++i ) {
result += popcnt32(*pa ^ *pb); result += popcnt32(*pa ^ *pb);
++pa; ++pa;
@ -525,6 +525,13 @@ struct Hamming2
#endif #endif
return result; return result;
} }
private:
#ifdef FLANN_PLATFORM_64_BIT
static const size_t long_word_size_ = sizeof(uint64_t)/sizeof(unsigned char);
#else
static const size_t long_word_size_ = sizeof(uint32_t)/sizeof(unsigned char);
#endif
}; };

View File

@ -34,7 +34,6 @@
//! @cond IGNORED //! @cond IGNORED
#include <vector> #include <vector>
#include <cassert>
#include <cstdio> #include <cstdio>
#include "general.h" #include "general.h"

View File

@ -35,7 +35,6 @@
#include <algorithm> #include <algorithm>
#include <map> #include <map>
#include <cassert>
#include <limits> #include <limits>
#include <cmath> #include <cmath>
@ -153,7 +152,7 @@ private:
int n = indices_length; int n = indices_length;
int rnd = rand_int(n); int rnd = rand_int(n);
assert(rnd >=0 && rnd < n); CV_DbgAssert(rnd >=0 && rnd < n);
centers[0] = dsindices[rnd]; centers[0] = dsindices[rnd];
@ -208,7 +207,7 @@ private:
// Choose one random center and set the closestDistSq values // Choose one random center and set the closestDistSq values
int index = rand_int(n); int index = rand_int(n);
assert(index >=0 && index < n); CV_DbgAssert(index >=0 && index < n);
centers[0] = dsindices[index]; centers[0] = dsindices[index];
// Computing distance^2 will have the advantage of even higher probability further to pick new centers // Computing distance^2 will have the advantage of even higher probability further to pick new centers
@ -295,7 +294,7 @@ private:
// Choose one random center and set the closestDistSq values // Choose one random center and set the closestDistSq values
int index = rand_int(n); int index = rand_int(n);
assert(index >=0 && index < n); CV_DbgAssert(index >=0 && index < n);
centers[0] = dsindices[index]; centers[0] = dsindices[index];
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
@ -386,7 +385,6 @@ public:
throw FLANNException("Unknown algorithm for choosing initial centers."); throw FLANNException("Unknown algorithm for choosing initial centers.");
} }
trees_ = get_param(params,"trees",4);
root = new NodePtr[trees_]; root = new NodePtr[trees_];
indices = new int*[trees_]; indices = new int*[trees_];
@ -565,10 +563,10 @@ public:
NodePtr node = branch.node; NodePtr node = branch.node;
findNN(node, result, vec, checks, maxChecks, heap, checked); findNN(node, result, vec, checks, maxChecks, heap, checked);
} }
assert(result.full());
delete heap; delete heap;
CV_Assert(result.full());
} }
IndexParams getParameters() const CV_OVERRIDE IndexParams getParameters() const CV_OVERRIDE

View File

@ -34,7 +34,6 @@
//! @cond IGNORED //! @cond IGNORED
#include <cstring> #include <cstring>
#include <cassert>
#include <cmath> #include <cmath>
#include "matrix.h" #include "matrix.h"

View File

@ -35,7 +35,6 @@
#include <algorithm> #include <algorithm>
#include <map> #include <map>
#include <cassert>
#include <cstring> #include <cstring>
#include "general.h" #include "general.h"
@ -433,7 +432,7 @@ private:
if (trees_>0) { if (trees_>0) {
searchLevelExact(result, vec, tree_roots_[0], 0.0, epsError); searchLevelExact(result, vec, tree_roots_[0], 0.0, epsError);
} }
assert(result.full()); CV_Assert(result.full());
} }
/** /**
@ -462,7 +461,7 @@ private:
delete heap; delete heap;
assert(result.full()); CV_Assert(result.full());
} }

View File

@ -35,7 +35,6 @@
#include <algorithm> #include <algorithm>
#include <map> #include <map>
#include <cassert>
#include <cstring> #include <cstring>
#include "general.h" #include "general.h"
@ -214,11 +213,11 @@ public:
*/ */
void knnSearch(const Matrix<ElementType>& queries, Matrix<int>& indices, Matrix<DistanceType>& dists, int knn, const SearchParams& params) CV_OVERRIDE void knnSearch(const Matrix<ElementType>& queries, Matrix<int>& indices, Matrix<DistanceType>& dists, int knn, const SearchParams& params) CV_OVERRIDE
{ {
assert(queries.cols == veclen()); CV_Assert(queries.cols == veclen());
assert(indices.rows >= queries.rows); CV_Assert(indices.rows >= queries.rows);
assert(dists.rows >= queries.rows); CV_Assert(dists.rows >= queries.rows);
assert(int(indices.cols) >= knn); CV_Assert(int(indices.cols) >= knn);
assert(int(dists.cols) >= knn); CV_Assert(int(dists.cols) >= knn);
KNNSimpleResultSet<DistanceType> resultSet(knn); KNNSimpleResultSet<DistanceType> resultSet(knn);
for (size_t i = 0; i < queries.rows; i++) { for (size_t i = 0; i < queries.rows; i++) {

View File

@ -35,7 +35,6 @@
#include <algorithm> #include <algorithm>
#include <map> #include <map>
#include <cassert>
#include <limits> #include <limits>
#include <cmath> #include <cmath>
@ -152,7 +151,7 @@ public:
int n = indices_length; int n = indices_length;
int rnd = rand_int(n); int rnd = rand_int(n);
assert(rnd >=0 && rnd < n); CV_DbgAssert(rnd >=0 && rnd < n);
centers[0] = indices[rnd]; centers[0] = indices[rnd];
@ -207,7 +206,7 @@ public:
// Choose one random center and set the closestDistSq values // Choose one random center and set the closestDistSq values
int index = rand_int(n); int index = rand_int(n);
assert(index >=0 && index < n); CV_DbgAssert(index >=0 && index < n);
centers[0] = indices[index]; centers[0] = indices[index];
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
@ -502,9 +501,9 @@ public:
KMeansNodePtr node = branch.node; KMeansNodePtr node = branch.node;
findNN(node, result, vec, checks, maxChecks, heap); findNN(node, result, vec, checks, maxChecks, heap);
} }
assert(result.full());
delete heap; delete heap;
CV_Assert(result.full());
} }
} }
@ -663,7 +662,7 @@ private:
memset(mean,0,veclen_*sizeof(DistanceType)); memset(mean,0,veclen_*sizeof(DistanceType));
for (size_t i=0; i<(size_t)indices_length; ++i) { for (int i=0; i<indices_length; ++i) {
ElementType* vec = dataset_[indices[i]]; ElementType* vec = dataset_[indices[i]];
for (size_t j=0; j<veclen_; ++j) { for (size_t j=0; j<veclen_; ++j) {
mean[j] += vec[j]; mean[j] += vec[j];
@ -671,9 +670,9 @@ private:
variance += distance_(vec, ZeroIterator<ElementType>(), veclen_); variance += distance_(vec, ZeroIterator<ElementType>(), veclen_);
} }
for (size_t j=0; j<veclen_; ++j) { for (size_t j=0; j<veclen_; ++j) {
mean[j] /= size_; mean[j] /= indices_length;
} }
variance /= size_; variance /= indices_length;
variance -= distance_(mean, ZeroIterator<ElementType>(), veclen_); variance -= distance_(mean, ZeroIterator<ElementType>(), veclen_);
DistanceType tmp = 0; DistanceType tmp = 0;
@ -726,15 +725,6 @@ private:
} }
cv::AutoBuffer<double> dcenters_buf(branching*veclen_);
Matrix<double> dcenters(dcenters_buf.data(), branching, veclen_);
for (int i=0; i<centers_length; ++i) {
ElementType* vec = dataset_[centers_idx[i]];
for (size_t k=0; k<veclen_; ++k) {
dcenters[i][k] = double(vec[k]);
}
}
std::vector<DistanceType> radiuses(branching); std::vector<DistanceType> radiuses(branching);
cv::AutoBuffer<int> count_buf(branching); cv::AutoBuffer<int> count_buf(branching);
int* count = count_buf.data(); int* count = count_buf.data();
@ -748,10 +738,10 @@ private:
int* belongs_to = belongs_to_buf.data(); int* belongs_to = belongs_to_buf.data();
for (int i=0; i<indices_length; ++i) { for (int i=0; i<indices_length; ++i) {
DistanceType sq_dist = distance_(dataset_[indices[i]], dcenters[0], veclen_); DistanceType sq_dist = distance_(dataset_[indices[i]], dataset_[centers_idx[0]], veclen_);
belongs_to[i] = 0; belongs_to[i] = 0;
for (int j=1; j<branching; ++j) { for (int j=1; j<branching; ++j) {
DistanceType new_sq_dist = distance_(dataset_[indices[i]], dcenters[j], veclen_); DistanceType new_sq_dist = distance_(dataset_[indices[i]], dataset_[centers_idx[j]], veclen_);
if (sq_dist>new_sq_dist) { if (sq_dist>new_sq_dist) {
belongs_to[i] = j; belongs_to[i] = j;
sq_dist = new_sq_dist; sq_dist = new_sq_dist;
@ -763,6 +753,15 @@ private:
count[belongs_to[i]]++; count[belongs_to[i]]++;
} }
cv::AutoBuffer<double> dcenters_buf(branching*veclen_);
Matrix<double> dcenters(dcenters_buf.data(), branching, veclen_);
for (int i=0; i<centers_length; ++i) {
ElementType* vec = dataset_[centers_idx[i]];
for (size_t k=0; k<veclen_; ++k) {
dcenters[i][k] = double(vec[k]);
}
}
bool converged = false; bool converged = false;
int iteration = 0; int iteration = 0;
while (!converged && iteration<iterations_) { while (!converged && iteration<iterations_) {

View File

@ -38,7 +38,6 @@
//! @cond IGNORED //! @cond IGNORED
#include <algorithm> #include <algorithm>
#include <cassert>
#include <cstring> #include <cstring>
#include <map> #include <map>
#include <vector> #include <vector>
@ -53,6 +52,11 @@
#include "random.h" #include "random.h"
#include "saving.h" #include "saving.h"
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4702) //disable unreachable code
#endif
namespace cvflann namespace cvflann
{ {
@ -191,11 +195,11 @@ public:
*/ */
virtual void knnSearch(const Matrix<ElementType>& queries, Matrix<int>& indices, Matrix<DistanceType>& dists, int knn, const SearchParams& params) CV_OVERRIDE virtual void knnSearch(const Matrix<ElementType>& queries, Matrix<int>& indices, Matrix<DistanceType>& dists, int knn, const SearchParams& params) CV_OVERRIDE
{ {
assert(queries.cols == veclen()); CV_Assert(queries.cols == veclen());
assert(indices.rows >= queries.rows); CV_Assert(indices.rows >= queries.rows);
assert(dists.rows >= queries.rows); CV_Assert(dists.rows >= queries.rows);
assert(int(indices.cols) >= knn); CV_Assert(int(indices.cols) >= knn);
assert(int(dists.cols) >= knn); CV_Assert(int(dists.cols) >= knn);
KNNUniqueResultSet<DistanceType> resultSet(knn); KNNUniqueResultSet<DistanceType> resultSet(knn);
@ -391,6 +395,10 @@ private:
}; };
} }
#ifdef _MSC_VER
#pragma warning(pop)
#endif
//! @endcond //! @endcond
#endif //OPENCV_FLANN_LSH_INDEX_H_ #endif //OPENCV_FLANN_LSH_INDEX_H_

View File

@ -58,6 +58,12 @@
#include "dynamic_bitset.h" #include "dynamic_bitset.h"
#include "matrix.h" #include "matrix.h"
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4702) //disable unreachable code
#endif
namespace cvflann namespace cvflann
{ {
@ -162,8 +168,7 @@ public:
{ {
feature_size_ = feature_size; feature_size_ = feature_size;
CV_UNUSED(key_size); CV_UNUSED(key_size);
std::cerr << "LSH is not implemented for that type" << std::endl; CV_Error(cv::Error::StsUnsupportedFormat, "LSH is not implemented for that type" );
assert(0);
} }
/** Add a feature to the table /** Add a feature to the table
@ -243,8 +248,7 @@ public:
*/ */
size_t getKey(const ElementType* /*feature*/) const size_t getKey(const ElementType* /*feature*/) const
{ {
std::cerr << "LSH is not implemented for that type" << std::endl; CV_Error(cv::Error::StsUnsupportedFormat, "LSH is not implemented for that type" );
assert(0);
return 0; return 0;
} }
@ -510,6 +514,10 @@ inline LshStats LshTable<unsigned char>::getStats() const
} }
} }
#ifdef _MSC_VER
#pragma warning(pop)
#endif
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//! @endcond //! @endcond

View File

@ -69,11 +69,11 @@ public:
*/ */
virtual void knnSearch(const Matrix<ElementType>& queries, Matrix<int>& indices, Matrix<DistanceType>& dists, int knn, const SearchParams& params) virtual void knnSearch(const Matrix<ElementType>& queries, Matrix<int>& indices, Matrix<DistanceType>& dists, int knn, const SearchParams& params)
{ {
assert(queries.cols == veclen()); CV_Assert(queries.cols == veclen());
assert(indices.rows >= queries.rows); CV_Assert(indices.rows >= queries.rows);
assert(dists.rows >= queries.rows); CV_Assert(dists.rows >= queries.rows);
assert(int(indices.cols) >= knn); CV_Assert(int(indices.cols) >= knn);
assert(int(dists.cols) >= knn); CV_Assert(int(dists.cols) >= knn);
#if 0 #if 0
KNNResultSet<DistanceType> resultSet(knn); KNNResultSet<DistanceType> resultSet(knn);

View File

@ -72,7 +72,7 @@ float optimizeSimplexDownhill(T* points, int n, F func, float* vals = NULL )
{ {
const int MAX_ITERATIONS = 10; const int MAX_ITERATIONS = 10;
assert(n>0); CV_DbgAssert(n>0);
T* p_o = new T[n]; T* p_o = new T[n];
T* p_r = new T[n]; T* p_r = new T[n];

View File

@ -801,7 +801,7 @@ bool Index::load(InputArray _data, const String& filename)
loadIndex< ::cvflann::MaxDistance<float> >(this, index, data, fin); loadIndex< ::cvflann::MaxDistance<float> >(this, index, data, fin);
break; break;
case FLANN_DIST_HIST_INTERSECT: case FLANN_DIST_HIST_INTERSECT:
loadIndex< ::cvflann::HistIntersectionDistance<float> >(index, data, fin); loadIndex< ::cvflann::HistIntersectionDistance<float> >(this, index, data, fin);
break; break;
case FLANN_DIST_HELLINGER: case FLANN_DIST_HELLINGER:
loadIndex< ::cvflann::HellingerDistance<float> >(this, index, data, fin); loadIndex< ::cvflann::HellingerDistance<float> >(this, index, data, fin);

View File

@ -208,16 +208,17 @@ can be saved using this function, with these exceptions:
- PNG images with an alpha channel can be saved using this function. To do this, create - PNG images with an alpha channel can be saved using this function. To do this, create
8-bit (or 16-bit) 4-channel image BGRA, where the alpha channel goes last. Fully transparent pixels 8-bit (or 16-bit) 4-channel image BGRA, where the alpha channel goes last. Fully transparent pixels
should have alpha set to 0, fully opaque pixels should have alpha set to 255/65535 (see the code sample below). should have alpha set to 0, fully opaque pixels should have alpha set to 255/65535 (see the code sample below).
- Multiple images (vector of Mat) can be saved in TIFF format (see the code sample below).
If the format, depth or channel order is different, use If the format, depth or channel order is different, use
Mat::convertTo and cv::cvtColor to convert it before saving. Or, use the universal FileStorage I/O Mat::convertTo and cv::cvtColor to convert it before saving. Or, use the universal FileStorage I/O
functions to save the image to XML or YAML format. functions to save the image to XML or YAML format.
The sample below shows how to create a BGRA image and save it to a PNG file. It also demonstrates how to set custom The sample below shows how to create a BGRA image, how to set custom compression parameters and save it to a PNG file.
compression parameters: It also demonstrates how to save multiple images in a TIFF file:
@include snippets/imgcodecs_imwrite.cpp @include snippets/imgcodecs_imwrite.cpp
@param filename Name of the file. @param filename Name of the file.
@param img Image to be saved. @param img (Mat or vector of Mat) Image or Images to be saved.
@param params Format-specific parameters encoded as pairs (paramId_1, paramValue_1, paramId_2, paramValue_2, ... .) see cv::ImwriteFlags @param params Format-specific parameters encoded as pairs (paramId_1, paramValue_1, paramId_2, paramValue_2, ... .) see cv::ImwriteFlags
*/ */
CV_EXPORTS_W bool imwrite( const String& filename, InputArray img, CV_EXPORTS_W bool imwrite( const String& filename, InputArray img,

View File

@ -31,6 +31,7 @@ const tuple<string, Size> images[] =
#ifdef HAVE_PNG #ifdef HAVE_PNG
make_tuple<string, Size>("../cv/shared/pic1.png", Size(400, 300)), make_tuple<string, Size>("../cv/shared/pic1.png", Size(400, 300)),
#endif #endif
make_tuple<string, Size>("../highgui/readwrite/ordinary.bmp", Size(480, 272)),
}; };
TEST_P(Imgcodecs_Resize, imread_reduce_flags) TEST_P(Imgcodecs_Resize, imread_reduce_flags)

View File

@ -385,7 +385,7 @@ enum FloodFillFlags {
//! @addtogroup imgproc_shape //! @addtogroup imgproc_shape
//! @{ //! @{
//! connected components algorithm output formats //! connected components statistics
enum ConnectedComponentsTypes { enum ConnectedComponentsTypes {
CC_STAT_LEFT = 0, //!< The leftmost (x) coordinate which is the inclusive start of the bounding CC_STAT_LEFT = 0, //!< The leftmost (x) coordinate which is the inclusive start of the bounding
//!< box in the horizontal direction. //!< box in the horizontal direction.
@ -3786,9 +3786,9 @@ parallel framework is enabled and if the rows of the image are at least twice th
@param image the 8-bit single-channel image to be labeled @param image the 8-bit single-channel image to be labeled
@param labels destination labeled image @param labels destination labeled image
@param stats statistics output for each label, including the background label, see below for @param stats statistics output for each label, including the background label.
available statistics. Statistics are accessed via stats(label, COLUMN) where COLUMN is one of Statistics are accessed via stats(label, COLUMN) where COLUMN is one of
#ConnectedComponentsTypes. The data type is CV_32S. #ConnectedComponentsTypes, selecting the statistic. The data type is CV_32S.
@param centroids centroid output for each label, including the background label. Centroids are @param centroids centroid output for each label, including the background label. Centroids are
accessed via centroids(label, 0) for x and centroids(label, 1) for y. The data type CV_64F. accessed via centroids(label, 0) for x and centroids(label, 1) for y. The data type CV_64F.
@param connectivity 8 or 4 for 8-way or 4-way connectivity respectively @param connectivity 8 or 4 for 8-way or 4-way connectivity respectively
@ -3802,9 +3802,9 @@ CV_EXPORTS_AS(connectedComponentsWithStatsWithAlgorithm) int connectedComponents
/** @overload /** @overload
@param image the 8-bit single-channel image to be labeled @param image the 8-bit single-channel image to be labeled
@param labels destination labeled image @param labels destination labeled image
@param stats statistics output for each label, including the background label, see below for @param stats statistics output for each label, including the background label.
available statistics. Statistics are accessed via stats(label, COLUMN) where COLUMN is one of Statistics are accessed via stats(label, COLUMN) where COLUMN is one of
#ConnectedComponentsTypes. The data type is CV_32S. #ConnectedComponentsTypes, selecting the statistic. The data type is CV_32S.
@param centroids centroid output for each label, including the background label. Centroids are @param centroids centroid output for each label, including the background label. Centroids are
accessed via centroids(label, 0) for x and centroids(label, 1) for y. The data type CV_64F. accessed via centroids(label, 0) for x and centroids(label, 1) for y. The data type CV_64F.
@param connectivity 8 or 4 for 8-way or 4-way connectivity respectively @param connectivity 8 or 4 for 8-way or 4-way connectivity respectively

View File

@ -3,7 +3,7 @@
using namespace cv; using namespace cv;
using namespace std; using namespace std;
static void createAlphaMat(Mat &mat) static void paintAlphaMat(Mat &mat)
{ {
CV_Assert(mat.channels() == 4); CV_Assert(mat.channels() == 4);
for (int i = 0; i < mat.rows; ++i) for (int i = 0; i < mat.rows; ++i)
@ -21,9 +21,9 @@ static void createAlphaMat(Mat &mat)
int main() int main()
{ {
// Create mat with alpha channel Mat mat(480, 640, CV_8UC4); // Create a matrix with alpha channel
Mat mat(480, 640, CV_8UC4); paintAlphaMat(mat);
createAlphaMat(mat);
vector<int> compression_params; vector<int> compression_params;
compression_params.push_back(IMWRITE_PNG_COMPRESSION); compression_params.push_back(IMWRITE_PNG_COMPRESSION);
compression_params.push_back(9); compression_params.push_back(9);
@ -37,9 +37,18 @@ int main()
{ {
fprintf(stderr, "Exception converting image to PNG format: %s\n", ex.what()); fprintf(stderr, "Exception converting image to PNG format: %s\n", ex.what());
} }
if (result) if (result)
printf("Saved PNG file with alpha data.\n"); printf("Saved PNG file with alpha data.\n");
else else
printf("ERROR: Can't save PNG file.\n"); printf("ERROR: Can't save PNG file.\n");
vector<Mat> imgs;
imgs.push_back(mat);
imgs.push_back(~mat);
imgs.push_back(mat(Rect(0, 0, mat.cols / 2, mat.rows / 2)));
imwrite("test.tiff", imgs);
printf("Multiple files saved in test.tiff\n");
return result ? 0 : 1; return result ? 0 : 1;
} }