mirror of
https://github.com/opencv/opencv.git
synced 2026-07-31 08:13:04 +04:00
Merge branch 4.x
This commit is contained in:
@@ -774,7 +774,7 @@ struct CV_EXPORTS_W_SIMPLE CirclesGridFinderParameters
|
||||
{
|
||||
SYMMETRIC_GRID, ASYMMETRIC_GRID
|
||||
};
|
||||
GridType gridType;
|
||||
CV_PROP_RW GridType gridType;
|
||||
|
||||
CV_PROP_RW float squareSize; //!< Distance between two adjacent points. Used by CALIB_CB_CLUSTERING.
|
||||
CV_PROP_RW float maxRectifiedDistance; //!< Max deviation from prediction. Used by CALIB_CB_CLUSTERING.
|
||||
|
||||
@@ -648,6 +648,31 @@
|
||||
"jni_var": "Vec3d %(n)s(%(n)s_val0, %(n)s_val1, %(n)s_val2)",
|
||||
"suffix": "DDD"
|
||||
},
|
||||
"Vec4i": {
|
||||
"j_type": "int[]",
|
||||
"jn_args": [
|
||||
[
|
||||
"int",
|
||||
".val[0]"
|
||||
],
|
||||
[
|
||||
"int",
|
||||
".val[1]"
|
||||
],
|
||||
[
|
||||
"int",
|
||||
".val[2]"
|
||||
],
|
||||
[
|
||||
"int",
|
||||
".val[3]"
|
||||
]
|
||||
],
|
||||
"jn_type": "int[]",
|
||||
"jni_type": "jintArray",
|
||||
"jni_var": "Vec4i %(n)s(%(n)s_val0, %(n)s_val1, %(n)s_val2, %(n)s_val3)",
|
||||
"suffix": "IIII"
|
||||
},
|
||||
"c_string": {
|
||||
"j_type": "String",
|
||||
"jn_type": "String",
|
||||
@@ -852,6 +877,15 @@
|
||||
"v_type": "Mat",
|
||||
"j_import": "org.opencv.core.MatOfByte"
|
||||
},
|
||||
"vector_vector_Mat": {
|
||||
"j_type": "List<List<Mat>>",
|
||||
"jn_type": "long",
|
||||
"jni_type": "jlong",
|
||||
"jni_var": "std::vector< std::vector<Mat> > %(n)s",
|
||||
"suffix": "J",
|
||||
"v_type": "vector_Mat",
|
||||
"j_import": "org.opencv.core.Mat"
|
||||
},
|
||||
"vector_vector_DMatch": {
|
||||
"j_type": "List<MatOfDMatch>",
|
||||
"jn_type": "long",
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
#ifdef HAVE_OPENCV_CORE
|
||||
|
||||
#include "dlpack/dlpack.h"
|
||||
|
||||
static PyObject* pycvMakeType(PyObject* , PyObject* args, PyObject* kw) {
|
||||
const char *keywords[] = { "depth", "channels", NULL };
|
||||
|
||||
@@ -20,6 +22,201 @@ static PyObject* pycvMakeTypeCh(PyObject*, PyObject *value) {
|
||||
return PyInt_FromLong(CV_MAKETYPE(depth, channels));
|
||||
}
|
||||
|
||||
#define CV_DLPACK_CAPSULE_NAME "dltensor"
|
||||
#define CV_DLPACK_USED_CAPSULE_NAME "used_dltensor"
|
||||
|
||||
template<typename T>
|
||||
bool fillDLPackTensor(const T& src, DLManagedTensor* tensor, const DLDevice& device);
|
||||
|
||||
template<typename T>
|
||||
bool parseDLPackTensor(DLManagedTensor* tensor, T& obj, bool copy);
|
||||
|
||||
template<typename T>
|
||||
int GetNumDims(const T& src);
|
||||
|
||||
// source: https://github.com/dmlc/dlpack/blob/7f393bbb86a0ddd71fde3e700fc2affa5cdce72d/docs/source/python_spec.rst#L110
|
||||
static void dlpack_capsule_deleter(PyObject *self){
|
||||
if (PyCapsule_IsValid(self, CV_DLPACK_USED_CAPSULE_NAME)) {
|
||||
return;
|
||||
}
|
||||
|
||||
DLManagedTensor *managed = (DLManagedTensor *)PyCapsule_GetPointer(self, CV_DLPACK_CAPSULE_NAME);
|
||||
if (managed == NULL) {
|
||||
PyErr_WriteUnraisable(self);
|
||||
return;
|
||||
}
|
||||
|
||||
if (managed->deleter) {
|
||||
managed->deleter(managed);
|
||||
}
|
||||
}
|
||||
|
||||
static void array_dlpack_deleter(DLManagedTensor *self)
|
||||
{
|
||||
if (!Py_IsInitialized()) {
|
||||
return;
|
||||
}
|
||||
|
||||
PyGILState_STATE state = PyGILState_Ensure();
|
||||
|
||||
PyObject *array = (PyObject *)self->manager_ctx;
|
||||
PyMem_Free(self);
|
||||
Py_XDECREF(array);
|
||||
|
||||
PyGILState_Release(state);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static PyObject* to_dlpack(const T& src, PyObject* self, PyObject* py_args, PyObject* kw)
|
||||
{
|
||||
int stream = 0;
|
||||
PyObject* maxVersion = nullptr;
|
||||
PyObject* dlDevice = nullptr;
|
||||
bool copy = false;
|
||||
const char* keywords[] = { "stream", "max_version", "dl_device", "copy", NULL };
|
||||
if (!PyArg_ParseTupleAndKeywords(py_args, kw, "|iOOp:__dlpack__", (char**)keywords, &stream, &maxVersion, &dlDevice, ©))
|
||||
return nullptr;
|
||||
|
||||
DLDevice device = {(DLDeviceType)-1, 0};
|
||||
if (dlDevice && dlDevice != Py_None && PyTuple_Check(dlDevice))
|
||||
{
|
||||
device.device_type = static_cast<DLDeviceType>(PyLong_AsLong(PyTuple_GetItem(dlDevice, 0)));
|
||||
device.device_id = PyLong_AsLong(PyTuple_GetItem(dlDevice, 1));
|
||||
}
|
||||
|
||||
int ndim = GetNumDims(src);
|
||||
void* ptr = PyMem_Malloc(sizeof(DLManagedTensor) + sizeof(int64_t) * ndim * 2);
|
||||
if (!ptr) {
|
||||
PyErr_NoMemory();
|
||||
return nullptr;
|
||||
}
|
||||
DLManagedTensor* tensor = reinterpret_cast<DLManagedTensor*>(ptr);
|
||||
tensor->manager_ctx = self;
|
||||
tensor->deleter = array_dlpack_deleter;
|
||||
tensor->dl_tensor.ndim = ndim;
|
||||
tensor->dl_tensor.shape = reinterpret_cast<int64_t*>(reinterpret_cast<char*>(ptr) + sizeof(DLManagedTensor));
|
||||
tensor->dl_tensor.strides = tensor->dl_tensor.shape + ndim;
|
||||
fillDLPackTensor(src, tensor, device);
|
||||
|
||||
PyObject* capsule = PyCapsule_New(ptr, CV_DLPACK_CAPSULE_NAME, dlpack_capsule_deleter);
|
||||
if (!capsule) {
|
||||
PyMem_Free(ptr);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// the capsule holds a reference
|
||||
Py_INCREF(self);
|
||||
|
||||
return capsule;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static PyObject* from_dlpack(PyObject* py_args, PyObject* kw)
|
||||
{
|
||||
PyObject* arr = nullptr;
|
||||
PyObject* device = nullptr;
|
||||
bool copy = false;
|
||||
const char* keywords[] = { "device", "copy", NULL };
|
||||
if (!PyArg_ParseTupleAndKeywords(py_args, kw, "O|Op:from_dlpack", (char**)keywords, &arr, &device, ©))
|
||||
return nullptr;
|
||||
|
||||
PyObject* capsule = nullptr;
|
||||
if (PyCapsule_CheckExact(arr))
|
||||
{
|
||||
capsule = arr;
|
||||
}
|
||||
else
|
||||
{
|
||||
PyGILState_STATE gstate;
|
||||
gstate = PyGILState_Ensure();
|
||||
capsule = PyObject_CallMethodObjArgs(arr, PyString_FromString("__dlpack__"), NULL);
|
||||
PyGILState_Release(gstate);
|
||||
}
|
||||
|
||||
DLManagedTensor* tensor = reinterpret_cast<DLManagedTensor*>(PyCapsule_GetPointer(capsule, CV_DLPACK_CAPSULE_NAME));
|
||||
if (tensor == nullptr)
|
||||
{
|
||||
if (capsule != arr)
|
||||
Py_DECREF(capsule);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
T retval;
|
||||
bool success = parseDLPackTensor(tensor, retval, copy);
|
||||
if (success)
|
||||
{
|
||||
PyCapsule_SetName(capsule, CV_DLPACK_USED_CAPSULE_NAME);
|
||||
}
|
||||
if (capsule != arr)
|
||||
Py_DECREF(capsule);
|
||||
|
||||
return success ? pyopencv_from(retval) : nullptr;
|
||||
}
|
||||
|
||||
static DLDataType GetDLPackType(size_t elemSize1, int depth) {
|
||||
DLDataType dtype;
|
||||
dtype.bits = static_cast<uint8_t>(8 * elemSize1);
|
||||
dtype.lanes = 1;
|
||||
switch (depth)
|
||||
{
|
||||
case CV_8S: case CV_16S: case CV_32S: dtype.code = kDLInt; break;
|
||||
case CV_8U: case CV_16U: dtype.code = kDLUInt; break;
|
||||
case CV_16F: case CV_32F: case CV_64F: dtype.code = kDLFloat; break;
|
||||
default:
|
||||
CV_Error(Error::StsNotImplemented, "__dlpack__ data type");
|
||||
}
|
||||
return dtype;
|
||||
}
|
||||
|
||||
static int DLPackTypeToCVType(const DLDataType& dtype, int channels) {
|
||||
if (dtype.code == kDLInt)
|
||||
{
|
||||
switch (dtype.bits)
|
||||
{
|
||||
case 8: return CV_8SC(channels);
|
||||
case 16: return CV_16SC(channels);
|
||||
case 32: return CV_32SC(channels);
|
||||
default:
|
||||
{
|
||||
PyErr_SetString(PyExc_BufferError,
|
||||
format("Unsupported int dlpack depth: %d", dtype.bits).c_str());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dtype.code == kDLUInt)
|
||||
{
|
||||
switch (dtype.bits)
|
||||
{
|
||||
case 8: return CV_8UC(channels);
|
||||
case 16: return CV_16UC(channels);
|
||||
default:
|
||||
{
|
||||
PyErr_SetString(PyExc_BufferError,
|
||||
format("Unsupported uint dlpack depth: %d", dtype.bits).c_str());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dtype.code == kDLFloat)
|
||||
{
|
||||
switch (dtype.bits)
|
||||
{
|
||||
case 16: return CV_16FC(channels);
|
||||
case 32: return CV_32FC(channels);
|
||||
case 64: return CV_64FC(channels);
|
||||
default:
|
||||
{
|
||||
PyErr_SetString(PyExc_BufferError,
|
||||
format("Unsupported float dlpack depth: %d", dtype.bits).c_str());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
PyErr_SetString(PyExc_BufferError, format("Unsupported dlpack data type: %d", dtype.code).c_str());
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define PYOPENCV_EXTRA_METHODS_CV \
|
||||
{"CV_MAKETYPE", CV_PY_FN_WITH_KW(pycvMakeType), "CV_MAKETYPE(depth, channels) -> retval"}, \
|
||||
{"CV_8UC", (PyCFunction)(pycvMakeTypeCh<CV_8U>), METH_O, "CV_8UC(channels) -> retval"}, \
|
||||
|
||||
@@ -21,17 +21,175 @@ template<> struct pyopencvVecConverter<cuda::GpuMat>
|
||||
};
|
||||
|
||||
CV_PY_TO_CLASS(cuda::GpuMat)
|
||||
CV_PY_TO_CLASS(cuda::GpuMatND)
|
||||
CV_PY_TO_CLASS(cuda::Stream)
|
||||
CV_PY_TO_CLASS(cuda::Event)
|
||||
CV_PY_TO_CLASS(cuda::HostMem)
|
||||
|
||||
CV_PY_TO_CLASS_PTR(cuda::GpuMat)
|
||||
CV_PY_TO_CLASS_PTR(cuda::GpuMatND)
|
||||
CV_PY_TO_CLASS_PTR(cuda::GpuMat::Allocator)
|
||||
|
||||
CV_PY_FROM_CLASS(cuda::GpuMat)
|
||||
CV_PY_FROM_CLASS(cuda::GpuMatND)
|
||||
CV_PY_FROM_CLASS(cuda::Stream)
|
||||
CV_PY_FROM_CLASS(cuda::HostMem)
|
||||
|
||||
CV_PY_FROM_CLASS_PTR(cuda::GpuMat::Allocator)
|
||||
|
||||
template<>
|
||||
bool fillDLPackTensor(const Ptr<cv::cuda::GpuMat>& src, DLManagedTensor* tensor, const DLDevice& device)
|
||||
{
|
||||
if ((device.device_type != -1 && device.device_type != kDLCUDA) || device.device_id != 0)
|
||||
{
|
||||
PyErr_SetString(PyExc_BufferError, "GpuMat can be exported only on GPU:0");
|
||||
return false;
|
||||
}
|
||||
tensor->dl_tensor.data = src->cudaPtr();
|
||||
tensor->dl_tensor.device.device_type = kDLCUDA;
|
||||
tensor->dl_tensor.device.device_id = 0;
|
||||
tensor->dl_tensor.dtype = GetDLPackType(src->elemSize1(), src->depth());
|
||||
tensor->dl_tensor.shape[0] = src->rows;
|
||||
tensor->dl_tensor.shape[1] = src->cols;
|
||||
tensor->dl_tensor.shape[2] = src->channels();
|
||||
tensor->dl_tensor.strides[0] = src->step1();
|
||||
tensor->dl_tensor.strides[1] = src->channels();
|
||||
tensor->dl_tensor.strides[2] = 1;
|
||||
tensor->dl_tensor.byte_offset = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<>
|
||||
bool fillDLPackTensor(const Ptr<cv::cuda::GpuMatND>& src, DLManagedTensor* tensor, const DLDevice& device)
|
||||
{
|
||||
if ((device.device_type != -1 && device.device_type != kDLCUDA) || device.device_id != 0)
|
||||
{
|
||||
PyErr_SetString(PyExc_BufferError, "GpuMatND can be exported only on GPU:0");
|
||||
return false;
|
||||
}
|
||||
tensor->dl_tensor.data = src->getDevicePtr();
|
||||
tensor->dl_tensor.device.device_type = kDLCUDA;
|
||||
tensor->dl_tensor.device.device_id = 0;
|
||||
tensor->dl_tensor.dtype = GetDLPackType(src->elemSize1(), CV_MAT_DEPTH(src->flags));
|
||||
for (int i = 0; i < src->dims; ++i)
|
||||
tensor->dl_tensor.shape[i] = src->size[i];
|
||||
for (int i = 0; i < src->dims; ++i)
|
||||
tensor->dl_tensor.strides[i] = src->step[i];
|
||||
tensor->dl_tensor.byte_offset = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
template<>
|
||||
bool parseDLPackTensor(DLManagedTensor* tensor, cv::cuda::GpuMat& obj, bool copy)
|
||||
{
|
||||
if (tensor->dl_tensor.byte_offset != 0)
|
||||
{
|
||||
PyErr_SetString(PyExc_BufferError, "Unimplemented from_dlpack for GpuMat with memory offset");
|
||||
return false;
|
||||
}
|
||||
if (tensor->dl_tensor.ndim != 3)
|
||||
{
|
||||
PyErr_SetString(PyExc_BufferError, "cuda_GpuMat.from_dlpack expects a 3D tensor. Use cuda_GpuMatND.from_dlpack instead");
|
||||
return false;
|
||||
}
|
||||
if (tensor->dl_tensor.device.device_type != kDLCUDA)
|
||||
{
|
||||
PyErr_SetString(PyExc_BufferError, "cuda_GpuMat.from_dlpack expects a tensor on CUDA device");
|
||||
return false;
|
||||
}
|
||||
if (tensor->dl_tensor.strides[1] != tensor->dl_tensor.shape[2] ||
|
||||
tensor->dl_tensor.strides[2] != 1)
|
||||
{
|
||||
PyErr_SetString(PyExc_BufferError, "Unexpected strides for image. Try use GpuMatND");
|
||||
return false;
|
||||
}
|
||||
int type = DLPackTypeToCVType(tensor->dl_tensor.dtype, (int)tensor->dl_tensor.shape[2]);
|
||||
if (type == -1)
|
||||
return false;
|
||||
|
||||
obj = cv::cuda::GpuMat(
|
||||
static_cast<int>(tensor->dl_tensor.shape[0]),
|
||||
static_cast<int>(tensor->dl_tensor.shape[1]),
|
||||
type,
|
||||
tensor->dl_tensor.data,
|
||||
tensor->dl_tensor.strides[0] * tensor->dl_tensor.dtype.bits / 8
|
||||
);
|
||||
if (copy)
|
||||
obj = obj.clone();
|
||||
return true;
|
||||
}
|
||||
|
||||
template<>
|
||||
bool parseDLPackTensor(DLManagedTensor* tensor, cv::cuda::GpuMatND& obj, bool copy)
|
||||
{
|
||||
if (tensor->dl_tensor.byte_offset != 0)
|
||||
{
|
||||
PyErr_SetString(PyExc_BufferError, "Unimplemented from_dlpack for GpuMat with memory offset");
|
||||
return false;
|
||||
}
|
||||
if (tensor->dl_tensor.device.device_type != kDLCUDA)
|
||||
{
|
||||
PyErr_SetString(PyExc_BufferError, "cuda_GpuMat.from_dlpack expects a tensor on CUDA device");
|
||||
return false;
|
||||
}
|
||||
int type = DLPackTypeToCVType(tensor->dl_tensor.dtype, (int)tensor->dl_tensor.shape[2]);
|
||||
if (type == -1)
|
||||
return false;
|
||||
|
||||
std::vector<size_t> steps(tensor->dl_tensor.ndim - 1);
|
||||
std::vector<int> sizes(tensor->dl_tensor.ndim);
|
||||
for (int i = 0; i < tensor->dl_tensor.ndim - 1; ++i)
|
||||
{
|
||||
steps[i] = tensor->dl_tensor.strides[i] * tensor->dl_tensor.dtype.bits / 8;
|
||||
sizes[i] = static_cast<int>(tensor->dl_tensor.shape[i]);
|
||||
}
|
||||
sizes.back() = static_cast<int>(tensor->dl_tensor.shape[tensor->dl_tensor.ndim - 1]);
|
||||
obj = cv::cuda::GpuMatND(sizes, type, tensor->dl_tensor.data, steps);
|
||||
if (copy)
|
||||
obj = obj.clone();
|
||||
return true;
|
||||
}
|
||||
|
||||
template<>
|
||||
int GetNumDims(const Ptr<cv::cuda::GpuMat>& src) { return 3; }
|
||||
|
||||
template<>
|
||||
int GetNumDims(const Ptr<cv::cuda::GpuMatND>& src) { return src->dims; }
|
||||
|
||||
static PyObject* pyDLPackGpuMat(PyObject* self, PyObject* py_args, PyObject* kw) {
|
||||
Ptr<cv::cuda::GpuMat> * self1 = 0;
|
||||
if (!pyopencv_cuda_GpuMat_getp(self, self1))
|
||||
return failmsgp("Incorrect type of self (must be 'cuda_GpuMat' or its derivative)");
|
||||
return to_dlpack(*(self1), self, py_args, kw);
|
||||
}
|
||||
|
||||
static PyObject* pyDLPackGpuMatND(PyObject* self, PyObject* py_args, PyObject* kw) {
|
||||
Ptr<cv::cuda::GpuMatND> * self1 = 0;
|
||||
if (!pyopencv_cuda_GpuMatND_getp(self, self1))
|
||||
return failmsgp("Incorrect type of self (must be 'cuda_GpuMatND' or its derivative)");
|
||||
return to_dlpack(*(self1), self, py_args, kw);
|
||||
}
|
||||
|
||||
static PyObject* pyDLPackDeviceCUDA(PyObject*, PyObject*, PyObject*) {
|
||||
return pyopencv_from(std::tuple<int, int>(kDLCUDA, 0));
|
||||
}
|
||||
|
||||
static PyObject* pyGpuMatFromDLPack(PyObject*, PyObject* py_args, PyObject* kw) {
|
||||
return from_dlpack<cv::cuda::GpuMat>(py_args, kw);
|
||||
}
|
||||
|
||||
static PyObject* pyGpuMatNDFromDLPack(PyObject*, PyObject* py_args, PyObject* kw) {
|
||||
return from_dlpack<cv::cuda::GpuMatND>(py_args, kw);
|
||||
}
|
||||
|
||||
#define PYOPENCV_EXTRA_METHODS_cuda_GpuMat \
|
||||
{"__dlpack__", CV_PY_FN_WITH_KW(pyDLPackGpuMat), ""}, \
|
||||
{"__dlpack_device__", CV_PY_FN_WITH_KW(pyDLPackDeviceCUDA), ""}, \
|
||||
{"from_dlpack", CV_PY_FN_WITH_KW_(pyGpuMatFromDLPack, METH_STATIC), ""}, \
|
||||
|
||||
#define PYOPENCV_EXTRA_METHODS_cuda_GpuMatND \
|
||||
{"__dlpack__", CV_PY_FN_WITH_KW(pyDLPackGpuMatND), ""}, \
|
||||
{"__dlpack_device__", CV_PY_FN_WITH_KW(pyDLPackDeviceCUDA), ""}, \
|
||||
{"from_dlpack", CV_PY_FN_WITH_KW_(pyGpuMatNDFromDLPack, METH_STATIC), ""}, \
|
||||
|
||||
#endif
|
||||
|
||||
@@ -60,6 +60,14 @@ namespace cv
|
||||
#undef USE_IPP_DFT
|
||||
#endif
|
||||
|
||||
#if defined USE_IPP_DFT
|
||||
#if IPP_VERSION_X100 >= 202220
|
||||
#define IPP_DISABLE_DFT32F ((depth == CV_32F) && (ippCPUID_AVX512F&cv::ipp::getIppFeatures()))
|
||||
#else
|
||||
#define IPP_DISABLE_DFT32F false
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/****************************************************************************************\
|
||||
Discrete Fourier Transform
|
||||
\****************************************************************************************/
|
||||
@@ -3258,7 +3266,7 @@ public:
|
||||
opt.ipp_spec = 0;
|
||||
opt.ipp_work = 0;
|
||||
|
||||
if( CV_IPP_CHECK_COND && (opt.n*count >= 64) ) // use IPP DFT if available
|
||||
if( CV_IPP_CHECK_COND && (opt.n*count >= 64) && !IPP_DISABLE_DFT32F) // use IPP DFT if available
|
||||
{
|
||||
int ipp_norm_flag = (flags & CV_HAL_DFT_SCALE) == 0 ? 8 : opt.isInverse ? 2 : 1;
|
||||
int specsize=0, initsize=0, worksize=0;
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
package org.opencv.test.dnn;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.opencv.core.Core;
|
||||
import org.opencv.core.CvType;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.MatOfByte;
|
||||
import org.opencv.core.Range;
|
||||
import org.opencv.dnn.Dnn;
|
||||
import org.opencv.dnn.Net;
|
||||
import org.opencv.test.OpenCVTestCase;
|
||||
|
||||
public class DnnForwardAndRetrieve extends OpenCVTestCase {
|
||||
|
||||
public void testForwardAndRetrieve()
|
||||
{
|
||||
// Create a simple Caffe prototxt with a Slice layer
|
||||
String prototxt =
|
||||
"input: \"data\"\n" +
|
||||
"layer {\n" +
|
||||
" name: \"testLayer\"\n" +
|
||||
" type: \"Slice\"\n" +
|
||||
" bottom: \"data\"\n" +
|
||||
" top: \"firstCopy\"\n" +
|
||||
" top: \"secondCopy\"\n" +
|
||||
" slice_param {\n" +
|
||||
" axis: 0\n" +
|
||||
" slice_point: 2\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
|
||||
// Read network from prototxt
|
||||
MatOfByte bufferProto = new MatOfByte();
|
||||
bufferProto.fromArray(prototxt.getBytes());
|
||||
MatOfByte bufferModel = new MatOfByte();
|
||||
Net net = Dnn.readNetFromCaffe(bufferProto, bufferModel, Dnn.ENGINE_CLASSIC);
|
||||
net.setPreferableBackend(Dnn.DNN_BACKEND_OPENCV);
|
||||
|
||||
// Create input data
|
||||
Mat inp = new Mat(4, 5, CvType.CV_32F);
|
||||
Core.randu(inp, -1, 1);
|
||||
net.setInput(inp);
|
||||
|
||||
// Define output names
|
||||
List<String> outNames = new ArrayList<>();
|
||||
outNames.add("testLayer");
|
||||
|
||||
// Forward and retrieve multiple outputs
|
||||
List<List<Mat>> outBlobs = new ArrayList<>();
|
||||
net.forwardAndRetrieve(outBlobs, outNames);
|
||||
|
||||
// Verify results
|
||||
assertEquals(1, outBlobs.size());
|
||||
assertEquals(2, outBlobs.get(0).size());
|
||||
|
||||
// Compare results
|
||||
Mat expectedFirst = inp.rowRange(0, 2);
|
||||
Mat expectedSecond = inp.rowRange(2, 4);
|
||||
|
||||
Mat actualFirst = outBlobs.get(0).get(0);
|
||||
Mat actualSecond = outBlobs.get(0).get(1);
|
||||
|
||||
assertEquals(0, Core.norm(expectedFirst, actualFirst, Core.NORM_INF), EPS);
|
||||
assertEquals(0, Core.norm(expectedSecond, actualSecond, Core.NORM_INF), EPS);
|
||||
}
|
||||
}
|
||||
@@ -1110,13 +1110,27 @@ public:
|
||||
*/
|
||||
CV_WRAP Subdiv2D(Rect rect);
|
||||
|
||||
/** @brief Creates a new empty Delaunay subdivision
|
||||
/** @overload */
|
||||
CV_WRAP Subdiv2D(Rect2f rect2f);
|
||||
|
||||
/** @overload
|
||||
|
||||
@brief Creates a new empty Delaunay subdivision
|
||||
|
||||
@param rect Rectangle that includes all of the 2D points that are to be added to the subdivision.
|
||||
|
||||
*/
|
||||
CV_WRAP void initDelaunay(Rect rect);
|
||||
|
||||
/** @overload
|
||||
|
||||
@brief Creates a new empty Delaunay subdivision
|
||||
|
||||
@param rect Rectangle that includes all of the 2d points that are to be added to the subdivision.
|
||||
|
||||
*/
|
||||
CV_WRAP_AS(initDelaunay2f) CV_WRAP void initDelaunay(Rect2f rect);
|
||||
|
||||
/** @brief Insert a single point into a Delaunay triangulation.
|
||||
|
||||
@param pt Point to insert.
|
||||
|
||||
@@ -118,6 +118,16 @@ Subdiv2D::Subdiv2D(Rect rect)
|
||||
initDelaunay(rect);
|
||||
}
|
||||
|
||||
Subdiv2D::Subdiv2D(Rect2f rect)
|
||||
{
|
||||
validGeometry = false;
|
||||
freeQEdge = 0;
|
||||
freePoint = 0;
|
||||
recentEdge = 0;
|
||||
|
||||
initDelaunay(rect);
|
||||
}
|
||||
|
||||
|
||||
Subdiv2D::QuadEdge::QuadEdge()
|
||||
{
|
||||
@@ -535,6 +545,52 @@ void Subdiv2D::initDelaunay( Rect rect )
|
||||
recentEdge = edge_AB;
|
||||
}
|
||||
|
||||
void Subdiv2D::initDelaunay( Rect2f rect )
|
||||
{
|
||||
CV_INSTRUMENT_REGION();
|
||||
|
||||
float big_coord = 6.f * MAX( rect.width, rect.height );
|
||||
float rx = rect.x;
|
||||
float ry = rect.y;
|
||||
|
||||
vtx.clear();
|
||||
qedges.clear();
|
||||
|
||||
recentEdge = 0;
|
||||
validGeometry = false;
|
||||
|
||||
topLeft = Point2f( rx, ry );
|
||||
bottomRight = Point2f( rx + rect.width, ry + rect.height );
|
||||
|
||||
Point2f ppA( rx + big_coord, ry );
|
||||
Point2f ppB( rx, ry + big_coord );
|
||||
Point2f ppC( rx - big_coord, ry - big_coord );
|
||||
|
||||
vtx.push_back(Vertex());
|
||||
qedges.push_back(QuadEdge());
|
||||
|
||||
freeQEdge = 0;
|
||||
freePoint = 0;
|
||||
|
||||
int pA = newPoint(ppA, false);
|
||||
int pB = newPoint(ppB, false);
|
||||
int pC = newPoint(ppC, false);
|
||||
|
||||
int edge_AB = newEdge();
|
||||
int edge_BC = newEdge();
|
||||
int edge_CA = newEdge();
|
||||
|
||||
setEdgePoints( edge_AB, pA, pB );
|
||||
setEdgePoints( edge_BC, pB, pC );
|
||||
setEdgePoints( edge_CA, pC, pA );
|
||||
|
||||
splice( edge_AB, symEdge( edge_CA ));
|
||||
splice( edge_BC, symEdge( edge_AB ));
|
||||
splice( edge_CA, symEdge( edge_BC ));
|
||||
|
||||
recentEdge = edge_AB;
|
||||
}
|
||||
|
||||
|
||||
void Subdiv2D::clearVoronoi()
|
||||
{
|
||||
|
||||
@@ -11,10 +11,13 @@ namespace opencv_test { namespace {
|
||||
// return true if point lies inside ellipse
|
||||
static bool check_pt_in_ellipse(const Point2f& pt, const RotatedRect& el) {
|
||||
Point2f to_pt = pt - el.center;
|
||||
double pt_angle = atan2(to_pt.y, to_pt.x);
|
||||
double el_angle = el.angle * CV_PI / 180;
|
||||
double x_dist = 0.5 * el.size.width * cos(pt_angle + el_angle);
|
||||
double y_dist = 0.5 * el.size.height * sin(pt_angle + el_angle);
|
||||
const Point2d to_pt_el(
|
||||
to_pt.x * cos(-el_angle) - to_pt.y * sin(-el_angle),
|
||||
to_pt.x * sin(-el_angle) + to_pt.y * cos(-el_angle));
|
||||
const double pt_angle = atan2(to_pt_el.y / el.size.height, to_pt_el.x / el.size.width);
|
||||
const double x_dist = 0.5 * el.size.width * cos(pt_angle);
|
||||
const double y_dist = 0.5 * el.size.height * sin(pt_angle);
|
||||
double el_dist = sqrt(x_dist * x_dist + y_dist * y_dist);
|
||||
return cv::norm(to_pt) < el_dist;
|
||||
}
|
||||
|
||||
@@ -64,4 +64,57 @@ TEST(Imgproc_Subdiv2D, issue_25696) {
|
||||
|
||||
ASSERT_EQ(static_cast<size_t>(2), triangles.size());
|
||||
}
|
||||
|
||||
// Initialization test
|
||||
TEST(Imgproc_Subdiv2D, rect2f_constructor_and_init)
|
||||
{
|
||||
cv::Rect2f rect_f(0.5f, 1.5f, 100.7f, 200.3f);
|
||||
cv::Subdiv2D subdiv_f(rect_f);
|
||||
|
||||
cv::Point2f pt1(50.2f, 80.1f);
|
||||
cv::Point2f pt2(75.8f, 120.9f);
|
||||
cv::Point2f pt3(25.5f, 150.3f);
|
||||
|
||||
EXPECT_NO_THROW(subdiv_f.insert(pt1));
|
||||
EXPECT_NO_THROW(subdiv_f.insert(pt2));
|
||||
EXPECT_NO_THROW(subdiv_f.insert(pt3));
|
||||
|
||||
cv::Subdiv2D subdiv_init;
|
||||
|
||||
EXPECT_NO_THROW(subdiv_init.initDelaunay(rect_f));
|
||||
EXPECT_NO_THROW(subdiv_init.insert(pt1));
|
||||
EXPECT_NO_THROW(subdiv_init.insert(pt2));
|
||||
EXPECT_NO_THROW(subdiv_init.insert(pt3));
|
||||
|
||||
std::vector<cv::Vec6f> triangles;
|
||||
|
||||
EXPECT_NO_THROW(subdiv_f.getTriangleList(triangles));
|
||||
EXPECT_GT(triangles.size(), 0u);
|
||||
}
|
||||
|
||||
// test with small coordinates
|
||||
TEST(Imgproc_Subdiv2D, rect2f_edge_cases)
|
||||
{
|
||||
cv::Rect2f small_rect(0.0f, 0.0f, 0.1f, 0.1f);
|
||||
cv::Subdiv2D subdiv_small(small_rect);
|
||||
|
||||
cv::Point2f small_pt(0.05f, 0.05f);
|
||||
EXPECT_NO_THROW(subdiv_small.insert(small_pt));
|
||||
cv::Rect2f float_rect(10.25f, 20.75f, 50.5f, 30.25f);
|
||||
|
||||
cv::Subdiv2D subdiv_float(float_rect);
|
||||
|
||||
cv::Point2f float_pt1(35.125f, 35.875f);
|
||||
cv::Point2f float_pt2(45.375f, 25.625f);
|
||||
cv::Point2f float_pt3(55.750f, 45.125f);
|
||||
|
||||
EXPECT_NO_THROW(subdiv_float.insert(float_pt1));
|
||||
EXPECT_NO_THROW(subdiv_float.insert(float_pt2));
|
||||
EXPECT_NO_THROW(subdiv_float.insert(float_pt3));
|
||||
|
||||
std::vector<cv::Vec6f> triangles;
|
||||
|
||||
subdiv_float.getTriangleList(triangles);
|
||||
EXPECT_GT(triangles.size(), 0u);
|
||||
}
|
||||
}}
|
||||
|
||||
@@ -756,6 +756,13 @@ class JavaWrapperGenerator(object):
|
||||
"jdouble _tmp_retval_[%(cnt)i] = {%(args)s}; " +
|
||||
"env->SetDoubleArrayRegion(_da_retval_, 0, %(cnt)i, _tmp_retval_);") %
|
||||
{ "cnt" : len(fields), "args" : ", ".join(["(jdouble)_retval_" + f[1] for f in fields]) } )
|
||||
elif type_dict[fi.ctype]["jni_type"] == "jintArray":
|
||||
fields = type_dict[fi.ctype]["jn_args"]
|
||||
c_epilogue.append(
|
||||
("jintArray _ia_retval_ = env->NewIntArray(%(cnt)i); " +
|
||||
"jint _tmp_retval_[%(cnt)i] = {%(args)s}; " +
|
||||
"env->SetIntArrayRegion(_ia_retval_, 0, %(cnt)i, _tmp_retval_);") %
|
||||
{ "cnt" : len(fields), "args" : ", ".join(["(jint)_retval_" + f[1] for f in fields]) } )
|
||||
if fi.classname and fi.ctype and not fi.static: # non-static class method except c-tor
|
||||
# adding 'self'
|
||||
jn_args.append ( ArgInfo([ "__int64", "nativeObj", "", [], "" ]) )
|
||||
@@ -803,7 +810,14 @@ class JavaWrapperGenerator(object):
|
||||
fields = type_dict[a.ctype].get("jn_args", ((a.ctype, ""),))
|
||||
if "I" in a.out or not a.out or self.isWrapped(a.ctype): # input arg, pass by primitive fields
|
||||
for f in fields:
|
||||
jn_args.append ( ArgInfo([ f[0], a.name + f[1], "", [], "" ]) )
|
||||
# Use array access format for Java code when jn_type is array type
|
||||
if type_dict[a.ctype].get("jn_type", "").endswith("[]"):
|
||||
# For Java code: convert .val[0] format to [0] format
|
||||
jn_args.append ( ArgInfo([ f[0], a.name + f[1].replace(".val[", "["), "", [], "" ]) )
|
||||
else:
|
||||
# For non-array types, use conventional format
|
||||
jn_args.append ( ArgInfo([ f[0], a.name + f[1], "", [], "" ]) )
|
||||
# For C++ code: use conventional format as is
|
||||
jni_args.append( ArgInfo([ f[0], a.name + normalize_field_name(f[1]), "", [], "" ]) )
|
||||
if "O" in a.out and not self.isWrapped(a.ctype): # out arg, pass as double[]
|
||||
jn_args.append ( ArgInfo([ "double[]", "%s_out" % a.name, "", [], "" ]) )
|
||||
@@ -818,9 +832,16 @@ class JavaWrapperGenerator(object):
|
||||
set_vals = []
|
||||
i = 0
|
||||
for f in fields:
|
||||
set_vals.append( "%(n)s%(f)s = %(t)s%(n)s_out[%(i)i]" %
|
||||
{"n" : a.name, "t": ("("+type_dict[f[0]]["j_type"]+")", "")[f[0]=="double"], "f" : f[1], "i" : i}
|
||||
)
|
||||
# Use array access format for Java code when jn_type is array type
|
||||
if type_dict[a.ctype].get("jn_type", "").endswith("[]"):
|
||||
# For Java code: convert .val[0] format to [0] format
|
||||
set_vals.append( "%(n)s%(f)s = %(t)s%(n)s_out[%(i)i]" %
|
||||
{"n" : a.name, "t": ("("+type_dict[f[0]]["j_type"]+")", "")[f[0]=="double"], "f" : f[1].replace(".val[", "["), "i" : i}
|
||||
)
|
||||
else:
|
||||
set_vals.append( "%(n)s%(f)s = %(t)s%(n)s_out[%(i)i]" %
|
||||
{"n" : a.name, "t": ("("+type_dict[f[0]]["j_type"]+")", "")[f[0]=="double"], "f" : f[1], "i" : i}
|
||||
)
|
||||
i += 1
|
||||
j_epilogue.append( "if("+a.name+"!=null){ " + "; ".join(set_vals) + "; } ")
|
||||
|
||||
@@ -1015,6 +1036,8 @@ class JavaWrapperGenerator(object):
|
||||
ret = "return (jlong) _retval_;"
|
||||
elif type_dict[fi.ctype]["jni_type"] == "jdoubleArray":
|
||||
ret = "return _da_retval_;"
|
||||
elif type_dict[fi.ctype]["jni_type"] == "jintArray":
|
||||
ret = "return _ia_retval_;"
|
||||
elif "jni_var" in type_dict[ret_type]:
|
||||
c_epilogue.append(type_dict[ret_type]["jni_var"] % {"n" : '_retval_'})
|
||||
ret = f"return {type_dict[ret_type]['jni_name'] % {'n' : '_retval_'}};"
|
||||
|
||||
@@ -219,6 +219,32 @@ void vector_Mat_to_Mat(std::vector<cv::Mat>& v_mat, cv::Mat& mat)
|
||||
}
|
||||
}
|
||||
|
||||
void Mat_to_vector_vector_Mat(Mat& mat, std::vector< std::vector< Mat > >& vv_mat)
|
||||
{
|
||||
std::vector<Mat> vm;
|
||||
vm.reserve( mat.rows );
|
||||
Mat_to_vector_Mat(mat, vm);
|
||||
for(size_t i=0; i<vm.size(); i++)
|
||||
{
|
||||
std::vector<Mat> vmat;
|
||||
Mat_to_vector_Mat(vm[i], vmat);
|
||||
vv_mat.push_back(vmat);
|
||||
}
|
||||
}
|
||||
|
||||
void vector_vector_Mat_to_Mat(std::vector< std::vector< Mat > >& vv_mat, Mat& mat)
|
||||
{
|
||||
std::vector<Mat> vm;
|
||||
vm.reserve( vv_mat.size() );
|
||||
for(size_t i=0; i<vv_mat.size(); i++)
|
||||
{
|
||||
Mat m;
|
||||
vector_Mat_to_Mat(vv_mat[i], m);
|
||||
vm.push_back(m);
|
||||
}
|
||||
vector_Mat_to_Mat(vm, mat);
|
||||
}
|
||||
|
||||
void Mat_to_vector_vector_Point(Mat& mat, std::vector< std::vector< Point > >& vv_pt)
|
||||
{
|
||||
std::vector<Mat> vm;
|
||||
|
||||
@@ -50,6 +50,9 @@ void vector_Vec6f_to_Mat(std::vector<cv::Vec6f>& v_vec, cv::Mat& mat);
|
||||
void Mat_to_vector_Mat(cv::Mat& mat, std::vector<cv::Mat>& v_mat);
|
||||
void vector_Mat_to_Mat(std::vector<cv::Mat>& v_mat, cv::Mat& mat);
|
||||
|
||||
void Mat_to_vector_vector_Mat(cv::Mat& mat, std::vector< std::vector< cv::Mat > >& vv_mat);
|
||||
void vector_vector_Mat_to_Mat(std::vector< std::vector< cv::Mat > >& vv_mat, cv::Mat& mat);
|
||||
|
||||
void Mat_to_vector_vector_char(cv::Mat& mat, std::vector< std::vector< char > >& vv_ch);
|
||||
void vector_vector_char_to_Mat(std::vector< std::vector< char > >& vv_ch, cv::Mat& mat);
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import org.opencv.core.CvType;
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.MatOfByte;
|
||||
import org.opencv.core.MatOfDMatch;
|
||||
import org.opencv.core.MatOfInt;
|
||||
import org.opencv.core.MatOfKeyPoint;
|
||||
import org.opencv.core.MatOfPoint;
|
||||
import org.opencv.core.MatOfPoint2f;
|
||||
@@ -514,6 +515,41 @@ public class Converters {
|
||||
}
|
||||
}
|
||||
|
||||
// vector_vector_Mat
|
||||
public static Mat vector_vector_Mat_to_Mat(List<List<Mat>> vecMats, List<Mat> mats) {
|
||||
Mat res;
|
||||
int lCount = (vecMats != null) ? vecMats.size() : 0;
|
||||
if (lCount > 0) {
|
||||
for (List<Mat> matList : vecMats) {
|
||||
Mat mat = vector_Mat_to_Mat(matList);
|
||||
mats.add(mat);
|
||||
}
|
||||
res = vector_Mat_to_Mat(mats);
|
||||
} else {
|
||||
res = new Mat();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public static void Mat_to_vector_vector_Mat(Mat m, List<List<Mat>> vecMats) {
|
||||
if (vecMats == null)
|
||||
throw new IllegalArgumentException("Output List can't be null");
|
||||
|
||||
if (m == null)
|
||||
throw new IllegalArgumentException("Input Mat can't be null");
|
||||
|
||||
vecMats.clear();
|
||||
List<Mat> mats = new ArrayList<Mat>(m.rows());
|
||||
Mat_to_vector_Mat(m, mats);
|
||||
for (Mat mi : mats) {
|
||||
List<Mat> rowList = new ArrayList<Mat>(mi.rows());
|
||||
Mat_to_vector_Mat(mi, rowList);
|
||||
vecMats.add(rowList);
|
||||
mi.release();
|
||||
}
|
||||
mats.clear();
|
||||
}
|
||||
|
||||
// vector_vector_Point
|
||||
public static Mat vector_vector_Point_to_Mat(List<MatOfPoint> pts, List<Mat> mats) {
|
||||
Mat res;
|
||||
@@ -803,4 +839,75 @@ public class Converters {
|
||||
rs.add(new RotatedRect(new Point(buff[5 * i], buff[5 * i + 1]), new Size(buff[5 * i + 2], buff[5 * i + 3]), buff[5 * i + 4]));
|
||||
}
|
||||
}
|
||||
|
||||
// vector_MatShape
|
||||
public static Mat vector_MatShape_to_Mat(List<MatOfInt> matOfInts) {
|
||||
Mat res;
|
||||
int count = (matOfInts != null) ? matOfInts.size() : 0;
|
||||
if (count > 0) {
|
||||
res = new Mat(count, 1, CvType.CV_32SC2);
|
||||
int[] buff = new int[count * 2];
|
||||
for (int i = 0; i < count; i++) {
|
||||
long addr = matOfInts.get(i).nativeObj;
|
||||
buff[i * 2] = (int) (addr >> 32);
|
||||
buff[i * 2 + 1] = (int) (addr & 0xffffffff);
|
||||
}
|
||||
res.put(0, 0, buff);
|
||||
} else {
|
||||
res = new Mat();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public static void Mat_to_vector_MatShape(Mat m, List<MatOfInt> matOfInts) {
|
||||
if (matOfInts == null)
|
||||
throw new IllegalArgumentException("matOfInts == null");
|
||||
int count = m.rows();
|
||||
if (CvType.CV_32SC2 != m.type() || m.cols() != 1)
|
||||
throw new IllegalArgumentException(
|
||||
"CvType.CV_32SC2 != m.type() || m.cols()!=1\n" + m);
|
||||
|
||||
matOfInts.clear();
|
||||
int[] buff = new int[count * 2];
|
||||
m.get(0, 0, buff);
|
||||
for (int i = 0; i < count; i++) {
|
||||
long addr = (((long) buff[i * 2]) << 32) | (((long) buff[i * 2 + 1]) & 0xffffffffL);
|
||||
matOfInts.add(MatOfInt.fromNativeAddr(addr));
|
||||
}
|
||||
}
|
||||
|
||||
// vector_vector_MatShape
|
||||
public static Mat vector_vector_MatShape_to_Mat(List<List<MatOfInt>> vecMatOfInts, List<Mat> mats) {
|
||||
Mat res;
|
||||
int lCount = (vecMatOfInts != null) ? vecMatOfInts.size() : 0;
|
||||
if (lCount > 0) {
|
||||
for (List<MatOfInt> matList : vecMatOfInts) {
|
||||
Mat mat = vector_MatShape_to_Mat(matList);
|
||||
mats.add(mat);
|
||||
}
|
||||
res = vector_Mat_to_Mat(mats);
|
||||
} else {
|
||||
res = new Mat();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public static void Mat_to_vector_vector_MatShape(Mat m, List<List<MatOfInt>> vecMatOfInts) {
|
||||
if (vecMatOfInts == null)
|
||||
throw new IllegalArgumentException("Output List can't be null");
|
||||
|
||||
if (m == null)
|
||||
throw new IllegalArgumentException("Input Mat can't be null");
|
||||
|
||||
vecMatOfInts.clear();
|
||||
List<Mat> mats = new ArrayList<Mat>(m.rows());
|
||||
Mat_to_vector_Mat(m, mats);
|
||||
for (Mat mi : mats) {
|
||||
List<MatOfInt> rowList = new ArrayList<MatOfInt>(mi.rows());
|
||||
Mat_to_vector_MatShape(mi, rowList);
|
||||
vecMatOfInts.add(rowList);
|
||||
mi.release();
|
||||
}
|
||||
mats.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,13 +68,20 @@ if(DEFINED OPENCV_PYTHON_INSTALL_PATH)
|
||||
endif()
|
||||
set(CMAKE_PYTHON_BINARIES_PATH "${CMAKE_PYTHON_BINARIES_INSTALL_PATH}")
|
||||
if (WIN32 AND HAVE_CUDA)
|
||||
set(_cuda_bin_dir "bin")
|
||||
if (ENABLE_CUDA_FIRST_CLASS_LANGUAGE)
|
||||
if (DEFINED CUDAToolkit_LIBRARY_ROOT)
|
||||
list(APPEND CMAKE_PYTHON_BINARIES_PATH "os.path.join(os.getenv('CUDA_PATH', '${CUDAToolkit_LIBRARY_ROOT}'), 'bin')")
|
||||
if(DEFINED CUDAToolkit_VERSION_MAJOR AND CUDAToolkit_VERSION_MAJOR GREATER_EQUAL 13)
|
||||
set(_cuda_bin_dir "bin/x64")
|
||||
endif()
|
||||
list(APPEND CMAKE_PYTHON_BINARIES_PATH "os.path.join(os.getenv('CUDA_PATH', '${CUDAToolkit_LIBRARY_ROOT}'), '${_cuda_bin_dir}')")
|
||||
endif()
|
||||
else()
|
||||
if (DEFINED CUDA_TOOLKIT_ROOT_DIR)
|
||||
list(APPEND CMAKE_PYTHON_BINARIES_PATH "os.path.join(os.getenv('CUDA_PATH', '${CUDA_TOOLKIT_ROOT_DIR}'), 'bin')")
|
||||
if(DEFINED CUDA_VERSION_MAJOR AND CUDA_VERSION_MAJOR GREATER_EQUAL 13)
|
||||
set(_cuda_bin_dir "bin/x64")
|
||||
endif()
|
||||
list(APPEND CMAKE_PYTHON_BINARIES_PATH "os.path.join(os.getenv('CUDA_PATH', '${CUDA_TOOLKIT_ROOT_DIR}'), '${_cuda_bin_dir}')")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -133,6 +133,9 @@ static PyGetSetDef pyopencv_${name}_getseters[] =
|
||||
|
||||
static PyMethodDef pyopencv_${name}_methods[] =
|
||||
{
|
||||
#ifdef PYOPENCV_EXTRA_METHODS_${name}
|
||||
PYOPENCV_EXTRA_METHODS_${name}
|
||||
#endif
|
||||
${methods_inits}
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
@@ -70,6 +70,7 @@ class cuda_test(NewOpenCVTests):
|
||||
self.assertTrue(cuMat.step == 0)
|
||||
self.assertTrue(cuMat.size() == (0, 0))
|
||||
|
||||
@unittest.skip("failed test")
|
||||
def test_cuda_convertTo(self):
|
||||
# setup
|
||||
npMat_8UC4 = (np.random.random((128, 128, 4)) * 255).astype(np.uint8)
|
||||
@@ -105,6 +106,7 @@ class cuda_test(NewOpenCVTests):
|
||||
stream.waitForCompletion()
|
||||
self.assertTrue(np.array_equal(npMat_32FC4, npMat_32FC4_out))
|
||||
|
||||
@unittest.skip("failed test")
|
||||
def test_cuda_copyTo(self):
|
||||
# setup
|
||||
npMat_8UC4 = (np.random.random((128, 128, 4)) * 255).astype(np.uint8)
|
||||
@@ -143,5 +145,18 @@ class cuda_test(NewOpenCVTests):
|
||||
self.assertEqual(True, hasattr(cv.cuda, 'fastNlMeansDenoisingColored'))
|
||||
self.assertEqual(True, hasattr(cv.cuda, 'nonLocalMeans'))
|
||||
|
||||
def test_dlpack_GpuMat(self):
|
||||
for dtype in [np.int8, np.uint8, np.int16, np.uint16, np.float16, np.int32, np.float32, np.float64]:
|
||||
for channels in [2, 3, 5]:
|
||||
ref = (np.random.random((64, 128, channels)) * 255).astype(dtype)
|
||||
src = cv.cuda_GpuMat()
|
||||
src.upload(ref)
|
||||
dst = cv.cuda_GpuMat.from_dlpack(src)
|
||||
test = dst.download()
|
||||
equal = np.array_equal(ref, test)
|
||||
if not equal:
|
||||
print(f"Failed test with dtype {dtype} and {channels} channels")
|
||||
self.assertTrue(equal)
|
||||
|
||||
if __name__ == '__main__':
|
||||
NewOpenCVTests.bootstrap()
|
||||
|
||||
@@ -711,7 +711,15 @@ enum VideoCaptureOBSensorProperties{
|
||||
CAP_PROP_OBSENSOR_DEPTH_POS_MSEC=26006,
|
||||
CAP_PROP_OBSENSOR_DEPTH_WIDTH=26007,
|
||||
CAP_PROP_OBSENSOR_DEPTH_HEIGHT=26008,
|
||||
CAP_PROP_OBSENSOR_DEPTH_FPS=26009
|
||||
CAP_PROP_OBSENSOR_DEPTH_FPS=26009,
|
||||
CAP_PROP_OBSENSOR_COLOR_DISTORTION_K1=26010,
|
||||
CAP_PROP_OBSENSOR_COLOR_DISTORTION_K2=26011,
|
||||
CAP_PROP_OBSENSOR_COLOR_DISTORTION_K3=26012,
|
||||
CAP_PROP_OBSENSOR_COLOR_DISTORTION_K4=26013,
|
||||
CAP_PROP_OBSENSOR_COLOR_DISTORTION_K5=26014,
|
||||
CAP_PROP_OBSENSOR_COLOR_DISTORTION_K6=26015,
|
||||
CAP_PROP_OBSENSOR_COLOR_DISTORTION_P1=26016,
|
||||
CAP_PROP_OBSENSOR_COLOR_DISTORTION_P2=26017
|
||||
};
|
||||
|
||||
//! @} OBSENSOR
|
||||
|
||||
@@ -685,7 +685,10 @@ void CvCapture_FFMPEG::close()
|
||||
if( video_st )
|
||||
{
|
||||
#ifdef CV_FFMPEG_CODECPAR
|
||||
// avcodec_close removed in FFmpeg release 8.0
|
||||
# if (LIBAVCODEC_BUILD < CALC_FFMPEG_VERSION(62, 11, 100))
|
||||
avcodec_close( context );
|
||||
# endif
|
||||
#endif
|
||||
video_st = NULL;
|
||||
}
|
||||
@@ -2005,7 +2008,18 @@ void CvCapture_FFMPEG::get_rotation_angle()
|
||||
rotation_angle = 0;
|
||||
#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(57, 68, 100)
|
||||
const uint8_t *data = 0;
|
||||
// av_stream_get_side_data removed in FFmpeg release 8.0
|
||||
# if (LIBAVCODEC_BUILD < CALC_FFMPEG_VERSION(62, 11, 100))
|
||||
data = av_stream_get_side_data(video_st, AV_PKT_DATA_DISPLAYMATRIX, NULL);
|
||||
# else
|
||||
AVPacketSideData* sd = video_st->codecpar->coded_side_data;
|
||||
int nb_sd = video_st->codecpar->nb_coded_side_data;
|
||||
if (sd && nb_sd > 0)
|
||||
{
|
||||
const AVPacketSideData* mtx = av_packet_side_data_get(sd, nb_sd, AV_PKT_DATA_DISPLAYMATRIX);
|
||||
data = mtx->data;
|
||||
}
|
||||
# endif
|
||||
if (data)
|
||||
{
|
||||
rotation_angle = -cvRound(av_display_rotation_get((const int32_t*)data));
|
||||
|
||||
@@ -84,10 +84,19 @@ VideoCapture_obsensor::VideoCapture_obsensor(int, const cv::VideoCaptureParamete
|
||||
});
|
||||
|
||||
auto param = pipe->getCameraParam();
|
||||
camParam.p1[0] = param.rgbIntrinsic.fx;
|
||||
camParam.p1[1] = param.rgbIntrinsic.fy;
|
||||
camParam.p1[2] = param.rgbIntrinsic.cx;
|
||||
camParam.p1[3] = param.rgbIntrinsic.cy;
|
||||
camParam.intrinsicColor[0] = param.rgbIntrinsic.fx;
|
||||
camParam.intrinsicColor[1] = param.rgbIntrinsic.fy;
|
||||
camParam.intrinsicColor[2] = param.rgbIntrinsic.cx;
|
||||
camParam.intrinsicColor[3] = param.rgbIntrinsic.cy;
|
||||
|
||||
camParam.distortionColor[0] = param.depthDistortion.k1;
|
||||
camParam.distortionColor[1] = param.depthDistortion.k2;
|
||||
camParam.distortionColor[2] = param.depthDistortion.k3;
|
||||
camParam.distortionColor[3] = param.depthDistortion.k4;
|
||||
camParam.distortionColor[4] = param.depthDistortion.k5;
|
||||
camParam.distortionColor[5] = param.depthDistortion.k6;
|
||||
camParam.distortionColor[6] = param.depthDistortion.p1;
|
||||
camParam.distortionColor[7] = param.depthDistortion.p2;
|
||||
}
|
||||
|
||||
VideoCapture_obsensor::~VideoCapture_obsensor(){
|
||||
@@ -101,17 +110,42 @@ double VideoCapture_obsensor::getProperty(int propIdx) const
|
||||
switch (propIdx)
|
||||
{
|
||||
case CAP_PROP_OBSENSOR_INTRINSIC_FX:
|
||||
rst = camParam.p1[0];
|
||||
rst = camParam.intrinsicColor[0];
|
||||
break;
|
||||
case CAP_PROP_OBSENSOR_INTRINSIC_FY:
|
||||
rst = camParam.p1[1];
|
||||
rst = camParam.intrinsicColor[1];
|
||||
break;
|
||||
case CAP_PROP_OBSENSOR_INTRINSIC_CX:
|
||||
rst = camParam.p1[2];
|
||||
rst = camParam.intrinsicColor[2];
|
||||
break;
|
||||
case CAP_PROP_OBSENSOR_INTRINSIC_CY:
|
||||
rst = camParam.p1[3];
|
||||
rst = camParam.intrinsicColor[3];
|
||||
break;
|
||||
case CAP_PROP_OBSENSOR_COLOR_DISTORTION_K1:
|
||||
rst = camParam.distortionColor[0];
|
||||
break;
|
||||
case CAP_PROP_OBSENSOR_COLOR_DISTORTION_K2:
|
||||
rst = camParam.distortionColor[1];
|
||||
break;
|
||||
case CAP_PROP_OBSENSOR_COLOR_DISTORTION_K3:
|
||||
rst = camParam.distortionColor[2];
|
||||
break;
|
||||
case CAP_PROP_OBSENSOR_COLOR_DISTORTION_K4:
|
||||
rst = camParam.distortionColor[3];
|
||||
break;
|
||||
case CAP_PROP_OBSENSOR_COLOR_DISTORTION_K5:
|
||||
rst = camParam.distortionColor[4];
|
||||
break;
|
||||
case CAP_PROP_OBSENSOR_COLOR_DISTORTION_K6:
|
||||
rst = camParam.distortionColor[5];
|
||||
break;
|
||||
case CAP_PROP_OBSENSOR_COLOR_DISTORTION_P1:
|
||||
rst = camParam.distortionColor[6];
|
||||
break;
|
||||
case CAP_PROP_OBSENSOR_COLOR_DISTORTION_P2:
|
||||
rst = camParam.distortionColor[7];
|
||||
break;
|
||||
|
||||
case CAP_PROP_POS_MSEC:
|
||||
case CAP_PROP_OBSENSOR_RGB_POS_MSEC:
|
||||
if (grabbedColorFrame)
|
||||
|
||||
@@ -33,14 +33,8 @@ namespace cv
|
||||
|
||||
struct CameraParam
|
||||
{
|
||||
float p0[4];
|
||||
float p1[4];
|
||||
float p2[9];
|
||||
float p3[3];
|
||||
float p4[5];
|
||||
float p5[5];
|
||||
uint32_t p6[2];
|
||||
uint32_t p7[2];
|
||||
float intrinsicColor[4];
|
||||
float distortionColor[8];
|
||||
};
|
||||
|
||||
class VideoCapture_obsensor : public IVideoCapture
|
||||
|
||||
Reference in New Issue
Block a user