Skip to content

Commit 442085f

Browse files
committed
Merge pull request #3267 from cudawarped:fix_python_bindings
2 parents 4eae7c8 + d276079 commit 442085f

File tree

6 files changed

+129
-21
lines changed

6 files changed

+129
-21
lines changed

modules/cudacodec/include/opencv2/cudacodec.hpp

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -353,8 +353,12 @@ class CV_EXPORTS_W VideoReader
353353

354354
/** @brief Grabs, decodes and returns the next video frame.
355355
356-
If no frames has been grabbed (there are no more frames in video file), the methods return false .
357-
The method throws Exception if error occurs.
356+
@param [out] frame The video frame.
357+
@param stream Stream for the asynchronous version.
358+
@return `false` if no frames have been grabbed.
359+
360+
If no frames have been grabbed (there are no more frames in video file), the methods return false.
361+
The method throws an Exception if error occurs.
358362
*/
359363
CV_WRAP virtual bool nextFrame(CV_OUT GpuMat& frame, Stream &stream = Stream::Null()) = 0;
360364

@@ -364,6 +368,7 @@ class CV_EXPORTS_W VideoReader
364368

365369
/** @brief Grabs the next frame from the video source.
366370
371+
@param stream Stream for the asynchronous version.
367372
@return `true` (non-zero) in the case of success.
368373
369374
The method/function grabs the next frame from video file or camera and returns true (non-zero) in
@@ -376,17 +381,44 @@ class CV_EXPORTS_W VideoReader
376381

377382
/** @brief Returns previously grabbed video data.
378383
379-
@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.
380-
@param idx Determins the returned data inside image. The returned data can be the:
381-
Decoded frame, idx = get(PROP_DECODED_FRAME_IDX).
382-
Extra data if available, idx = get(PROP_EXTRA_DATA_INDEX).
383-
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)
384-
@return `false` if no frames has been grabbed
384+
@param [out] frame The returned data which depends on the provided idx.
385+
@param idx Determines the returned data inside image. The returned data can be the:
386+
- Decoded frame, idx = get(PROP_DECODED_FRAME_IDX).
387+
- Extra data if available, idx = get(PROP_EXTRA_DATA_INDEX).
388+
- 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)
389+
@return `false` if no frames have been grabbed
390+
391+
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
392+
the method returns false and the function returns an empty image.
393+
*/
394+
virtual bool retrieve(OutputArray frame, const size_t idx = static_cast<size_t>(VideoReaderProps::PROP_DECODED_FRAME_IDX)) const = 0;
395+
396+
/** @brief Returns previously grabbed encoded video data.
397+
398+
@param [out] frame The encoded video data.
399+
@param idx Determines the returned data inside image. The returned data can be the:
400+
- Extra data if available, idx = get(PROP_EXTRA_DATA_INDEX).
401+
- 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)
402+
@return `false` if no frames have been grabbed
385403
386404
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
387405
the method returns false and the function returns an empty image.
388406
*/
389-
CV_WRAP virtual bool retrieve(CV_OUT OutputArray frame, const size_t idx = static_cast<size_t>(VideoReaderProps::PROP_DECODED_FRAME_IDX)) const = 0;
407+
CV_WRAP inline bool retrieve(CV_OUT Mat& frame, const size_t idx) const {
408+
return retrieve(OutputArray(frame), idx);
409+
}
410+
411+
/** @brief Returns the next video frame.
412+
413+
@param [out] frame The video frame. If grab() has not been called then this will be empty().
414+
@return `false` if no frames have been grabbed
415+
416+
The method returns data associated with the current video source since the last call to grab(). If no data is present
417+
the method returns false and the function returns an empty image.
418+
*/
419+
CV_WRAP inline bool retrieve(CV_OUT GpuMat& frame) const {
420+
return retrieve(OutputArray(frame));
421+
}
390422

391423
/** @brief Sets a property in the VideoReader.
392424
@@ -395,7 +427,10 @@ class CV_EXPORTS_W VideoReader
395427
@param propertyVal Value of the property.
396428
@return `true` if the property has been set.
397429
*/
398-
CV_WRAP virtual bool set(const VideoReaderProps propertyId, const double propertyVal) = 0;
430+
virtual bool set(const VideoReaderProps propertyId, const double propertyVal) = 0;
431+
CV_WRAP inline bool setVideoReaderProps(const VideoReaderProps propertyId, double propertyVal) {
432+
return set(propertyId, propertyVal);
433+
}
399434

400435
/** @brief Set the desired ColorFormat for the frame returned by nextFrame()/retrieve().
401436
@@ -408,11 +443,12 @@ class CV_EXPORTS_W VideoReader
408443
@param propertyId Property identifier from cv::cudacodec::VideoReaderProps (eg. cv::cudacodec::VideoReaderProps::PROP_DECODED_FRAME_IDX,
409444
cv::cudacodec::VideoReaderProps::PROP_EXTRA_DATA_INDEX, ...).
410445
@param propertyVal
411-
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).
412-
Out - Value of the property.
446+
- 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).
447+
- Out: Value of the property.
413448
@return `true` unless the property is not supported.
414449
*/
415-
CV_WRAP virtual bool get(const VideoReaderProps propertyId, CV_IN_OUT double& propertyVal) const = 0;
450+
virtual bool get(const VideoReaderProps propertyId, double& propertyVal) const = 0;
451+
CV_WRAP virtual bool getVideoReaderProps(const VideoReaderProps propertyId, CV_OUT double& propertyValOut, double propertyValIn = 0) const = 0;
416452

417453
/** @brief Retrieves the specified property used by the VideoSource.
418454

modules/cudacodec/misc/python/test/test_cudacodec.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,35 @@ def test_reader(self):
3434
ret, _gpu_mat2 = reader.nextFrame(gpu_mat)
3535
#TODO: self.assertTrue(gpu_mat == gpu_mat2)
3636
self.assertTrue(ret)
37+
38+
params = cv.cudacodec.VideoReaderInitParams()
39+
params.rawMode = True
40+
ms_gs = 1234
41+
reader = cv.cudacodec.createVideoReader(vid_path,[cv.CAP_PROP_OPEN_TIMEOUT_MSEC, ms_gs], params)
42+
ret, ms = reader.get(cv.CAP_PROP_OPEN_TIMEOUT_MSEC)
43+
self.assertTrue(ret and ms == ms_gs)
44+
ret, raw_mode = reader.getVideoReaderProps(cv.cudacodec.VideoReaderProps_PROP_RAW_MODE)
45+
self.assertTrue(ret and raw_mode)
46+
47+
ret, colour_code = reader.getVideoReaderProps(cv.cudacodec.VideoReaderProps_PROP_COLOR_FORMAT)
48+
self.assertTrue(ret and colour_code == cv.cudacodec.ColorFormat_BGRA)
49+
colour_code_gs = cv.cudacodec.ColorFormat_GRAY
50+
reader.set(colour_code_gs)
51+
ret, colour_code = reader.getVideoReaderProps(cv.cudacodec.VideoReaderProps_PROP_COLOR_FORMAT)
52+
self.assertTrue(ret and colour_code == colour_code_gs)
53+
54+
ret, i_base = reader.getVideoReaderProps(cv.cudacodec.VideoReaderProps_PROP_RAW_PACKAGES_BASE_INDEX)
55+
self.assertTrue(ret and i_base == 2.0)
56+
self.assertTrue(reader.grab())
57+
ret, gpu_mat3 = reader.retrieve()
58+
self.assertTrue(ret and isinstance(gpu_mat3,cv.cuda.GpuMat) and not gpu_mat3.empty())
59+
ret = reader.retrieve(gpu_mat3)
60+
self.assertTrue(ret and isinstance(gpu_mat3,cv.cuda.GpuMat) and not gpu_mat3.empty())
61+
ret, n_raw_packages_since_last_grab = reader.getVideoReaderProps(cv.cudacodec.VideoReaderProps_PROP_NUMBER_OF_RAW_PACKAGES_SINCE_LAST_GRAB)
62+
self.assertTrue(ret and n_raw_packages_since_last_grab > 0)
63+
ret, raw_data = reader.retrieve(int(i_base))
64+
self.assertTrue(ret and isinstance(raw_data,np.ndarray) and np.any(raw_data))
65+
3766
except cv.error as e:
3867
notSupported = (e.code == cv.Error.StsNotImplemented or e.code == cv.Error.StsUnsupportedFormat or e.code == cv.Error.GPU_API_CALL_ERROR)
3968
self.assertTrue(notSupported)

modules/cudacodec/src/video_reader.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ namespace
102102
void set(const ColorFormat _colorFormat) CV_OVERRIDE;
103103

104104
bool get(const VideoReaderProps propertyId, double& propertyVal) const CV_OVERRIDE;
105+
bool getVideoReaderProps(const VideoReaderProps propertyId, double& propertyValOut, double propertyValIn) const CV_OVERRIDE;
105106

106107
bool get(const int propertyId, double& propertyVal) const CV_OVERRIDE;
107108

@@ -246,13 +247,13 @@ namespace
246247
}
247248
else if (idx == extraDataIdx) {
248249
if (!frame.isMat())
249-
CV_Error(Error::StsUnsupportedFormat, "Extra data is stored on the host and must be retrueved using a cv::Mat");
250+
CV_Error(Error::StsUnsupportedFormat, "Extra data is stored on the host and must be retrieved using a cv::Mat");
250251
videoSource_->getExtraData(frame.getMatRef());
251252
}
252253
else{
253254
if (idx >= rawPacketsBaseIdx && idx < rawPacketsBaseIdx + rawPackets.size()) {
254255
if (!frame.isMat())
255-
CV_Error(Error::StsUnsupportedFormat, "Raw data is stored on the host and must retrievd using a cv::Mat");
256+
CV_Error(Error::StsUnsupportedFormat, "Raw data is stored on the host and must be retrieved using a cv::Mat");
256257
Mat tmp(1, rawPackets.at(idx - rawPacketsBaseIdx).size, CV_8UC1, rawPackets.at(idx - rawPacketsBaseIdx).Data(), rawPackets.at(idx - rawPacketsBaseIdx).size);
257258
frame.getMatRef() = tmp;
258259
}
@@ -264,8 +265,9 @@ namespace
264265
switch (propertyId) {
265266
case VideoReaderProps::PROP_RAW_MODE :
266267
videoSource_->SetRawMode(static_cast<bool>(propertyVal));
268+
return true;
267269
}
268-
return true;
270+
return false;
269271
}
270272

271273
void VideoReaderImpl::set(const ColorFormat _colorFormat) {
@@ -303,20 +305,28 @@ namespace
303305
else
304306
break;
305307
}
306-
case VideoReaderProps::PROP_ALLOW_FRAME_DROP: {
308+
case VideoReaderProps::PROP_ALLOW_FRAME_DROP:
307309
propertyVal = videoParser_->allowFrameDrops();
308310
return true;
309-
}
310-
case VideoReaderProps::PROP_UDP_SOURCE: {
311+
case VideoReaderProps::PROP_UDP_SOURCE:
311312
propertyVal = videoParser_->udpSource();
312313
return true;
313-
}
314+
case VideoReaderProps::PROP_COLOR_FORMAT:
315+
propertyVal = static_cast<double>(colorFormat);
316+
return true;
314317
default:
315318
break;
316319
}
317320
return false;
318321
}
319322

323+
bool VideoReaderImpl::getVideoReaderProps(const VideoReaderProps propertyId, double& propertyValOut, double propertyValIn) const {
324+
double propertyValInOut = propertyValIn;
325+
const bool ret = get(propertyId, propertyValInOut);
326+
propertyValOut = propertyValInOut;
327+
return ret;
328+
}
329+
320330
bool VideoReaderImpl::get(const int propertyId, double& propertyVal) const {
321331
return videoSource_->get(propertyId, propertyVal);
322332
}

modules/cudacodec/test/test_video.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,8 @@ CUDA_TEST_P(Video, Reader)
201201
// request a different colour format for each frame
202202
const std::pair< cudacodec::ColorFormat, int>& formatToChannels = formatsToChannels[i % formatsToChannels.size()];
203203
reader->set(formatToChannels.first);
204+
double colorFormat;
205+
ASSERT_TRUE(reader->get(cudacodec::VideoReaderProps::PROP_COLOR_FORMAT, colorFormat) && static_cast<cudacodec::ColorFormat>(colorFormat) == formatToChannels.first);
204206
ASSERT_TRUE(reader->nextFrame(frame));
205207
if(!fmt.valid)
206208
fmt = reader->format();

modules/cudastereo/include/opencv2/cudastereo.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,10 @@ disparity map.
355355
356356
@sa reprojectImageTo3D
357357
*/
358-
CV_EXPORTS_W void reprojectImageTo3D(InputArray disp, OutputArray xyzw, InputArray Q, int dst_cn = 4, Stream& stream = Stream::Null());
358+
CV_EXPORTS void reprojectImageTo3D(InputArray disp, OutputArray xyzw, InputArray Q, int dst_cn = 4, Stream& stream = Stream::Null());
359+
CV_EXPORTS_W inline void reprojectImageTo3D(GpuMat disp, CV_OUT GpuMat& xyzw, Mat Q, int dst_cn = 4, Stream& stream = Stream::Null()) {
360+
reprojectImageTo3D((InputArray)disp, (OutputArray)xyzw, (InputArray)Q, dst_cn, stream);
361+
}
359362

360363
/** @brief Colors a disparity image.
361364
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/usr/bin/env python
2+
import os
3+
import cv2 as cv
4+
import numpy as np
5+
6+
from tests_common import NewOpenCVTests, unittest
7+
8+
class cudastereo_test(NewOpenCVTests):
9+
def setUp(self):
10+
super(cudastereo_test, self).setUp()
11+
if not cv.cuda.getCudaEnabledDeviceCount():
12+
self.skipTest("No CUDA-capable device is detected")
13+
14+
def test_reprojectImageTo3D(self):
15+
# Test's the functionality but not the results from reprojectImageTo3D
16+
sz = (128,128)
17+
np_disparity = np.random.randint(0, 64, sz, dtype=np.int16)
18+
cu_disparity = cv.cuda_GpuMat(np_disparity)
19+
np_q = np.random.randint(0, 100, (4, 4)).astype(np.float32)
20+
stream = cv.cuda.Stream()
21+
cu_xyz = cv.cuda.reprojectImageTo3D(cu_disparity, np_q, stream = stream)
22+
self.assertTrue(cu_xyz.type() == cv.CV_32FC4 and cu_xyz.size() == sz)
23+
cu_xyz1 = cv.cuda.GpuMat(sz, cv.CV_32FC3)
24+
cv.cuda.reprojectImageTo3D(cu_disparity, np_q, cu_xyz1, 3, stream)
25+
self.assertTrue(cu_xyz1.type() == cv.CV_32FC3 and cu_xyz1.size() == sz)
26+
27+
if __name__ == '__main__':
28+
NewOpenCVTests.bootstrap()

0 commit comments

Comments
 (0)