mirror of
https://github.com/opencv/opencv.git
synced 2026-07-22 11:53:04 +04:00
Compare commits
100 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1eb1d4c370 | |||
| d9a5603fa3 | |||
| 29388f80a5 | |||
| d4f81c6d24 | |||
| 3b264d5877 | |||
| b7947d861c | |||
| fe93724d3f | |||
| 65b957a5b3 | |||
| 9eaa7bd566 | |||
| c97c22b7cf | |||
| 805946baaf | |||
| ddcbd2cc26 | |||
| 67fd2d02ef | |||
| e625b32841 | |||
| dc37883702 | |||
| e1ce2146f5 | |||
| 84457a5dcd | |||
| 66f86e898c | |||
| d1b158b9dd | |||
| 749935866d | |||
| cbda161c39 | |||
| 65487946cc | |||
| e09684647a | |||
| 98d678c2d2 | |||
| d00a96315e | |||
| 3f3c821800 | |||
| 53b678d5cf | |||
| ae8c90301f | |||
| 4eec739624 | |||
| be84824530 | |||
| 05084aa63e | |||
| 685a47b2e2 | |||
| 658f18c713 | |||
| d19a05734e | |||
| 38e35d5137 | |||
| fd8b346c3e | |||
| 4c2584d729 | |||
| 72c715ff4f | |||
| bac7180e02 | |||
| b34fc422a2 | |||
| 20eee64426 | |||
| 85a04185d3 | |||
| 57460b1e30 | |||
| 26ca124150 | |||
| 1c6c3dfa8d | |||
| 83a49b4f6a | |||
| 36a03dbdbf | |||
| 1af790ecc3 | |||
| 8c64adb000 | |||
| 6ffe686ba8 | |||
| a94cd6d6e8 | |||
| ea7efd57d8 | |||
| c9e42c5050 | |||
| 6033599c88 | |||
| a924bbfc30 | |||
| 0d2f21b51e | |||
| 5c5ef9746c | |||
| 42793e16dd | |||
| 8483f2ef2f | |||
| 94b3bad3c9 | |||
| 2e927c2dbd | |||
| 69fd82fc46 | |||
| 68e2df56e7 | |||
| 56a4877e30 | |||
| b204c39815 | |||
| 9f2182abbb | |||
| 7ea6b356c7 | |||
| 8ad8ec679f | |||
| fe59a5695f | |||
| 2ab7b7c09e | |||
| 6b5be4f1a7 | |||
| a87b9fb4b6 | |||
| 56102737d7 | |||
| c280cd7290 | |||
| 0981814473 | |||
| 3d635cb4a7 | |||
| cb2052dbfe | |||
| 400572b19f | |||
| deaf632881 | |||
| c67d4fc633 | |||
| bd9d60c4c6 | |||
| bf29a4d746 | |||
| 4009bca59a | |||
| b71a168937 | |||
| 17e860a288 | |||
| e200b88a5a | |||
| 1833b034fe | |||
| 69020666fe | |||
| 53144ee0eb | |||
| c664cf3717 | |||
| f3a03aefad | |||
| 6a7d54f550 | |||
| 974102bc7f | |||
| 5bacd8753b | |||
| cbc9745b79 | |||
| e0aa677388 | |||
| a64b51dd94 | |||
| 7b7774476e | |||
| 54449b614b | |||
| eab7faf536 |
Vendored
+5
-5
@@ -1,8 +1,8 @@
|
||||
# Binaries branch name: ffmpeg/3.4_20211220
|
||||
# Binaries were created for OpenCV: a22dd28e0272ec0f1cfee8811d3f5f0392827c65
|
||||
ocv_update(FFMPEG_BINARIES_COMMIT "5a7644ec3940c6eed41c6ebb5a0602a5615fdb3f")
|
||||
ocv_update(FFMPEG_FILE_HASH_BIN32 "8ad9de6f1f2ca77786748d1f3a4e83ea")
|
||||
ocv_update(FFMPEG_FILE_HASH_BIN64 "2c670f068252e7cd28d3883993dc1d6e")
|
||||
# Binaries branch name: 3.4_20230620
|
||||
# Binaries were created for OpenCV: c97c22b7cf2ef0f82cd4203a2e9a6eda94e9f7f1
|
||||
ocv_update(FFMPEG_BINARIES_COMMIT "7c4bb90fd43a13732ae907981a88fb983a7e2197")
|
||||
ocv_update(FFMPEG_FILE_HASH_BIN32 "d7db86de29b0460294489c5ed3180b56")
|
||||
ocv_update(FFMPEG_FILE_HASH_BIN64 "9df93d8afff2eee368ad484098a12b18")
|
||||
ocv_update(FFMPEG_FILE_HASH_CMAKE "3b90f67f4b429e77d3da36698cef700c")
|
||||
|
||||
function(download_win_ffmpeg script_var)
|
||||
|
||||
Vendored
+11
-11
@@ -2,32 +2,32 @@ function(download_ippicv root_var)
|
||||
set(${root_var} "" PARENT_SCOPE)
|
||||
|
||||
# Commit SHA in the opencv_3rdparty repo
|
||||
set(IPPICV_COMMIT "a56b6ac6f030c312b2dce17430eef13aed9af274")
|
||||
set(IPPICV_COMMIT "1224f78da6684df04397ac0f40c961ed37f79ccb")
|
||||
# Define actual ICV versions
|
||||
if(APPLE)
|
||||
set(OPENCV_ICV_PLATFORM "macosx")
|
||||
set(OPENCV_ICV_PACKAGE_SUBDIR "ippicv_mac")
|
||||
set(OPENCV_ICV_NAME "ippicv_2020_mac_intel64_20191018_general.tgz")
|
||||
set(OPENCV_ICV_HASH "1c3d675c2a2395d094d523024896e01b")
|
||||
set(OPENCV_ICV_NAME "ippicv_2021.8_mac_intel64_20230330_general.tgz")
|
||||
set(OPENCV_ICV_HASH "d2b234a86af1b616958619a4560356d9")
|
||||
elseif((UNIX AND NOT ANDROID) OR (UNIX AND ANDROID_ABI MATCHES "x86"))
|
||||
set(OPENCV_ICV_PLATFORM "linux")
|
||||
set(OPENCV_ICV_PACKAGE_SUBDIR "ippicv_lnx")
|
||||
if(X86_64)
|
||||
set(OPENCV_ICV_NAME "ippicv_2020_lnx_intel64_20191018_general.tgz")
|
||||
set(OPENCV_ICV_HASH "7421de0095c7a39162ae13a6098782f9")
|
||||
set(OPENCV_ICV_NAME "ippicv_2021.8_lnx_intel64_20230330_general.tgz")
|
||||
set(OPENCV_ICV_HASH "43219bdc7e3805adcbe3a1e2f1f3ef3b")
|
||||
else()
|
||||
set(OPENCV_ICV_NAME "ippicv_2020_lnx_ia32_20191018_general.tgz")
|
||||
set(OPENCV_ICV_HASH "ad189a940fb60eb71f291321322fe3e8")
|
||||
set(OPENCV_ICV_NAME "ippicv_2021.8_lnx_ia32_20230330_general.tgz")
|
||||
set(OPENCV_ICV_HASH "165875443d72faa3fd2146869da90d07")
|
||||
endif()
|
||||
elseif(WIN32 AND NOT ARM)
|
||||
set(OPENCV_ICV_PLATFORM "windows")
|
||||
set(OPENCV_ICV_PACKAGE_SUBDIR "ippicv_win")
|
||||
if(X86_64)
|
||||
set(OPENCV_ICV_NAME "ippicv_2020_win_intel64_20191018_general.zip")
|
||||
set(OPENCV_ICV_HASH "879741a7946b814455eee6c6ffde2984")
|
||||
set(OPENCV_ICV_NAME "ippicv_2021.8_win_intel64_20230330_general.zip")
|
||||
set(OPENCV_ICV_HASH "71e4f58de939f0348ec7fb58ffb17dbf")
|
||||
else()
|
||||
set(OPENCV_ICV_NAME "ippicv_2020_win_ia32_20191018_general.zip")
|
||||
set(OPENCV_ICV_HASH "cd39bdf0c2e1cac9a61101dad7a2413e")
|
||||
set(OPENCV_ICV_NAME "ippicv_2021.8_win_ia32_20230330_general.zip")
|
||||
set(OPENCV_ICV_HASH "57fd4648cfe64eae9e2ad9d50173a553")
|
||||
endif()
|
||||
else()
|
||||
return()
|
||||
|
||||
Vendored
+5
@@ -66,6 +66,11 @@ if(PPC64LE OR PPC64)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(APPLE AND CV_CLANG AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13.1)
|
||||
ocv_warnings_disable(CMAKE_C_FLAGS -Wnull-pointer-subtraction)
|
||||
ocv_warnings_disable(CMAKE_C_FLAGS -Wunused-but-set-variable)
|
||||
endif()
|
||||
|
||||
# ----------------------------------------------------------------------------------
|
||||
# Define the library target:
|
||||
# ----------------------------------------------------------------------------------
|
||||
|
||||
Vendored
+1
-1
@@ -170,4 +170,4 @@ ocv_install_target(tbb EXPORT OpenCVModules
|
||||
|
||||
ocv_install_3rdparty_licenses(tbb "${tbb_src_dir}/LICENSE" "${tbb_src_dir}/README")
|
||||
|
||||
ocv_tbb_read_version("${tbb_src_dir}/include")
|
||||
ocv_tbb_read_version("${tbb_src_dir}/include" tbb)
|
||||
|
||||
@@ -11,9 +11,9 @@ Copyright (C) 2000-2022, Intel Corporation, all rights reserved.
|
||||
Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved.
|
||||
Copyright (C) 2009-2016, NVIDIA Corporation, all rights reserved.
|
||||
Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved.
|
||||
Copyright (C) 2015-2022, OpenCV Foundation, all rights reserved.
|
||||
Copyright (C) 2015-2023, OpenCV Foundation, all rights reserved.
|
||||
Copyright (C) 2015-2016, Itseez Inc., all rights reserved.
|
||||
Copyright (C) 2019-2022, Xperience AI, all rights reserved.
|
||||
Copyright (C) 2019-2023, Xperience AI, all rights reserved.
|
||||
Third party copyrights are property of their respective owners.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
|
||||
@@ -70,7 +70,7 @@ using namespace cv;
|
||||
|
||||
static int icvMkDir( const char* filename )
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
char path[PATH_MAX+1];
|
||||
char* p;
|
||||
int pos;
|
||||
|
||||
@@ -83,7 +83,8 @@ static int icvMkDir( const char* filename )
|
||||
mode = 0755;
|
||||
#endif /* _WIN32 */
|
||||
|
||||
strcpy( path, filename );
|
||||
path[0] = '\0';
|
||||
strncat( path, filename, PATH_MAX );
|
||||
|
||||
p = path;
|
||||
for( ; ; )
|
||||
|
||||
@@ -54,7 +54,7 @@ bool CvCascadeImageReader::NegReader::nextImg()
|
||||
size_t count = imgFilenames.size();
|
||||
for( size_t i = 0; i < count; i++ )
|
||||
{
|
||||
src = imread( imgFilenames[last++], 0 );
|
||||
src = imread( imgFilenames[last++], IMREAD_GRAYSCALE );
|
||||
if( src.empty() ){
|
||||
last %= count;
|
||||
continue;
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
# - "tbb" target exists and added to OPENCV_LINKER_LIBS
|
||||
|
||||
function(ocv_tbb_cmake_guess _found)
|
||||
find_package(TBB QUIET COMPONENTS tbb PATHS "$ENV{TBBROOT}/cmake")
|
||||
find_package(TBB QUIET COMPONENTS tbb PATHS "$ENV{TBBROOT}/cmake" "$ENV{TBBROOT}/lib/cmake/tbb")
|
||||
if(TBB_FOUND)
|
||||
if(NOT TARGET TBB::tbb)
|
||||
message(WARNING "No TBB::tbb target found!")
|
||||
@@ -28,11 +28,11 @@ function(ocv_tbb_cmake_guess _found)
|
||||
get_target_property(_lib TBB::tbb IMPORTED_LOCATION_RELEASE)
|
||||
message(STATUS "Found TBB (cmake): ${_lib}")
|
||||
get_target_property(_inc TBB::tbb INTERFACE_INCLUDE_DIRECTORIES)
|
||||
ocv_tbb_read_version("${_inc}")
|
||||
add_library(tbb INTERFACE IMPORTED)
|
||||
set_target_properties(tbb PROPERTIES
|
||||
INTERFACE_LINK_LIBRARIES TBB::tbb
|
||||
)
|
||||
ocv_tbb_read_version("${_inc}" tbb)
|
||||
set(${_found} TRUE PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
@@ -66,7 +66,6 @@ function(ocv_tbb_env_guess _found)
|
||||
find_library(TBB_ENV_LIB_DEBUG NAMES "tbb_debug")
|
||||
if (TBB_ENV_INCLUDE AND (TBB_ENV_LIB OR TBB_ENV_LIB_DEBUG))
|
||||
ocv_tbb_env_verify()
|
||||
ocv_tbb_read_version("${TBB_ENV_INCLUDE}")
|
||||
add_library(tbb UNKNOWN IMPORTED)
|
||||
set_target_properties(tbb PROPERTIES
|
||||
IMPORTED_LOCATION "${TBB_ENV_LIB}"
|
||||
@@ -82,12 +81,14 @@ function(ocv_tbb_env_guess _found)
|
||||
get_filename_component(_dir "${TBB_ENV_LIB}" DIRECTORY)
|
||||
set_target_properties(tbb PROPERTIES INTERFACE_LINK_LIBRARIES "-L${_dir}")
|
||||
endif()
|
||||
ocv_tbb_read_version("${TBB_ENV_INCLUDE}" tbb)
|
||||
message(STATUS "Found TBB (env): ${TBB_ENV_LIB}")
|
||||
set(${_found} TRUE PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(ocv_tbb_read_version _path)
|
||||
function(ocv_tbb_read_version _path _tgt)
|
||||
find_file(TBB_VER_FILE oneapi/tbb/version.h "${_path}" NO_DEFAULT_PATH CMAKE_FIND_ROOT_PATH_BOTH)
|
||||
find_file(TBB_VER_FILE tbb/tbb_stddef.h "${_path}" NO_DEFAULT_PATH CMAKE_FIND_ROOT_PATH_BOTH)
|
||||
ocv_parse_header("${TBB_VER_FILE}" TBB_VERSION_LINES TBB_VERSION_MAJOR TBB_VERSION_MINOR TBB_INTERFACE_VERSION CACHE)
|
||||
endfunction()
|
||||
|
||||
@@ -118,16 +118,10 @@ if(MKL_USE_SINGLE_DYNAMIC_LIBRARY AND NOT (MKL_VERSION_STR VERSION_LESS "10.3.0"
|
||||
|
||||
elseif(NOT (MKL_VERSION_STR VERSION_LESS "11.3.0"))
|
||||
|
||||
foreach(MKL_ARCH ${MKL_ARCH_LIST})
|
||||
list(APPEND mkl_lib_find_paths
|
||||
${MKL_ROOT_DIR}/../tbb/lib/${MKL_ARCH}
|
||||
)
|
||||
endforeach()
|
||||
|
||||
set(mkl_lib_list "mkl_intel_${MKL_ARCH_SUFFIX}")
|
||||
|
||||
if(MKL_WITH_TBB)
|
||||
list(APPEND mkl_lib_list mkl_tbb_thread tbb)
|
||||
list(APPEND mkl_lib_list mkl_tbb_thread)
|
||||
elseif(MKL_WITH_OPENMP)
|
||||
if(MSVC)
|
||||
list(APPEND mkl_lib_list mkl_intel_thread libiomp5md)
|
||||
@@ -155,6 +149,7 @@ if(NOT MKL_LIBRARIES)
|
||||
endif()
|
||||
list(APPEND MKL_LIBRARIES ${${lib_var_name}})
|
||||
endforeach()
|
||||
list(APPEND MKL_LIBRARIES ${OPENCV_EXTRA_MKL_LIBRARIES})
|
||||
endif()
|
||||
|
||||
message(STATUS "Found MKL ${MKL_VERSION_STR} at: ${MKL_ROOT_DIR}")
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
<script src="utils.js" type="text/javascript"></script>
|
||||
<script id="codeSnippet" type="text/code-snippet">
|
||||
let src = cv.imread('canvasInput');
|
||||
let dst = cv.Mat.zeros(src.cols, src.rows, cv.CV_8UC3);
|
||||
let dst = cv.Mat.zeros(src.rows, src.cols, cv.CV_8UC3);
|
||||
cv.cvtColor(src, src, cv.COLOR_RGBA2GRAY, 0);
|
||||
cv.threshold(src, src, 120, 200, cv.THRESH_BINARY);
|
||||
let contours = new cv.MatVector();
|
||||
|
||||
@@ -147,7 +147,7 @@ if (dataset === 'COCO') {
|
||||
["Neck", "LShoulder"], ["RShoulder", "RElbow"],
|
||||
["RElbow", "RWrist"], ["LShoulder", "LElbow"],
|
||||
["LElbow", "LWrist"], ["Nose", "REye"],
|
||||
["REye", "REar"], ["Neck", "LEye"],
|
||||
["REye", "REar"], ["Nose", "LEye"],
|
||||
["LEye", "LEar"], ["Neck", "MidHip"],
|
||||
["MidHip", "RHip"], ["RHip", "RKnee"],
|
||||
["RKnee", "RAnkle"], ["RAnkle", "RBigToe"],
|
||||
|
||||
@@ -1314,3 +1314,10 @@
|
||||
journal = {IEEE transactions on pattern analysis and machine intelligence},
|
||||
doi = {10.1109/TPAMI.2006.153}
|
||||
}
|
||||
@article{Buades2005DenoisingIS,
|
||||
title={Denoising image sequences does not require motion estimation},
|
||||
author={Antoni Buades and Bartomeu Coll and Jean-Michel Morel},
|
||||
journal={IEEE Conference on Advanced Video and Signal Based Surveillance, 2005.},
|
||||
year={2005},
|
||||
pages={70-74}
|
||||
}
|
||||
|
||||
@@ -41,8 +41,8 @@ import numpy as np
|
||||
import cv2 as cv
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
imgL = cv.imread('tsukuba_l.png',0)
|
||||
imgR = cv.imread('tsukuba_r.png',0)
|
||||
imgL = cv.imread('tsukuba_l.png', cv.IMREAD_GRAYSCALE)
|
||||
imgR = cv.imread('tsukuba_r.png', cv.IMREAD_GRAYSCALE)
|
||||
|
||||
stereo = cv.StereoBM_create(numDisparities=16, blockSize=15)
|
||||
disparity = stereo.compute(imgL,imgR)
|
||||
|
||||
@@ -76,8 +76,8 @@ import numpy as np
|
||||
import cv2 as cv
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
img1 = cv.imread('myleft.jpg',0) #queryimage # left image
|
||||
img2 = cv.imread('myright.jpg',0) #trainimage # right image
|
||||
img1 = cv.imread('myleft.jpg', cv.IMREAD_GRAYSCALE) #queryimage # left image
|
||||
img2 = cv.imread('myright.jpg', cv.IMREAD_GRAYSCALE) #trainimage # right image
|
||||
|
||||
sift = cv.SIFT_create()
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ Let's load a color image first:
|
||||
>>> import cv2 as cv
|
||||
|
||||
>>> img = cv.imread('messi5.jpg')
|
||||
>>> assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
@endcode
|
||||
You can access a pixel value by its row and column coordinates. For BGR image, it returns an array
|
||||
of Blue, Green, Red values. For grayscale image, just corresponding intensity is returned.
|
||||
@@ -173,6 +174,7 @@ from matplotlib import pyplot as plt
|
||||
BLUE = [255,0,0]
|
||||
|
||||
img1 = cv.imread('opencv-logo.png')
|
||||
assert img1 is not None, "file could not be read, check with os.path.exists()"
|
||||
|
||||
replicate = cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_REPLICATE)
|
||||
reflect = cv.copyMakeBorder(img1,10,10,10,10,cv.BORDER_REFLECT)
|
||||
|
||||
@@ -50,6 +50,8 @@ Here \f$\gamma\f$ is taken as zero.
|
||||
@code{.py}
|
||||
img1 = cv.imread('ml.png')
|
||||
img2 = cv.imread('opencv-logo.png')
|
||||
assert img1 is not None, "file could not be read, check with os.path.exists()"
|
||||
assert img2 is not None, "file could not be read, check with os.path.exists()"
|
||||
|
||||
dst = cv.addWeighted(img1,0.7,img2,0.3,0)
|
||||
|
||||
@@ -76,6 +78,8 @@ bitwise operations as shown below:
|
||||
# Load two images
|
||||
img1 = cv.imread('messi5.jpg')
|
||||
img2 = cv.imread('opencv-logo-white.png')
|
||||
assert img1 is not None, "file could not be read, check with os.path.exists()"
|
||||
assert img2 is not None, "file could not be read, check with os.path.exists()"
|
||||
|
||||
# I want to put logo on top-left corner, So I create a ROI
|
||||
rows,cols,channels = img2.shape
|
||||
|
||||
@@ -37,6 +37,7 @@ of odd sizes ranging from 5 to 49. (Don't worry about what the result will look
|
||||
goal):
|
||||
@code{.py}
|
||||
img1 = cv.imread('messi5.jpg')
|
||||
assert img1 is not None, "file could not be read, check with os.path.exists()"
|
||||
|
||||
e1 = cv.getTickCount()
|
||||
for i in range(5,49,2):
|
||||
|
||||
@@ -63,7 +63,7 @@ import numpy as np
|
||||
import cv2 as cv
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
img = cv.imread('simple.jpg',0)
|
||||
img = cv.imread('simple.jpg', cv.IMREAD_GRAYSCALE)
|
||||
|
||||
# Initiate FAST detector
|
||||
star = cv.xfeatures2d.StarDetector_create()
|
||||
|
||||
@@ -98,7 +98,7 @@ import numpy as np
|
||||
import cv2 as cv
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
img = cv.imread('blox.jpg',0) # `<opencv_root>/samples/data/blox.jpg`
|
||||
img = cv.imread('blox.jpg', cv.IMREAD_GRAYSCALE) # `<opencv_root>/samples/data/blox.jpg`
|
||||
|
||||
# Initiate FAST object with default values
|
||||
fast = cv.FastFeatureDetector_create()
|
||||
|
||||
@@ -40,8 +40,8 @@ from matplotlib import pyplot as plt
|
||||
|
||||
MIN_MATCH_COUNT = 10
|
||||
|
||||
img1 = cv.imread('box.png',0) # queryImage
|
||||
img2 = cv.imread('box_in_scene.png',0) # trainImage
|
||||
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()
|
||||
|
||||
@@ -67,7 +67,7 @@ import numpy as np
|
||||
import cv2 as cv
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
img = cv.imread('simple.jpg',0)
|
||||
img = cv.imread('simple.jpg', cv.IMREAD_GRAYSCALE)
|
||||
|
||||
# Initiate ORB detector
|
||||
orb = cv.ORB_create()
|
||||
|
||||
@@ -76,7 +76,7 @@ and descriptors.
|
||||
First we will see a simple demo on how to find SURF keypoints and descriptors and draw it. All
|
||||
examples are shown in Python terminal since it is just same as SIFT only.
|
||||
@code{.py}
|
||||
>>> img = cv.imread('fly.png',0)
|
||||
>>> img = cv.imread('fly.png', cv.IMREAD_GRAYSCALE)
|
||||
|
||||
# Create SURF object. You can specify params here or later.
|
||||
# Here I set Hessian Threshold to 400
|
||||
|
||||
@@ -83,7 +83,8 @@ import numpy as np
|
||||
import cv2 as cv
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
img = cv.imread('messi5.jpg',0)
|
||||
img = cv.imread('messi5.jpg', cv.IMREAD_GRAYSCALE)
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
edges = cv.Canny(img,100,200)
|
||||
|
||||
plt.subplot(121),plt.imshow(img,cmap = 'gray')
|
||||
|
||||
+2
-1
@@ -24,7 +24,8 @@ The function **cv.moments()** gives a dictionary of all moment values calculated
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
|
||||
img = cv.imread('star.jpg',0)
|
||||
img = cv.imread('star.jpg', cv.IMREAD_GRAYSCALE)
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
ret,thresh = cv.threshold(img,127,255,0)
|
||||
im2,contours,hierarchy = cv.findContours(thresh, 1, 2)
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import numpy as np
|
||||
import cv2 as cv
|
||||
|
||||
im = cv.imread('test.jpg')
|
||||
assert im is not None, "file could not be read, check with os.path.exists()"
|
||||
imgray = cv.cvtColor(im, cv.COLOR_BGR2GRAY)
|
||||
ret, thresh = cv.threshold(imgray, 127, 255, 0)
|
||||
im2, contours, hierarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
|
||||
|
||||
+5
-2
@@ -41,6 +41,7 @@ import cv2 as cv
|
||||
import numpy as np
|
||||
|
||||
img = cv.imread('star.jpg')
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
img_gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
|
||||
ret,thresh = cv.threshold(img_gray, 127, 255,0)
|
||||
im2,contours,hierarchy = cv.findContours(thresh,2,1)
|
||||
@@ -92,8 +93,10 @@ docs.
|
||||
import cv2 as cv
|
||||
import numpy as np
|
||||
|
||||
img1 = cv.imread('star.jpg',0)
|
||||
img2 = cv.imread('star2.jpg',0)
|
||||
img1 = cv.imread('star.jpg', cv.IMREAD_GRAYSCALE)
|
||||
img2 = cv.imread('star2.jpg', cv.IMREAD_GRAYSCALE)
|
||||
assert img1 is not None, "file could not be read, check with os.path.exists()"
|
||||
assert img2 is not None, "file could not be read, check with os.path.exists()"
|
||||
|
||||
ret, thresh = cv.threshold(img1, 127, 255,0)
|
||||
ret, thresh2 = cv.threshold(img2, 127, 255,0)
|
||||
|
||||
@@ -29,6 +29,7 @@ import cv2 as cv
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
img = cv.imread('opencv_logo.png')
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
|
||||
kernel = np.ones((5,5),np.float32)/25
|
||||
dst = cv.filter2D(img,-1,kernel)
|
||||
@@ -70,6 +71,7 @@ import numpy as np
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
img = cv.imread('opencv-logo-white.png')
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
|
||||
blur = cv.blur(img,(5,5))
|
||||
|
||||
|
||||
+7
-2
@@ -28,6 +28,7 @@ import numpy as np
|
||||
import cv2 as cv
|
||||
|
||||
img = cv.imread('messi5.jpg')
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
|
||||
res = cv.resize(img,None,fx=2, fy=2, interpolation = cv.INTER_CUBIC)
|
||||
|
||||
@@ -49,7 +50,8 @@ function. See the below example for a shift of (100,50):
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
|
||||
img = cv.imread('messi5.jpg',0)
|
||||
img = cv.imread('messi5.jpg', cv.IMREAD_GRAYSCALE)
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
rows,cols = img.shape
|
||||
|
||||
M = np.float32([[1,0,100],[0,1,50]])
|
||||
@@ -87,7 +89,8 @@ where:
|
||||
To find this transformation matrix, OpenCV provides a function, **cv.getRotationMatrix2D**. Check out the
|
||||
below example which rotates the image by 90 degree with respect to center without any scaling.
|
||||
@code{.py}
|
||||
img = cv.imread('messi5.jpg',0)
|
||||
img = cv.imread('messi5.jpg', cv.IMREAD_GRAYSCALE)
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
rows,cols = img.shape
|
||||
|
||||
# cols-1 and rows-1 are the coordinate limits.
|
||||
@@ -108,6 +111,7 @@ which is to be passed to **cv.warpAffine**.
|
||||
Check the below example, and also look at the points I selected (which are marked in green color):
|
||||
@code{.py}
|
||||
img = cv.imread('drawing.png')
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
rows,cols,ch = img.shape
|
||||
|
||||
pts1 = np.float32([[50,50],[200,50],[50,200]])
|
||||
@@ -137,6 +141,7 @@ matrix.
|
||||
See the code below:
|
||||
@code{.py}
|
||||
img = cv.imread('sudoku.png')
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
rows,cols,ch = img.shape
|
||||
|
||||
pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
|
||||
|
||||
@@ -93,6 +93,7 @@ import cv2 as cv
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
img = cv.imread('messi5.jpg')
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
mask = np.zeros(img.shape[:2],np.uint8)
|
||||
|
||||
bgdModel = np.zeros((1,65),np.float64)
|
||||
@@ -122,7 +123,8 @@ remaining background with gray. Then loaded that mask image in OpenCV, edited or
|
||||
got with corresponding values in newly added mask image. Check the code below:*
|
||||
@code{.py}
|
||||
# newmask is the mask image I manually labelled
|
||||
newmask = cv.imread('newmask.png',0)
|
||||
newmask = cv.imread('newmask.png', cv.IMREAD_GRAYSCALE)
|
||||
assert newmask is not None, "file could not be read, check with os.path.exists()"
|
||||
|
||||
# wherever it is marked white (sure foreground), change mask=1
|
||||
# wherever it is marked black (sure background), change mask=0
|
||||
|
||||
@@ -42,7 +42,8 @@ import numpy as np
|
||||
import cv2 as cv
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
img = cv.imread('dave.jpg',0)
|
||||
img = cv.imread('dave.jpg', cv.IMREAD_GRAYSCALE)
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
|
||||
laplacian = cv.Laplacian(img,cv.CV_64F)
|
||||
sobelx = cv.Sobel(img,cv.CV_64F,1,0,ksize=5)
|
||||
@@ -79,7 +80,8 @@ import numpy as np
|
||||
import cv2 as cv
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
img = cv.imread('box.png',0)
|
||||
img = cv.imread('box.png', cv.IMREAD_GRAYSCALE)
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
|
||||
# Output dtype = cv.CV_8U
|
||||
sobelx8u = cv.Sobel(img,cv.CV_8U,1,0,ksize=5)
|
||||
|
||||
@@ -38,6 +38,7 @@ import numpy as np
|
||||
import cv2 as cv
|
||||
|
||||
img = cv.imread('home.jpg')
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
hsv = cv.cvtColor(img,cv.COLOR_BGR2HSV)
|
||||
|
||||
hist = cv.calcHist([hsv], [0, 1], None, [180, 256], [0, 180, 0, 256])
|
||||
@@ -55,6 +56,7 @@ import cv2 as cv
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
img = cv.imread('home.jpg')
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
hsv = cv.cvtColor(img,cv.COLOR_BGR2HSV)
|
||||
|
||||
hist, xbins, ybins = np.histogram2d(h.ravel(),s.ravel(),[180,256],[[0,180],[0,256]])
|
||||
@@ -89,6 +91,7 @@ import cv2 as cv
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
img = cv.imread('home.jpg')
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
hsv = cv.cvtColor(img,cv.COLOR_BGR2HSV)
|
||||
hist = cv.calcHist( [hsv], [0, 1], None, [180, 256], [0, 180, 0, 256] )
|
||||
|
||||
|
||||
+4
@@ -38,10 +38,12 @@ import cv2 as cvfrom matplotlib import pyplot as plt
|
||||
|
||||
#roi is the object or region of object we need to find
|
||||
roi = cv.imread('rose_red.png')
|
||||
assert roi is not None, "file could not be read, check with os.path.exists()"
|
||||
hsv = cv.cvtColor(roi,cv.COLOR_BGR2HSV)
|
||||
|
||||
#target is the image we search in
|
||||
target = cv.imread('rose.png')
|
||||
assert target is not None, "file could not be read, check with os.path.exists()"
|
||||
hsvt = cv.cvtColor(target,cv.COLOR_BGR2HSV)
|
||||
|
||||
# Find the histograms using calcHist. Can be done with np.histogram2d also
|
||||
@@ -85,9 +87,11 @@ import numpy as np
|
||||
import cv2 as cv
|
||||
|
||||
roi = cv.imread('rose_red.png')
|
||||
assert roi is not None, "file could not be read, check with os.path.exists()"
|
||||
hsv = cv.cvtColor(roi,cv.COLOR_BGR2HSV)
|
||||
|
||||
target = cv.imread('rose.png')
|
||||
assert target is not None, "file could not be read, check with os.path.exists()"
|
||||
hsvt = cv.cvtColor(target,cv.COLOR_BGR2HSV)
|
||||
|
||||
# calculating object histogram
|
||||
|
||||
+7
-3
@@ -77,7 +77,8 @@ and its parameters :
|
||||
So let's start with a sample image. Simply load an image in grayscale mode and find its full
|
||||
histogram.
|
||||
@code{.py}
|
||||
img = cv.imread('home.jpg',0)
|
||||
img = cv.imread('home.jpg', cv.IMREAD_GRAYSCALE)
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
hist = cv.calcHist([img],[0],None,[256],[0,256])
|
||||
@endcode
|
||||
hist is a 256x1 array, each value corresponds to number of pixels in that image with its
|
||||
@@ -121,7 +122,8 @@ import numpy as np
|
||||
import cv2 as cv
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
img = cv.imread('home.jpg',0)
|
||||
img = cv.imread('home.jpg', cv.IMREAD_GRAYSCALE)
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
plt.hist(img.ravel(),256,[0,256]); plt.show()
|
||||
@endcode
|
||||
You will get a plot as below :
|
||||
@@ -136,6 +138,7 @@ import cv2 as cv
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
img = cv.imread('home.jpg')
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
color = ('b','g','r')
|
||||
for i,col in enumerate(color):
|
||||
histr = cv.calcHist([img],[i],None,[256],[0,256])
|
||||
@@ -164,7 +167,8 @@ We used cv.calcHist() to find the histogram of the full image. What if you want
|
||||
of some regions of an image? Just create a mask image with white color on the region you want to
|
||||
find histogram and black otherwise. Then pass this as the mask.
|
||||
@code{.py}
|
||||
img = cv.imread('home.jpg',0)
|
||||
img = cv.imread('home.jpg', cv.IMREAD_GRAYSCALE)
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
|
||||
# create a mask
|
||||
mask = np.zeros(img.shape[:2], np.uint8)
|
||||
|
||||
+6
-3
@@ -30,7 +30,8 @@ import numpy as np
|
||||
import cv2 as cv
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
img = cv.imread('wiki.jpg',0)
|
||||
img = cv.imread('wiki.jpg', cv.IMREAD_GRAYSCALE)
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
|
||||
hist,bins = np.histogram(img.flatten(),256,[0,256])
|
||||
|
||||
@@ -81,7 +82,8 @@ output is our histogram equalized image.
|
||||
|
||||
Below is a simple code snippet showing its usage for same image we used :
|
||||
@code{.py}
|
||||
img = cv.imread('wiki.jpg',0)
|
||||
img = cv.imread('wiki.jpg', cv.IMREAD_GRAYSCALE)
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
equ = cv.equalizeHist(img)
|
||||
res = np.hstack((img,equ)) #stacking images side-by-side
|
||||
cv.imwrite('res.png',res)
|
||||
@@ -124,7 +126,8 @@ Below code snippet shows how to apply CLAHE in OpenCV:
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
|
||||
img = cv.imread('tsukuba_l.png',0)
|
||||
img = cv.imread('tsukuba_l.png', cv.IMREAD_GRAYSCALE)
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
|
||||
# create a CLAHE object (Arguments are optional).
|
||||
clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
|
||||
|
||||
@@ -23,7 +23,8 @@ explained in the documentation. So we directly go to the code.
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
|
||||
img = cv.imread('opencv-logo-white.png',0)
|
||||
img = cv.imread('opencv-logo-white.png', cv.IMREAD_GRAYSCALE)
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
img = cv.medianBlur(img,5)
|
||||
cimg = cv.cvtColor(img,cv.COLOR_GRAY2BGR)
|
||||
|
||||
|
||||
@@ -38,7 +38,8 @@ Here, as an example, I would use a 5x5 kernel with full of ones. Let's see it ho
|
||||
import cv2 as cv
|
||||
import numpy as np
|
||||
|
||||
img = cv.imread('j.png',0)
|
||||
img = cv.imread('j.png', cv.IMREAD_GRAYSCALE)
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
kernel = np.ones((5,5),np.uint8)
|
||||
erosion = cv.erode(img,kernel,iterations = 1)
|
||||
@endcode
|
||||
|
||||
@@ -31,6 +31,7 @@ Similarly while expanding, area becomes 4 times in each level. We can find Gauss
|
||||
**cv.pyrDown()** and **cv.pyrUp()** functions.
|
||||
@code{.py}
|
||||
img = cv.imread('messi5.jpg')
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
lower_reso = cv.pyrDown(higher_reso)
|
||||
@endcode
|
||||
Below is the 4 levels in an image pyramid.
|
||||
@@ -84,6 +85,8 @@ import numpy as np,sys
|
||||
|
||||
A = cv.imread('apple.jpg')
|
||||
B = cv.imread('orange.jpg')
|
||||
assert A is not None, "file could not be read, check with os.path.exists()"
|
||||
assert B is not None, "file could not be read, check with os.path.exists()"
|
||||
|
||||
# generate Gaussian pyramid for A
|
||||
G = A.copy()
|
||||
|
||||
@@ -38,9 +38,11 @@ import cv2 as cv
|
||||
import numpy as np
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
img = cv.imread('messi5.jpg',0)
|
||||
img = cv.imread('messi5.jpg', cv.IMREAD_GRAYSCALE)
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
img2 = img.copy()
|
||||
template = cv.imread('template.jpg',0)
|
||||
template = cv.imread('template.jpg', cv.IMREAD_GRAYSCALE)
|
||||
assert template is not None, "file could not be read, check with os.path.exists()"
|
||||
w, h = template.shape[::-1]
|
||||
|
||||
# All the 6 methods for comparison in a list
|
||||
@@ -113,8 +115,10 @@ import numpy as np
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
img_rgb = cv.imread('mario.png')
|
||||
assert img_rgb is not None, "file could not be read, check with os.path.exists()"
|
||||
img_gray = cv.cvtColor(img_rgb, cv.COLOR_BGR2GRAY)
|
||||
template = cv.imread('mario_coin.png',0)
|
||||
template = cv.imread('mario_coin.png', cv.IMREAD_GRAYSCALE)
|
||||
assert template is not None, "file could not be read, check with os.path.exists()"
|
||||
w, h = template.shape[::-1]
|
||||
|
||||
res = cv.matchTemplate(img_gray,template,cv.TM_CCOEFF_NORMED)
|
||||
|
||||
@@ -37,7 +37,8 @@ import cv2 as cv
|
||||
import numpy as np
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
img = cv.imread('gradient.png',0)
|
||||
img = cv.imread('gradient.png', cv.IMREAD_GRAYSCALE)
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
ret,thresh1 = cv.threshold(img,127,255,cv.THRESH_BINARY)
|
||||
ret,thresh2 = cv.threshold(img,127,255,cv.THRESH_BINARY_INV)
|
||||
ret,thresh3 = cv.threshold(img,127,255,cv.THRESH_TRUNC)
|
||||
@@ -85,7 +86,8 @@ import cv2 as cv
|
||||
import numpy as np
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
img = cv.imread('sudoku.png',0)
|
||||
img = cv.imread('sudoku.png', cv.IMREAD_GRAYSCALE)
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
img = cv.medianBlur(img,5)
|
||||
|
||||
ret,th1 = cv.threshold(img,127,255,cv.THRESH_BINARY)
|
||||
@@ -133,7 +135,8 @@ import cv2 as cv
|
||||
import numpy as np
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
img = cv.imread('noisy2.png',0)
|
||||
img = cv.imread('noisy2.png', cv.IMREAD_GRAYSCALE)
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
|
||||
# global thresholding
|
||||
ret1,th1 = cv.threshold(img,127,255,cv.THRESH_BINARY)
|
||||
@@ -183,7 +186,8 @@ where
|
||||
It actually finds a value of t which lies in between two peaks such that variances to both classes
|
||||
are minimal. It can be simply implemented in Python as follows:
|
||||
@code{.py}
|
||||
img = cv.imread('noisy2.png',0)
|
||||
img = cv.imread('noisy2.png', cv.IMREAD_GRAYSCALE)
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
blur = cv.GaussianBlur(img,(5,5),0)
|
||||
|
||||
# find normalized_histogram, and its cumulative distribution function
|
||||
|
||||
+6
-3
@@ -54,7 +54,8 @@ import cv2 as cv
|
||||
import numpy as np
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
img = cv.imread('messi5.jpg',0)
|
||||
img = cv.imread('messi5.jpg', cv.IMREAD_GRAYSCALE)
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
f = np.fft.fft2(img)
|
||||
fshift = np.fft.fftshift(f)
|
||||
magnitude_spectrum = 20*np.log(np.abs(fshift))
|
||||
@@ -121,7 +122,8 @@ import numpy as np
|
||||
import cv2 as cv
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
img = cv.imread('messi5.jpg',0)
|
||||
img = cv.imread('messi5.jpg', cv.IMREAD_GRAYSCALE)
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
|
||||
dft = cv.dft(np.float32(img),flags = cv.DFT_COMPLEX_OUTPUT)
|
||||
dft_shift = np.fft.fftshift(dft)
|
||||
@@ -184,7 +186,8 @@ So how do we find this optimal size ? OpenCV provides a function, **cv.getOptima
|
||||
this. It is applicable to both **cv.dft()** and **np.fft.fft2()**. Let's check their performance
|
||||
using IPython magic command %timeit.
|
||||
@code{.py}
|
||||
In [16]: img = cv.imread('messi5.jpg',0)
|
||||
In [15]: img = cv.imread('messi5.jpg', cv.IMREAD_GRAYSCALE)
|
||||
In [16]: assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
In [17]: rows,cols = img.shape
|
||||
In [18]: print("{} {}".format(rows,cols))
|
||||
342 548
|
||||
|
||||
@@ -49,6 +49,7 @@ import cv2 as cv
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
img = cv.imread('coins.png')
|
||||
assert img is not None, "file could not be read, check with os.path.exists()"
|
||||
gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
|
||||
ret, thresh = cv.threshold(gray,0,255,cv.THRESH_BINARY_INV+cv.THRESH_OTSU)
|
||||
@endcode
|
||||
|
||||
@@ -56,7 +56,7 @@ import numpy as np
|
||||
import cv2 as cv
|
||||
|
||||
img = cv.imread('messi_2.jpg')
|
||||
mask = cv.imread('mask2.png',0)
|
||||
mask = cv.imread('mask2.png', cv.IMREAD_GRAYSCALE)
|
||||
|
||||
dst = cv.inpaint(img,mask,3,cv.INPAINT_TELEA)
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ programmer to express ideas in fewer lines of code without reducing readability.
|
||||
Compared to languages like C/C++, Python is slower. That said, Python can be easily extended with
|
||||
C/C++, which allows us to write computationally intensive code in C/C++ and create Python wrappers
|
||||
that can be used as Python modules. This gives us two advantages: first, the code is as fast as the
|
||||
original C/C++ code (since it is the actual C++ code working in background) and second, it easier to
|
||||
original C/C++ code (since it is the actual C++ code working in background) and second, it is easier to
|
||||
code in Python than C/C++. OpenCV-Python is a Python wrapper for the original OpenCV C++
|
||||
implementation.
|
||||
|
||||
@@ -79,8 +79,9 @@ Below is the list of contributors who submitted tutorials to OpenCV-Python.
|
||||
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)
|
||||
4. [OpenCV Documentation](http://docs.opencv.org/)
|
||||
-# A Quick guide to Python - [A Byte of Python](https://python.swaroopch.com/)
|
||||
1. [A Quick guide to Python](https://www.freecodecamp.org/news/the-python-guide-for-beginners/)
|
||||
2. [NumPy Quickstart tutorial](https://numpy.org/doc/stable/user/quickstart.html)
|
||||
3. [NumPy Reference](https://numpy.org/doc/stable/reference/index.html)
|
||||
4. [OpenCV Documentation](https://docs.opencv.org/)
|
||||
5. [OpenCV Forum](https://forum.opencv.org/)
|
||||
|
||||
@@ -33,6 +33,8 @@ Installing OpenCV from prebuilt binaries
|
||||
|
||||
-# Copy **cv2.pyd** to **C:/Python27/lib/site-packages**.
|
||||
|
||||
-# Copy the **opencv_world.dll** file to **C:/Python27/lib/site-packages**
|
||||
|
||||
-# Open Python IDLE and type following codes in Python terminal.
|
||||
@code
|
||||
>>> import cv2 as cv
|
||||
|
||||
@@ -3,29 +3,30 @@
|
||||
@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
|
||||
ones or implement outstanding researching ideas.
|
||||
Deep learning is a fast-growing area. New approaches to building neural networks
|
||||
usually introduce new types of layers. These could be modifications of existing
|
||||
ones or implementation of outstanding research ideas.
|
||||
|
||||
OpenCV gives an opportunity to import and run networks from different deep learning
|
||||
frameworks. There are a number of the most popular layers. However you can face
|
||||
a problem that your network cannot be imported using OpenCV because of unimplemented layers.
|
||||
OpenCV allows importing and running networks from different deep learning frameworks.
|
||||
There is a number of the most popular layers. However, you can face a problem that
|
||||
your network cannot be imported using OpenCV because some layers of your network
|
||||
can be not implemented in the deep learning engine of OpenCV.
|
||||
|
||||
The first solution is to create a feature request at https://github.com/opencv/opencv/issues
|
||||
mentioning details such a source of model and type of new layer. A new layer could
|
||||
be implemented if OpenCV community shares this need.
|
||||
mentioning details such as a source of a model and a type of new layer.
|
||||
The new layer could be implemented if the OpenCV community shares this need.
|
||||
|
||||
The second way is to define a **custom layer** so OpenCV's deep learning engine
|
||||
The second way is to define a **custom layer** so that OpenCV's deep learning engine
|
||||
will know how to use it. This tutorial is dedicated to show you a process of deep
|
||||
learning models import customization.
|
||||
learning model's import customization.
|
||||
|
||||
## Define a custom layer in C++
|
||||
Deep learning layer is a building block of network's pipeline.
|
||||
It has connections to **input blobs** and produces results to **output blobs**.
|
||||
There are trained **weights** and **hyper-parameters**.
|
||||
Layers' names, types, weights and hyper-parameters are stored in files are generated by
|
||||
native frameworks during training. If OpenCV mets unknown layer type it throws an
|
||||
exception trying to read a model:
|
||||
Layers' names, types, weights and hyper-parameters are stored in files are
|
||||
generated by native frameworks during training. If OpenCV encounters unknown
|
||||
layer type it throws an exception while trying to read a model:
|
||||
|
||||
```
|
||||
Unspecified error: Can't create layer "layer_name" of type "MyType" in function getLayerInstance
|
||||
@@ -61,7 +62,7 @@ This method should create an instance of you layer and return cv::Ptr with it.
|
||||
|
||||
@snippet dnn/custom_layers.hpp MyLayer::getMemoryShapes
|
||||
|
||||
Returns layer's output shapes depends on input shapes. You may request an extra
|
||||
Returns layer's output shapes depending on input shapes. You may request an extra
|
||||
memory using `internals`.
|
||||
|
||||
- Run a layer
|
||||
@@ -71,20 +72,20 @@ memory using `internals`.
|
||||
Implement a layer's logic here. Compute outputs for given inputs.
|
||||
|
||||
@note OpenCV manages memory allocated for layers. In the most cases the same memory
|
||||
can be reused between layers. So your `forward` implementation should not rely that
|
||||
the second invocation of `forward` will has the same data at `outputs` and `internals`.
|
||||
can be reused between layers. So your `forward` implementation should not rely on that
|
||||
the second invocation of `forward` will have the same data at `outputs` and `internals`.
|
||||
|
||||
- Optional `finalize` method
|
||||
|
||||
@snippet dnn/custom_layers.hpp MyLayer::finalize
|
||||
|
||||
The chain of methods are the following: OpenCV deep learning engine calls `create`
|
||||
method once then it calls `getMemoryShapes` for an every created layer then you
|
||||
can make some preparations depends on known input dimensions at cv::dnn::Layer::finalize.
|
||||
After network was initialized only `forward` method is called for an every network's input.
|
||||
The chain of methods is the following: OpenCV deep learning engine calls `create`
|
||||
method once, then it calls `getMemoryShapes` for every created layer, then you
|
||||
can make some preparations depend on known input dimensions at cv::dnn::Layer::finalize.
|
||||
After network was initialized only `forward` method is called for every network's input.
|
||||
|
||||
@note Varying input blobs' sizes such height or width or batch size you make OpenCV
|
||||
reallocate all the internal memory. That leads efficiency gaps. Try to initialize
|
||||
@note Varying input blobs' sizes such height, width or batch size make OpenCV
|
||||
reallocate all the internal memory. That leads to efficiency gaps. Try to initialize
|
||||
and deploy models using a fixed batch size and image's dimensions.
|
||||
|
||||
## Example: custom layer from Caffe
|
||||
@@ -201,7 +202,7 @@ deep learning model. That was trained with one and only difference comparing to
|
||||
a current version of [Caffe framework](http://caffe.berkeleyvision.org/). `Crop`
|
||||
layers that receive two input blobs and crop the first one to match spatial dimensions
|
||||
of the second one used to crop from the center. Nowadays Caffe's layer does it
|
||||
from the top-left corner. So using the latest version of Caffe or OpenCV you'll
|
||||
from the top-left corner. So using the latest version of Caffe or OpenCV you will
|
||||
get shifted results with filled borders.
|
||||
|
||||
Next we're going to replace OpenCV's `Crop` layer that makes top-left cropping by
|
||||
@@ -217,7 +218,7 @@ a centric one.
|
||||
|
||||
@snippet dnn/edge_detection.py Register
|
||||
|
||||
That's it! We've replaced an implemented OpenCV's layer to a custom one.
|
||||
That's it! We have replaced an implemented OpenCV's layer to a custom one.
|
||||
You may find a full script in the [source code](https://github.com/opencv/opencv/tree/3.4/samples/dnn/edge_detection.py).
|
||||
|
||||
<table border="0">
|
||||
|
||||
@@ -39,14 +39,14 @@ Open your Doxyfile using your favorite text editor and search for the key
|
||||
`TAGFILES`. Change it as follows:
|
||||
|
||||
@code
|
||||
TAGFILES = ./docs/doxygen-tags/opencv.tag=http://docs.opencv.org/3.4.19
|
||||
TAGFILES = ./docs/doxygen-tags/opencv.tag=http://docs.opencv.org/3.4.20
|
||||
@endcode
|
||||
|
||||
If you had other definitions already, you can append the line using a `\`:
|
||||
|
||||
@code
|
||||
TAGFILES = ./docs/doxygen-tags/libstdc++.tag=https://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen \
|
||||
./docs/doxygen-tags/opencv.tag=http://docs.opencv.org/3.4.19
|
||||
./docs/doxygen-tags/opencv.tag=http://docs.opencv.org/3.4.20
|
||||
@endcode
|
||||
|
||||
Doxygen can now use the information from the tag file to link to the OpenCV
|
||||
|
||||
@@ -55,7 +55,7 @@ Making a project
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
Mat image;
|
||||
image = imread( argv[1], 1 );
|
||||
image = imread( argv[1], IMREAD_COLOR );
|
||||
|
||||
if( argc != 2 || !image.data )
|
||||
{
|
||||
|
||||
@@ -35,7 +35,7 @@ int main(int argc, char** argv )
|
||||
}
|
||||
|
||||
Mat image;
|
||||
image = imread( argv[1], 1 );
|
||||
image = imread( argv[1], IMREAD_COLOR );
|
||||
|
||||
if ( !image.data )
|
||||
{
|
||||
|
||||
@@ -1549,6 +1549,12 @@ static double cvCalibrateCamera2Internal( const CvMat* objectPoints,
|
||||
}
|
||||
}
|
||||
|
||||
Mat mask = cvarrToMat(solver.mask);
|
||||
int nparams_nz = countNonZero(mask);
|
||||
if (nparams_nz >= 2 * total)
|
||||
CV_Error_(CV_StsBadArg,
|
||||
("There should be less vars to optimize (having %d) than the number of residuals (%d = 2 per point)", nparams_nz, 2 * total));
|
||||
|
||||
// 2. initialize extrinsic parameters
|
||||
for( i = 0, pos = 0; i < nimages; i++, pos += ni )
|
||||
{
|
||||
@@ -1651,27 +1657,24 @@ static double cvCalibrateCamera2Internal( const CvMat* objectPoints,
|
||||
{
|
||||
if( stdDevs )
|
||||
{
|
||||
Mat mask = cvarrToMat(solver.mask);
|
||||
int nparams_nz = countNonZero(mask);
|
||||
Mat JtJinv, JtJN;
|
||||
JtJN.create(nparams_nz, nparams_nz, CV_64F);
|
||||
subMatrix(cvarrToMat(_JtJ), JtJN, mask, mask);
|
||||
completeSymm(JtJN, false);
|
||||
cv::invert(JtJN, JtJinv, DECOMP_SVD);
|
||||
//sigma2 is deviation of the noise
|
||||
//see any papers about variance of the least squares estimator for
|
||||
//detailed description of the variance estimation methods
|
||||
double sigma2 = norm(allErrors, NORM_L2SQR) / (total - nparams_nz);
|
||||
// an explanation of that denominator correction can be found here:
|
||||
// R. Hartley, A. Zisserman, Multiple View Geometry in Computer Vision, 2004, section 5.1.3, page 134
|
||||
// see the discussion for more details: https://github.com/opencv/opencv/pull/22992
|
||||
int nErrors = 2 * total - nparams_nz;
|
||||
double sigma2 = norm(allErrors, NORM_L2SQR) / nErrors;
|
||||
Mat stdDevsM = cvarrToMat(stdDevs);
|
||||
int j = 0;
|
||||
for ( int s = 0; s < nparams; s++ )
|
||||
{
|
||||
stdDevsM.at<double>(s) = mask.data[s] ? std::sqrt(JtJinv.at<double>(j,j) * sigma2) : 0.0;
|
||||
if( mask.data[s] )
|
||||
{
|
||||
stdDevsM.at<double>(s) = std::sqrt(JtJinv.at<double>(j,j) * sigma2);
|
||||
j++;
|
||||
}
|
||||
else
|
||||
stdDevsM.at<double>(s) = 0.;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -2255,28 +2258,28 @@ double cvStereoCalibrate( const CvMat* _objectPoints, const CvMat* _imagePoints1
|
||||
static void
|
||||
icvGetRectangles( const CvMat* cameraMatrix, const CvMat* distCoeffs,
|
||||
const CvMat* R, const CvMat* newCameraMatrix, CvSize imgSize,
|
||||
cv::Rect_<float>& inner, cv::Rect_<float>& outer )
|
||||
cv::Rect_<double>& inner, cv::Rect_<double>& outer )
|
||||
{
|
||||
const int N = 9;
|
||||
int x, y, k;
|
||||
cv::Ptr<CvMat> _pts(cvCreateMat(1, N*N, CV_32FC2));
|
||||
CvPoint2D32f* pts = (CvPoint2D32f*)(_pts->data.ptr);
|
||||
cv::Ptr<CvMat> _pts(cvCreateMat(1, N*N, CV_64FC2));
|
||||
CvPoint2D64f* pts = (CvPoint2D64f*)(_pts->data.ptr);
|
||||
|
||||
for( y = k = 0; y < N; y++ )
|
||||
for( x = 0; x < N; x++ )
|
||||
pts[k++] = cvPoint2D32f((float)x*imgSize.width/(N-1),
|
||||
(float)y*imgSize.height/(N-1));
|
||||
pts[k++] = cvPoint2D64f((double)x*(imgSize.width-1)/(N-1),
|
||||
(double)y*(imgSize.height-1)/(N-1));
|
||||
|
||||
cvUndistortPoints(_pts, _pts, cameraMatrix, distCoeffs, R, newCameraMatrix);
|
||||
|
||||
float iX0=-FLT_MAX, iX1=FLT_MAX, iY0=-FLT_MAX, iY1=FLT_MAX;
|
||||
float oX0=FLT_MAX, oX1=-FLT_MAX, oY0=FLT_MAX, oY1=-FLT_MAX;
|
||||
double iX0=-FLT_MAX, iX1=FLT_MAX, iY0=-FLT_MAX, iY1=FLT_MAX;
|
||||
double oX0=FLT_MAX, oX1=-FLT_MAX, oY0=FLT_MAX, oY1=-FLT_MAX;
|
||||
// find the inscribed rectangle.
|
||||
// the code will likely not work with extreme rotation matrices (R) (>45%)
|
||||
for( y = k = 0; y < N; y++ )
|
||||
for( x = 0; x < N; x++ )
|
||||
{
|
||||
CvPoint2D32f p = pts[k++];
|
||||
CvPoint2D64f p = pts[k++];
|
||||
oX0 = MIN(oX0, p.x);
|
||||
oX1 = MAX(oX1, p.x);
|
||||
oY0 = MIN(oY0, p.y);
|
||||
@@ -2291,8 +2294,8 @@ icvGetRectangles( const CvMat* cameraMatrix, const CvMat* distCoeffs,
|
||||
if( y == N-1 )
|
||||
iY1 = MIN(iY1, p.y);
|
||||
}
|
||||
inner = cv::Rect_<float>(iX0, iY0, iX1-iX0, iY1-iY0);
|
||||
outer = cv::Rect_<float>(oX0, oY0, oX1-oX0, oY1-oY0);
|
||||
inner = cv::Rect_<double>(iX0, iY0, iX1-iX0, iY1-iY0);
|
||||
outer = cv::Rect_<double>(oX0, oY0, oX1-oX0, oY1-oY0);
|
||||
}
|
||||
|
||||
|
||||
@@ -2305,7 +2308,7 @@ void cvStereoRectify( const CvMat* _cameraMatrix1, const CvMat* _cameraMatrix2,
|
||||
{
|
||||
double _om[3], _t[3] = {0}, _uu[3]={0,0,0}, _r_r[3][3], _pp[3][4];
|
||||
double _ww[3], _wr[3][3], _z[3] = {0,0,0}, _ri[3][3];
|
||||
cv::Rect_<float> inner1, inner2, outer1, outer2;
|
||||
cv::Rect_<double> inner1, inner2, outer1, outer2;
|
||||
|
||||
CvMat om = cvMat(3, 1, CV_64F, _om);
|
||||
CvMat t = cvMat(3, 1, CV_64F, _t);
|
||||
@@ -2512,7 +2515,7 @@ void cvGetOptimalNewCameraMatrix( const CvMat* cameraMatrix, const CvMat* distCo
|
||||
CvMat* newCameraMatrix, CvSize newImgSize,
|
||||
CvRect* validPixROI, int centerPrincipalPoint )
|
||||
{
|
||||
cv::Rect_<float> inner, outer;
|
||||
cv::Rect_<double> inner, outer;
|
||||
newImgSize = newImgSize.width*newImgSize.height != 0 ? newImgSize : imgSize;
|
||||
|
||||
double M[3][3];
|
||||
@@ -2542,10 +2545,10 @@ void cvGetOptimalNewCameraMatrix( const CvMat* cameraMatrix, const CvMat* distCo
|
||||
|
||||
if( validPixROI )
|
||||
{
|
||||
inner = cv::Rect_<float>((float)((inner.x - cx0)*s + cx),
|
||||
(float)((inner.y - cy0)*s + cy),
|
||||
(float)(inner.width*s),
|
||||
(float)(inner.height*s));
|
||||
inner = cv::Rect_<double>((double)((inner.x - cx0)*s + cx),
|
||||
(double)((inner.y - cy0)*s + cy),
|
||||
(double)(inner.width*s),
|
||||
(double)(inner.height*s));
|
||||
cv::Rect r(cvCeil(inner.x), cvCeil(inner.y), cvFloor(inner.width), cvFloor(inner.height));
|
||||
r &= cv::Rect(0, 0, newImgSize.width, newImgSize.height);
|
||||
*validPixROI = cvRect(r);
|
||||
|
||||
@@ -421,7 +421,7 @@ void cv::fisheye::undistortPoints( InputArray distorted, OutputArray undistorted
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// cv::fisheye::undistortPoints
|
||||
/// cv::fisheye::initUndistortRectifyMap
|
||||
|
||||
void cv::fisheye::initUndistortRectifyMap( InputArray K, InputArray D, InputArray R, InputArray P,
|
||||
const cv::Size& size, int m1type, OutputArray map1, OutputArray map2 )
|
||||
@@ -1527,13 +1527,18 @@ void cv::internal::EstimateUncertainties(InputArrayOfArrays objectPoints, InputA
|
||||
|
||||
Vec<double, 1> sigma_x;
|
||||
meanStdDev(ex.reshape(1, 1), noArray(), sigma_x);
|
||||
sigma_x *= sqrt(2.0 * (double)ex.total()/(2.0 * (double)ex.total() - 1.0));
|
||||
|
||||
Mat JJ2, ex3;
|
||||
ComputeJacobians(objectPoints, imagePoints, params, omc, Tc, check_cond, thresh_cond, JJ2, ex3);
|
||||
|
||||
sqrt(JJ2.inv(), JJ2);
|
||||
|
||||
int nParams = JJ2.rows;
|
||||
// an explanation of that denominator correction can be found here:
|
||||
// R. Hartley, A. Zisserman, Multiple View Geometry in Computer Vision, 2004, section 5.1.3, page 134
|
||||
// see the discussion for more details: https://github.com/opencv/opencv/pull/22992
|
||||
sigma_x *= sqrt(2.0 * (double)ex.total()/(2.0 * (double)ex.total() - nParams));
|
||||
|
||||
errors = 3 * sigma_x(0) * JJ2.diag();
|
||||
rms = sqrt(norm(ex, NORM_L2SQR)/ex.total());
|
||||
}
|
||||
|
||||
@@ -559,12 +559,9 @@ void CV_CameraCalibrationTest::run( int start_from )
|
||||
i = 0;
|
||||
double dx,dy;
|
||||
double rx,ry;
|
||||
double meanDx,meanDy;
|
||||
double maxDx = 0.0;
|
||||
double maxDy = 0.0;
|
||||
|
||||
meanDx = 0;
|
||||
meanDy = 0;
|
||||
for( currImage = 0; currImage < numImages; currImage++ )
|
||||
{
|
||||
double imageMeanDx = 0;
|
||||
@@ -576,9 +573,6 @@ void CV_CameraCalibrationTest::run( int start_from )
|
||||
dx = rx - imagePoints[i].x;
|
||||
dy = ry - imagePoints[i].y;
|
||||
|
||||
meanDx += dx;
|
||||
meanDy += dy;
|
||||
|
||||
imageMeanDx += dx*dx;
|
||||
imageMeanDy += dy*dy;
|
||||
|
||||
@@ -601,9 +595,6 @@ void CV_CameraCalibrationTest::run( int start_from )
|
||||
perViewErrors[currImage] = goodPerViewErrors[currImage];
|
||||
}
|
||||
|
||||
meanDx /= numImages * etalonSize.width * etalonSize.height;
|
||||
meanDy /= numImages * etalonSize.width * etalonSize.height;
|
||||
|
||||
/* ========= Compare parameters ========= */
|
||||
|
||||
/* ----- Compare focal lengths ----- */
|
||||
|
||||
@@ -216,7 +216,7 @@ void CV_ChessboardDetectorTest::run_batch( const string& filename )
|
||||
|
||||
/* read the image */
|
||||
String img_file = board_list[idx * 2];
|
||||
Mat gray = imread( folder + img_file, 0);
|
||||
Mat gray = imread( folder + img_file, IMREAD_GRAYSCALE);
|
||||
|
||||
if( gray.empty() )
|
||||
{
|
||||
|
||||
@@ -398,9 +398,9 @@ TEST_F(fisheyeTest, EstimateUncertainties)
|
||||
cv::internal::EstimateUncertainties(objectPoints, imagePoints, param, rvec, tvec,
|
||||
errors, err_std, thresh_cond, check_cond, rms);
|
||||
|
||||
EXPECT_MAT_NEAR(errors.f, cv::Vec2d(1.29837104202046, 1.31565641071524), 1e-10);
|
||||
EXPECT_MAT_NEAR(errors.c, cv::Vec2d(0.890439368129246, 0.816096854937896), 1e-10);
|
||||
EXPECT_MAT_NEAR(errors.k, cv::Vec4d(0.00516248605191506, 0.0168181467500934, 0.0213118690274604, 0.00916010877545648), 1e-10);
|
||||
EXPECT_MAT_NEAR(errors.f, cv::Vec2d(1.34250246865020720, 1.36037536429654530), 1e-10);
|
||||
EXPECT_MAT_NEAR(errors.c, cv::Vec2d(0.92070526160049848, 0.84383585812851514), 1e-10);
|
||||
EXPECT_MAT_NEAR(errors.k, cv::Vec4d(0.0053379581373996041, 0.017389792901700545, 0.022036256089491224, 0.0094714594258908952), 1e-10);
|
||||
EXPECT_MAT_NEAR(err_std, cv::Vec2d(0.187475975266883, 0.185678953263995), 1e-10);
|
||||
CV_Assert(fabs(rms - 0.263782587133546) < 1e-10);
|
||||
CV_Assert(errors.alpha == 0);
|
||||
|
||||
@@ -73,60 +73,27 @@ int METHOD[METHODS_COUNT] = {0, cv::RANSAC, cv::LMEDS, cv::RHO};
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
|
||||
class CV_HomographyTest: public cvtest::ArrayTest
|
||||
{
|
||||
public:
|
||||
CV_HomographyTest();
|
||||
~CV_HomographyTest();
|
||||
|
||||
void run (int);
|
||||
namespace HomographyTestUtils {
|
||||
|
||||
protected:
|
||||
static const float max_diff = 0.032f;
|
||||
static const float max_2diff = 0.020f;
|
||||
static const int image_size = 100;
|
||||
static const double reproj_threshold = 3.0;
|
||||
static const double sigma = 0.01;
|
||||
|
||||
int method;
|
||||
int image_size;
|
||||
double reproj_threshold;
|
||||
double sigma;
|
||||
|
||||
private:
|
||||
float max_diff, max_2diff;
|
||||
bool check_matrix_size(const cv::Mat& H);
|
||||
bool check_matrix_diff(const cv::Mat& original, const cv::Mat& found, const int norm_type, double &diff);
|
||||
int check_ransac_mask_1(const Mat& src, const Mat& mask);
|
||||
int check_ransac_mask_2(const Mat& original_mask, const Mat& found_mask);
|
||||
|
||||
void print_information_1(int j, int N, int method, const Mat& H);
|
||||
void print_information_2(int j, int N, int method, const Mat& H, const Mat& H_res, int k, double diff);
|
||||
void print_information_3(int method, int j, int N, const Mat& mask);
|
||||
void print_information_4(int method, int j, int N, int k, int l, double diff);
|
||||
void print_information_5(int method, int j, int N, int l, double diff);
|
||||
void print_information_6(int method, int j, int N, int k, double diff, bool value);
|
||||
void print_information_7(int method, int j, int N, int k, double diff, bool original_value, bool found_value);
|
||||
void print_information_8(int method, int j, int N, int k, int l, double diff);
|
||||
};
|
||||
|
||||
CV_HomographyTest::CV_HomographyTest() : max_diff(1e-2f), max_2diff(2e-2f)
|
||||
{
|
||||
method = 0;
|
||||
image_size = 100;
|
||||
reproj_threshold = 3.0;
|
||||
sigma = 0.01;
|
||||
}
|
||||
|
||||
CV_HomographyTest::~CV_HomographyTest() {}
|
||||
|
||||
bool CV_HomographyTest::check_matrix_size(const cv::Mat& H)
|
||||
static bool check_matrix_size(const cv::Mat& H)
|
||||
{
|
||||
return (H.rows == 3) && (H.cols == 3);
|
||||
}
|
||||
|
||||
bool CV_HomographyTest::check_matrix_diff(const cv::Mat& original, const cv::Mat& found, const int norm_type, double &diff)
|
||||
static bool check_matrix_diff(const cv::Mat& original, const cv::Mat& found, const int norm_type, double &diff)
|
||||
{
|
||||
diff = cvtest::norm(original, found, norm_type);
|
||||
return diff <= max_diff;
|
||||
}
|
||||
|
||||
int CV_HomographyTest::check_ransac_mask_1(const Mat& src, const Mat& mask)
|
||||
static int check_ransac_mask_1(const Mat& src, const Mat& mask)
|
||||
{
|
||||
if (!(mask.cols == 1) && (mask.rows == src.cols)) return 1;
|
||||
if (countNonZero(mask) < mask.rows) return 2;
|
||||
@@ -134,14 +101,14 @@ int CV_HomographyTest::check_ransac_mask_1(const Mat& src, const Mat& mask)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CV_HomographyTest::check_ransac_mask_2(const Mat& original_mask, const Mat& found_mask)
|
||||
static int check_ransac_mask_2(const Mat& original_mask, const Mat& found_mask)
|
||||
{
|
||||
if (!(found_mask.cols == 1) && (found_mask.rows == original_mask.rows)) return 1;
|
||||
for (int i = 0; i < found_mask.rows; ++i) if (found_mask.at<uchar>(i, 0) > 1) return 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CV_HomographyTest::print_information_1(int j, int N, int _method, const Mat& H)
|
||||
static void print_information_1(int j, int N, int _method, const Mat& H)
|
||||
{
|
||||
cout << endl; cout << "Checking for homography matrix sizes..." << endl; cout << endl;
|
||||
cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>";
|
||||
@@ -153,7 +120,7 @@ void CV_HomographyTest::print_information_1(int j, int N, int _method, const Mat
|
||||
cout << "Number of rows: " << H.rows << " Number of cols: " << H.cols << endl; cout << endl;
|
||||
}
|
||||
|
||||
void CV_HomographyTest::print_information_2(int j, int N, int _method, const Mat& H, const Mat& H_res, int k, double diff)
|
||||
static void print_information_2(int j, int N, int _method, const Mat& H, const Mat& H_res, int k, double diff)
|
||||
{
|
||||
cout << endl; cout << "Checking for accuracy of homography matrix computing..." << endl; cout << endl;
|
||||
cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>";
|
||||
@@ -169,7 +136,7 @@ void CV_HomographyTest::print_information_2(int j, int N, int _method, const Mat
|
||||
cout << "Maximum allowed difference: " << max_diff << endl; cout << endl;
|
||||
}
|
||||
|
||||
void CV_HomographyTest::print_information_3(int _method, int j, int N, const Mat& mask)
|
||||
static void print_information_3(int _method, int j, int N, const Mat& mask)
|
||||
{
|
||||
cout << endl; cout << "Checking for inliers/outliers mask..." << endl; cout << endl;
|
||||
cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>";
|
||||
@@ -181,7 +148,7 @@ void CV_HomographyTest::print_information_3(int _method, int j, int N, const Mat
|
||||
cout << "Number of rows: " << mask.rows << " Number of cols: " << mask.cols << endl; cout << endl;
|
||||
}
|
||||
|
||||
void CV_HomographyTest::print_information_4(int _method, int j, int N, int k, int l, double diff)
|
||||
static void print_information_4(int _method, int j, int N, int k, int l, double diff)
|
||||
{
|
||||
cout << endl; cout << "Checking for accuracy of reprojection error computing..." << endl; cout << endl;
|
||||
cout << "Method: "; if (_method == 0) cout << 0 << endl; else cout << "CV_LMEDS" << endl;
|
||||
@@ -195,7 +162,7 @@ void CV_HomographyTest::print_information_4(int _method, int j, int N, int k, in
|
||||
cout << "Maximum allowed difference: " << max_2diff << endl; cout << endl;
|
||||
}
|
||||
|
||||
void CV_HomographyTest::print_information_5(int _method, int j, int N, int l, double diff)
|
||||
static void print_information_5(int _method, int j, int N, int l, double diff)
|
||||
{
|
||||
cout << endl; cout << "Checking for accuracy of reprojection error computing..." << endl; cout << endl;
|
||||
cout << "Method: "; if (_method == 0) cout << 0 << endl; else cout << "CV_LMEDS" << endl;
|
||||
@@ -208,7 +175,7 @@ void CV_HomographyTest::print_information_5(int _method, int j, int N, int l, do
|
||||
cout << "Maximum allowed difference: " << max_diff << endl; cout << endl;
|
||||
}
|
||||
|
||||
void CV_HomographyTest::print_information_6(int _method, int j, int N, int k, double diff, bool value)
|
||||
static void print_information_6(int _method, int j, int N, int k, double diff, bool value)
|
||||
{
|
||||
cout << endl; cout << "Checking for inliers/outliers mask..." << endl; cout << endl;
|
||||
cout << "Method: "; if (_method == RANSAC) cout << "RANSAC" << endl; else if (_method == cv::RHO) cout << "RHO" << endl; else cout << _method << endl;
|
||||
@@ -221,7 +188,7 @@ void CV_HomographyTest::print_information_6(int _method, int j, int N, int k, do
|
||||
cout << "Value of found mask: "<< value << endl; cout << endl;
|
||||
}
|
||||
|
||||
void CV_HomographyTest::print_information_7(int _method, int j, int N, int k, double diff, bool original_value, bool found_value)
|
||||
static void print_information_7(int _method, int j, int N, int k, double diff, bool original_value, bool found_value)
|
||||
{
|
||||
cout << endl; cout << "Checking for inliers/outliers mask..." << endl; cout << endl;
|
||||
cout << "Method: "; if (_method == RANSAC) cout << "RANSAC" << endl; else if (_method == cv::RHO) cout << "RHO" << endl; else cout << _method << endl;
|
||||
@@ -234,7 +201,7 @@ void CV_HomographyTest::print_information_7(int _method, int j, int N, int k, do
|
||||
cout << "Value of original mask: "<< original_value << " Value of found mask: " << found_value << endl; cout << endl;
|
||||
}
|
||||
|
||||
void CV_HomographyTest::print_information_8(int _method, int j, int N, int k, int l, double diff)
|
||||
static void print_information_8(int _method, int j, int N, int k, int l, double diff)
|
||||
{
|
||||
cout << endl; cout << "Checking for reprojection error of inlier..." << endl; cout << endl;
|
||||
cout << "Method: "; if (_method == RANSAC) cout << "RANSAC" << endl; else if (_method == cv::RHO) cout << "RHO" << endl; else cout << _method << endl;
|
||||
@@ -248,11 +215,15 @@ void CV_HomographyTest::print_information_8(int _method, int j, int N, int k, in
|
||||
cout << "Maximum allowed difference: " << max_2diff << endl; cout << endl;
|
||||
}
|
||||
|
||||
void CV_HomographyTest::run(int)
|
||||
} // HomographyTestUtils::
|
||||
|
||||
|
||||
TEST(Calib3d_Homography, accuracy)
|
||||
{
|
||||
using namespace HomographyTestUtils;
|
||||
for (int N = MIN_COUNT_OF_POINTS; N <= MAX_COUNT_OF_POINTS; ++N)
|
||||
{
|
||||
RNG& rng = ts->get_rng();
|
||||
RNG& rng = cv::theRNG();
|
||||
|
||||
float *src_data = new float [2*N];
|
||||
|
||||
@@ -308,7 +279,7 @@ void CV_HomographyTest::run(int)
|
||||
|
||||
for (int i = 0; i < METHODS_COUNT; ++i)
|
||||
{
|
||||
method = METHOD[i];
|
||||
const int method = METHOD[i];
|
||||
switch (method)
|
||||
{
|
||||
case 0:
|
||||
@@ -411,7 +382,7 @@ void CV_HomographyTest::run(int)
|
||||
|
||||
for (int i = 0; i < METHODS_COUNT; ++i)
|
||||
{
|
||||
method = METHOD[i];
|
||||
const int method = METHOD[i];
|
||||
switch (method)
|
||||
{
|
||||
case 0:
|
||||
@@ -573,8 +544,6 @@ void CV_HomographyTest::run(int)
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Calib3d_Homography, accuracy) { CV_HomographyTest test; test.safe_run(); }
|
||||
|
||||
TEST(Calib3d_Homography, EKcase)
|
||||
{
|
||||
float pt1data[] =
|
||||
|
||||
@@ -456,8 +456,8 @@ void CV_StereoMatchingTest::run(int)
|
||||
string datasetFullDirName = dataPath + DATASETS_DIR + datasetName + "/";
|
||||
Mat leftImg = imread(datasetFullDirName + LEFT_IMG_NAME);
|
||||
Mat rightImg = imread(datasetFullDirName + RIGHT_IMG_NAME);
|
||||
Mat trueLeftDisp = imread(datasetFullDirName + TRUE_LEFT_DISP_NAME, 0);
|
||||
Mat trueRightDisp = imread(datasetFullDirName + TRUE_RIGHT_DISP_NAME, 0);
|
||||
Mat trueLeftDisp = imread(datasetFullDirName + TRUE_LEFT_DISP_NAME, IMREAD_GRAYSCALE);
|
||||
Mat trueRightDisp = imread(datasetFullDirName + TRUE_RIGHT_DISP_NAME, IMREAD_GRAYSCALE);
|
||||
Rect calcROI;
|
||||
|
||||
if( leftImg.empty() || rightImg.empty() || trueLeftDisp.empty() )
|
||||
@@ -835,9 +835,9 @@ TEST_P(Calib3d_StereoBM_BufferBM, memAllocsTest)
|
||||
const int SADWindowSize = get<1>(get<1>(GetParam()));
|
||||
|
||||
String path = cvtest::TS::ptr()->get_data_path() + "cv/stereomatching/datasets/teddy/";
|
||||
Mat leftImg = imread(path + "im2.png", 0);
|
||||
Mat leftImg = imread(path + "im2.png", IMREAD_GRAYSCALE);
|
||||
ASSERT_FALSE(leftImg.empty());
|
||||
Mat rightImg = imread(path + "im6.png", 0);
|
||||
Mat rightImg = imread(path + "im6.png", IMREAD_GRAYSCALE);
|
||||
ASSERT_FALSE(rightImg.empty());
|
||||
Mat leftDisp;
|
||||
{
|
||||
@@ -923,9 +923,9 @@ TEST(Calib3d_StereoSGBM, regression) { CV_StereoSGBMTest test; test.safe_run();
|
||||
TEST(Calib3d_StereoSGBM_HH4, regression)
|
||||
{
|
||||
String path = cvtest::TS::ptr()->get_data_path() + "cv/stereomatching/datasets/teddy/";
|
||||
Mat leftImg = imread(path + "im2.png", 0);
|
||||
Mat leftImg = imread(path + "im2.png", IMREAD_GRAYSCALE);
|
||||
ASSERT_FALSE(leftImg.empty());
|
||||
Mat rightImg = imread(path + "im6.png", 0);
|
||||
Mat rightImg = imread(path + "im6.png", IMREAD_GRAYSCALE);
|
||||
ASSERT_FALSE(rightImg.empty());
|
||||
Mat testData = imread(path + "disp2_hh4.png",-1);
|
||||
ASSERT_FALSE(testData.empty());
|
||||
|
||||
@@ -157,6 +157,104 @@ void CV_DefaultNewCameraMatrixTest::prepare_to_validation( int /*test_case_idx*/
|
||||
|
||||
//---------
|
||||
|
||||
class CV_GetOptimalNewCameraMatrixNoDistortionTest : public cvtest::ArrayTest
|
||||
{
|
||||
public:
|
||||
CV_GetOptimalNewCameraMatrixNoDistortionTest();
|
||||
protected:
|
||||
int prepare_test_case (int test_case_idx);
|
||||
void prepare_to_validation(int test_case_idx);
|
||||
void get_test_array_types_and_sizes(int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types);
|
||||
void run_func();
|
||||
|
||||
private:
|
||||
cv::Mat camera_mat;
|
||||
cv::Mat distortion_coeffs;
|
||||
cv::Mat new_camera_mat;
|
||||
|
||||
cv::Size img_size;
|
||||
double alpha;
|
||||
bool center_principal_point;
|
||||
|
||||
int matrix_type;
|
||||
|
||||
static const int MAX_X = 2048;
|
||||
static const int MAX_Y = 2048;
|
||||
};
|
||||
|
||||
CV_GetOptimalNewCameraMatrixNoDistortionTest::CV_GetOptimalNewCameraMatrixNoDistortionTest()
|
||||
{
|
||||
test_array[INPUT].push_back(NULL); // camera_mat
|
||||
test_array[INPUT].push_back(NULL); // distortion_coeffs
|
||||
test_array[OUTPUT].push_back(NULL); // new_camera_mat
|
||||
test_array[REF_OUTPUT].push_back(NULL);
|
||||
|
||||
alpha = 0.0;
|
||||
center_principal_point = false;
|
||||
matrix_type = 0;
|
||||
}
|
||||
|
||||
void CV_GetOptimalNewCameraMatrixNoDistortionTest::get_test_array_types_and_sizes(int test_case_idx, vector<vector<Size> >& sizes, vector<vector<int> >& types)
|
||||
{
|
||||
cvtest::ArrayTest::get_test_array_types_and_sizes(test_case_idx, sizes, types);
|
||||
RNG& rng = ts->get_rng();
|
||||
matrix_type = types[INPUT][0] = types[INPUT][1] = types[OUTPUT][0] = types[REF_OUTPUT][0] = cvtest::randInt(rng)%2 ? CV_64F : CV_32F;
|
||||
sizes[INPUT][0] = sizes[OUTPUT][0] = sizes[REF_OUTPUT][0] = cvSize(3,3);
|
||||
sizes[INPUT][1] = cvSize(1,4);
|
||||
}
|
||||
|
||||
int CV_GetOptimalNewCameraMatrixNoDistortionTest::prepare_test_case(int test_case_idx)
|
||||
{
|
||||
int code = cvtest::ArrayTest::prepare_test_case( test_case_idx );
|
||||
|
||||
if (code <= 0)
|
||||
return code;
|
||||
|
||||
RNG& rng = ts->get_rng();
|
||||
|
||||
alpha = cvtest::randReal(rng);
|
||||
center_principal_point = ((cvtest::randInt(rng) % 2)!=0);
|
||||
|
||||
// Generate random camera matrix. Use floating point precision for source to avoid precision loss
|
||||
img_size.width = cvtest::randInt(rng) % MAX_X + 1;
|
||||
img_size.height = cvtest::randInt(rng) % MAX_Y + 1;
|
||||
const float aspect_ratio = static_cast<float>(img_size.width) / img_size.height;
|
||||
float cam_array[9] = {0,0,0,0,0,0,0,0,1};
|
||||
cam_array[2] = static_cast<float>((img_size.width - 1)*0.5); // center
|
||||
cam_array[5] = static_cast<float>((img_size.height - 1)*0.5); // center
|
||||
cam_array[0] = static_cast<float>(MAX(img_size.width, img_size.height)/(0.9 - cvtest::randReal(rng)*0.6));
|
||||
cam_array[4] = aspect_ratio*cam_array[0];
|
||||
|
||||
Mat& input_camera_mat = test_mat[INPUT][0];
|
||||
cvtest::convert(Mat(3, 3, CV_32F, cam_array), input_camera_mat, input_camera_mat.type());
|
||||
camera_mat = input_camera_mat;
|
||||
|
||||
// Generate zero distortion matrix
|
||||
const Mat zero_dist_coeffs = Mat::zeros(1, 4, CV_32F);
|
||||
Mat& input_dist_coeffs = test_mat[INPUT][1];
|
||||
cvtest::convert(zero_dist_coeffs, input_dist_coeffs, input_dist_coeffs.type());
|
||||
distortion_coeffs = input_dist_coeffs;
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
void CV_GetOptimalNewCameraMatrixNoDistortionTest::run_func()
|
||||
{
|
||||
new_camera_mat = cv::getOptimalNewCameraMatrix(camera_mat, distortion_coeffs, img_size, alpha, img_size, NULL, center_principal_point);
|
||||
}
|
||||
|
||||
void CV_GetOptimalNewCameraMatrixNoDistortionTest::prepare_to_validation(int /*test_case_idx*/)
|
||||
{
|
||||
const Mat& src = test_mat[INPUT][0];
|
||||
Mat& dst = test_mat[REF_OUTPUT][0];
|
||||
cvtest::copy(src, dst);
|
||||
|
||||
Mat& output = test_mat[OUTPUT][0];
|
||||
cvtest::convert(new_camera_mat, output, output.type());
|
||||
}
|
||||
|
||||
//---------
|
||||
|
||||
class CV_UndistortPointsTest : public cvtest::ArrayTest
|
||||
{
|
||||
public:
|
||||
@@ -935,6 +1033,7 @@ double CV_InitUndistortRectifyMapTest::get_success_error_level( int /*test_case_
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST(Calib3d_DefaultNewCameraMatrix, accuracy) { CV_DefaultNewCameraMatrixTest test; test.safe_run(); }
|
||||
TEST(Calib3d_GetOptimalNewCameraMatrixNoDistortion, accuracy) { CV_GetOptimalNewCameraMatrixNoDistortionTest test; test.safe_run(); }
|
||||
TEST(Calib3d_UndistortPoints, accuracy) { CV_UndistortPointsTest test; test.safe_run(); }
|
||||
TEST(Calib3d_InitUndistortRectifyMap, accuracy) { CV_InitUndistortRectifyMapTest test; test.safe_run(); }
|
||||
|
||||
|
||||
@@ -52,7 +52,9 @@
|
||||
#include "opencv2/core.hpp"
|
||||
|
||||
#if defined _MSC_VER && _MSC_VER >= 1200
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX // fix https://github.com/opencv/opencv/issues/17548
|
||||
#endif
|
||||
#pragma warning( disable: 4714 ) //__forceinline is not inlined
|
||||
#pragma warning( disable: 4127 ) //conditional expression is constant
|
||||
#pragma warning( disable: 4244 ) //conversion from '__int64' to 'int', possible loss of data
|
||||
|
||||
@@ -295,7 +295,7 @@ CV_INLINE int cvIsInf( double value )
|
||||
#elif defined(__x86_64__) || defined(_M_X64) || defined(__aarch64__) || defined(_M_ARM64) || defined(__PPC64__)
|
||||
Cv64suf ieee754;
|
||||
ieee754.f = value;
|
||||
return (ieee754.u & 0x7fffffff00000000) ==
|
||||
return (ieee754.u & 0x7fffffffffffffff) ==
|
||||
0x7ff0000000000000;
|
||||
#else
|
||||
Cv64suf ieee754;
|
||||
|
||||
@@ -879,14 +879,10 @@ OPENCV_HAL_IMPL_CMP_OP(<=)
|
||||
For all types except 64-bit integer values. */
|
||||
OPENCV_HAL_IMPL_CMP_OP(>=)
|
||||
|
||||
/** @brief Equal comparison
|
||||
|
||||
For all types except 64-bit integer values. */
|
||||
/** @brief Equal comparison */
|
||||
OPENCV_HAL_IMPL_CMP_OP(==)
|
||||
|
||||
/** @brief Not equal comparison
|
||||
|
||||
For all types except 64-bit integer values. */
|
||||
/** @brief Not equal comparison */
|
||||
OPENCV_HAL_IMPL_CMP_OP(!=)
|
||||
|
||||
template<int n>
|
||||
|
||||
@@ -1038,18 +1038,6 @@ OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_float64x2, v_min, vminq_f64)
|
||||
OPENCV_HAL_IMPL_NEON_BIN_FUNC(v_float64x2, v_max, vmaxq_f64)
|
||||
#endif
|
||||
|
||||
#if CV_SIMD128_64F
|
||||
inline int64x2_t vmvnq_s64(int64x2_t a)
|
||||
{
|
||||
int64x2_t vx = vreinterpretq_s64_u32(vdupq_n_u32(0xFFFFFFFF));
|
||||
return veorq_s64(a, vx);
|
||||
}
|
||||
inline uint64x2_t vmvnq_u64(uint64x2_t a)
|
||||
{
|
||||
uint64x2_t vx = vreinterpretq_u64_u32(vdupq_n_u32(0xFFFFFFFF));
|
||||
return veorq_u64(a, vx);
|
||||
}
|
||||
#endif
|
||||
#define OPENCV_HAL_IMPL_NEON_INT_CMP_OP(_Tpvec, cast, suffix, not_suffix) \
|
||||
inline _Tpvec operator == (const _Tpvec& a, const _Tpvec& b) \
|
||||
{ return _Tpvec(cast(vceqq_##suffix(a.val, b.val))); } \
|
||||
@@ -1071,9 +1059,47 @@ OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_int16x8, vreinterpretq_s16_u16, s16, u16)
|
||||
OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_uint32x4, OPENCV_HAL_NOP, u32, u32)
|
||||
OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_int32x4, vreinterpretq_s32_u32, s32, u32)
|
||||
OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_float32x4, vreinterpretq_f32_u32, f32, u32)
|
||||
#if defined(__aarch64__) || defined(_M_ARM64)
|
||||
static inline uint64x2_t vmvnq_u64(uint64x2_t a)
|
||||
{
|
||||
uint64x2_t vx = vreinterpretq_u64_u32(vdupq_n_u32(0xFFFFFFFF));
|
||||
return veorq_u64(a, vx);
|
||||
}
|
||||
//OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_uint64x2, OPENCV_HAL_NOP, u64, u64)
|
||||
//OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_int64x2, vreinterpretq_s64_u64, s64, u64)
|
||||
static inline v_uint64x2 operator == (const v_uint64x2& a, const v_uint64x2& b)
|
||||
{ return v_uint64x2(vceqq_u64(a.val, b.val)); }
|
||||
static inline v_uint64x2 operator != (const v_uint64x2& a, const v_uint64x2& b)
|
||||
{ return v_uint64x2(vmvnq_u64(vceqq_u64(a.val, b.val))); }
|
||||
static inline v_int64x2 operator == (const v_int64x2& a, const v_int64x2& b)
|
||||
{ return v_int64x2(vreinterpretq_s64_u64(vceqq_s64(a.val, b.val))); }
|
||||
static inline v_int64x2 operator != (const v_int64x2& a, const v_int64x2& b)
|
||||
{ return v_int64x2(vreinterpretq_s64_u64(vmvnq_u64(vceqq_s64(a.val, b.val)))); }
|
||||
#else
|
||||
static inline v_uint64x2 operator == (const v_uint64x2& a, const v_uint64x2& b)
|
||||
{
|
||||
uint32x4_t cmp = vceqq_u32(vreinterpretq_u32_u64(a.val), vreinterpretq_u32_u64(b.val));
|
||||
uint32x4_t swapped = vrev64q_u32(cmp);
|
||||
return v_uint64x2(vreinterpretq_u64_u32(vandq_u32(cmp, swapped)));
|
||||
}
|
||||
static inline v_uint64x2 operator != (const v_uint64x2& a, const v_uint64x2& b)
|
||||
{
|
||||
uint32x4_t cmp = vceqq_u32(vreinterpretq_u32_u64(a.val), vreinterpretq_u32_u64(b.val));
|
||||
uint32x4_t swapped = vrev64q_u32(cmp);
|
||||
uint64x2_t v_eq = vreinterpretq_u64_u32(vandq_u32(cmp, swapped));
|
||||
uint64x2_t vx = vreinterpretq_u64_u32(vdupq_n_u32(0xFFFFFFFF));
|
||||
return v_uint64x2(veorq_u64(v_eq, vx));
|
||||
}
|
||||
static inline v_int64x2 operator == (const v_int64x2& a, const v_int64x2& b)
|
||||
{
|
||||
return v_reinterpret_as_s64(v_reinterpret_as_u64(a) == v_reinterpret_as_u64(b));
|
||||
}
|
||||
static inline v_int64x2 operator != (const v_int64x2& a, const v_int64x2& b)
|
||||
{
|
||||
return v_reinterpret_as_s64(v_reinterpret_as_u64(a) != v_reinterpret_as_u64(b));
|
||||
}
|
||||
#endif
|
||||
#if CV_SIMD128_64F
|
||||
OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_uint64x2, OPENCV_HAL_NOP, u64, u64)
|
||||
OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_int64x2, vreinterpretq_s64_u64, s64, u64)
|
||||
OPENCV_HAL_IMPL_NEON_INT_CMP_OP(v_float64x2, vreinterpretq_f64_u64, f64, u64)
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1921,11 +1921,12 @@ OPENCV_HAL_IMPL_SSE_EXPAND(v_int16x8, v_int32x4, short, _v128_cvtepi16_epi
|
||||
OPENCV_HAL_IMPL_SSE_EXPAND(v_uint32x4, v_uint64x2, unsigned, _v128_cvtepu32_epi64)
|
||||
OPENCV_HAL_IMPL_SSE_EXPAND(v_int32x4, v_int64x2, int, _v128_cvtepi32_epi64)
|
||||
|
||||
#define OPENCV_HAL_IMPL_SSE_EXPAND_Q(_Tpvec, _Tp, intrin) \
|
||||
inline _Tpvec v_load_expand_q(const _Tp* ptr) \
|
||||
{ \
|
||||
__m128i a = _mm_cvtsi32_si128(*(const int*)ptr); \
|
||||
return _Tpvec(intrin(a)); \
|
||||
#define OPENCV_HAL_IMPL_SSE_EXPAND_Q(_Tpvec, _Tp, intrin) \
|
||||
inline _Tpvec v_load_expand_q(const _Tp* ptr) \
|
||||
{ \
|
||||
typedef int CV_DECL_ALIGNED(1) unaligned_int; \
|
||||
__m128i a = _mm_cvtsi32_si128(*(const unaligned_int*)ptr); \
|
||||
return _Tpvec(intrin(a)); \
|
||||
}
|
||||
|
||||
OPENCV_HAL_IMPL_SSE_EXPAND_Q(v_uint32x4, uchar, _v128_cvtepu8_epi32)
|
||||
|
||||
@@ -1305,15 +1305,36 @@ public:
|
||||
t(); // finally, transpose the Nx3 matrix.
|
||||
// This involves copying all the elements
|
||||
@endcode
|
||||
3-channel 2x2 matrix reshaped to 1-channel 4x3 matrix, each column has values from one of original channels:
|
||||
@code
|
||||
Mat m(Size(2, 2), CV_8UC3, Scalar(1, 2, 3));
|
||||
vector<int> new_shape {4, 3};
|
||||
m = m.reshape(1, new_shape);
|
||||
@endcode
|
||||
or:
|
||||
@code
|
||||
Mat m(Size(2, 2), CV_8UC3, Scalar(1, 2, 3));
|
||||
const int new_shape[] = {4, 3};
|
||||
m = m.reshape(1, 2, new_shape);
|
||||
@endcode
|
||||
@param cn New number of channels. If the parameter is 0, the number of channels remains the same.
|
||||
@param rows New number of rows. If the parameter is 0, the number of rows remains the same.
|
||||
*/
|
||||
Mat reshape(int cn, int rows=0) const;
|
||||
|
||||
/** @overload */
|
||||
/** @overload
|
||||
* @param cn New number of channels. If the parameter is 0, the number of channels remains the same.
|
||||
* @param newndims New number of dimentions.
|
||||
* @param newsz Array with new matrix size by all dimentions. If some sizes are zero,
|
||||
* the original sizes in those dimensions are presumed.
|
||||
*/
|
||||
Mat reshape(int cn, int newndims, const int* newsz) const;
|
||||
|
||||
/** @overload */
|
||||
/** @overload
|
||||
* @param cn New number of channels. If the parameter is 0, the number of channels remains the same.
|
||||
* @param newshape Vector with new matrix size by all dimentions. If some sizes are zero,
|
||||
* the original sizes in those dimensions are presumed.
|
||||
*/
|
||||
Mat reshape(int cn, const std::vector<int>& newshape) const;
|
||||
|
||||
/** @brief Transposes a matrix.
|
||||
|
||||
@@ -256,6 +256,7 @@ public:
|
||||
//! return codes for cv::solveLP() function
|
||||
enum SolveLPResult
|
||||
{
|
||||
SOLVELP_LOST = -3, //!< problem is feasible, but solver lost solution due to floating-point arithmetic errors
|
||||
SOLVELP_UNBOUNDED = -2, //!< problem is unbounded (target function can achieve arbitrary high values)
|
||||
SOLVELP_UNFEASIBLE = -1, //!< problem is unfeasible (there are no points that satisfy all the constraints imposed)
|
||||
SOLVELP_SINGLE = 0, //!< there is only one maximum for target function
|
||||
@@ -291,9 +292,13 @@ in the latter case it is understood to correspond to \f$c^T\f$.
|
||||
and the remaining to \f$A\f$. It should contain 32- or 64-bit floating point numbers.
|
||||
@param z The solution will be returned here as a column-vector - it corresponds to \f$c\f$ in the
|
||||
formulation above. It will contain 64-bit floating point numbers.
|
||||
@param constr_eps allowed numeric disparity for constraints
|
||||
@return One of cv::SolveLPResult
|
||||
*/
|
||||
CV_EXPORTS_W int solveLP(const Mat& Func, const Mat& Constr, Mat& z);
|
||||
CV_EXPORTS_W int solveLP(const Mat& Func, const Mat& Constr, Mat& z, double constr_eps);
|
||||
|
||||
/** @overload */
|
||||
CV_EXPORTS int solveLP(const Mat& Func, const Mat& Constr, Mat& z);
|
||||
|
||||
//! @}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#define CV_VERSION_MAJOR 3
|
||||
#define CV_VERSION_MINOR 4
|
||||
#define CV_VERSION_REVISION 19
|
||||
#define CV_VERSION_REVISION 20
|
||||
#define CV_VERSION_STATUS ""
|
||||
|
||||
#define CVAUX_STR_EXP(__A) #__A
|
||||
|
||||
@@ -122,10 +122,7 @@
|
||||
"}",
|
||||
"\n"
|
||||
]
|
||||
},
|
||||
"checkHardwareSupport" : {"j_code" : [""], "jn_code" : [""], "cpp_code" : [""] },
|
||||
"setUseOptimized" : {"j_code" : [""], "jn_code" : [""], "cpp_code" : [""] },
|
||||
"useOptimized" : {"j_code" : [""], "jn_code" : [""], "cpp_code" : [""] }
|
||||
}
|
||||
}
|
||||
},
|
||||
"func_arg_fix" : {
|
||||
|
||||
@@ -2059,4 +2059,12 @@ public class CoreTest extends OpenCVTestCase {
|
||||
assertEquals(Core.VERSION, Core.getVersionString());
|
||||
}
|
||||
|
||||
public void testHardwareOptions() {
|
||||
Core.checkHardwareSupport(0);
|
||||
boolean original_status = Core.useOptimized();
|
||||
Core.setUseOptimized(!original_status);
|
||||
assertEquals(!original_status, Core.useOptimized());
|
||||
Core.setUseOptimized(original_status);
|
||||
assertEquals(original_status, Core.useOptimized());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,10 +62,6 @@ static bool ipp_countNonZero( Mat &src, int &res )
|
||||
{
|
||||
CV_INSTRUMENT_REGION_IPP();
|
||||
|
||||
// see https://github.com/opencv/opencv/issues/17453
|
||||
if (src.dims <= 2 && src.step > 520000 && cv::ipp::getIppTopFeatures() == ippCPUID_SSE42)
|
||||
return false;
|
||||
|
||||
#if IPP_VERSION_X100 < 201801
|
||||
// Poor performance of SSE42
|
||||
if(cv::ipp::getIppTopFeatures() == ippCPUID_SSE42)
|
||||
|
||||
@@ -531,7 +531,7 @@ inline int hal_ni_dftFree1D(cvhalDFT *context) { return CV_HAL_ERROR_NOT_IMPLEME
|
||||
/**
|
||||
@param context double pointer to context storing all necessary data
|
||||
@param width,height image dimensions
|
||||
@param depth image type (CV_32F or CV64F)
|
||||
@param depth image type (CV_32F or CV_64F)
|
||||
@param src_channels number of channels in input image
|
||||
@param dst_channels number of channels in output image
|
||||
@param flags algorithm options (combination of CV_HAL_DFT_INVERSE, ...)
|
||||
@@ -558,7 +558,7 @@ inline int hal_ni_dftFree2D(cvhalDFT *context) { return CV_HAL_ERROR_NOT_IMPLEME
|
||||
/**
|
||||
@param context double pointer to context storing all necessary data
|
||||
@param width,height image dimensions
|
||||
@param depth image type (CV_32F or CV64F)
|
||||
@param depth image type (CV_32F or CV_64F)
|
||||
@param flags algorithm options (combination of CV_HAL_DFT_INVERSE, ...)
|
||||
*/
|
||||
inline int hal_ni_dctInit2D(cvhalDFT **context, int width, int height, int depth, int flags) { return CV_HAL_ERROR_NOT_IMPLEMENTED; }
|
||||
|
||||
@@ -90,7 +90,7 @@ static void swap_columns(Mat_<double>& A,int col1,int col2);
|
||||
#define SWAP(type,a,b) {type tmp=(a);(a)=(b);(b)=tmp;}
|
||||
|
||||
//return codes:-2 (no_sol - unbdd),-1(no_sol - unfsbl), 0(single_sol), 1(multiple_sol=>least_l2_norm)
|
||||
int solveLP(const Mat& Func, const Mat& Constr, Mat& z){
|
||||
int solveLP(const Mat& Func, const Mat& Constr, Mat& z, double constr_eps){
|
||||
dprintf(("call to solveLP\n"));
|
||||
|
||||
//sanity check (size, type, no. of channels)
|
||||
@@ -140,9 +140,24 @@ int solveLP(const Mat& Func, const Mat& Constr, Mat& z){
|
||||
}
|
||||
}
|
||||
|
||||
//check constraints feasibility
|
||||
Mat prod = Constr(Rect(0, 0, Constr.cols - 1, Constr.rows)) * z;
|
||||
Mat constr_check = Constr.col(Constr.cols - 1) - prod;
|
||||
double min_value = 0.0;
|
||||
minMaxIdx(constr_check, &min_value);
|
||||
if (min_value < -constr_eps)
|
||||
{
|
||||
return SOLVELP_LOST;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
CV_EXPORTS_W int solveLP(const Mat& Func, const Mat& Constr, Mat& z)
|
||||
{
|
||||
return solveLP(Func, Constr, z, 1e-12);
|
||||
}
|
||||
|
||||
static int initialize_simplex(Mat_<double>& c, Mat_<double>& b,double& v,vector<int>& N,vector<int>& B,vector<unsigned int>& indexToRow){
|
||||
N.resize(c.cols);
|
||||
N[0]=0;
|
||||
@@ -255,7 +270,7 @@ static int inner_simplex(Mat_<double>& c, Mat_<double>& b,double& v,vector<int>&
|
||||
dprintf(("iteration #%d\n",count));
|
||||
count++;
|
||||
|
||||
static MatIterator_<double> pos_ptr;
|
||||
MatIterator_<double> pos_ptr;
|
||||
int e=-1,pos_ctr=0,min_var=INT_MAX;
|
||||
bool all_nonzero=true;
|
||||
for(pos_ptr=c.begin();pos_ptr!=c.end();pos_ptr++,pos_ctr++){
|
||||
|
||||
@@ -7,10 +7,6 @@
|
||||
#include "mathfuncs_core.simd.hpp"
|
||||
#include "mathfuncs_core.simd_declarations.hpp" // defines CV_CPU_DISPATCH_MODES_ALL=AVX2,...,BASELINE based on CMakeLists.txt content
|
||||
|
||||
|
||||
#define IPP_DISABLE_MAGNITUDE_32F 1 // accuracy: https://github.com/opencv/opencv/issues/19506
|
||||
|
||||
|
||||
namespace cv { namespace hal {
|
||||
|
||||
///////////////////////////////////// ATAN2 ////////////////////////////////////
|
||||
@@ -48,25 +44,8 @@ void magnitude32f(const float* x, const float* y, float* mag, int len)
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
CALL_HAL(magnitude32f, cv_hal_magnitude32f, x, y, mag, len);
|
||||
|
||||
#ifdef HAVE_IPP
|
||||
bool allowIPP = true;
|
||||
#ifdef IPP_DISABLE_MAGNITUDE_32F
|
||||
if (cv::ipp::getIppTopFeatures() & (
|
||||
#if IPP_VERSION_X100 >= 201700
|
||||
ippCPUID_AVX512F |
|
||||
#endif
|
||||
ippCPUID_AVX2)
|
||||
)
|
||||
{
|
||||
allowIPP = (len & 7) == 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// SSE42 performance issues
|
||||
CV_IPP_RUN((IPP_VERSION_X100 > 201800 || cv::ipp::getIppTopFeatures() != ippCPUID_SSE42) && allowIPP,
|
||||
CV_INSTRUMENT_FUN_IPP(ippsMagnitude_32f, x, y, mag, len) >= 0);
|
||||
#endif
|
||||
CV_IPP_RUN(IPP_VERSION_X100 > 201800 || cv::ipp::getIppTopFeatures() != ippCPUID_SSE42, CV_INSTRUMENT_FUN_IPP(ippsMagnitude_32f, x, y, mag, len) >= 0);
|
||||
|
||||
CV_CPU_DISPATCH(magnitude32f, (x, y, mag, len),
|
||||
CV_CPU_DISPATCH_MODES_ALL);
|
||||
|
||||
@@ -972,16 +972,6 @@ static bool ipp_norm(InputArray _src1, InputArray _src2, int normType, InputArra
|
||||
type == CV_16UC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_L2_16u_C3CMR :
|
||||
type == CV_32FC3 ? (ippiMaskNormDiffFuncC3)ippiNormDiff_L2_32f_C3CMR :
|
||||
0) : 0;
|
||||
if (cv::ipp::getIppTopFeatures() & (
|
||||
#if IPP_VERSION_X100 >= 201700
|
||||
ippCPUID_AVX512F |
|
||||
#endif
|
||||
ippCPUID_AVX2)
|
||||
) // IPP_DISABLE_NORM_16UC3_mask_small (#11399)
|
||||
{
|
||||
if (normType == NORM_L1 && type == CV_16UC3 && sz.width < 16)
|
||||
return false;
|
||||
}
|
||||
if( ippiNormDiff_C3CMR )
|
||||
{
|
||||
Ipp64f norm1, norm2, norm3;
|
||||
|
||||
@@ -1240,7 +1240,7 @@ struct Device::Impl
|
||||
if (vendorName_ == "Advanced Micro Devices, Inc." ||
|
||||
vendorName_ == "AMD")
|
||||
vendorID_ = VENDOR_AMD;
|
||||
else if (vendorName_ == "Intel(R) Corporation" || vendorName_ == "Intel" || strstr(name_.c_str(), "Iris") != 0)
|
||||
else if (vendorName_ == "Intel(R) Corporation" || vendorName_ == "Intel" || vendorName_ == "Intel Inc." || strstr(name_.c_str(), "Iris") != 0)
|
||||
vendorID_ = VENDOR_INTEL;
|
||||
else if (vendorName_ == "NVIDIA Corporation")
|
||||
vendorID_ = VENDOR_NVIDIA;
|
||||
|
||||
@@ -101,7 +101,6 @@
|
||||
#endif
|
||||
#include "tbb/tbb.h"
|
||||
#include "tbb/task.h"
|
||||
#include "tbb/tbb_stddef.h"
|
||||
#if TBB_INTERFACE_VERSION >= 8000
|
||||
#include "tbb/task_arena.h"
|
||||
#endif
|
||||
@@ -119,6 +118,8 @@
|
||||
#include <ppltasks.h>
|
||||
#elif defined HAVE_CONCURRENCY
|
||||
#include <ppl.h>
|
||||
#elif defined HAVE_PTHREADS_PF
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
|
||||
@@ -263,7 +264,9 @@ namespace {
|
||||
void recordException(const cv::String& msg)
|
||||
#endif
|
||||
{
|
||||
#ifndef CV_THREAD_SANITIZER
|
||||
if (!hasException)
|
||||
#endif
|
||||
{
|
||||
cv::AutoLock lock(cv::getInitializationMutex());
|
||||
if (!hasException)
|
||||
|
||||
@@ -243,6 +243,7 @@ std::wstring GetTempFileNameWinRT(std::wstring prefix)
|
||||
#if defined __MACH__ && defined __APPLE__
|
||||
#include <mach/mach.h>
|
||||
#include <mach/mach_time.h>
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -627,6 +628,14 @@ struct HWFeatures
|
||||
#if (defined __ARM_FP && (((__ARM_FP & 0x2) != 0) && defined __ARM_NEON__))
|
||||
have[CV_CPU_FP16] = true;
|
||||
#endif
|
||||
#if (defined __ARM_FEATURE_DOTPROD)
|
||||
int has_feat_dotprod = 0;
|
||||
size_t has_feat_dotprod_size = sizeof(has_feat_dotprod);
|
||||
sysctlbyname("hw.optional.arm.FEAT_DotProd", &has_feat_dotprod, &has_feat_dotprod_size, NULL, 0);
|
||||
if (has_feat_dotprod) {
|
||||
have[CV_CPU_NEON_DOTPROD] = true;
|
||||
}
|
||||
#endif
|
||||
#elif (defined __clang__)
|
||||
#if (defined __ARM_NEON__ || (defined __ARM_NEON && defined __aarch64__))
|
||||
have[CV_CPU_NEON] = true;
|
||||
|
||||
@@ -97,7 +97,7 @@ template <typename R> struct Data
|
||||
{
|
||||
*this = r;
|
||||
}
|
||||
operator R ()
|
||||
operator R () const
|
||||
{
|
||||
return initializer<R::nlanes>().init(*this);
|
||||
}
|
||||
@@ -1559,11 +1559,34 @@ template<typename R> struct TheTest
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CV_SIMD_64F
|
||||
void do_check_cmp64(const Data<R>& dataA, const Data<R>& dataB)
|
||||
{
|
||||
R a = dataA;
|
||||
R b = dataB;
|
||||
|
||||
Data<R> dataEQ = (a == b);
|
||||
Data<R> dataNE = (a != b);
|
||||
|
||||
for (int i = 0; i < R::nlanes; ++i)
|
||||
{
|
||||
SCOPED_TRACE(cv::format("i=%d", i));
|
||||
if (cvtest::debugLevel > 0) cout << "i=" << i << " ( " << dataA[i] << " vs " << dataB[i] << " ): eq=" << dataEQ[i] << " ne=" << dataNE[i] << endl;
|
||||
EXPECT_NE((LaneType)dataEQ[i], (LaneType)dataNE[i]);
|
||||
if (dataA[i] == dataB[i])
|
||||
EXPECT_EQ((LaneType)-1, (LaneType)dataEQ[i]);
|
||||
else
|
||||
EXPECT_EQ((LaneType)0, (LaneType)dataEQ[i]);
|
||||
if (dataA[i] != dataB[i])
|
||||
EXPECT_EQ((LaneType)-1, (LaneType)dataNE[i]);
|
||||
else
|
||||
EXPECT_EQ((LaneType)0, (LaneType)dataNE[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TheTest & test_cmp64()
|
||||
{
|
||||
Data<R> dataA, dataB;
|
||||
R a = dataA, b = dataB;
|
||||
Data<R> dataA;
|
||||
Data<R> dataB;
|
||||
|
||||
for (int i = 0; i < R::nlanes; ++i)
|
||||
{
|
||||
@@ -1571,37 +1594,25 @@ template<typename R> struct TheTest
|
||||
}
|
||||
dataA[0]++;
|
||||
|
||||
a = dataA, b = dataB;
|
||||
do_check_cmp64(dataA, dataB);
|
||||
do_check_cmp64(dataB, dataA);
|
||||
|
||||
Data<R> resC = (a == b);
|
||||
Data<R> resD = (a != b);
|
||||
dataA[0] = dataB[0];
|
||||
dataA[1] += (((LaneType)1) << 32);
|
||||
do_check_cmp64(dataA, dataB);
|
||||
do_check_cmp64(dataB, dataA);
|
||||
|
||||
for (int i = 0; i < R::nlanes; ++i)
|
||||
{
|
||||
SCOPED_TRACE(cv::format("i=%d", i));
|
||||
EXPECT_EQ(dataA[i] == dataB[i], resC[i] != 0);
|
||||
EXPECT_EQ(dataA[i] != dataB[i], resD[i] != 0);
|
||||
}
|
||||
dataA[0] = (LaneType)-1;
|
||||
dataB[0] = (LaneType)-1;
|
||||
dataA[1] = (LaneType)-1;
|
||||
dataB[1] = (LaneType)2;
|
||||
|
||||
for (int i = 0; i < R::nlanes; ++i)
|
||||
{
|
||||
dataA[i] = dataB[i] = (LaneType)-1;
|
||||
}
|
||||
do_check_cmp64(dataA, dataB);
|
||||
do_check_cmp64(dataB, dataA);
|
||||
|
||||
a = dataA, b = dataB;
|
||||
|
||||
resC = (a == b);
|
||||
resD = (a != b);
|
||||
|
||||
for (int i = 0; i < R::nlanes; ++i)
|
||||
{
|
||||
SCOPED_TRACE(cv::format("i=%d", i));
|
||||
EXPECT_EQ(dataA[i] == dataB[i], resC[i] != 0);
|
||||
EXPECT_EQ(dataA[i] != dataB[i], resD[i] != 0);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -1837,9 +1848,8 @@ void test_hal_intrin_uint64()
|
||||
TheTest<v_uint64>()
|
||||
.test_loadstore()
|
||||
.test_addsub()
|
||||
#if CV_SIMD_64F
|
||||
.test_cmp64()
|
||||
#endif
|
||||
//.test_cmp() - not declared as supported
|
||||
.test_shift<1>().test_shift<8>()
|
||||
.test_logic()
|
||||
.test_reverse()
|
||||
@@ -1857,9 +1867,8 @@ void test_hal_intrin_int64()
|
||||
TheTest<v_int64>()
|
||||
.test_loadstore()
|
||||
.test_addsub()
|
||||
#if CV_SIMD_64F
|
||||
.test_cmp64()
|
||||
#endif
|
||||
//.test_cmp() - not declared as supported
|
||||
.test_shift<1>().test_shift<8>()
|
||||
.test_logic()
|
||||
.test_reverse()
|
||||
@@ -1936,7 +1945,8 @@ void test_hal_intrin_float64()
|
||||
.test_rotate<2>().test_rotate<3>()
|
||||
#endif
|
||||
;
|
||||
|
||||
#else
|
||||
std::cout << "SKIP: CV_SIMD_64F is not available" << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -151,4 +151,18 @@ TEST(Core_LPSolver, issue_12337)
|
||||
//need to update interface: EXPECT_ANY_THROW(Mat1b z_8u; cv::solveLP(A, B, z_8u));
|
||||
}
|
||||
|
||||
// NOTE: Test parameters found experimentally to get numerically inaccurate result.
|
||||
// The test behaviour may change after algorithm tuning and may removed.
|
||||
TEST(Core_LPSolver, issue_12343)
|
||||
{
|
||||
Mat A = (cv::Mat_<double>(4, 1) << 3., 3., 3., 4.);
|
||||
Mat B = (cv::Mat_<double>(4, 5) << 0., 1., 4., 4., 3.,
|
||||
3., 1., 2., 2., 3.,
|
||||
4., 4., 0., 1., 4.,
|
||||
4., 0., 4., 1., 4.);
|
||||
Mat z;
|
||||
int result = cv::solveLP(A, B, z);
|
||||
EXPECT_EQ(SOLVELP_LOST, result);
|
||||
}
|
||||
|
||||
}} // namespace
|
||||
|
||||
@@ -3992,6 +3992,13 @@ TEST(Core_FastMath, InlineNaN)
|
||||
EXPECT_EQ( cvIsNaN((double) NAN), 1);
|
||||
EXPECT_EQ( cvIsNaN((double) -NAN), 1);
|
||||
EXPECT_EQ( cvIsNaN(0.0), 0);
|
||||
|
||||
// Regression: check the +/-Inf cases
|
||||
Cv64suf suf;
|
||||
suf.u = 0x7FF0000000000000UL;
|
||||
EXPECT_EQ( cvIsNaN(suf.f), 0);
|
||||
suf.u = 0xFFF0000000000000UL;
|
||||
EXPECT_EQ( cvIsNaN(suf.f), 0);
|
||||
}
|
||||
|
||||
TEST(Core_FastMath, InlineIsInf)
|
||||
@@ -4003,6 +4010,13 @@ TEST(Core_FastMath, InlineIsInf)
|
||||
EXPECT_EQ( cvIsInf((double) HUGE_VAL), 1);
|
||||
EXPECT_EQ( cvIsInf((double) -HUGE_VAL), 1);
|
||||
EXPECT_EQ( cvIsInf(0.0), 0);
|
||||
|
||||
// Regression: check the cases of 0x7FF00000xxxxxxxx
|
||||
Cv64suf suf;
|
||||
suf.u = 0x7FF0000000000001UL;
|
||||
EXPECT_EQ( cvIsInf(suf.f), 0);
|
||||
suf.u = 0x7FF0000012345678UL;
|
||||
EXPECT_EQ( cvIsInf(suf.f), 0);
|
||||
}
|
||||
|
||||
}} // namespace
|
||||
|
||||
@@ -680,7 +680,14 @@ struct SigmoidFunctor : public BaseDefaultFunctor<SigmoidFunctor>
|
||||
|
||||
inline float calculate(float x) const
|
||||
{
|
||||
return 1.f / (1.f + exp(-x));
|
||||
float y;
|
||||
if (x >= 0)
|
||||
y = 1.f / (1.f + exp(-x));
|
||||
else {
|
||||
y = exp(x);
|
||||
y = y / (1 + y);
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
#ifdef HAVE_HALIDE
|
||||
|
||||
@@ -243,7 +243,7 @@ private:
|
||||
else
|
||||
mask0 = mask;
|
||||
pose = Matx23f(1,0,0,
|
||||
0,1,0);
|
||||
0,1,0);
|
||||
|
||||
if( phi == 0 )
|
||||
image.copyTo(rotImage);
|
||||
@@ -276,6 +276,8 @@ private:
|
||||
}
|
||||
if( phi != 0 || tilt != 1 )
|
||||
warpAffine(mask0, warpedMask, pose, warpedImage.size(), INTER_NEAREST);
|
||||
else
|
||||
warpedMask = mask0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -807,11 +807,18 @@ if( dstMat.type() == CV_32F )
|
||||
__dst = v_min(v_max(v_cvt_f32(v_round(__dst * __nrm2)), __min), __max);
|
||||
v_store(dst + k, __dst);
|
||||
}
|
||||
#endif
|
||||
#if defined(__GNUC__) && __GNUC__ >= 9
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Waggressive-loop-optimizations" // iteration XX invokes undefined behavior
|
||||
#endif
|
||||
for( ; k < len; k++ )
|
||||
{
|
||||
dst[k] = saturate_cast<uchar>(rawDst[k]*nrm2);
|
||||
}
|
||||
#if defined(__GNUC__) && __GNUC__ >= 9
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
}
|
||||
else // CV_8U
|
||||
{
|
||||
@@ -831,9 +838,8 @@ else // CV_8U
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ >= 9
|
||||
// avoid warning "iteration 7 invokes undefined behavior" on Linux ARM64
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Waggressive-loop-optimizations"
|
||||
#pragma GCC diagnostic ignored "-Waggressive-loop-optimizations" // iteration XX invokes undefined behavior
|
||||
#endif
|
||||
for( ; k < len; k++ )
|
||||
{
|
||||
@@ -844,7 +850,6 @@ else // CV_8U
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
float* dst = dstMat.ptr<float>(row);
|
||||
float nrm1 = 0;
|
||||
for( k = 0; k < len; k++ )
|
||||
{
|
||||
@@ -852,20 +857,22 @@ else // CV_8U
|
||||
nrm1 += rawDst[k];
|
||||
}
|
||||
nrm1 = 1.f/std::max(nrm1, FLT_EPSILON);
|
||||
if( dstMat.type() == CV_32F )
|
||||
{
|
||||
for( k = 0; k < len; k++ )
|
||||
if( dstMat.type() == CV_32F )
|
||||
{
|
||||
dst[k] = std::sqrt(rawDst[k] * nrm1);
|
||||
float *dst = dstMat.ptr<float>(row);
|
||||
for( k = 0; k < len; k++ )
|
||||
{
|
||||
dst[k] = std::sqrt(rawDst[k] * nrm1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else // CV_8U
|
||||
{
|
||||
for( k = 0; k < len; k++ )
|
||||
else // CV_8U
|
||||
{
|
||||
dst[k] = saturate_cast<uchar>(std::sqrt(rawDst[k] * nrm1)*SIFT_INT_DESCR_FCTR);
|
||||
uint8_t *dst = dstMat.ptr<uint8_t>(row);
|
||||
for( k = 0; k < len; k++ )
|
||||
{
|
||||
dst[k] = saturate_cast<uchar>(std::sqrt(rawDst[k] * nrm1)*SIFT_INT_DESCR_FCTR);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -182,4 +182,26 @@ TEST(Features2d_AFFINE_FEATURE, regression)
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Features2d_AFFINE_FEATURE, mask)
|
||||
{
|
||||
Mat gray = imread(cvtest::findDataFile("features2d/tsukuba.png"), IMREAD_GRAYSCALE);
|
||||
ASSERT_FALSE(gray.empty()) << "features2d/tsukuba.png image was not found in test data!";
|
||||
|
||||
// small tilt range to limit internal mask warping
|
||||
Ptr<AffineFeature> ext = AffineFeature::create(SIFT::create(), 1, 0);
|
||||
Mat mask = Mat::zeros(gray.size(), CV_8UC1);
|
||||
mask(Rect(50, 50, mask.cols-100, mask.rows-100)).setTo(255);
|
||||
|
||||
// calc and compare keypoints
|
||||
vector<KeyPoint> calcKeypoints;
|
||||
ext->detectAndCompute(gray, mask, calcKeypoints, noArray(), false);
|
||||
|
||||
// added expanded test range to cover sub-pixel coordinates for features on mask border
|
||||
for( size_t i = 0; i < calcKeypoints.size(); i++ )
|
||||
{
|
||||
ASSERT_TRUE((calcKeypoints[i].pt.x >= 50-1) && (calcKeypoints[i].pt.x <= mask.cols-50+1));
|
||||
ASSERT_TRUE((calcKeypoints[i].pt.y >= 50-1) && (calcKeypoints[i].pt.y <= mask.rows-50+1));
|
||||
}
|
||||
}
|
||||
|
||||
}} // namespace
|
||||
|
||||
@@ -406,7 +406,7 @@ TEST( Features2d_DescriptorExtractor, batch_ORB )
|
||||
for( i = 0; i < n; i++ )
|
||||
{
|
||||
string imgname = format("%s/img%d.png", path.c_str(), i+1);
|
||||
Mat img = imread(imgname, 0);
|
||||
Mat img = imread(imgname, IMREAD_GRAYSCALE);
|
||||
imgs.push_back(img);
|
||||
}
|
||||
|
||||
@@ -434,7 +434,7 @@ TEST( Features2d_DescriptorExtractor, batch_SIFT )
|
||||
for( i = 0; i < n; i++ )
|
||||
{
|
||||
string imgname = format("%s/img%d.png", path.c_str(), i+1);
|
||||
Mat img = imread(imgname, 0);
|
||||
Mat img = imread(imgname, IMREAD_GRAYSCALE);
|
||||
imgs.push_back(img);
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,21 @@
|
||||
|
||||
namespace cvflann
|
||||
{
|
||||
class FILEScopeGuard {
|
||||
|
||||
public:
|
||||
explicit FILEScopeGuard(FILE* file) {
|
||||
file_ = file;
|
||||
};
|
||||
|
||||
~FILEScopeGuard() {
|
||||
fclose(file_);
|
||||
};
|
||||
|
||||
private:
|
||||
FILE* file_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the log level used for all flann functions
|
||||
@@ -69,7 +84,6 @@ struct SavedIndexParams : public IndexParams
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename Distance>
|
||||
NNIndex<Distance>* load_saved_index(const Matrix<typename Distance::ElementType>& dataset, const cv::String& filename, Distance distance)
|
||||
{
|
||||
@@ -79,13 +93,13 @@ NNIndex<Distance>* load_saved_index(const Matrix<typename Distance::ElementType>
|
||||
if (fin == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
FILEScopeGuard fscgd(fin);
|
||||
|
||||
IndexHeader header = load_header(fin);
|
||||
if (header.data_type != Datatype<ElementType>::type()) {
|
||||
fclose(fin);
|
||||
FLANN_THROW(cv::Error::StsError, "Datatype of saved index is different than of the one to be created.");
|
||||
}
|
||||
if ((size_t(header.rows) != dataset.rows)||(size_t(header.cols) != dataset.cols)) {
|
||||
fclose(fin);
|
||||
FLANN_THROW(cv::Error::StsError, "The index saved belongs to a different dataset");
|
||||
}
|
||||
|
||||
@@ -93,7 +107,6 @@ NNIndex<Distance>* load_saved_index(const Matrix<typename Distance::ElementType>
|
||||
params["algorithm"] = header.index_type;
|
||||
NNIndex<Distance>* nnIndex = create_index_by_type<Distance>(dataset, params, distance);
|
||||
nnIndex->loadIndex(fin);
|
||||
fclose(fin);
|
||||
|
||||
return nnIndex;
|
||||
}
|
||||
@@ -107,7 +120,7 @@ public:
|
||||
typedef typename Distance::ResultType DistanceType;
|
||||
|
||||
Index(const Matrix<ElementType>& features, const IndexParams& params, Distance distance = Distance() )
|
||||
: index_params_(params)
|
||||
:index_params_(params)
|
||||
{
|
||||
flann_algorithm_t index_type = get_param<flann_algorithm_t>(params,"algorithm");
|
||||
loaded_ = false;
|
||||
|
||||
@@ -246,7 +246,6 @@ void test_index_precisions(NNIndex<Distance>& index, const Matrix<typename Dista
|
||||
float p2;
|
||||
|
||||
int c1 = 1;
|
||||
float p1;
|
||||
|
||||
float time;
|
||||
DistanceType dist;
|
||||
@@ -270,7 +269,6 @@ void test_index_precisions(NNIndex<Distance>& index, const Matrix<typename Dista
|
||||
precision = precisions[i];
|
||||
while (p2<precision) {
|
||||
c1 = c2;
|
||||
p1 = p2;
|
||||
c2 *=2;
|
||||
p2 = search_with_ground_truth(index, inputData, testData, matches, nn, c2, time, dist, distance, skipMatches);
|
||||
if ((maxTime> 0)&&(time > maxTime)&&(p2<precision)) return;
|
||||
|
||||
@@ -767,11 +767,15 @@ bool Index::load(InputArray _data, const String& filename)
|
||||
Mat data = _data.getMat();
|
||||
bool ok = true;
|
||||
release();
|
||||
|
||||
FILE* fin = fopen(filename.c_str(), "rb");
|
||||
if (fin == NULL)
|
||||
if (fin == NULL) {
|
||||
return false;
|
||||
}
|
||||
FILEScopeGuard fscgd(fin);
|
||||
|
||||
::cvflann::IndexHeader header = ::cvflann::load_header(fin);
|
||||
|
||||
algo = header.index_type;
|
||||
featureType = header.data_type == FLANN_UINT8 ? CV_8U :
|
||||
header.data_type == FLANN_INT8 ? CV_8S :
|
||||
@@ -786,7 +790,6 @@ bool Index::load(InputArray _data, const String& filename)
|
||||
{
|
||||
fprintf(stderr, "Reading FLANN index error: the saved data size (%d, %d) or type (%d) is different from the passed one (%d, %d), %d\n",
|
||||
(int)header.rows, (int)header.cols, featureType, data.rows, data.cols, data.type());
|
||||
fclose(fin);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -799,7 +802,6 @@ bool Index::load(InputArray _data, const String& filename)
|
||||
(distType != FLANN_DIST_HAMMING && featureType == CV_32F)) )
|
||||
{
|
||||
fprintf(stderr, "Reading FLANN index error: unsupported feature type %d for the index type %d\n", featureType, algo);
|
||||
fclose(fin);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -839,8 +841,6 @@ bool Index::load(InputArray _data, const String& filename)
|
||||
ok = false;
|
||||
}
|
||||
|
||||
if( fin )
|
||||
fclose(fin);
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
@@ -618,7 +618,7 @@ CV_IMPL int cvWaitKey (int maxWait)
|
||||
inMode:NSDefaultRunLoopMode
|
||||
dequeue:YES];
|
||||
|
||||
if([event type] == NSKeyDown) {
|
||||
if([event type] == NSKeyDown && [[event characters] length]) {
|
||||
returnCode = [[event characters] characterAtIndex:0];
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2205,21 +2205,6 @@ icvCreateTrackbar( const char* trackbar_name, const char* window_name,
|
||||
/* Retrieve current buttons count */
|
||||
bcount = (int)SendMessage(window->toolbar.toolbar, TB_BUTTONCOUNT, 0, 0);
|
||||
|
||||
if (bcount > 0)
|
||||
{
|
||||
/* If this is not the first button then we need to
|
||||
separate it from the previous one */
|
||||
tbs.iBitmap = 0;
|
||||
tbs.idCommand = bcount; // Set button id to it's number
|
||||
tbs.iString = 0;
|
||||
tbs.fsStyle = TBSTYLE_SEP;
|
||||
tbs.fsState = TBSTATE_ENABLED;
|
||||
SendMessage(window->toolbar.toolbar, TB_ADDBUTTONS, 1, (LPARAM)&tbs);
|
||||
|
||||
// Retrieve current buttons count
|
||||
bcount = (int)SendMessage(window->toolbar.toolbar, TB_BUTTONCOUNT, 0, 0);
|
||||
}
|
||||
|
||||
/* Add a button which we're going to cover with the slider */
|
||||
tbs.iBitmap = 0;
|
||||
tbs.idCommand = bcount; // Set button id to it's number
|
||||
|
||||
@@ -218,17 +218,26 @@ CV_EXPORTS_W bool imreadmulti(const String& filename, CV_OUT std::vector<Mat>& m
|
||||
/** @brief Saves an image to a specified file.
|
||||
|
||||
The function imwrite saves the image to the specified file. The image format is chosen based on the
|
||||
filename extension (see cv::imread for the list of extensions). In general, only 8-bit
|
||||
filename extension (see cv::imread for the list of extensions). In general, only 8-bit unsigned (CV_8U)
|
||||
single-channel or 3-channel (with 'BGR' channel order) images
|
||||
can be saved using this function, with these exceptions:
|
||||
|
||||
- 16-bit unsigned (CV_16U) images can be saved in the case of PNG, JPEG 2000, and TIFF formats
|
||||
- 32-bit float (CV_32F) images can be saved in TIFF, OpenEXR, and Radiance HDR formats; 3-channel
|
||||
(CV_32FC3) TIFF images will be saved using the LogLuv high dynamic range encoding (4 bytes per pixel)
|
||||
- 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
|
||||
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).
|
||||
- With OpenEXR encoder, only 32-bit float (CV_32F) images can be saved.
|
||||
- 8-bit unsigned (CV_8U) images are not supported.
|
||||
- With Radiance HDR encoder, non 64-bit float (CV_64F) images can be saved.
|
||||
- All images will be converted to 32-bit float (CV_32F).
|
||||
- With JPEG 2000 encoder, 8-bit unsigned (CV_8U) and 16-bit unsigned (CV_16U) images can be saved.
|
||||
- With PAM encoder, 8-bit unsigned (CV_8U) and 16-bit unsigned (CV_16U) images can be saved.
|
||||
- With PNG encoder, 8-bit unsigned (CV_8U) and 16-bit unsigned (CV_16U) images can be saved.
|
||||
- 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
|
||||
should have alpha set to 0, fully opaque pixels should have alpha set to 255/65535 (see the code sample below).
|
||||
- With PGM/PPM encoder, 8-bit unsigned (CV_8U) and 16-bit unsigned (CV_16U) images can be saved.
|
||||
- With TIFF encoder, 8-bit unsigned (CV_8U), 16-bit unsigned (CV_16U),
|
||||
32-bit float (CV_32F) and 64-bit float (CV_64F) images can be saved.
|
||||
- Multiple images (vector of Mat) can be saved in TIFF format (see the code sample below).
|
||||
- 32-bit float 3-channel (CV_32FC3) TIFF images will be saved
|
||||
using the LogLuv high dynamic range encoding (4 bytes per pixel)
|
||||
|
||||
If the image format is not supported, the image will be converted to 8-bit unsigned (CV_8U) and saved that way.
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ public class ImgcodecsTest extends OpenCVTestCase {
|
||||
}
|
||||
|
||||
public void testImreadStringInt() {
|
||||
dst = Imgcodecs.imread(OpenCVTestRunner.LENA_PATH, 0);
|
||||
dst = Imgcodecs.imread(OpenCVTestRunner.LENA_PATH, Imgcodecs.IMREAD_GRAYSCALE);
|
||||
assertFalse(dst.empty());
|
||||
assertEquals(1, dst.channels());
|
||||
assertTrue(512 == dst.cols());
|
||||
|
||||
@@ -72,7 +72,7 @@ struct Set<i0, -1, -1>
|
||||
|
||||
enum SizePolicy
|
||||
{
|
||||
TO_YUV, FROM_YUV, NONE
|
||||
TO_YUV, FROM_YUV, FROM_UYVY, NONE
|
||||
};
|
||||
|
||||
template< typename VScn, typename VDcn, typename VDepth, SizePolicy sizePolicy = NONE >
|
||||
@@ -104,6 +104,10 @@ struct CvtHelper
|
||||
CV_Assert( sz.width % 2 == 0 && sz.height % 3 == 0);
|
||||
dstSz = Size(sz.width, sz.height * 2 / 3);
|
||||
break;
|
||||
case FROM_UYVY:
|
||||
CV_Assert( sz.width % 2 == 0);
|
||||
dstSz = sz;
|
||||
break;
|
||||
case NONE:
|
||||
default:
|
||||
dstSz = sz;
|
||||
|
||||
@@ -419,6 +419,14 @@ inline void HSV2RGB_simd(const v_float32& h, const v_float32& s, const v_float32
|
||||
}
|
||||
#endif
|
||||
|
||||
// Compute the sector and the new H for HSV and HLS 2 RGB conversions.
|
||||
inline void ComputeSectorAndClampedH(float& h, int §or) {
|
||||
sector = cvFloor(h);
|
||||
h -= sector;
|
||||
sector %= 6;
|
||||
sector += sector < 0 ? 6 : 0;
|
||||
}
|
||||
|
||||
|
||||
inline void HSV2RGB_native(float h, float s, float v,
|
||||
float& b, float& g, float& r,
|
||||
@@ -433,14 +441,7 @@ inline void HSV2RGB_native(float h, float s, float v,
|
||||
float tab[4];
|
||||
int sector;
|
||||
h *= hscale;
|
||||
h = fmod(h, 6.f);
|
||||
sector = cvFloor(h);
|
||||
h -= sector;
|
||||
if( (unsigned)sector >= 6u )
|
||||
{
|
||||
sector = 0;
|
||||
h = 0.f;
|
||||
}
|
||||
ComputeSectorAndClampedH(h, sector);
|
||||
|
||||
tab[0] = v;
|
||||
tab[1] = v*(1.f - s);
|
||||
@@ -987,13 +988,7 @@ struct HLS2RGB_f
|
||||
float p1 = 2*l - p2;
|
||||
|
||||
h *= hscale;
|
||||
// We need both loops to clamp (e.g. for h == -1e-40).
|
||||
while( h < 0 ) h += 6;
|
||||
while( h >= 6 ) h -= 6;
|
||||
|
||||
CV_DbgAssert( 0 <= h && h < 6 );
|
||||
sector = cvFloor(h);
|
||||
h -= sector;
|
||||
ComputeSectorAndClampedH(h, sector);
|
||||
|
||||
tab[0] = p2;
|
||||
tab[1] = p1;
|
||||
|
||||
@@ -354,7 +354,7 @@ void cvtColorYUV2BGR(InputArray _src, OutputArray _dst, int dcn, bool swapb, boo
|
||||
|
||||
void cvtColorOnePlaneYUV2BGR( InputArray _src, OutputArray _dst, int dcn, bool swapb, int uidx, int ycn)
|
||||
{
|
||||
CvtHelper< Set<2>, Set<3, 4>, Set<CV_8U> > h(_src, _dst, dcn);
|
||||
CvtHelper< Set<2>, Set<3, 4>, Set<CV_8U>, FROM_UYVY > h(_src, _dst, dcn);
|
||||
|
||||
hal::cvtOnePlaneYUVtoBGR(h.src.data, h.src.step, h.dst.data, h.dst.step, h.src.cols, h.src.rows,
|
||||
dcn, swapb, uidx, ycn);
|
||||
|
||||
@@ -448,7 +448,7 @@ static void getDistanceTransformMask( int maskType, float *metrics )
|
||||
|
||||
struct DTColumnInvoker : ParallelLoopBody
|
||||
{
|
||||
DTColumnInvoker( const Mat* _src, Mat* _dst, const int* _sat_tab, const float* _sqr_tab)
|
||||
DTColumnInvoker( const Mat* _src, Mat* _dst, const int* _sat_tab, const int* _sqr_tab)
|
||||
{
|
||||
src = _src;
|
||||
dst = _dst;
|
||||
@@ -481,7 +481,7 @@ struct DTColumnInvoker : ParallelLoopBody
|
||||
{
|
||||
dist = dist + 1 - sat_tab[dist - d[j]];
|
||||
d[j] = dist;
|
||||
dptr[0] = sqr_tab[dist];
|
||||
dptr[0] = (float)sqr_tab[dist];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -489,12 +489,12 @@ struct DTColumnInvoker : ParallelLoopBody
|
||||
const Mat* src;
|
||||
Mat* dst;
|
||||
const int* sat_tab;
|
||||
const float* sqr_tab;
|
||||
const int* sqr_tab;
|
||||
};
|
||||
|
||||
struct DTRowInvoker : ParallelLoopBody
|
||||
{
|
||||
DTRowInvoker( Mat* _dst, const float* _sqr_tab, const float* _inv_tab )
|
||||
DTRowInvoker( Mat* _dst, const int* _sqr_tab, const float* _inv_tab )
|
||||
{
|
||||
dst = _dst;
|
||||
sqr_tab = _sqr_tab;
|
||||
@@ -529,7 +529,7 @@ struct DTRowInvoker : ParallelLoopBody
|
||||
for(;;k--)
|
||||
{
|
||||
p = v[k];
|
||||
float s = (fq + sqr_tab[q] - d[p] - sqr_tab[p])*inv_tab[q - p];
|
||||
float s = (fq - d[p] + (sqr_tab[q]-sqr_tab[p]))*inv_tab[q - p];
|
||||
if( s > z[k] )
|
||||
{
|
||||
k++;
|
||||
@@ -552,28 +552,28 @@ struct DTRowInvoker : ParallelLoopBody
|
||||
}
|
||||
|
||||
Mat* dst;
|
||||
const float* sqr_tab;
|
||||
const int* sqr_tab;
|
||||
const float* inv_tab;
|
||||
};
|
||||
|
||||
static void
|
||||
trueDistTrans( const Mat& src, Mat& dst )
|
||||
{
|
||||
const float inf = 1e15f;
|
||||
const int inf = INT_MAX;
|
||||
|
||||
CV_Assert( src.size() == dst.size() );
|
||||
|
||||
CV_Assert( src.type() == CV_8UC1 && dst.type() == CV_32FC1 );
|
||||
int i, m = src.rows, n = src.cols;
|
||||
|
||||
cv::AutoBuffer<uchar> _buf(std::max(m*2*sizeof(float) + (m*3+1)*sizeof(int), n*2*sizeof(float)));
|
||||
cv::AutoBuffer<uchar> _buf(std::max(m*2*sizeof(int) + (m*3+1)*sizeof(int), n*2*sizeof(float)));
|
||||
// stage 1: compute 1d distance transform of each column
|
||||
float* sqr_tab = (float*)_buf.data();
|
||||
int* sqr_tab = (int*)_buf.data();
|
||||
int* sat_tab = cv::alignPtr((int*)(sqr_tab + m*2), sizeof(int));
|
||||
int shift = m*2;
|
||||
|
||||
for( i = 0; i < m; i++ )
|
||||
sqr_tab[i] = (float)(i*i);
|
||||
sqr_tab[i] = i*i;
|
||||
for( i = m; i < m*2; i++ )
|
||||
sqr_tab[i] = inf;
|
||||
for( i = 0; i < shift; i++ )
|
||||
@@ -584,13 +584,14 @@ trueDistTrans( const Mat& src, Mat& dst )
|
||||
cv::parallel_for_(cv::Range(0, n), cv::DTColumnInvoker(&src, &dst, sat_tab, sqr_tab), src.total()/(double)(1<<16));
|
||||
|
||||
// stage 2: compute modified distance transform for each row
|
||||
float* inv_tab = sqr_tab + n;
|
||||
float* inv_tab = (float*)sqr_tab + n;
|
||||
|
||||
inv_tab[0] = sqr_tab[0] = 0.f;
|
||||
inv_tab[0] = 0.f;
|
||||
sqr_tab[0] = 0;
|
||||
for( i = 1; i < n; i++ )
|
||||
{
|
||||
inv_tab[i] = (float)(0.5/i);
|
||||
sqr_tab[i] = (float)(i*i);
|
||||
sqr_tab[i] = i*i;
|
||||
}
|
||||
|
||||
cv::parallel_for_(cv::Range(0, m), cv::DTRowInvoker(&dst, sqr_tab, inv_tab));
|
||||
@@ -752,7 +753,9 @@ void cv::distanceTransform( InputArray _src, OutputArray _dst, OutputArray _labe
|
||||
CV_IPP_CHECK()
|
||||
{
|
||||
#if IPP_DISABLE_PERF_TRUE_DIST_MT
|
||||
if(cv::getNumThreads()<=1 || (src.total()<(int)(1<<14)))
|
||||
// IPP uses floats, but 4097 cannot be squared into a float
|
||||
if((cv::getNumThreads()<=1 || (src.total()<(int)(1<<14))) &&
|
||||
src.rows < 4097 && src.cols < 4097)
|
||||
#endif
|
||||
{
|
||||
IppStatus status;
|
||||
|
||||
@@ -63,7 +63,7 @@ CollectPolyEdges( Mat& img, const Point2l* v, int npts,
|
||||
int shift, Point offset=Point() );
|
||||
|
||||
static void
|
||||
FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color );
|
||||
FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color, int line_type);
|
||||
|
||||
static void
|
||||
PolyLine( Mat& img, const Point2l* v, int npts, bool closed,
|
||||
@@ -1031,7 +1031,7 @@ EllipseEx( Mat& img, Point2l center, Size2l axes,
|
||||
v.push_back(center);
|
||||
std::vector<PolyEdge> edges;
|
||||
CollectPolyEdges( img, &v[0], (int)v.size(), edges, color, line_type, XY_SHIFT );
|
||||
FillEdgeCollection( img, edges, color );
|
||||
FillEdgeCollection( img, edges, color, line_type );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1259,37 +1259,60 @@ CollectPolyEdges( Mat& img, const Point2l* v, int count, std::vector<PolyEdge>&
|
||||
pt1.x = (pt1.x + offset.x) << (XY_SHIFT - shift);
|
||||
pt1.y = (pt1.y + delta) >> shift;
|
||||
|
||||
if( line_type < CV_AA )
|
||||
Point2l pt0c(pt0), pt1c(pt1);
|
||||
|
||||
if (line_type < CV_AA)
|
||||
{
|
||||
t0.y = pt0.y; t1.y = pt1.y;
|
||||
t0.x = (pt0.x + (XY_ONE >> 1)) >> XY_SHIFT;
|
||||
t1.x = (pt1.x + (XY_ONE >> 1)) >> XY_SHIFT;
|
||||
Line( img, t0, t1, color, line_type );
|
||||
Line(img, t0, t1, color, line_type);
|
||||
|
||||
// use clipped endpoints to create a more accurate PolyEdge
|
||||
if ((unsigned)t0.x >= (unsigned)(img.cols) ||
|
||||
(unsigned)t1.x >= (unsigned)(img.cols) ||
|
||||
(unsigned)t0.y >= (unsigned)(img.rows) ||
|
||||
(unsigned)t1.y >= (unsigned)(img.rows))
|
||||
{
|
||||
clipLine(img.size(), t0, t1);
|
||||
|
||||
if (t0.y != t1.y)
|
||||
{
|
||||
pt0c.y = t0.y; pt1c.y = t1.y;
|
||||
pt0c.x = (int64)(t0.x) << XY_SHIFT;
|
||||
pt1c.x = (int64)(t1.x) << XY_SHIFT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pt0c.x += XY_ONE >> 1;
|
||||
pt1c.x += XY_ONE >> 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
t0.x = pt0.x; t1.x = pt1.x;
|
||||
t0.y = pt0.y << XY_SHIFT;
|
||||
t1.y = pt1.y << XY_SHIFT;
|
||||
LineAA( img, t0, t1, color );
|
||||
LineAA(img, t0, t1, color);
|
||||
}
|
||||
|
||||
if( pt0.y == pt1.y )
|
||||
if (pt0.y == pt1.y)
|
||||
continue;
|
||||
|
||||
if( pt0.y < pt1.y )
|
||||
edge.dx = (pt1c.x - pt0c.x) / (pt1c.y - pt0c.y);
|
||||
if (pt0.y < pt1.y)
|
||||
{
|
||||
edge.y0 = (int)(pt0.y);
|
||||
edge.y1 = (int)(pt1.y);
|
||||
edge.x = pt0.x;
|
||||
edge.x = pt0c.x + (pt0.y - pt0c.y) * edge.dx; // correct starting point for clipped lines
|
||||
}
|
||||
else
|
||||
{
|
||||
edge.y0 = (int)(pt1.y);
|
||||
edge.y1 = (int)(pt0.y);
|
||||
edge.x = pt1.x;
|
||||
edge.x = pt1c.x + (pt1.y - pt1c.y) * edge.dx; // correct starting point for clipped lines
|
||||
}
|
||||
edge.dx = (pt1.x - pt0.x) / (pt1.y - pt0.y);
|
||||
edges.push_back(edge);
|
||||
}
|
||||
}
|
||||
@@ -1306,7 +1329,7 @@ struct CmpEdges
|
||||
/**************** helper macros and functions for sequence/contour processing ***********/
|
||||
|
||||
static void
|
||||
FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color )
|
||||
FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color, int line_type)
|
||||
{
|
||||
PolyEdge tmp;
|
||||
int i, y, total = (int)edges.size();
|
||||
@@ -1315,6 +1338,12 @@ FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color )
|
||||
int y_max = INT_MIN, y_min = INT_MAX;
|
||||
int64 x_max = 0xFFFFFFFFFFFFFFFF, x_min = 0x7FFFFFFFFFFFFFFF;
|
||||
int pix_size = (int)img.elemSize();
|
||||
int delta;
|
||||
|
||||
if (line_type < CV_AA)
|
||||
delta = 0;
|
||||
else
|
||||
delta = XY_ONE - 1;
|
||||
|
||||
if( total < 2 )
|
||||
return;
|
||||
@@ -1394,12 +1423,12 @@ FillEdgeCollection( Mat& img, std::vector<PolyEdge>& edges, const void* color )
|
||||
|
||||
if (keep_prelast->x > prelast->x)
|
||||
{
|
||||
x1 = (int)((prelast->x + XY_ONE - 1) >> XY_SHIFT);
|
||||
x1 = (int)((prelast->x + delta) >> XY_SHIFT);
|
||||
x2 = (int)(keep_prelast->x >> XY_SHIFT);
|
||||
}
|
||||
else
|
||||
{
|
||||
x1 = (int)((keep_prelast->x + XY_ONE - 1) >> XY_SHIFT);
|
||||
x1 = (int)((keep_prelast->x + delta) >> XY_SHIFT);
|
||||
x2 = (int)(prelast->x >> XY_SHIFT);
|
||||
}
|
||||
|
||||
@@ -1995,7 +2024,7 @@ void fillPoly( Mat& img, const Point** pts, const int* npts, int ncontours,
|
||||
CollectPolyEdges(img, _pts.data(), npts[i], edges, buf, line_type, shift, offset);
|
||||
}
|
||||
|
||||
FillEdgeCollection(img, edges, buf);
|
||||
FillEdgeCollection(img, edges, buf, line_type);
|
||||
}
|
||||
|
||||
|
||||
@@ -2654,7 +2683,7 @@ cvDrawContours( void* _img, CvSeq* contour,
|
||||
}
|
||||
|
||||
if( thickness < 0 )
|
||||
cv::FillEdgeCollection( img, edges, ext_buf );
|
||||
cv::FillEdgeCollection( img, edges, ext_buf, line_type);
|
||||
|
||||
if( h_next && contour0 )
|
||||
contour0->h_next = h_next;
|
||||
|
||||
+51
-105
@@ -69,12 +69,6 @@ const double DEG_TO_RADS = CV_PI / 180;
|
||||
|
||||
#define log_gamma(x) ((x)>15.0?log_gamma_windschitl(x):log_gamma_lanczos(x))
|
||||
|
||||
struct edge
|
||||
{
|
||||
cv::Point p;
|
||||
bool taken;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline double distSq(const double x1, const double y1,
|
||||
@@ -120,10 +114,20 @@ inline bool double_equal(const double& a, const double& b)
|
||||
return (abs_diff / abs_max) <= (RELATIVE_ERROR_FACTOR * DBL_EPSILON);
|
||||
}
|
||||
|
||||
inline bool AsmallerB_XoverY(const edge& a, const edge& b)
|
||||
{
|
||||
if (a.p.x == b.p.x) return a.p.y < b.p.y;
|
||||
else return a.p.x < b.p.x;
|
||||
// function to sort points by y and then by x
|
||||
inline bool AsmallerB_YoverX(const cv::Point2d &a, const cv::Point2d &b) {
|
||||
if (a.y == b.y) return a.x < b.x;
|
||||
else return a.y < b.y;
|
||||
}
|
||||
|
||||
// function to get the slope of the rectangle for a specific row
|
||||
inline double get_slope(cv::Point2d p1, cv::Point2d p2) {
|
||||
return ((int) ceil(p2.y) != (int) ceil(p1.y)) ? (p2.x - p1.x) / (p2.y - p1.y) : 0;
|
||||
}
|
||||
|
||||
// function to get the limit of the rectangle for a specific row
|
||||
inline double get_limit(cv::Point2d p, int row, double slope) {
|
||||
return p.x + (row - p.y) * slope;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -588,8 +592,8 @@ void LineSegmentDetectorImpl::ll_angle(const double& threshold,
|
||||
}
|
||||
}
|
||||
|
||||
// Sort
|
||||
std::sort(ordered_points.begin(), ordered_points.end(), compare_norm);
|
||||
// Use stable sort to ensure deterministic region growing and thus overall LSD result determinism.
|
||||
std::stable_sort(ordered_points.begin(), ordered_points.end(), compare_norm);
|
||||
}
|
||||
|
||||
void LineSegmentDetectorImpl::region_grow(const Point2i& s, std::vector<RegionPoint>& reg,
|
||||
@@ -945,105 +949,53 @@ double LineSegmentDetectorImpl::rect_nfa(const rect& rec) const
|
||||
double dyhw = rec.dy * half_width;
|
||||
double dxhw = rec.dx * half_width;
|
||||
|
||||
edge ordered_x[4];
|
||||
edge* min_y = &ordered_x[0];
|
||||
edge* max_y = &ordered_x[0]; // Will be used for loop range
|
||||
cv::Point2d v_tmp[4];
|
||||
v_tmp[0] = cv::Point2d(rec.x1 - dyhw, rec.y1 + dxhw);
|
||||
v_tmp[1] = cv::Point2d(rec.x2 - dyhw, rec.y2 + dxhw);
|
||||
v_tmp[2] = cv::Point2d(rec.x2 + dyhw, rec.y2 - dxhw);
|
||||
v_tmp[3] = cv::Point2d(rec.x1 + dyhw, rec.y1 - dxhw);
|
||||
|
||||
ordered_x[0].p.x = int(rec.x1 - dyhw); ordered_x[0].p.y = int(rec.y1 + dxhw); ordered_x[0].taken = false;
|
||||
ordered_x[1].p.x = int(rec.x2 - dyhw); ordered_x[1].p.y = int(rec.y2 + dxhw); ordered_x[1].taken = false;
|
||||
ordered_x[2].p.x = int(rec.x2 + dyhw); ordered_x[2].p.y = int(rec.y2 - dxhw); ordered_x[2].taken = false;
|
||||
ordered_x[3].p.x = int(rec.x1 + dyhw); ordered_x[3].p.y = int(rec.y1 - dxhw); ordered_x[3].taken = false;
|
||||
|
||||
std::sort(ordered_x, ordered_x + 4, AsmallerB_XoverY);
|
||||
|
||||
// Find min y. And mark as taken. find max y.
|
||||
for(unsigned int i = 1; i < 4; ++i)
|
||||
{
|
||||
if(min_y->p.y > ordered_x[i].p.y) {min_y = &ordered_x[i]; }
|
||||
if(max_y->p.y < ordered_x[i].p.y) {max_y = &ordered_x[i]; }
|
||||
}
|
||||
min_y->taken = true;
|
||||
|
||||
// Find leftmost untaken point;
|
||||
edge* leftmost = 0;
|
||||
for(unsigned int i = 0; i < 4; ++i)
|
||||
{
|
||||
if(!ordered_x[i].taken)
|
||||
{
|
||||
if(!leftmost) // if uninitialized
|
||||
{
|
||||
leftmost = &ordered_x[i];
|
||||
}
|
||||
else if (leftmost->p.x > ordered_x[i].p.x)
|
||||
{
|
||||
leftmost = &ordered_x[i];
|
||||
}
|
||||
// Find the vertex with the smallest y coordinate (or the smallest x if there is a tie).
|
||||
int offset = 0;
|
||||
for (int i = 1; i < 4; ++i) {
|
||||
if (AsmallerB_YoverX(v_tmp[i], v_tmp[offset])){
|
||||
offset = i;
|
||||
}
|
||||
}
|
||||
CV_Assert(leftmost != NULL);
|
||||
leftmost->taken = true;
|
||||
|
||||
// Find rightmost untaken point;
|
||||
edge* rightmost = 0;
|
||||
for(unsigned int i = 0; i < 4; ++i)
|
||||
{
|
||||
if(!ordered_x[i].taken)
|
||||
{
|
||||
if(!rightmost) // if uninitialized
|
||||
{
|
||||
rightmost = &ordered_x[i];
|
||||
}
|
||||
else if (rightmost->p.x < ordered_x[i].p.x)
|
||||
{
|
||||
rightmost = &ordered_x[i];
|
||||
}
|
||||
}
|
||||
// Rotate the vertices so that the first one is the one with the smallest y coordinate (or the smallest x if there is a tie).
|
||||
// The rest will be then ordered counterclockwise.
|
||||
cv::Point2d ordered_y[4];
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
ordered_y[i] = v_tmp[(i + offset) % 4];
|
||||
}
|
||||
CV_Assert(rightmost != NULL);
|
||||
rightmost->taken = true;
|
||||
|
||||
// Find last untaken point;
|
||||
edge* tailp = 0;
|
||||
for(unsigned int i = 0; i < 4; ++i)
|
||||
{
|
||||
if(!ordered_x[i].taken)
|
||||
{
|
||||
if(!tailp) // if uninitialized
|
||||
{
|
||||
tailp = &ordered_x[i];
|
||||
}
|
||||
else if (tailp->p.x > ordered_x[i].p.x)
|
||||
{
|
||||
tailp = &ordered_x[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
CV_Assert(tailp != NULL);
|
||||
tailp->taken = true;
|
||||
double flstep = get_slope(ordered_y[0], ordered_y[1]); //first left step
|
||||
double slstep = get_slope(ordered_y[1], ordered_y[2]); //second left step
|
||||
|
||||
double flstep = (min_y->p.y != leftmost->p.y) ?
|
||||
(min_y->p.x - leftmost->p.x) / (min_y->p.y - leftmost->p.y) : 0; //first left step
|
||||
double slstep = (leftmost->p.y != tailp->p.x) ?
|
||||
(leftmost->p.x - tailp->p.x) / (leftmost->p.y - tailp->p.x) : 0; //second left step
|
||||
double frstep = get_slope(ordered_y[0], ordered_y[3]); //first right step
|
||||
double srstep = get_slope(ordered_y[3], ordered_y[2]); //second right step
|
||||
|
||||
double frstep = (min_y->p.y != rightmost->p.y) ?
|
||||
(min_y->p.x - rightmost->p.x) / (min_y->p.y - rightmost->p.y) : 0; //first right step
|
||||
double srstep = (rightmost->p.y != tailp->p.x) ?
|
||||
(rightmost->p.x - tailp->p.x) / (rightmost->p.y - tailp->p.x) : 0; //second right step
|
||||
|
||||
double lstep = flstep, rstep = frstep;
|
||||
|
||||
double left_x = min_y->p.x, right_x = min_y->p.x;
|
||||
double top_y = ordered_y[0].y, bottom_y = ordered_y[2].y;
|
||||
|
||||
// Loop around all points in the region and count those that are aligned.
|
||||
int min_iter = min_y->p.y;
|
||||
int max_iter = max_y->p.y;
|
||||
for(int y = min_iter; y <= max_iter; ++y)
|
||||
std::vector<cv::Point> points;
|
||||
double left_limit, right_limit;
|
||||
for(int y = (int) ceil(top_y); y <= (int) ceil(bottom_y); ++y)
|
||||
{
|
||||
if (y < 0 || y >= img_height) continue;
|
||||
|
||||
for(int x = int(left_x); x <= int(right_x); ++x)
|
||||
{
|
||||
if(y <= int(ceil(ordered_y[1].y)))
|
||||
left_limit = get_limit(ordered_y[0], y, flstep);
|
||||
else
|
||||
left_limit = get_limit(ordered_y[1], y, slstep);
|
||||
|
||||
if(y < int(ceil(ordered_y[3].y)))
|
||||
right_limit = get_limit(ordered_y[0], y, frstep);
|
||||
else
|
||||
right_limit = get_limit(ordered_y[3], y, srstep);
|
||||
|
||||
for(int x = (int) ceil(left_limit); x <= (int)(right_limit); ++x) {
|
||||
if (x < 0 || x >= img_width) continue;
|
||||
|
||||
++total_pts;
|
||||
@@ -1052,12 +1004,6 @@ double LineSegmentDetectorImpl::rect_nfa(const rect& rec) const
|
||||
++alg_pts;
|
||||
}
|
||||
}
|
||||
|
||||
if(y >= leftmost->p.y) { lstep = slstep; }
|
||||
if(y >= rightmost->p.y) { rstep = srstep; }
|
||||
|
||||
left_x += lstep;
|
||||
right_x += rstep;
|
||||
}
|
||||
|
||||
return nfa(total_pts, alg_pts, rec.p);
|
||||
@@ -1071,7 +1017,7 @@ double LineSegmentDetectorImpl::nfa(const int& n, const int& k, const double& p)
|
||||
|
||||
double p_term = p / (1 - p);
|
||||
|
||||
double log1term = (double(n) + 1) - log_gamma(double(k) + 1)
|
||||
double log1term = log_gamma(double(n) + 1) - log_gamma(double(k) + 1)
|
||||
- log_gamma(double(n-k) + 1)
|
||||
+ double(k) * log(p) + double(n-k) * log(1.0 - p);
|
||||
double term = exp(log1term);
|
||||
|
||||
@@ -1077,7 +1077,7 @@ double CV_ColorLabTest::get_success_error_level( int /*test_case_idx*/, int i, i
|
||||
{
|
||||
int depth = test_mat[i][j].depth();
|
||||
// j == 0 is for forward code, j == 1 is for inverse code
|
||||
return (depth == CV_8U) ? (srgb ? 32 : 8) :
|
||||
return (depth == CV_8U) ? (srgb ? 37 : 8) :
|
||||
//(depth == CV_16U) ? 32 : // 16u is disabled
|
||||
srgb ? ((j == 0) ? 0.4 : 0.0055) : 1e-3;
|
||||
}
|
||||
@@ -1256,7 +1256,7 @@ double CV_ColorLuvTest::get_success_error_level( int /*test_case_idx*/, int i, i
|
||||
{
|
||||
int depth = test_mat[i][j].depth();
|
||||
// j == 0 is for forward code, j == 1 is for inverse code
|
||||
return (depth == CV_8U) ? (srgb ? 36 : 8) :
|
||||
return (depth == CV_8U) ? (srgb ? 37 : 8) :
|
||||
//(depth == CV_16U) ? 32 : // 16u is disabled
|
||||
5e-2;
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ void CV_ConnectedComponentsTest::run(int /* start_from */)
|
||||
int ccltype[] = { cv::CCL_DEFAULT, cv::CCL_WU, cv::CCL_GRANA, cv::CCL_BOLELLI, cv::CCL_SAUF, cv::CCL_BBDT, cv::CCL_SPAGHETTI };
|
||||
|
||||
string exp_path = string(ts->get_data_path()) + "connectedcomponents/ccomp_exp.png";
|
||||
Mat exp = imread(exp_path, 0);
|
||||
Mat exp = imread(exp_path, IMREAD_GRAYSCALE);
|
||||
Mat orig = imread(string(ts->get_data_path()) + "connectedcomponents/concentric_circles.png", 0);
|
||||
|
||||
if (orig.empty())
|
||||
|
||||
@@ -180,7 +180,7 @@ cvTsIsPointOnLineSegment(const cv::Point2f &x, const cv::Point2f &a, const cv::P
|
||||
double d2 = cvTsDist(cvPoint2D32f(x.x, x.y), cvPoint2D32f(b.x, b.y));
|
||||
double d3 = cvTsDist(cvPoint2D32f(a.x, a.y), cvPoint2D32f(b.x, b.y));
|
||||
|
||||
return (abs(d1 + d2 - d3) <= (1E-5));
|
||||
return (abs(d1 + d2 - d3) <= (1E-4));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -724,4 +724,13 @@ INSTANTIATE_TEST_CASE_P(cvt422, Imgproc_ColorYUV,
|
||||
(int)COLOR_YUV2RGBA_YUY2, (int)COLOR_YUV2BGRA_YUY2, (int)COLOR_YUV2RGBA_YVYU, (int)COLOR_YUV2BGRA_YVYU,
|
||||
(int)COLOR_YUV2GRAY_UYVY, (int)COLOR_YUV2GRAY_YUY2));
|
||||
|
||||
}} // namespace
|
||||
}
|
||||
|
||||
TEST(cvtColorUYVY, size_issue_21035)
|
||||
{
|
||||
Mat input = Mat::zeros(1, 1, CV_8UC2);
|
||||
Mat output;
|
||||
EXPECT_THROW(cv::cvtColor(input, output, cv::COLOR_YUV2BGR_UYVY), cv::Exception);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -302,4 +302,46 @@ BIGDATA_TEST(Imgproc_DistanceTransform, large_image_12218)
|
||||
EXPECT_EQ(nz, (size.height*size.width / 2));
|
||||
}
|
||||
|
||||
TEST(Imgproc_DistanceTransform, wide_image_22732)
|
||||
{
|
||||
Mat src = Mat::zeros(1, 4099, CV_8U); // 4099 or larger used to be bad
|
||||
Mat dist(src.rows, src.cols, CV_32F);
|
||||
distanceTransform(src, dist, DIST_L2, DIST_MASK_PRECISE, CV_32F);
|
||||
int nz = countNonZero(dist);
|
||||
EXPECT_EQ(nz, 0);
|
||||
}
|
||||
|
||||
TEST(Imgproc_DistanceTransform, large_square_22732)
|
||||
{
|
||||
Mat src = Mat::zeros(8000, 8005, CV_8U), dist;
|
||||
distanceTransform(src, dist, DIST_L2, DIST_MASK_PRECISE, CV_32F);
|
||||
int nz = countNonZero(dist);
|
||||
EXPECT_EQ(dist.size(), src.size());
|
||||
EXPECT_EQ(dist.type(), CV_32F);
|
||||
EXPECT_EQ(nz, 0);
|
||||
|
||||
Point p0(src.cols-1, src.rows-1);
|
||||
src.setTo(1);
|
||||
src.at<uchar>(p0) = 0;
|
||||
distanceTransform(src, dist, DIST_L2, DIST_MASK_PRECISE, CV_32F);
|
||||
EXPECT_EQ(dist.size(), src.size());
|
||||
EXPECT_EQ(dist.type(), CV_32F);
|
||||
bool first = true;
|
||||
int nerrs = 0;
|
||||
for (int y = 0; y < dist.rows; y++)
|
||||
for (int x = 0; x < dist.cols; x++) {
|
||||
float d = dist.at<float>(y, x);
|
||||
double dx = (double)(x - p0.x), dy = (double)(y - p0.y);
|
||||
float d0 = (float)sqrt(dx*dx + dy*dy);
|
||||
if (std::abs(d0 - d) > 1) {
|
||||
if (first) {
|
||||
printf("y=%d, x=%d. dist_ref=%.2f, dist=%.2f\n", y, x, d0, d);
|
||||
first = false;
|
||||
}
|
||||
nerrs++;
|
||||
}
|
||||
}
|
||||
EXPECT_EQ(0, nerrs) << "reference distance map is different from computed one at " << nerrs << " pixels\n";
|
||||
}
|
||||
|
||||
}} // namespace
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user