1
0
mirror of https://github.com/opencv/opencv_contrib.git synced 2025-10-16 22:35:51 +08:00

Merge pull request #3267 from cudawarped:fix_python_bindings

This commit is contained in:
Alexander Alekhin
2022-06-04 23:06:09 +00:00
6 changed files with 129 additions and 21 deletions

View File

@@ -353,8 +353,12 @@ public:
/** @brief Grabs, decodes and returns the next video frame.
If no frames has been grabbed (there are no more frames in video file), the methods return false .
The method throws Exception if error occurs.
@param [out] frame The video frame.
@param stream Stream for the asynchronous version.
@return `false` if no frames have been grabbed.
If no frames have been grabbed (there are no more frames in video file), the methods return false.
The method throws an Exception if error occurs.
*/
CV_WRAP virtual bool nextFrame(CV_OUT GpuMat& frame, Stream &stream = Stream::Null()) = 0;
@@ -364,6 +368,7 @@ public:
/** @brief Grabs the next frame from the video source.
@param stream Stream for the asynchronous version.
@return `true` (non-zero) in the case of success.
The method/function grabs the next frame from video file or camera and returns true (non-zero) in
@@ -376,17 +381,44 @@ public:
/** @brief Returns previously grabbed video data.
@param [out] frame The returned data which depends on the provided idx. If there is no new data since the last call to grab() the image will be empty.
@param idx Determins the returned data inside image. The returned data can be the:
Decoded frame, idx = get(PROP_DECODED_FRAME_IDX).
Extra data if available, idx = get(PROP_EXTRA_DATA_INDEX).
Raw encoded data package. To retrieve package i, idx = get(PROP_RAW_PACKAGES_BASE_INDEX) + i with i < get(PROP_NUMBER_OF_RAW_PACKAGES_SINCE_LAST_GRAB)
@return `false` if no frames has been grabbed
@param [out] frame The returned data which depends on the provided idx.
@param idx Determines the returned data inside image. The returned data can be the:
- Decoded frame, idx = get(PROP_DECODED_FRAME_IDX).
- Extra data if available, idx = get(PROP_EXTRA_DATA_INDEX).
- Raw encoded data package. To retrieve package i, idx = get(PROP_RAW_PACKAGES_BASE_INDEX) + i with i < get(PROP_NUMBER_OF_RAW_PACKAGES_SINCE_LAST_GRAB)
@return `false` if no frames have been grabbed
The method returns data associated with the current video source since the last call to grab() or the creation of the VideoReader. If no data is present
the method returns false and the function returns an empty image.
*/
CV_WRAP virtual bool retrieve(CV_OUT OutputArray frame, const size_t idx = static_cast<size_t>(VideoReaderProps::PROP_DECODED_FRAME_IDX)) const = 0;
virtual bool retrieve(OutputArray frame, const size_t idx = static_cast<size_t>(VideoReaderProps::PROP_DECODED_FRAME_IDX)) const = 0;
/** @brief Returns previously grabbed encoded video data.
@param [out] frame The encoded video data.
@param idx Determines the returned data inside image. The returned data can be the:
- Extra data if available, idx = get(PROP_EXTRA_DATA_INDEX).
- Raw encoded data package. To retrieve package i, idx = get(PROP_RAW_PACKAGES_BASE_INDEX) + i with i < get(PROP_NUMBER_OF_RAW_PACKAGES_SINCE_LAST_GRAB)
@return `false` if no frames have been grabbed
The method returns data associated with the current video source since the last call to grab() or the creation of the VideoReader. If no data is present
the method returns false and the function returns an empty image.
*/
CV_WRAP inline bool retrieve(CV_OUT Mat& frame, const size_t idx) const {
return retrieve(OutputArray(frame), idx);
}
/** @brief Returns the next video frame.
@param [out] frame The video frame. If grab() has not been called then this will be empty().
@return `false` if no frames have been grabbed
The method returns data associated with the current video source since the last call to grab(). If no data is present
the method returns false and the function returns an empty image.
*/
CV_WRAP inline bool retrieve(CV_OUT GpuMat& frame) const {
return retrieve(OutputArray(frame));
}
/** @brief Sets a property in the VideoReader.
@@ -395,7 +427,10 @@ public:
@param propertyVal Value of the property.
@return `true` if the property has been set.
*/
CV_WRAP virtual bool set(const VideoReaderProps propertyId, const double propertyVal) = 0;
virtual bool set(const VideoReaderProps propertyId, const double propertyVal) = 0;
CV_WRAP inline bool setVideoReaderProps(const VideoReaderProps propertyId, double propertyVal) {
return set(propertyId, propertyVal);
}
/** @brief Set the desired ColorFormat for the frame returned by nextFrame()/retrieve().
@@ -408,11 +443,12 @@ public:
@param propertyId Property identifier from cv::cudacodec::VideoReaderProps (eg. cv::cudacodec::VideoReaderProps::PROP_DECODED_FRAME_IDX,
cv::cudacodec::VideoReaderProps::PROP_EXTRA_DATA_INDEX, ...).
@param propertyVal
In - Optional value required for querying specific propertyId's, e.g. the index of the raw package to be checked for a key frame (cv::cudacodec::VideoReaderProps::PROP_LRF_HAS_KEY_FRAME).
Out - Value of the property.
- In: Optional value required for querying specific propertyId's, e.g. the index of the raw package to be checked for a key frame (cv::cudacodec::VideoReaderProps::PROP_LRF_HAS_KEY_FRAME).
- Out: Value of the property.
@return `true` unless the property is not supported.
*/
CV_WRAP virtual bool get(const VideoReaderProps propertyId, CV_IN_OUT double& propertyVal) const = 0;
virtual bool get(const VideoReaderProps propertyId, double& propertyVal) const = 0;
CV_WRAP virtual bool getVideoReaderProps(const VideoReaderProps propertyId, CV_OUT double& propertyValOut, double propertyValIn = 0) const = 0;
/** @brief Retrieves the specified property used by the VideoSource.

View File

@@ -34,6 +34,35 @@ class cudacodec_test(NewOpenCVTests):
ret, _gpu_mat2 = reader.nextFrame(gpu_mat)
#TODO: self.assertTrue(gpu_mat == gpu_mat2)
self.assertTrue(ret)
params = cv.cudacodec.VideoReaderInitParams()
params.rawMode = True
ms_gs = 1234
reader = cv.cudacodec.createVideoReader(vid_path,[cv.CAP_PROP_OPEN_TIMEOUT_MSEC, ms_gs], params)
ret, ms = reader.get(cv.CAP_PROP_OPEN_TIMEOUT_MSEC)
self.assertTrue(ret and ms == ms_gs)
ret, raw_mode = reader.getVideoReaderProps(cv.cudacodec.VideoReaderProps_PROP_RAW_MODE)
self.assertTrue(ret and raw_mode)
ret, colour_code = reader.getVideoReaderProps(cv.cudacodec.VideoReaderProps_PROP_COLOR_FORMAT)
self.assertTrue(ret and colour_code == cv.cudacodec.ColorFormat_BGRA)
colour_code_gs = cv.cudacodec.ColorFormat_GRAY
reader.set(colour_code_gs)
ret, colour_code = reader.getVideoReaderProps(cv.cudacodec.VideoReaderProps_PROP_COLOR_FORMAT)
self.assertTrue(ret and colour_code == colour_code_gs)
ret, i_base = reader.getVideoReaderProps(cv.cudacodec.VideoReaderProps_PROP_RAW_PACKAGES_BASE_INDEX)
self.assertTrue(ret and i_base == 2.0)
self.assertTrue(reader.grab())
ret, gpu_mat3 = reader.retrieve()
self.assertTrue(ret and isinstance(gpu_mat3,cv.cuda.GpuMat) and not gpu_mat3.empty())
ret = reader.retrieve(gpu_mat3)
self.assertTrue(ret and isinstance(gpu_mat3,cv.cuda.GpuMat) and not gpu_mat3.empty())
ret, n_raw_packages_since_last_grab = reader.getVideoReaderProps(cv.cudacodec.VideoReaderProps_PROP_NUMBER_OF_RAW_PACKAGES_SINCE_LAST_GRAB)
self.assertTrue(ret and n_raw_packages_since_last_grab > 0)
ret, raw_data = reader.retrieve(int(i_base))
self.assertTrue(ret and isinstance(raw_data,np.ndarray) and np.any(raw_data))
except cv.error as e:
notSupported = (e.code == cv.Error.StsNotImplemented or e.code == cv.Error.StsUnsupportedFormat or e.code == cv.Error.GPU_API_CALL_ERROR)
self.assertTrue(notSupported)

View File

@@ -102,6 +102,7 @@ namespace
void set(const ColorFormat _colorFormat) CV_OVERRIDE;
bool get(const VideoReaderProps propertyId, double& propertyVal) const CV_OVERRIDE;
bool getVideoReaderProps(const VideoReaderProps propertyId, double& propertyValOut, double propertyValIn) const CV_OVERRIDE;
bool get(const int propertyId, double& propertyVal) const CV_OVERRIDE;
@@ -246,13 +247,13 @@ namespace
}
else if (idx == extraDataIdx) {
if (!frame.isMat())
CV_Error(Error::StsUnsupportedFormat, "Extra data is stored on the host and must be retrueved using a cv::Mat");
CV_Error(Error::StsUnsupportedFormat, "Extra data is stored on the host and must be retrieved using a cv::Mat");
videoSource_->getExtraData(frame.getMatRef());
}
else{
if (idx >= rawPacketsBaseIdx && idx < rawPacketsBaseIdx + rawPackets.size()) {
if (!frame.isMat())
CV_Error(Error::StsUnsupportedFormat, "Raw data is stored on the host and must retrievd using a cv::Mat");
CV_Error(Error::StsUnsupportedFormat, "Raw data is stored on the host and must be retrieved using a cv::Mat");
Mat tmp(1, rawPackets.at(idx - rawPacketsBaseIdx).size, CV_8UC1, rawPackets.at(idx - rawPacketsBaseIdx).Data(), rawPackets.at(idx - rawPacketsBaseIdx).size);
frame.getMatRef() = tmp;
}
@@ -264,8 +265,9 @@ namespace
switch (propertyId) {
case VideoReaderProps::PROP_RAW_MODE :
videoSource_->SetRawMode(static_cast<bool>(propertyVal));
return true;
}
return true;
return false;
}
void VideoReaderImpl::set(const ColorFormat _colorFormat) {
@@ -303,20 +305,28 @@ namespace
else
break;
}
case VideoReaderProps::PROP_ALLOW_FRAME_DROP: {
case VideoReaderProps::PROP_ALLOW_FRAME_DROP:
propertyVal = videoParser_->allowFrameDrops();
return true;
}
case VideoReaderProps::PROP_UDP_SOURCE: {
case VideoReaderProps::PROP_UDP_SOURCE:
propertyVal = videoParser_->udpSource();
return true;
}
case VideoReaderProps::PROP_COLOR_FORMAT:
propertyVal = static_cast<double>(colorFormat);
return true;
default:
break;
}
return false;
}
bool VideoReaderImpl::getVideoReaderProps(const VideoReaderProps propertyId, double& propertyValOut, double propertyValIn) const {
double propertyValInOut = propertyValIn;
const bool ret = get(propertyId, propertyValInOut);
propertyValOut = propertyValInOut;
return ret;
}
bool VideoReaderImpl::get(const int propertyId, double& propertyVal) const {
return videoSource_->get(propertyId, propertyVal);
}

View File

@@ -201,6 +201,8 @@ CUDA_TEST_P(Video, Reader)
// request a different colour format for each frame
const std::pair< cudacodec::ColorFormat, int>& formatToChannels = formatsToChannels[i % formatsToChannels.size()];
reader->set(formatToChannels.first);
double colorFormat;
ASSERT_TRUE(reader->get(cudacodec::VideoReaderProps::PROP_COLOR_FORMAT, colorFormat) && static_cast<cudacodec::ColorFormat>(colorFormat) == formatToChannels.first);
ASSERT_TRUE(reader->nextFrame(frame));
if(!fmt.valid)
fmt = reader->format();

View File

@@ -355,7 +355,10 @@ disparity map.
@sa reprojectImageTo3D
*/
CV_EXPORTS_W void reprojectImageTo3D(InputArray disp, OutputArray xyzw, InputArray Q, int dst_cn = 4, Stream& stream = Stream::Null());
CV_EXPORTS void reprojectImageTo3D(InputArray disp, OutputArray xyzw, InputArray Q, int dst_cn = 4, Stream& stream = Stream::Null());
CV_EXPORTS_W inline void reprojectImageTo3D(GpuMat disp, CV_OUT GpuMat& xyzw, Mat Q, int dst_cn = 4, Stream& stream = Stream::Null()) {
reprojectImageTo3D((InputArray)disp, (OutputArray)xyzw, (InputArray)Q, dst_cn, stream);
}
/** @brief Colors a disparity image.

View File

@@ -0,0 +1,28 @@
#!/usr/bin/env python
import os
import cv2 as cv
import numpy as np
from tests_common import NewOpenCVTests, unittest
class cudastereo_test(NewOpenCVTests):
def setUp(self):
super(cudastereo_test, self).setUp()
if not cv.cuda.getCudaEnabledDeviceCount():
self.skipTest("No CUDA-capable device is detected")
def test_reprojectImageTo3D(self):
# Test's the functionality but not the results from reprojectImageTo3D
sz = (128,128)
np_disparity = np.random.randint(0, 64, sz, dtype=np.int16)
cu_disparity = cv.cuda_GpuMat(np_disparity)
np_q = np.random.randint(0, 100, (4, 4)).astype(np.float32)
stream = cv.cuda.Stream()
cu_xyz = cv.cuda.reprojectImageTo3D(cu_disparity, np_q, stream = stream)
self.assertTrue(cu_xyz.type() == cv.CV_32FC4 and cu_xyz.size() == sz)
cu_xyz1 = cv.cuda.GpuMat(sz, cv.CV_32FC3)
cv.cuda.reprojectImageTo3D(cu_disparity, np_q, cu_xyz1, 3, stream)
self.assertTrue(cu_xyz1.type() == cv.CV_32FC3 and cu_xyz1.size() == sz)
if __name__ == '__main__':
NewOpenCVTests.bootstrap()