...
 
Commits (16)
    https://gitcode.net/opencv/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/opencv/opencv/-/commit/32251c9b04a3d84d6bd3ed3918fa9493bc5208d0 Add missing properties to error class 2023-07-04T17:57:30-04:00 Avasam samuel.06@hotmail.com https://gitcode.net/opencv/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/opencv/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/opencv/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/opencv/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/opencv/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/opencv/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/opencv/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/opencv/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/opencv/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/opencv/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/opencv/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/opencv/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/opencv/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/opencv/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()
......
......@@ -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;
......
......@@ -302,59 +302,58 @@ bool CvCapture_Images::open(const std::string& _filename)
if (filename_pattern.empty())
{
filename_pattern = _filename;
cv::String filename = _filename.c_str();
if (!utils::fs::exists(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))
if (!haveImageReader(filename_pattern))
{
CV_LOG_INFO(NULL, "CAP_IMAGES: Stop scanning. Can't read image file: " << filename);
CV_LOG_INFO(NULL, "CAP_IMAGES: File is not an image: " << filename_pattern);
close();
return false;
}
length = 1;
// grab frame to enable properties retrieval
bool grabRes = grabFrame();
grabbedInOpen = true;
currentframe = 0;
return grabRes;
}
// determine the length of the sequence
for (length = 0; ;)
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))
{
offset++;
continue;
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;
}
break;
if(!haveImageReader(filename))
{
CV_LOG_INFO(NULL, "CAP_IMAGES: File is not an image: " << filename);
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);
......
......@@ -5,6 +5,7 @@
#define __OPENCV_TEST_PRECOMP_HPP__
#include <sstream>
#include <algorithm>
#include "opencv2/ts.hpp"
#include "opencv2/ts/ocl_test.hpp"
......@@ -56,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