...
 
Commits (23)
    https://gitcode.net/greenplum/opencv/-/commit/8762c37c22e37a5102778dc5524e84e27c017f5a solve issue 23808 2023-06-15T21:29:18+02:00 unknown laurent.berger@univ-lemans.fr https://gitcode.net/greenplum/opencv/-/commit/1eaa074a49f40b207bb67c6de46431861106aa86 remove line 2023-06-16T11:28:11+02:00 unknown laurent.berger@univ-lemans.fr https://gitcode.net/greenplum/opencv/-/commit/1d9c0d3e1270880971474b6c421a7a453d19018c videoio: tests for CAP_IMAGES 2023-07-03T10:33:16+03:00 Maksim Shabunin maksim.shabunin@gmail.com https://gitcode.net/greenplum/opencv/-/commit/a58214f015d5511b0f8c1d0c14b9044f4841d643 use CPACK_PACKAGE_VERSION instead of OPENCV_VCSVERSION for... 2023-07-04T07:41:16+00:00 kallaballa amir@viel-zu.org use CPACK_PACKAGE_VERSION instead of OPENCV_VCSVERSION for CPACK_PACKAGE_FILE_NAME so that OPENCV_CUSTOM_PACKAGE_INFO actually has full effect https://gitcode.net/greenplum/opencv/-/commit/356e5d30280c57ba1c8fc7c019eb3e93150eeba1 Merge pull request #23918 from kallaballa:custom_package_name 2023-07-04T14:06:32+03:00 Alexander Smorkalov 2536374+asmorkalov@users.noreply.github.com use CPACK_PACKAGE_VERSION instead of OPENCV_VCSVERSION for CPACK_PACKAGE_FILE_NAME https://gitcode.net/greenplum/opencv/-/commit/c9d8b541fc111a1069534c7f261386418fee57d5 Merge pull request #23896 from mshabunin:test-cap-images 2023-07-04T16:30:53+03:00 Alexander Smorkalov 2536374+asmorkalov@users.noreply.github.com videoio: tests for CAP_IMAGES https://gitcode.net/greenplum/opencv/-/commit/8839bd572ea8078a9b33d1cdcae19a12443277a8 Merge pull request #23815 from LaurentBerger:CAP_IMAGES 2023-07-04T16:31:29+03:00 Alexander Smorkalov 2536374+asmorkalov@users.noreply.github.com Add single image support to VideoCapture https://gitcode.net/greenplum/opencv/-/commit/71796edf95cd9b0f9769fef345d00372ef16c506 removed trailing semicolon after function 2023-07-04T21:18:30+03:00 Berke iamberkeyavas@gmail.com It gives error when building projects with -Wpedantic -Werror error: extra ‘;’ [-Werror=pedantic] Issue ##23916 https://gitcode.net/greenplum/opencv/-/commit/32251c9b04a3d84d6bd3ed3918fa9493bc5208d0 Add missing properties to error class 2023-07-04T17:57:30-04:00 Avasam samuel.06@hotmail.com https://gitcode.net/greenplum/opencv/-/commit/b8e3bc9dd866b028e33b769e3c0992fc2b55a660 Merge pull request #23924 from ocpalo:patch-2 2023-07-05T09:38:29+03:00 Alexander Smorkalov 2536374+asmorkalov@users.noreply.github.com removed trailing semicolon after function https://gitcode.net/greenplum/opencv/-/commit/2d92f42878f45e023c5ae4e8e9c570283a084f6f Disable finite-math-only option with ENABLE_FAST_MATH=1 case to handle NaN an... 2023-07-06T15:41:04+03:00 Alexander Smorkalov alexander.smorkalov@xperience.ai Disable finite-math-only option with ENABLE_FAST_MATH=1 case to handle NaN and Inf checks correctly. https://gitcode.net/greenplum/opencv/-/commit/8931f083623412c55d8a98c775f86193b0d66d96 videoio: fix CAP_IMAGES with non-numbered file 2023-07-06T22:26:53+03:00 Maksim Shabunin maksim.shabunin@gmail.com https://gitcode.net/greenplum/opencv/-/commit/601a159f25342a96862585ede1ed6b14a9c17037 Merge pull request #23881 from asmorkalov:as/fast_math_nan 2023-07-07T09:04:08+03:00 Alexander Smorkalov 2536374+asmorkalov@users.noreply.github.com Disable finite-math-only option with ENABLE_FAST_MATH=1 case to handle NaN and Inf checks correctly https://gitcode.net/greenplum/opencv/-/commit/cb2e831da43f4426353b2b2ae961175720447f9f Merge pull request #23940 from mshabunin:fix-cap-images 2023-07-07T11:12:38+03:00 Alexander Smorkalov 2536374+asmorkalov@users.noreply.github.com videoio: fix CAP_IMAGES with non-numbered file https://gitcode.net/greenplum/opencv/-/commit/e43bc88fc37d04fbb4fcf5436ca568b0987944b4 videoio: test for V4L using virtual device 2023-07-07T17:33:33+03:00 Maksim Shabunin maksim.shabunin@gmail.com https://gitcode.net/greenplum/opencv/-/commit/09944a83d9f9970b97e5d71b963276023a5c86f6 build: w/a compiler warnings for GCC 11-12 and Clang 13, reduce build output 2023-07-10T11:27:59+03:00 Maksim Shabunin maksim.shabunin@gmail.com https://gitcode.net/greenplum/opencv/-/commit/d2951d6d4c4f452091dbc7036b01dd9b6fda7c83 Merge pull request #23928 from Avasam:Add-missing-properties-to-error-class 2023-07-10T12:40:06+03:00 Alexander Smorkalov 2536374+asmorkalov@users.noreply.github.com Add missing properties to error class https://gitcode.net/greenplum/opencv/-/commit/05becd56e511defdf7322823a431de3b7df14d49 Merge pull request #23938 from mshabunin/fix-warnings-gcc 2023-07-10T12:41:37+03:00 Alexander Smorkalov 2536374+asmorkalov@users.noreply.github.com Fix compiler warnings for GCC 11-12 and Clang 13 https://gitcode.net/greenplum/opencv/-/commit/fdc0c12b7fff00e1b41f75e11401073eee23b7e7 Merge pull request #23944 from mshabunin:test-v4l2 2023-07-10T12:54:43+03:00 Alexander Smorkalov 2536374+asmorkalov@users.noreply.github.com videoio: test for V4L using virtual device https://gitcode.net/greenplum/opencv/-/commit/8097bdc2f40b1da62d975266b88b54fa55a08056 fix: typing stubs overload presence check 2023-07-10T14:30:44+03:00 Vadim Levin vadim.levin@xperience.ai https://gitcode.net/greenplum/opencv/-/commit/de8e6abd1ef6a97f768b03b14f336f4f941ad620 Merge pull request #23955 from VadimLevin:dev/vlevin/overload-presence-check-fix 2023-07-10T15:37:59+03:00 Alexander Smorkalov 2536374+asmorkalov@users.noreply.github.com fix: typing stubs overload presence check https://gitcode.net/greenplum/opencv/-/commit/986e379f280a79e0f68b848c412a99776026aafc feat: add matrix type stubs generation 2023-07-10T17:35:27+03:00 Vadim Levin vadim.levin@xperience.ai Adds missing typing stubs: - Matrix depths: `CV_8U`, `CV_8S` and etc. - Matrix type constants: `CV_8UC1`, `CV_32FC3` and etc. - Matrix type factory functions: `CV_*(channels) -> int` and `CV_MAKETYPE` https://gitcode.net/greenplum/opencv/-/commit/bb61cc0dbad4f503291c85ec375471a5db9a9528 Merge pull request #23954 from VadimLevin:dev/vlevin/matrix-type-constants-stubs 2023-07-10T18:48:01+03:00 Alexander Smorkalov 2536374+asmorkalov@users.noreply.github.com feat: add matrix type stubs generation
......@@ -26,6 +26,7 @@ else()
-Wsuggest-override -Winconsistent-missing-override
-Wimplicit-fallthrough
-Warray-bounds # GCC 9+
-Wstringop-overflow -Wstringop-overread # GCC 11-12
)
endif()
if(CV_ICC)
......
......@@ -108,6 +108,7 @@ elseif(CV_ICC)
elseif(CV_GCC OR CV_CLANG)
if(ENABLE_FAST_MATH)
add_extra_compiler_option(-ffast-math)
add_extra_compiler_option(-fno-finite-math-only)
endif()
endif()
......
......@@ -52,8 +52,8 @@ else()
set(OPENCV_PACKAGE_ARCH_SUFFIX ${CMAKE_SYSTEM_PROCESSOR})
endif()
set(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${OPENCV_VCSVERSION}-${OPENCV_PACKAGE_ARCH_SUFFIX}")
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${OPENCV_VCSVERSION}-${OPENCV_PACKAGE_ARCH_SUFFIX}")
set(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${CPACK_PACKAGE_VERSION}-${OPENCV_PACKAGE_ARCH_SUFFIX}")
set(CPACK_SOURCE_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${CPACK_PACKAGE_VERSION}-${OPENCV_PACKAGE_ARCH_SUFFIX}")
#rpm options
set(CPACK_RPM_COMPONENT_INSTALL TRUE)
......
......@@ -21,7 +21,7 @@ macro(copy_file_ src dst prefix)
endif()
if(use_symlink)
if(local_update OR NOT IS_SYMLINK "${dst}")
message("${prefix}Symlink: '${dst_name}' ...")
#message("${prefix}Symlink: '${dst_name}' ...")
endif()
get_filename_component(target_path "${dst}" PATH)
file(MAKE_DIRECTORY "${target_path}")
......@@ -38,7 +38,7 @@ macro(copy_file_ src dst prefix)
set(local_update 1)
endif()
if(local_update)
message("${prefix}Copying: '${dst_name}' ...")
#message("${prefix}Copying: '${dst_name}' ...")
configure_file(${src} ${dst} COPYONLY)
else()
#message("${prefix}Up-to-date: '${dst_name}'")
......@@ -55,7 +55,7 @@ if(NOT DEFINED COPYLIST_VAR)
set(COPYLIST_VAR "COPYLIST")
endif()
list(LENGTH ${COPYLIST_VAR} __length)
message("${prefix}... ${__length} entries (${COPYLIST_VAR})")
#message("${prefix}... ${__length} entries (${COPYLIST_VAR})")
foreach(id ${${COPYLIST_VAR}})
set(src "${${COPYLIST_VAR}_SRC_${id}}")
set(dst "${${COPYLIST_VAR}_DST_${id}}")
......@@ -80,7 +80,7 @@ foreach(id ${${COPYLIST_VAR}})
endif()
file(GLOB_RECURSE _files RELATIVE "${src}" ${src_glob})
list(LENGTH _files __length)
message("${prefix} ... directory '.../${src_name2}/${src_name}' with ${__length} files")
#message("${prefix} ... directory '.../${src_name2}/${src_name}' with ${__length} files")
foreach(f ${_files})
if(NOT EXISTS "${src}/${f}")
message(FATAL_ERROR "COPY ERROR: Source file is missing: ${src}/${f}")
......@@ -98,12 +98,12 @@ else()
endif()
if(NOT "${__state}" STREQUAL "${__prev_state}")
file(WRITE "${STATE_FILE}" "${__state}")
message("${prefix}Updated!")
#message("${prefix}Updated!")
set(update_dephelper 1)
endif()
if(NOT update_dephelper)
message("${prefix}All files are up-to-date.")
#message("${prefix}All files are up-to-date.")
elseif(DEFINED DEPHELPER)
file(WRITE "${DEPHELPER}" "")
endif()
......@@ -1531,8 +1531,8 @@ TEST(Calib3d_SolvePnP, generic)
}
else
{
p3f = p3f_;
p2f = p2f_;
p3f = vector<Point3f>(p3f_.begin(), p3f_.end());
p2f = vector<Point2f>(p2f_.begin(), p2f_.end());
}
vector<double> reprojectionErrors;
......
......@@ -577,7 +577,7 @@ CV_EXPORTS_W void ensureSizeIsEnough(int rows, int cols, int type, OutputArray a
*/
CV_EXPORTS_W GpuMat inline createGpuMatFromCudaMemory(int rows, int cols, int type, size_t cudaMemoryAddress, size_t step = Mat::AUTO_STEP) {
return GpuMat(rows, cols, type, reinterpret_cast<void*>(cudaMemoryAddress), step);
};
}
/** @overload
@param size 2D array size: Size(cols, rows). In the Size() constructor, the number of rows and the number of columns go in the reverse order.
......@@ -588,7 +588,7 @@ CV_EXPORTS_W GpuMat inline createGpuMatFromCudaMemory(int rows, int cols, int ty
*/
CV_EXPORTS_W inline GpuMat createGpuMatFromCudaMemory(Size size, int type, size_t cudaMemoryAddress, size_t step = Mat::AUTO_STEP) {
return GpuMat(size, type, reinterpret_cast<void*>(cudaMemoryAddress), step);
};
}
/** @brief BufferPool for use with CUDA streams
......
......@@ -18,7 +18,7 @@ class Core_ReduceTest : public cvtest::BaseTest
public:
Core_ReduceTest() {}
protected:
void run( int);
void run( int) CV_OVERRIDE;
int checkOp( const Mat& src, int dstType, int opType, const Mat& opRes, int dim );
int checkCase( int srcType, int dstType, int dim, Size sz );
int checkDim( int dim, Size sz );
......@@ -495,7 +495,7 @@ public:
Core_ArrayOpTest();
~Core_ArrayOpTest();
protected:
void run(int);
void run(int) CV_OVERRIDE;
};
......@@ -599,6 +599,11 @@ static void setValue(SparseMat& M, const int* idx, double value, RNG& rng)
CV_Error(CV_StsUnsupportedFormat, "");
}
#if defined(__GNUC__) && (__GNUC__ == 11 || __GNUC__ == 12)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Warray-bounds"
#endif
template<typename Pixel>
struct InitializerFunctor{
/// Initializer for cv::Mat::forEach test
......@@ -621,6 +626,11 @@ struct InitializerFunctor5D{
}
};
#if defined(__GNUC__) && (__GNUC__ == 11 || __GNUC__ == 12)
#pragma GCC diagnostic pop
#endif
template<typename Pixel>
struct EmptyFunctor
{
......@@ -1023,7 +1033,7 @@ class Core_MergeSplitBaseTest : public cvtest::BaseTest
protected:
virtual int run_case(int depth, size_t channels, const Size& size, RNG& rng) = 0;
virtual void run(int)
virtual void run(int) CV_OVERRIDE
{
// m is Mat
// mv is vector<Mat>
......@@ -1068,7 +1078,7 @@ public:
~Core_MergeTest() {}
protected:
virtual int run_case(int depth, size_t matCount, const Size& size, RNG& rng)
virtual int run_case(int depth, size_t matCount, const Size& size, RNG& rng) CV_OVERRIDE
{
const int maxMatChannels = 10;
......@@ -1126,7 +1136,7 @@ public:
~Core_SplitTest() {}
protected:
virtual int run_case(int depth, size_t channels, const Size& size, RNG& rng)
virtual int run_case(int depth, size_t channels, const Size& size, RNG& rng) CV_OVERRIDE
{
Mat src(size, CV_MAKETYPE(depth, (int)channels));
rng.fill(src, RNG::UNIFORM, 0, 100, true);
......@@ -1990,7 +2000,6 @@ TEST(Core_InputArray, fetch_MatExpr)
}
#ifdef CV_CXX11
class TestInputArrayRangeChecking {
static const char *kind2str(cv::_InputArray ia)
{
......@@ -2137,8 +2146,6 @@ TEST(Core_InputArray, range_checking)
{
TestInputArrayRangeChecking::run();
}
#endif
TEST(Core_Vectors, issue_13078)
{
......
......@@ -509,6 +509,11 @@ namespace util
return v.index() == util::variant<Types...>::template index_of<T>();
}
#if defined(__GNUC__) && (__GNUC__ == 11 || __GNUC__ == 12)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
template<typename... Us> bool operator==(const variant<Us...> &lhs,
const variant<Us...> &rhs)
{
......@@ -524,6 +529,10 @@ namespace util
return (eqs[lhs.index()])(lhs.memory, rhs.memory);
}
#if defined(__GNUC__) && (__GNUC__ == 11 || __GNUC__ == 12)
#pragma GCC diagnostic pop
#endif
template<typename... Us> bool operator!=(const variant<Us...> &lhs,
const variant<Us...> &rhs)
{
......
......@@ -560,8 +560,15 @@ int cv::floodFill( InputOutputArray _image, InputOutputArray _mask,
if( depth == CV_8U )
for( i = 0; i < cn; i++ )
{
#if defined(__GNUC__) && (__GNUC__ == 12)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstringop-overflow"
#endif
ld_buf.b[i] = saturate_cast<uchar>(cvFloor(loDiff[i]));
ud_buf.b[i] = saturate_cast<uchar>(cvFloor(upDiff[i]));
#if defined(__GNUC__) && (__GNUC__ == 12)
#pragma GCC diagnostic pop
#endif
}
else if( depth == CV_32S )
for( i = 0; i < cn; i++ )
......
......@@ -686,7 +686,7 @@ class JavaWrapperGenerator(object):
msg = "// Return type '%s' is not supported, skipping the function\n\n" % fi.ctype
self.skipped_func_list.append(c_decl + "\n" + msg)
j_code.write( " "*4 + msg )
logging.warning("SKIP:" + c_decl.strip() + "\t due to RET type " + fi.ctype)
logging.info("SKIP:" + c_decl.strip() + "\t due to RET type " + fi.ctype)
return
for a in fi.args:
if a.ctype not in type_dict:
......@@ -698,7 +698,7 @@ class JavaWrapperGenerator(object):
msg = "// Unknown type '%s' (%s), skipping the function\n\n" % (a.ctype, a.out or "I")
self.skipped_func_list.append(c_decl + "\n" + msg)
j_code.write( " "*4 + msg )
logging.warning("SKIP:" + c_decl.strip() + "\t due to ARG type " + a.ctype + "/" + (a.out or "I"))
logging.info("SKIP:" + c_decl.strip() + "\t due to ARG type " + a.ctype + "/" + (a.out or "I"))
return
self.ported_func_list.append(c_decl)
......
......@@ -3,19 +3,49 @@ __all__ = [
]
from typing import Sequence, Callable
from .nodes import NamespaceNode, FunctionNode, OptionalTypeNode
from .nodes import (NamespaceNode, FunctionNode, OptionalTypeNode,
ClassProperty, PrimitiveTypeNode)
from .ast_utils import find_function_node, SymbolName
def apply_manual_api_refinement(root: NamespaceNode) -> None:
export_matrix_type_constants(root)
# Export OpenCV exception class
builtin_exception = root.add_class("Exception")
builtin_exception.is_exported = False
root.add_class("error", (builtin_exception, ))
root.add_class("error", (builtin_exception, ), ERROR_CLASS_PROPERTIES)
for symbol_name, refine_symbol in NODES_TO_REFINE.items():
refine_symbol(root, symbol_name)
def export_matrix_type_constants(root: NamespaceNode) -> None:
MAX_PREDEFINED_CHANNELS = 4
depth_names = ("CV_8U", "CV_8S", "CV_16U", "CV_16S", "CV_32S",
"CV_32F", "CV_64F", "CV_16F")
for depth_value, depth_name in enumerate(depth_names):
# Export depth constants
root.add_constant(depth_name, str(depth_value))
# Export predefined types
for c in range(MAX_PREDEFINED_CHANNELS):
root.add_constant(f"{depth_name}C{c + 1}",
f"{depth_value + 8 * c}")
# Export type creation function
root.add_function(
f"{depth_name}C",
(FunctionNode.Arg("channels", PrimitiveTypeNode.int_()), ),
FunctionNode.RetType(PrimitiveTypeNode.int_())
)
# Export CV_MAKETYPE
root.add_function(
"CV_MAKETYPE",
(FunctionNode.Arg("depth", PrimitiveTypeNode.int_()),
FunctionNode.Arg("channels", PrimitiveTypeNode.int_())),
FunctionNode.RetType(PrimitiveTypeNode.int_())
)
def make_optional_arg(arg_name: str) -> Callable[[NamespaceNode, SymbolName], None]:
def _make_optional_arg(root_node: NamespaceNode,
function_symbol_name: SymbolName) -> None:
......@@ -46,3 +76,11 @@ NODES_TO_REFINE = {
SymbolName(("cv", ), (), "resize"): make_optional_arg("dsize"),
SymbolName(("cv", ), (), "calcHist"): make_optional_arg("mask"),
}
ERROR_CLASS_PROPERTIES = (
ClassProperty("code", PrimitiveTypeNode.int_(), False),
ClassProperty("err", PrimitiveTypeNode.str_(), False),
ClassProperty("file", PrimitiveTypeNode.str_(), False),
ClassProperty("func", PrimitiveTypeNode.str_(), False),
ClassProperty("line", PrimitiveTypeNode.int_(), False),
ClassProperty("msg", PrimitiveTypeNode.str_(), False),
)
......@@ -103,9 +103,6 @@ def _generate_typing_stubs(root: NamespaceNode, output_path: Path) -> None:
_write_reexported_symbols_section(root, output_stream)
# Write constants section, because constants don't impose any dependencies
_generate_section_stub(StubSection("# Constants", ConstantNode), root,
output_stream, 0)
# NOTE: Enumerations require special handling, because all enumeration
# constants are exposed as module attributes
has_enums = _generate_section_stub(StubSection("# Enumerations", EnumerationNode),
......@@ -535,7 +532,7 @@ def check_overload_presence(node: Union[NamespaceNode, ClassNode]) -> bool:
otherwise.
"""
for func_node in node.functions.values():
if len(func_node.overloads):
if len(func_node.overloads) > 1:
return True
return False
......
......@@ -7,5 +7,5 @@ from .constant_node import ConstantNode
from .type_node import (
TypeNode, OptionalTypeNode, UnionTypeNode, NoneTypeNode, TupleTypeNode,
ASTNodeTypeNode, AliasTypeNode, SequenceTypeNode, AnyTypeNode,
AggregatedTypeNode, NDArrayTypeNode, AliasRefTypeNode,
AggregatedTypeNode, NDArrayTypeNode, AliasRefTypeNode, PrimitiveTypeNode
)
......@@ -17501,6 +17501,7 @@ CartesianProductHolder2(const Generator1& g1, const Generator2& g2)
static_cast<ParamGenerator<T2> >(g2_)));
}
CartesianProductHolder2(const CartesianProductHolder2 & other) = default;
private:
// No implementation - assignment is unsupported.
void operator=(const CartesianProductHolder2& other) = delete;
......@@ -17523,7 +17524,7 @@ CartesianProductHolder3(const Generator1& g1, const Generator2& g2,
static_cast<ParamGenerator<T2> >(g2_),
static_cast<ParamGenerator<T3> >(g3_)));
}
CartesianProductHolder3(const CartesianProductHolder3 &) = default;
private:
// No implementation - assignment is unsupported.
void operator=(const CartesianProductHolder3& other) = delete;
......@@ -17549,7 +17550,7 @@ CartesianProductHolder4(const Generator1& g1, const Generator2& g2,
static_cast<ParamGenerator<T3> >(g3_),
static_cast<ParamGenerator<T4> >(g4_)));
}
CartesianProductHolder4(const CartesianProductHolder4 &) = default;
private:
// No implementation - assignment is unsupported.
void operator=(const CartesianProductHolder4& other) = delete;
......@@ -17577,7 +17578,7 @@ CartesianProductHolder5(const Generator1& g1, const Generator2& g2,
static_cast<ParamGenerator<T4> >(g4_),
static_cast<ParamGenerator<T5> >(g5_)));
}
CartesianProductHolder5(const CartesianProductHolder5 &) = default;
private:
// No implementation - assignment is unsupported.
void operator=(const CartesianProductHolder5& other) = delete;
......@@ -17609,7 +17610,7 @@ CartesianProductHolder6(const Generator1& g1, const Generator2& g2,
static_cast<ParamGenerator<T5> >(g5_),
static_cast<ParamGenerator<T6> >(g6_)));
}
CartesianProductHolder6(const CartesianProductHolder6 &) = default;
private:
// No implementation - assignment is unsupported.
void operator=(const CartesianProductHolder6& other) = delete;
......@@ -17644,7 +17645,7 @@ CartesianProductHolder7(const Generator1& g1, const Generator2& g2,
static_cast<ParamGenerator<T6> >(g6_),
static_cast<ParamGenerator<T7> >(g7_)));
}
CartesianProductHolder7(const CartesianProductHolder7 &) = default;
private:
// No implementation - assignment is unsupported.
void operator=(const CartesianProductHolder7& other) = delete;
......@@ -17683,7 +17684,7 @@ CartesianProductHolder8(const Generator1& g1, const Generator2& g2,
static_cast<ParamGenerator<T7> >(g7_),
static_cast<ParamGenerator<T8> >(g8_)));
}
CartesianProductHolder8(const CartesianProductHolder8 &) = default;
private:
// No implementation - assignment is unsupported.
void operator=(const CartesianProductHolder8& other) = delete;
......@@ -17726,7 +17727,7 @@ CartesianProductHolder9(const Generator1& g1, const Generator2& g2,
static_cast<ParamGenerator<T8> >(g8_),
static_cast<ParamGenerator<T9> >(g9_)));
}
CartesianProductHolder9(const CartesianProductHolder9 &) = default;
private:
// No implementation - assignment is unsupported.
void operator=(const CartesianProductHolder9& other) = delete;
......
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#ifndef OPENCV_VIDEOIO_UTILS_PRIVATE_HPP
#define OPENCV_VIDEOIO_UTILS_PRIVATE_HPP
#include "opencv2/core/cvdef.h"
#include <string>
namespace cv {
CV_EXPORTS std::string icvExtractPattern(const std::string& filename, unsigned *offset);
}
#endif // OPENCV_VIDEOIO_UTILS_PRIVATE_HPP
......@@ -51,8 +51,8 @@
#include "precomp.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/core/utils/filesystem.hpp"
#include "opencv2/videoio/utils.private.hpp"
#if 0
#define CV_WARN(message)
......@@ -113,7 +113,16 @@ void CvCapture_Images::close()
bool CvCapture_Images::grabFrame()
{
cv::String filename = cv::format(filename_pattern.c_str(), (int)(firstframe + currentframe));
cv::String filename;
if (length == 1)
if (currentframe < length)
filename = filename_pattern;
else
{
return false;
}
else
filename = cv::format(filename_pattern.c_str(), (int)(firstframe + currentframe));
CV_Assert(!filename.empty());
if (grabbedInOpen)
......@@ -200,7 +209,7 @@ bool CvCapture_Images::setProperty(int id, double value)
return false;
}
static
// static
std::string icvExtractPattern(const std::string& filename, unsigned *offset)
{
size_t len = filename.size();
......@@ -249,9 +258,7 @@ std::string icvExtractPattern(const std::string& filename, unsigned *offset)
while (pos < len && !isdigit(filename[pos])) pos++;
if (pos == len)
{
CV_Error_(Error::StsBadArg, ("CAP_IMAGES: can't find starting number (in the name of file): %s", filename.c_str()));
}
return "";
std::string::size_type pos0 = pos;
......@@ -292,44 +299,61 @@ bool CvCapture_Images::open(const std::string& _filename)
CV_Assert(!_filename.empty());
filename_pattern = icvExtractPattern(_filename, &offset);
CV_Assert(!filename_pattern.empty());
// determine the length of the sequence
for (length = 0; ;)
if (filename_pattern.empty())
{
filename_pattern = _filename;
if (!utils::fs::exists(filename_pattern))
{
CV_LOG_INFO(NULL, "CAP_IMAGES: File does not exist: " << filename_pattern);
close();
return false;
}
if (!haveImageReader(filename_pattern))
{
CV_LOG_INFO(NULL, "CAP_IMAGES: File is not an image: " << filename_pattern);
close();
return false;
}
length = 1;
}
else
{
cv::String filename = cv::format(filename_pattern.c_str(), (int)(offset + length));
if (!utils::fs::exists(filename))
// determine the length of the sequence
for (length = 0; ;)
{
if (length == 0 && offset == 0) // allow starting with 0 or 1
cv::String filename = cv::format(filename_pattern.c_str(), (int)(offset + length));
if (!utils::fs::exists(filename))
{
if (length == 0 && offset == 0) // allow starting with 0 or 1
{
offset++;
continue;
}
CV_LOG_INFO(NULL, "CAP_IMAGES: File does not exist: " << filename);
break;
}
if(!haveImageReader(filename))
{
offset++;
continue;
CV_LOG_INFO(NULL, "CAP_IMAGES: File is not an image: " << filename);
break;
}
break;
length++;
}
if(!haveImageReader(filename))
if (length == 0)
{
CV_LOG_INFO(NULL, "CAP_IMAGES: Stop scanning. Can't read image file: " << filename);
break;
close();
return false;
}
length++;
firstframe = offset;
}
if (length == 0)
{
close();
return false;
}
firstframe = offset;
// grab frame to enable properties retrieval
bool grabRes = grabFrame();
bool grabRes = CvCapture_Images::grabFrame();
grabbedInOpen = true;
currentframe = 0;
return grabRes;
}
......
......@@ -1854,8 +1854,12 @@ static inline cv::String capPropertyName(int prop)
return "auto wb";
case CAP_PROP_WB_TEMPERATURE:
return "wb temperature";
case CAP_PROP_ORIENTATION_META:
return "orientation meta";
case CAP_PROP_ORIENTATION_AUTO:
return "orientation auto";
default:
return "unknown";
return cv::format("unknown (%d)", prop);
}
}
......@@ -1970,7 +1974,7 @@ bool CvCaptureCAM_V4L::controlInfo(int property_id, __u32 &_v4l2id, cv::Range &r
v4l2_queryctrl queryctrl = v4l2_queryctrl();
queryctrl.id = __u32(v4l2id);
if (v4l2id == -1 || !tryIoctl(VIDIOC_QUERYCTRL, &queryctrl)) {
CV_LOG_INFO(NULL, "VIDEOIO(V4L2:" << deviceName << "): property " << capPropertyName(property_id) << " is not supported");
CV_LOG_INFO(NULL, "VIDEOIO(V4L2:" << deviceName << "): property '" << capPropertyName(property_id) << "' is not supported");
return false;
}
_v4l2id = __u32(v4l2id);
......
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
#include "test_precomp.hpp"
#include "opencv2/core/utils/filesystem.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/videoio/utils.private.hpp"
using namespace std;
namespace opencv_test { namespace {
struct ImageCollection
{
string dirname;
string base;
string ext;
size_t first_idx;
size_t last_idx;
size_t width;
public:
ImageCollection(const char *dirname_template = "opencv_test_images")
: first_idx(0), last_idx(0), width(0)
{
dirname = cv::tempfile(dirname_template);
cv::utils::fs::createDirectory(dirname);
}
~ImageCollection()
{
cleanup();
}
void cleanup()
{
cv::utils::fs::remove_all(dirname);
}
void generate(size_t count, size_t first = 0, size_t width_ = 4, const string & base_ = "test", const string & ext_ = "png")
{
base = base_;
ext = ext_;
first_idx = first;
last_idx = first + count - 1;
width = width_;
for (size_t idx = first_idx; idx <= last_idx; ++idx)
{
const string filename = getFilename(idx);
imwrite(filename, getFrame(idx));
}
}
string getFilename(size_t idx = 0) const
{
ostringstream buf;
buf << dirname << "/" << base << setw(width) << setfill('0') << idx << "." << ext;
return buf.str();
}
string getPatternFilename() const
{
ostringstream buf;
buf << dirname << "/" << base << "%0" << width << "d" << "." << ext;
return buf.str();
}
string getFirstFilename() const
{
return getFilename(first_idx);
}
Mat getFirstFrame() const
{
return getFrame(first_idx);
}
size_t getCount() const
{
return last_idx - first_idx + 1;
}
string getDirname() const
{
return dirname;
}
static Mat getFrame(size_t idx)
{
const int sz = 100; // 100x100 or bigger
Mat res(sz, sz, CV_8UC3, Scalar::all(0));
circle(res, Point(idx % 100), idx % 50, Scalar::all(255), 2, LINE_8);
return res;
}
};
//==================================================================================================
TEST(videoio_images, basic_read)
{
ImageCollection col;
col.generate(20);
VideoCapture cap(col.getFirstFilename(), CAP_IMAGES);
ASSERT_TRUE(cap.isOpened());
size_t idx = 0;
while (cap.isOpened()) // TODO: isOpened is always true, even if there are no more images
{
Mat img;
const bool read_res = cap.read(img);
if (!read_res)
break;
EXPECT_MAT_N_DIFF(img, col.getFrame(idx), 0);
++idx;
}
EXPECT_EQ(col.getCount(), idx);
}
TEST(videoio_images, basic_write)
{
// writer should create files: test0000.png, ... test0019.png
ImageCollection col;
col.generate(1);
VideoWriter wri(col.getFirstFilename(), CAP_IMAGES, 0, 0, col.getFrame(0).size());
ASSERT_TRUE(wri.isOpened());
size_t idx = 0;
while (wri.isOpened())
{
wri << col.getFrame(idx);
Mat actual = imread(col.getFilename(idx));
EXPECT_MAT_N_DIFF(col.getFrame(idx), actual, 0);
if (++idx >= 20)
break;
}
wri.release();
ASSERT_FALSE(wri.isOpened());
}
TEST(videoio_images, bad)
{
ImageCollection col;
{
ostringstream buf; buf << col.getDirname() << "/missing0000.png";
VideoCapture cap(buf.str(), CAP_IMAGES);
EXPECT_FALSE(cap.isOpened());
Mat img;
EXPECT_FALSE(cap.read(img));
}
}
TEST(videoio_images, seek)
{
// check files: test0005.png, ..., test0024.png
// seek to valid and invalid frame numbers
// position is zero-based: valid frame numbers are 0, ..., 19
const int count = 20;
ImageCollection col;
col.generate(count, 5);
VideoCapture cap(col.getFirstFilename(), CAP_IMAGES);
ASSERT_TRUE(cap.isOpened());
EXPECT_EQ((size_t)count, (size_t)cap.get(CAP_PROP_FRAME_COUNT));
vector<int> positions { count / 2, 0, 1, count - 1, count, count + 100, -1, -100 };
for (const auto &pos : positions)
{
Mat img;
const bool res = cap.set(CAP_PROP_POS_FRAMES, pos);
if (pos >= count || pos < 0) // invalid position
{
// EXPECT_FALSE(res); // TODO: backend clamps invalid value to valid range, actual result is 'true'
}
else
{
EXPECT_TRUE(res);
EXPECT_GE(1., cap.get(CAP_PROP_POS_AVI_RATIO));
EXPECT_NEAR((double)pos / (count - 1), cap.get(CAP_PROP_POS_AVI_RATIO), 1e-2);
EXPECT_EQ(pos, static_cast<decltype(pos)>(cap.get(CAP_PROP_POS_FRAMES)));
EXPECT_TRUE(cap.read(img));
EXPECT_MAT_N_DIFF(img, col.getFrame(col.first_idx + pos), 0);
}
}
}
TEST(videoio_images, pattern_overflow)
{
// check files: test0.png, ..., test11.png
ImageCollection col;
col.generate(12, 0, 1);
{
VideoCapture cap(col.getFirstFilename(), CAP_IMAGES);
ASSERT_TRUE(cap.isOpened());
for (size_t idx = col.first_idx; idx <= col.last_idx; ++idx)
{
Mat img;
EXPECT_TRUE(cap.read(img));
EXPECT_MAT_N_DIFF(img, col.getFrame(idx), 0);
}
}
{
VideoCapture cap(col.getPatternFilename(), CAP_IMAGES);
ASSERT_TRUE(cap.isOpened());
for (size_t idx = col.first_idx; idx <= col.last_idx; ++idx)
{
Mat img;
EXPECT_TRUE(cap.read(img));
EXPECT_MAT_N_DIFF(img, col.getFrame(idx), 0);
}
}
}
TEST(videoio_images, pattern_max)
{
// max supported number width for starting image is 9 digits
// but following images can be read as well
// test999999999.png ; test1000000000.png
ImageCollection col;
col.generate(2, 1000000000 - 1);
{
VideoCapture cap(col.getFirstFilename(), CAP_IMAGES);
ASSERT_TRUE(cap.isOpened());
Mat img;
EXPECT_TRUE(cap.read(img));
EXPECT_MAT_N_DIFF(img, col.getFrame(col.first_idx), 0);
EXPECT_TRUE(cap.read(img));
EXPECT_MAT_N_DIFF(img, col.getFrame(col.first_idx + 1), 0);
}
{
VideoWriter wri(col.getFirstFilename(), CAP_IMAGES, 0, 0, col.getFirstFrame().size());
ASSERT_TRUE(wri.isOpened());
Mat img = col.getFrame(0);
wri.write(img);
wri.write(img);
Mat actual;
actual = imread(col.getFilename(col.first_idx));
EXPECT_MAT_N_DIFF(actual, img, 0);
actual = imread(col.getFilename(col.first_idx));
EXPECT_MAT_N_DIFF(actual, img, 0);
}
}
TEST(videoio_images, extract_pattern)
{
unsigned offset = 0;
// Min and max values
EXPECT_EQ("%01d.png", cv::icvExtractPattern("0.png", &offset));
EXPECT_EQ(0u, offset);
EXPECT_EQ("%09d.png", cv::icvExtractPattern("999999999.png", &offset));
EXPECT_EQ(999999999u, offset);
// Regular usage - start, end, middle
EXPECT_EQ("abc%04ddef.png", cv::icvExtractPattern("abc0048def.png", &offset));
EXPECT_EQ(48u, offset);
EXPECT_EQ("%05dabcdef.png", cv::icvExtractPattern("00049abcdef.png", &offset));
EXPECT_EQ(49u, offset);
EXPECT_EQ("abcdef%06d.png", cv::icvExtractPattern("abcdef000050.png", &offset));
EXPECT_EQ(50u, offset);
// Minus handling (should not handle)
EXPECT_EQ("abcdef-%01d.png", cv::icvExtractPattern("abcdef-8.png", &offset));
EXPECT_EQ(8u, offset);
// Two numbers (should select first)
// TODO: shouldn't it be last number?
EXPECT_EQ("%01d-abcdef-8.png", cv::icvExtractPattern("7-abcdef-8.png", &offset));
EXPECT_EQ(7u, offset);
// Paths (should select filename)
EXPECT_EQ("images005/abcdef%03d.png", cv::icvExtractPattern("images005/abcdef006.png", &offset));
EXPECT_EQ(6u, offset);
// TODO: fix
// EXPECT_EQ("images03\\abcdef%02d.png", cv::icvExtractPattern("images03\\abcdef04.png", &offset));
// EXPECT_EQ(4, offset);
EXPECT_EQ("/home/user/test/0/3348/../../3442/./0/1/3/4/5/14304324234/%01d.png",
cv::icvExtractPattern("/home/user/test/0/3348/../../3442/./0/1/3/4/5/14304324234/2.png", &offset));
EXPECT_EQ(2u, offset);
// Patterns '%0?[0-9][du]'
EXPECT_EQ("test%d.png", cv::icvExtractPattern("test%d.png", &offset));
EXPECT_EQ(0u, offset);
EXPECT_EQ("test%0d.png", cv::icvExtractPattern("test%0d.png", &offset));
EXPECT_EQ(0u, offset);
EXPECT_EQ("test%09d.png", cv::icvExtractPattern("test%09d.png", &offset));
EXPECT_EQ(0u, offset);
EXPECT_EQ("test%5u.png", cv::icvExtractPattern("test%5u.png", &offset));
EXPECT_EQ(0u, offset);
// Invalid arguments
EXPECT_THROW(cv::icvExtractPattern(string(), &offset), cv::Exception);
// TODO: fix?
// EXPECT_EQ(0u, offset);
EXPECT_THROW(cv::icvExtractPattern("test%010d.png", &offset), cv::Exception);
EXPECT_EQ(0u, offset);
EXPECT_THROW(cv::icvExtractPattern("1000000000.png", &offset), cv::Exception);
EXPECT_EQ(0u, offset);
EXPECT_THROW(cv::icvExtractPattern("1.png", NULL), cv::Exception);
}
// TODO: should writer overwrite files?
// TODO: is clamping good for seeking?
// TODO: missing files? E.g. 3, 4, 6, 7, 8 (should it finish OR jump over OR return empty frame?)
// TODO: non-numbered files (https://github.com/opencv/opencv/pull/23815)
// TODO: when opening with pattern (e.g. test%01d.png), first frame can be only 0 (test0.png)
}} // opencv_test::<anonymous>::
......@@ -5,8 +5,10 @@
#define __OPENCV_TEST_PRECOMP_HPP__
#include <sstream>
#include <algorithm>
#include "opencv2/ts.hpp"
#include "opencv2/ts/ocl_test.hpp"
#include "opencv2/videoio.hpp"
#include "opencv2/videoio/registry.hpp"
#include "opencv2/core/private.hpp"
......@@ -55,6 +57,13 @@ inline std::string fourccToString(int fourcc)
return cv::format("%c%c%c%c", fourcc & 255, (fourcc >> 8) & 255, (fourcc >> 16) & 255, (fourcc >> 24) & 255);
}
inline std::string fourccToStringSafe(int fourcc)
{
std::string res = fourccToString(fourcc);
std::replace_if(res.begin(), res.end(), [](uint8_t c){ return c < '0' || c > 'z'; }, '_');
return res;
}
inline int fourccFromString(const std::string &fourcc)
{
if (fourcc.size() != 4) return 0;
......
// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
// Reference: https://www.kernel.org/doc/html/v4.8/media/v4l-drivers/vivid.html
// create 1 virtual device of type CAP (0x1) at /dev/video10
// sudo modprobe vivid ndevs=1 node_types=0x1 vid_cap_nr=10
// make sure user have read/write access (e.g. via group 'video')
// $ ls -l /dev/video10
// crw-rw----+ 1 root video ... /dev/video10
// set environment variable:
// export OPENCV_TEST_V4L2_VIVID_DEVICE=/dev/video10
// run v4l2 tests:
// opencv_test_videoio --gtest_filter=*videoio_v4l2*
#ifdef HAVE_CAMV4L2
#include "test_precomp.hpp"
#include <opencv2/core/utils/configuration.private.hpp>
#include <linux/videodev2.h>
using namespace cv;
namespace opencv_test { namespace {
struct Format_Channels_Depth
{
uint32_t pixel_format;
uint8_t channels;
uint8_t depth;
float mul_width;
float mul_height;
};
typedef testing::TestWithParam<Format_Channels_Depth> videoio_v4l2;
TEST_P(videoio_v4l2, formats)
{
utils::Paths devs = utils::getConfigurationParameterPaths("OPENCV_TEST_V4L2_VIVID_DEVICE");
if (devs.size() != 1)
{
throw SkipTestException("OPENCV_TEST_V4L2_VIVID_DEVICE is not set");
}
const string device = devs[0];
const Size sz(640, 480);
const Format_Channels_Depth params = GetParam();
{
// Case with RAW output
VideoCapture cap;
ASSERT_TRUE(cap.open(device, CAP_V4L2));
// VideoCapture will set device's format automatically, vivid device will accept it
ASSERT_TRUE(cap.set(CAP_PROP_FOURCC, params.pixel_format));
ASSERT_TRUE(cap.set(CAP_PROP_CONVERT_RGB, false));
for (size_t idx = 0; idx < 3; ++idx)
{
Mat img;
EXPECT_TRUE(cap.grab());
EXPECT_TRUE(cap.retrieve(img));
EXPECT_EQ(Size(sz.width * params.mul_width, sz.height * params.mul_height), img.size());
EXPECT_EQ(params.channels, img.channels());
EXPECT_EQ(params.depth, img.depth());
}
}
{
// case with BGR output
VideoCapture cap;
ASSERT_TRUE(cap.open(device, CAP_V4L2));
// VideoCapture will set device's format automatically, vivid device will accept it
ASSERT_TRUE(cap.set(CAP_PROP_FOURCC, params.pixel_format));
for (size_t idx = 0; idx < 3; ++idx)
{
Mat img;
EXPECT_TRUE(cap.grab());
EXPECT_TRUE(cap.retrieve(img));
EXPECT_EQ(sz, img.size());
EXPECT_EQ(3, img.channels());
EXPECT_EQ(CV_8U, img.depth());
}
}
}
vector<Format_Channels_Depth> all_params = {
{ V4L2_PIX_FMT_YVU420, 1, CV_8U, 1.f, 1.5f },
{ V4L2_PIX_FMT_YUV420, 1, CV_8U, 1.f, 1.5f },
{ V4L2_PIX_FMT_NV12, 1, CV_8U, 1.f, 1.5f },
{ V4L2_PIX_FMT_NV21, 1, CV_8U, 1.f, 1.5f },
{ V4L2_PIX_FMT_YUV411P, 3, CV_8U, 1.f, 1.f },
// { V4L2_PIX_FMT_MJPEG, 1, CV_8U, 1.f, 1.f },
// { V4L2_PIX_FMT_JPEG, 1, CV_8U, 1.f, 1.f },
{ V4L2_PIX_FMT_YUYV, 2, CV_8U, 1.f, 1.f },
{ V4L2_PIX_FMT_UYVY, 2, CV_8U, 1.f, 1.f },
// { V4L2_PIX_FMT_SBGGR8, 1, CV_8U, 1.f, 1.f },
// { V4L2_PIX_FMT_SN9C10X, 3, CV_8U, 1.f, 1.f },
// { V4L2_PIX_FMT_SGBRG8, 1, CV_8U, 1.f, 1.f },
{ V4L2_PIX_FMT_RGB24, 3, CV_8U, 1.f, 1.f },
{ V4L2_PIX_FMT_Y16, 1, CV_16U, 1.f, 1.f },
{ V4L2_PIX_FMT_Y10, 1, CV_16U, 1.f, 1.f },
{ V4L2_PIX_FMT_GREY, 1, CV_8U, 1.f, 1.f },
{ V4L2_PIX_FMT_BGR24, 3, CV_8U, 1.f, 1.f },
{ V4L2_PIX_FMT_XBGR32, 3, CV_8U, 1.f, 1.f },
{ V4L2_PIX_FMT_ABGR32, 3, CV_8U, 1.f, 1.f },
};
inline static std::string param_printer(const testing::TestParamInfo<videoio_v4l2::ParamType>& info)
{
return fourccToStringSafe(info.param.pixel_format);
}
INSTANTIATE_TEST_CASE_P(/*videoio_v4l2*/, videoio_v4l2, ValuesIn(all_params), param_printer);
}} // opencv_test::<anonymous>::
#endif // HAVE_CAMV4L2