Skip to content

Commit a9d5b85

Browse files
committed
Merge branch 4.x
2 parents 31a01cf + daaf645 commit a9d5b85

File tree

17 files changed

+477
-215
lines changed

17 files changed

+477
-215
lines changed

modules/bioinspired/src/transientareassegmentationmodule.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ class TransientAreasSegmentationModuleImpl : protected BasicRetinaFilter
136136
/**
137137
* @return the current parameters setup
138138
*/
139-
struct SegmentationParameters getParameters();
139+
SegmentationParameters getParameters();
140140

141141
/**
142142
* parameters setup display method
@@ -202,7 +202,7 @@ class TransientAreasSegmentationModuleImpl : protected BasicRetinaFilter
202202
*/
203203
inline const std::valarray<float> &getMotionContextPicture() const {return _contextMotionEnergy;}
204204

205-
struct cv::bioinspired::SegmentationParameters _segmentationParameters;
205+
cv::bioinspired::SegmentationParameters _segmentationParameters;
206206
// template buffers and related acess pointers
207207
std::valarray<float> _inputToSegment;
208208
std::valarray<float> _contextMotionEnergy;
@@ -233,7 +233,7 @@ class TransientAreasSegmentationModuleImpl_: public TransientAreasSegmentationM
233233
inline virtual void setup(cv::FileStorage &fs, const bool applyDefaultSetupOnFailure) CV_OVERRIDE { _segmTool.setup(fs, applyDefaultSetupOnFailure); }
234234
inline virtual void setup(SegmentationParameters newParameters) CV_OVERRIDE { _segmTool.setup(newParameters); }
235235
inline virtual String printSetup() CV_OVERRIDE { return _segmTool.printSetup(); }
236-
inline virtual struct SegmentationParameters getParameters() CV_OVERRIDE { return _segmTool.getParameters(); }
236+
inline virtual SegmentationParameters getParameters() CV_OVERRIDE { return _segmTool.getParameters(); }
237237
inline virtual void write( String fs ) const CV_OVERRIDE { _segmTool.write(fs); }
238238
inline virtual void run(InputArray inputToSegment, const int channelIndex) CV_OVERRIDE { _segmTool.run(inputToSegment, channelIndex); }
239239
inline virtual void getSegmentationPicture(OutputArray transientAreas) CV_OVERRIDE { return _segmTool.getSegmentationPicture(transientAreas); }
@@ -285,7 +285,7 @@ void TransientAreasSegmentationModuleImpl::clearAllBuffers()
285285
_segmentedAreas=0;
286286
}
287287

288-
struct SegmentationParameters TransientAreasSegmentationModuleImpl::getParameters()
288+
SegmentationParameters TransientAreasSegmentationModuleImpl::getParameters()
289289
{
290290
return _segmentationParameters;
291291
}
@@ -343,7 +343,7 @@ void TransientAreasSegmentationModuleImpl::setup(cv::FileStorage &fs, const bool
343343
std::cout<<"Retina::setup: resetting retina with default parameters"<<std::endl;
344344
if (applyDefaultSetupOnFailure)
345345
{
346-
struct cv::bioinspired::SegmentationParameters defaults;
346+
cv::bioinspired::SegmentationParameters defaults;
347347
setup(defaults);
348348
}
349349
std::cout<<"SegmentationModule::setup: wrong/unappropriate xml parameter file : error report :`n=>"<<e.what()<<std::endl;
@@ -356,7 +356,7 @@ void TransientAreasSegmentationModuleImpl::setup(cv::bioinspired::SegmentationPa
356356
{
357357

358358
// copy structure contents
359-
memcpy(&_segmentationParameters, &newParameters, sizeof(cv::bioinspired::SegmentationParameters));
359+
_segmentationParameters = newParameters;
360360
// apply setup
361361
// init local motion energy extraction low pass filter
362362
BasicRetinaFilter::setLPfilterParameters(0, newParameters.localEnergy_temporalConstant, newParameters.localEnergy_spatialConstant);

modules/cudacodec/include/opencv2/cudacodec.hpp

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,6 @@
5959

6060
namespace cv { namespace cudacodec {
6161

62-
using namespace cuda; // Stream
63-
6462
//! @addtogroup cudacodec
6563
//! @{
6664

@@ -264,7 +262,7 @@ class CV_EXPORTS_W VideoWriter
264262
@param stream Stream for frame pre-processing.
265263
*/
266264
CV_EXPORTS_W Ptr<cudacodec::VideoWriter> createVideoWriter(const String& fileName, const Size frameSize, const Codec codec = Codec::H264, const double fps = 25.0,
267-
const ColorFormat colorFormat = ColorFormat::BGR, Ptr<EncoderCallback> encoderCallback = 0, const Stream& stream = Stream::Null());
265+
const ColorFormat colorFormat = ColorFormat::BGR, Ptr<EncoderCallback> encoderCallback = 0, const cuda::Stream& stream = cuda::Stream::Null());
268266

269267
/** @brief Creates video writer.
270268
@@ -278,7 +276,7 @@ CV_EXPORTS_W Ptr<cudacodec::VideoWriter> createVideoWriter(const String& fileNam
278276
@param stream Stream for frame pre-processing.
279277
*/
280278
CV_EXPORTS_W Ptr<cudacodec::VideoWriter> createVideoWriter(const String& fileName, const Size frameSize, const Codec codec, const double fps, const ColorFormat colorFormat,
281-
const EncoderParams& params, Ptr<EncoderCallback> encoderCallback = 0, const Stream& stream = Stream::Null());
279+
const EncoderParams& params, Ptr<EncoderCallback> encoderCallback = 0, const cuda::Stream& stream = cuda::Stream::Null());
282280

283281
////////////////////////////////// Video Decoding //////////////////////////////////////////
284282

@@ -295,7 +293,7 @@ enum ChromaFormat
295293

296294
/** @brief Deinterlacing mode used by decoder.
297295
* @param Weave Weave both fields (no deinterlacing). For progressive content and for content that doesn't need deinterlacing.
298-
* Bob Drop one field.
296+
* @param Bob Drop one field.
299297
* @param Adaptive Adaptive deinterlacing needs more video memory than other deinterlacing modes.
300298
* */
301299
enum DeinterlaceMode
@@ -305,12 +303,22 @@ enum DeinterlaceMode
305303
Adaptive = 2
306304
};
307305

306+
/** @brief Utility function demonstrating how to map the luma histogram when FormatInfo::videoFullRangeFlag == false
307+
@param hist Luma histogram \a hist returned from VideoReader::nextFrame(GpuMat& frame, GpuMat& hist, Stream& stream).
308+
@param histFull Host histogram equivelent to downloading \a hist after calling cuda::calcHist(InputArray frame, OutputArray hist, Stream& stream).
309+
310+
@note
311+
- This function demonstrates how to map the luma histogram back so that it is equivalent to the result obtained from cuda::calcHist()
312+
if the returned frame was colorFormat::GRAY.
313+
*/
314+
CV_EXPORTS_W void MapHist(const cuda::GpuMat& hist, CV_OUT Mat& histFull);
315+
308316
/** @brief Struct providing information about video file format. :
309317
*/
310318
struct CV_EXPORTS_W_SIMPLE FormatInfo
311319
{
312-
CV_WRAP FormatInfo() : nBitDepthMinus8(-1), nBitDepthChromaMinus8(-1), ulWidth(0), ulHeight(0), width(0), height(0), ulMaxWidth(0), ulMaxHeight(0), valid(false),
313-
fps(0), ulNumDecodeSurfaces(0), videoFullRangeFlag(false) {};
320+
CV_WRAP FormatInfo() : nBitDepthMinus8(-1), ulWidth(0), ulHeight(0), width(0), height(0), ulMaxWidth(0), ulMaxHeight(0), valid(false),
321+
fps(0), ulNumDecodeSurfaces(0), videoFullRangeFlag(false), enableHistogram(false), nCounterBitDepth(0), nMaxHistogramBins(0){};
314322

315323
CV_PROP_RW Codec codec;
316324
CV_PROP_RW ChromaFormat chromaFormat;
@@ -331,6 +339,9 @@ struct CV_EXPORTS_W_SIMPLE FormatInfo
331339
CV_PROP_RW cv::Rect srcRoi;//!< Region of interest decoded from video source.
332340
CV_PROP_RW cv::Rect targetRoi;//!< Region of interest in the output frame containing the decoded frame.
333341
CV_PROP_RW bool videoFullRangeFlag;//!< Output value indicating if the black level, luma and chroma of the source are represented using the full or limited range (AKA TV or "analogue" range) of values as defined in Annex E of the ITU-T Specification. Internally the conversion from NV12 to BGR obeys ITU 709.
342+
CV_PROP_RW bool enableHistogram;//!< Flag requesting histogram output if supported. Exception will be thrown when requested but not supported.
343+
CV_PROP_RW int nCounterBitDepth;//!< Bit depth of histogram bins if histogram output is requested and supported.
344+
CV_PROP_RW int nMaxHistogramBins;//!< Max number of histogram bins if histogram output is requested and supported.
334345
};
335346

336347
/** @brief cv::cudacodec::VideoReader generic properties identifier.
@@ -374,7 +385,21 @@ class CV_EXPORTS_W VideoReader
374385
If no frames have been grabbed (there are no more frames in video file), the methods return false.
375386
The method throws an Exception if error occurs.
376387
*/
377-
CV_WRAP virtual bool nextFrame(CV_OUT GpuMat& frame, Stream &stream = Stream::Null()) = 0;
388+
CV_WRAP virtual bool nextFrame(CV_OUT cuda::GpuMat& frame, cuda::Stream &stream = cuda::Stream::Null()) = 0;
389+
390+
/** @brief Grabs, decodes and returns the next video frame and frame luma histogram.
391+
392+
@param [out] frame The video frame.
393+
@param [out] histogram Histogram of the luma component of the encoded frame, see note.
394+
@param stream Stream for the asynchronous version.
395+
@return `false` if no frames have been grabbed.
396+
397+
If no frames have been grabbed (there are no more frames in video file), the methods return false.
398+
The method throws an Exception if error occurs.
399+
400+
@note Histogram data is collected by NVDEC during the decoding process resulting in zero performance penalty. NVDEC computes the histogram data for only the luma component of decoded output, not on post-processed frame(i.e. when scaling, cropping, etc. applied). If the source is encoded using a limited range of luma values (FormatInfo::videoFullRangeFlag == false) then the histogram bin values will correspond to to this limited range of values and will need to be mapped to contain the same output as cuda::calcHist(). The MapHist() utility function can be used to perform this mapping on the host if required.
401+
*/
402+
CV_WRAP_AS(nextFrameWithHist) virtual bool nextFrame(CV_OUT cuda::GpuMat& frame, CV_OUT cuda::GpuMat& histogram, cuda::Stream& stream = cuda::Stream::Null()) = 0;
378403

379404
/** @brief Returns information about video file format.
380405
*/
@@ -391,7 +416,7 @@ class CV_EXPORTS_W VideoReader
391416
The primary use of the function is for reading both the encoded and decoded video data when rawMode is enabled. With rawMode enabled
392417
retrieve() can be called following grab() to retrieve all the data associated with the current video source since the last call to grab() or the creation of the VideoReader.
393418
*/
394-
CV_WRAP virtual bool grab(Stream& stream = Stream::Null()) = 0;
419+
CV_WRAP virtual bool grab(cuda::Stream& stream = cuda::Stream::Null()) = 0;
395420

396421
/** @brief Returns previously grabbed video data.
397422
@@ -430,7 +455,7 @@ class CV_EXPORTS_W VideoReader
430455
The method returns data associated with the current video source since the last call to grab(). If no data is present
431456
the method returns false and the function returns an empty image.
432457
*/
433-
CV_WRAP inline bool retrieve(CV_OUT GpuMat& frame) const {
458+
CV_WRAP inline bool retrieve(CV_OUT cuda::GpuMat& frame) const {
434459
return retrieve(OutputArray(frame));
435460
}
436461

@@ -535,16 +560,18 @@ but it cannot go below the number determined by NVDEC.
535560
@param srcRoi Region of interest (x/width should be multiples of 4 and y/height multiples of 2) decoded from video source, defaults to the full frame.
536561
@param targetRoi Region of interest (x/width should be multiples of 4 and y/height multiples of 2) within the output frame to copy and resize the decoded frame to,
537562
defaults to the full frame.
563+
@param enableHistogram Request output of decoded luma histogram \a hist from VideoReader::nextFrame(GpuMat& frame, GpuMat& hist, Stream& stream), if hardware supported.
538564
*/
539565
struct CV_EXPORTS_W_SIMPLE VideoReaderInitParams {
540-
CV_WRAP VideoReaderInitParams() : udpSource(false), allowFrameDrop(false), minNumDecodeSurfaces(0), rawMode(0) {};
566+
CV_WRAP VideoReaderInitParams() : udpSource(false), allowFrameDrop(false), minNumDecodeSurfaces(0), rawMode(0), enableHistogram(false){};
541567
CV_PROP_RW bool udpSource;
542568
CV_PROP_RW bool allowFrameDrop;
543569
CV_PROP_RW int minNumDecodeSurfaces;
544570
CV_PROP_RW bool rawMode;
545571
CV_PROP_RW cv::Size targetSz;
546572
CV_PROP_RW cv::Rect srcRoi;
547573
CV_PROP_RW cv::Rect targetRoi;
574+
CV_PROP_RW bool enableHistogram;
548575
};
549576

550577
/** @brief Creates video reader.

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

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,43 +14,59 @@ def setUp(self):
1414
@unittest.skipIf('OPENCV_TEST_DATA_PATH' not in os.environ,
1515
"OPENCV_TEST_DATA_PATH is not defined")
1616
def test_reader(self):
17-
#Test the functionality but not the results of the video reader
17+
# Test the functionality but not the results of the VideoReader
1818

19-
vid_path = os.environ['OPENCV_TEST_DATA_PATH'] + '/cv/video/1920x1080.avi'
19+
vid_path = os.environ['OPENCV_TEST_DATA_PATH'] + '/highgui/video/big_buck_bunny.h264'
2020
try:
2121
reader = cv.cudacodec.createVideoReader(vid_path)
2222
format_info = reader.format()
2323
ret, gpu_mat = reader.nextFrame()
2424
self.assertTrue(ret)
25-
self.assertTrue('GpuMat' in str(type(gpu_mat)), msg=type(gpu_mat))
25+
self.assertTrue(isinstance(gpu_mat, cv.cuda.GpuMat), msg=type(gpu_mat))
2626
#TODO: print(cv.utils.dumpInputArray(gpu_mat)) # - no support for GpuMat
2727

28+
# Retrieve format info
2829
if(not format_info.valid):
2930
format_info = reader.format()
3031
sz = gpu_mat.size()
3132
self.assertTrue(sz[0] == format_info.width and sz[1] == format_info.height)
3233

3334
# not checking output, therefore sepearate tests for different signatures is unecessary
34-
ret, _gpu_mat2 = reader.nextFrame(gpu_mat)
35-
#TODO: self.assertTrue(gpu_mat == gpu_mat2)
36-
self.assertTrue(ret)
35+
ret, gpu_mat_ = reader.nextFrame(gpu_mat)
36+
self.assertTrue(ret and gpu_mat_.cudaPtr() == gpu_mat.cudaPtr())
3737

38+
# Pass VideoReaderInitParams to the decoder and initialization params to the source (cv::VideoCapture)
3839
params = cv.cudacodec.VideoReaderInitParams()
3940
params.rawMode = True
41+
params.enableHistogram = False
4042
ms_gs = 1234
43+
post_processed_sz = (gpu_mat.size()[0]*2, gpu_mat.size()[1]*2)
44+
params.targetSz = post_processed_sz
4145
reader = cv.cudacodec.createVideoReader(vid_path,[cv.CAP_PROP_OPEN_TIMEOUT_MSEC, ms_gs], params)
4246
ret, ms = reader.get(cv.CAP_PROP_OPEN_TIMEOUT_MSEC)
4347
self.assertTrue(ret and ms == ms_gs)
4448
ret, raw_mode = reader.getVideoReaderProps(cv.cudacodec.VideoReaderProps_PROP_RAW_MODE)
4549
self.assertTrue(ret and raw_mode)
4650

51+
# Retrieve image histogram. Not all GPUs support histogram. Just check the method is called correctly
52+
ret, gpu_mat, hist = reader.nextFrameWithHist()
53+
self.assertTrue(ret and not gpu_mat.empty())
54+
ret, gpu_mat_, hist_ = reader.nextFrameWithHist(gpu_mat, hist)
55+
self.assertTrue(ret and not gpu_mat.empty())
56+
self.assertTrue(gpu_mat_.cudaPtr() == gpu_mat.cudaPtr())
57+
58+
# Check post processing applied
59+
self.assertTrue(gpu_mat.size() == post_processed_sz)
60+
61+
# Change color format
4762
ret, colour_code = reader.getVideoReaderProps(cv.cudacodec.VideoReaderProps_PROP_COLOR_FORMAT)
4863
self.assertTrue(ret and colour_code == cv.cudacodec.ColorFormat_BGRA)
4964
colour_code_gs = cv.cudacodec.ColorFormat_GRAY
5065
reader.set(colour_code_gs)
5166
ret, colour_code = reader.getVideoReaderProps(cv.cudacodec.VideoReaderProps_PROP_COLOR_FORMAT)
5267
self.assertTrue(ret and colour_code == colour_code_gs)
5368

69+
# Read raw encoded bitstream
5470
ret, i_base = reader.getVideoReaderProps(cv.cudacodec.VideoReaderProps_PROP_RAW_PACKAGES_BASE_INDEX)
5571
self.assertTrue(ret and i_base == 2.0)
5672
self.assertTrue(reader.grab())
@@ -75,8 +91,14 @@ def test_reader(self):
7591
else:
7692
self.skipTest(e.err)
7793

78-
def test_writer_existence(self):
79-
#Test at least the existence of wrapped functions for now
94+
def test_map_histogram(self):
95+
hist = cv.cuda_GpuMat((1,256), cv.CV_8UC1)
96+
hist.setTo(1)
97+
hist_host = cv.cudacodec.MapHist(hist)
98+
self.assertTrue(hist_host.shape == (256, 1) and isinstance(hist_host, np.ndarray))
99+
100+
def test_writer(self):
101+
# Test the functionality but not the results of the VideoWriter
80102

81103
try:
82104
fd, fname = tempfile.mkstemp(suffix=".h264")
@@ -91,16 +113,17 @@ def test_writer_existence(self):
91113
writer.write(blankFrameIn)
92114
writer.release()
93115
encoder_params_out = writer.getEncoderParams()
94-
self.assert_true(encoder_params_in.gopLength == encoder_params_out.gopLength)
116+
self.assertTrue(encoder_params_in.gopLength == encoder_params_out.gopLength)
95117
cap = cv.VideoCapture(fname,cv.CAP_FFMPEG)
96-
self.assert_true(cap.isOpened())
118+
self.assertTrue(cap.isOpened())
97119
ret, blankFrameOut = cap.read()
98-
self.assert_true(ret and blankFrameOut.shape == blankFrameIn.download().shape)
120+
self.assertTrue(ret and blankFrameOut.shape == blankFrameIn.download().shape)
121+
cap.release()
99122
except cv.error as e:
100123
self.assertEqual(e.code, cv.Error.StsNotImplemented)
101124
self.skipTest("Either NVCUVENC or a GPU hardware encoder is missing or the encoding profile is not supported.")
102125

103126
os.remove(fname)
104127

105128
if __name__ == '__main__':
106-
NewOpenCVTests.bootstrap()
129+
NewOpenCVTests.bootstrap()

modules/cudacodec/src/ffmpeg_video_source.cpp

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,10 @@ static std::string fourccToString(int fourcc)
6666
(i32_c.c[3] >= ' ' && i32_c.c[3] < 128) ? i32_c.c[3] : '?');
6767
}
6868

69+
// handle old FFmpeg backend - remove when windows shared library is updated
70+
#ifdef _WIN32
6971
static
70-
Codec FourccToCodec(int codec)
72+
Codec FourccToCodecWin32Old(int codec)
7173
{
7274
switch (codec)
7375
{
@@ -100,9 +102,34 @@ Codec FourccToCodec(int codec)
100102
case CV_FOURCC_MACRO('a', 'v', '0', '1'): // fallthru
101103
case CV_FOURCC_MACRO('A', 'V', '0', '1'): return AV1;
102104
default:
103-
break;
105+
return NumCodecs;
104106
}
107+
}
108+
#endif
105109

110+
static
111+
Codec FourccToCodec(int codec)
112+
{
113+
#ifdef _WIN32 // handle old FFmpeg backend - remove when windows shared library is updated
114+
Codec win32OldCodec = FourccToCodecWin32Old(codec);
115+
if(win32OldCodec != NumCodecs)
116+
return win32OldCodec;
117+
#endif
118+
switch (codec)
119+
{
120+
case CV_FOURCC_MACRO('m', 'p', 'g', '1'): return MPEG1;
121+
case CV_FOURCC_MACRO('m', 'p', 'g', '2'): return MPEG2;
122+
case CV_FOURCC_MACRO('F', 'M', 'P', '4'): return MPEG4;
123+
case CV_FOURCC_MACRO('W', 'V', 'C', '1'): return VC1;
124+
case CV_FOURCC_MACRO('h', '2', '6', '4'): return H264;
125+
case CV_FOURCC_MACRO('h', 'e', 'v', 'c'): return HEVC;
126+
case CV_FOURCC_MACRO('M', 'J', 'P', 'G'): return JPEG;
127+
case CV_FOURCC_MACRO('V', 'P', '8', '0'): return VP8;
128+
case CV_FOURCC_MACRO('V', 'P', '9', '0'): return VP9;
129+
case CV_FOURCC_MACRO('A', 'V', '0', '1'): return AV1;
130+
default:
131+
break;
132+
}
106133
std::string msg = cv::format("Unknown codec FOURCC: 0x%08X (%s)", codec, fourccToString(codec).c_str());
107134
CV_LOG_WARNING(NULL, msg);
108135
CV_Error(Error::StsUnsupportedFormat, msg);
@@ -163,7 +190,6 @@ cv::cudacodec::detail::FFmpegVideoSource::FFmpegVideoSource(const String& fname,
163190

164191
int codec = (int)cap.get(CAP_PROP_FOURCC);
165192
int pixelFormat = (int)cap.get(CAP_PROP_CODEC_PIXEL_FORMAT);
166-
167193
format_.codec = FourccToCodec(codec);
168194
format_.height = cap.get(CAP_PROP_FRAME_HEIGHT);
169195
format_.width = cap.get(CAP_PROP_FRAME_WIDTH);

0 commit comments

Comments
 (0)