diff --git a/Modules/Video/BridgeOpenCV/include/itkOpenCVBasicTypeBridge.h b/Modules/Video/BridgeOpenCV/include/itkOpenCVBasicTypeBridge.h index 54f38c8d402..6e49eb5172d 100644 --- a/Modules/Video/BridgeOpenCV/include/itkOpenCVBasicTypeBridge.h +++ b/Modules/Video/BridgeOpenCV/include/itkOpenCVBasicTypeBridge.h @@ -161,10 +161,14 @@ struct OpenCVBasicTypeBridge, cv::Size> } }; -template -struct OpenCVBasicTypeBridge, cv::Matx> +// cv::Matx uses int template params; itk::Matrix uses unsigned int. +// Using int for VRows/VColumns (matching OpenCV) with a cast in the ITK +// pattern allows the compiler to deduce both sides correctly. +template +struct OpenCVBasicTypeBridge(VRows), static_cast(VColumns)>, + cv::Matx> { - using ITKDataType = itk::Matrix; + using ITKDataType = itk::Matrix(VRows), static_cast(VColumns)>; using OpenCVDataType = cv::Matx; static ITKDataType diff --git a/Modules/Video/BridgeOpenCV/include/itkOpenCVVideoCapture.hxx b/Modules/Video/BridgeOpenCV/include/itkOpenCVVideoCapture.hxx index cba85219993..ef38f12e33c 100644 --- a/Modules/Video/BridgeOpenCV/include/itkOpenCVVideoCapture.hxx +++ b/Modules/Video/BridgeOpenCV/include/itkOpenCVVideoCapture.hxx @@ -20,18 +20,8 @@ #include "itkNumericTraits.h" -#include "opencv2/core/version.hpp" -#if !defined(CV_VERSION_EPOCH) // OpenCV >= 3.0 -# include "opencv2/videoio.hpp" -# include "opencv2/imgproc/types_c.h" // CV_RGB2BGR, CV_BGR2GRAY, ... -# include "opencv2/imgproc/imgproc_c.h" -# if CV_VERSION_MAJOR > 3 // OpenCV 4.x -# include "opencv2/videoio/legacy/constants_c.h" -# endif -#else -// OpenCV 2.4.x -# include "cv.h" -#endif +#include "opencv2/videoio.hpp" +#include "opencv2/imgproc.hpp" namespace itk { @@ -50,7 +40,7 @@ OpenCVVideoCapture::OpenCVVideoCapture() m_FpS = 24; // Default to mp4.2 - m_FourCC = CV_FOURCC('M', 'P', '4', '2'); + m_FourCC = cv::VideoWriter::fourcc('M', 'P', '4', '2'); } // @@ -65,7 +55,7 @@ OpenCVVideoCapture::OpenCVVideoCapture(TVideoStream * videoStream) m_FpS = 24; // Default to mp4.2 - m_FourCC = CV_FOURCC('M', 'P', '4', '2'); + m_FourCC = cv::VideoWriter::fourcc('M', 'P', '4', '2'); } @@ -121,7 +111,7 @@ OpenCVVideoCapture::grab() // Move the current frame forward by 1 SizeValueType currentFrame = m_VideoStream->GetRequestedTemporalRegion().GetFrameStart(); - return set(CV_CAP_PROP_POS_FRAMES, currentFrame + 1); + return set(cv::CAP_PROP_POS_FRAMES, currentFrame + 1); } // @@ -162,35 +152,28 @@ OpenCVVideoCapture::retrieve(cv::Mat & image, int itkNotUsed(chann unsigned int channels = itk::NumericTraits::MeasurementVectorType::Dimension; int matrixType = CV_MAKETYPE(depth, channels); - // Copy the pixels -- There is probably a faster way to do this + // Copy the pixels using cv::Mat (no IplImage needed) // Currently only support mono and RGB (unsigned) char pixels - IplImage * iplImg = cvCreateImage(cvSize(size[0], size[1]), IPL_DEPTH_8U, channels); + // cv::Mat(rows, cols, type, data): rows=height=size[1], cols=width=size[0] + cv::Mat srcMat(static_cast(size[1]), + static_cast(size[0]), + matrixType, + reinterpret_cast(frame->GetBufferPointer())); if (matrixType == CV_8UC1 || matrixType == CV_8SC1) { - // Insert the buffer into iplImg - cvSetData(iplImg, reinterpret_cast(frame->GetBufferPointer()), iplImg->widthStep); + srcMat.copyTo(image); } else if (matrixType == CV_8UC3 || matrixType == CV_8SC3) { - // Place the contents of the buffer into an OpenCV image - IplImage * tempImg = cvCreateImage(cvSize(size[0], size[1]), IPL_DEPTH_8U, channels); - - // Insert the buffer into tempImg - cvSetData(tempImg, reinterpret_cast(frame->GetBufferPointer()), tempImg->widthStep); - - // Convert to BGR - cvCvtColor(tempImg, iplImg, CV_RGB2BGR); + // Convert ITK RGB to OpenCV BGR + cv::cvtColor(srcMat, image, cv::COLOR_RGB2BGR); } else { itkExceptionStringMacro("itk::OpenCVVideoCaptures -> Pixel type not supported"); } - // Pass off to the Mat - image.create(size[0], size[1], matrixType); - image = cv::cvarrToMat(iplImg, true); - // Return success return true; } @@ -255,12 +238,12 @@ OpenCVVideoCapture::set(int propId, double value) switch (propId) { // Figure out the frame numbers from the value -- This is not currently supported - case CV_CAP_PROP_POS_MSEC: + case cv::CAP_PROP_POS_MSEC: itkExceptionStringMacro("OpenCVVideoCapture: Video Pipeline does not currently support RealTime"); break; // Set the frame start of the requested region and update the pipeline - case CV_CAP_PROP_POS_FRAMES: + case cv::CAP_PROP_POS_FRAMES: // Get the largest temporal region and make sure it has some duration m_VideoStream->UpdateOutputInformation(); @@ -293,7 +276,7 @@ OpenCVVideoCapture::set(int propId, double value) break; // Figure out the frame number from the AVI ratio and set accordingly - case CV_CAP_PROP_POS_AVI_RATIO: + case cv::CAP_PROP_POS_AVI_RATIO: // Compute the new frame m_VideoStream->UpdateOutputInformation(); @@ -301,17 +284,17 @@ OpenCVVideoCapture::set(int propId, double value) ratioFrameOffset = (SizeValueType)(static_cast(largestPossible.GetFrameDuration()) * value); newFrame = largestPossible.GetFrameStart() + ratioFrameOffset; - // Use the CV_CAP_PROP_POS_FRAMES property to update - set(CV_CAP_PROP_POS_FRAMES, newFrame); + // Use the cv::CAP_PROP_POS_FRAMES property to update + set(cv::CAP_PROP_POS_FRAMES, newFrame); break; // Set FourCC - case CV_CAP_PROP_FOURCC: + case cv::CAP_PROP_FOURCC: m_FourCC = static_cast(value); break; // Set FpS - case CV_CAP_PROP_FPS: + case cv::CAP_PROP_FPS: m_FpS = value; break; @@ -347,16 +330,16 @@ OpenCVVideoCapture::get(int propId) switch (propId) { // Figure out the frame numbers from the value -- This is not currently supported - case CV_CAP_PROP_POS_MSEC: + case cv::CAP_PROP_POS_MSEC: itkExceptionStringMacro("OpenCVVideoCapture: Video Pipeline does not currently support RealTime"); break; // Get the frame start of the requested region and update the pipeline - case CV_CAP_PROP_POS_FRAMES: + case cv::CAP_PROP_POS_FRAMES: return frameNum; // Figure out the frame number from the AVI ratio and set accordingly - case CV_CAP_PROP_POS_AVI_RATIO: + case cv::CAP_PROP_POS_AVI_RATIO: // Compute the frame number from the ratio m_VideoStream->UpdateOutputInformation(); @@ -366,20 +349,20 @@ OpenCVVideoCapture::get(int propId) return static_cast(currentOffset) / static_cast(largest.GetFrameDuration()); // Get FourCC - case CV_CAP_PROP_FOURCC: + case cv::CAP_PROP_FOURCC: return m_FourCC; // Set FpS - case CV_CAP_PROP_FPS: + case cv::CAP_PROP_FPS: return m_FpS; // Get Frame Width - case CV_CAP_PROP_FRAME_WIDTH: + case cv::CAP_PROP_FRAME_WIDTH: m_VideoStream->UpdateOutputInformation(); return m_VideoStream->GetFrameLargestPossibleSpatialRegion(frameNum).GetSize()[0]; // Get Frame Height - case CV_CAP_PROP_FRAME_HEIGHT: + case cv::CAP_PROP_FRAME_HEIGHT: m_VideoStream->UpdateOutputInformation(); return m_VideoStream->GetFrameLargestPossibleSpatialRegion(frameNum).GetSize()[1]; diff --git a/Modules/Video/BridgeOpenCV/include/itkOpenCVVideoIO.h b/Modules/Video/BridgeOpenCV/include/itkOpenCVVideoIO.h index f2bea3588c9..d396a30ec9a 100644 --- a/Modules/Video/BridgeOpenCV/include/itkOpenCVVideoIO.h +++ b/Modules/Video/BridgeOpenCV/include/itkOpenCVVideoIO.h @@ -20,17 +20,7 @@ #include "itkVideoIOBase.h" -#include "opencv2/core/version.hpp" -#if !defined(CV_VERSION_EPOCH) -// OpenCV 3.x -# include "opencv2/videoio/videoio.hpp" -# include "opencv2/videoio/videoio_c.h" -# include "opencv2/imgproc/imgproc_c.h" -#else -// OpenCV 2.4.x -# include "cv.h" -# include "highgui.h" -#endif +#include "opencv2/videoio.hpp" #include "ITKVideoBridgeOpenCVExport.h" @@ -194,12 +184,10 @@ class ITKVideoBridgeOpenCV_EXPORT OpenCVVideoIO : public VideoIOBase OpenWriter(); private: -private: - IplImage * m_CVImage{}; - IplImage * m_TempImage{}; - CvCapture * m_Capture{}; - CvVideoWriter * m_Writer{}; - int m_FourCC{}; + cv::Mat m_CVImage{}; + cv::VideoCapture m_Capture{}; + cv::VideoWriter m_Writer{}; + int m_FourCC{}; int m_CameraIndex{}; }; diff --git a/Modules/Video/BridgeOpenCV/src/itkOpenCVVideoIO.cxx b/Modules/Video/BridgeOpenCV/src/itkOpenCVVideoIO.cxx index 2135257c747..ecbe78217a3 100644 --- a/Modules/Video/BridgeOpenCV/src/itkOpenCVVideoIO.cxx +++ b/Modules/Video/BridgeOpenCV/src/itkOpenCVVideoIO.cxx @@ -17,6 +17,10 @@ *=========================================================================*/ #include "itkOpenCVVideoIO.h" +#include + +#include "opencv2/imgproc.hpp" + namespace itk { @@ -28,19 +32,6 @@ OpenCVVideoIO::~OpenCVVideoIO() { this->FinishReadingOrWriting(); } void OpenCVVideoIO::FinishReadingOrWriting() { - if (this->m_Writer != nullptr) - { - cvReleaseVideoWriter(&(this->m_Writer)); - } - if (this->m_Capture != nullptr) - { - cvReleaseCapture(&(this->m_Capture)); - } - if (this->m_CVImage != nullptr) - { - cvReleaseImage(&(this->m_CVImage)); - } - this->ResetMembers(); } @@ -158,39 +149,24 @@ OpenCVVideoIO::CanReadFile(const char * filename) } // Try opening to read - CvCapture * localCapture = cvCaptureFromFile(filename); - if (!localCapture) - { - return false; - } - - // Close the file and return true if successful - cvReleaseCapture(&localCapture); - return true; + cv::VideoCapture localCapture(filename); + return localCapture.isOpened(); } bool OpenCVVideoIO::CanReadCamera(CameraIDType cameraID) const { // Try capture from current camera index - CvCapture * localCapture = cvCaptureFromCAM(cameraID); - if (!localCapture) - { - return false; - } - - // Close the file and return true if successful - cvReleaseCapture(&localCapture); - return true; + cv::VideoCapture localCapture(static_cast(cameraID)); + return localCapture.isOpened(); } void OpenCVVideoIO::ReadImageInformation() { - - // Set up a local capture and image - CvCapture * localCapture; - IplImage * tempImage; + // Set up a local capture and frame + cv::VideoCapture localCapture; + cv::Mat tempFrame; // Open capture from a file if (this->m_ReadFrom == ReadFromEnum::ReadFromFile) @@ -204,22 +180,21 @@ OpenCVVideoIO::ReadImageInformation() } // Open the video file - localCapture = cvCaptureFromFile(filename.c_str()); + localCapture.open(filename.c_str()); // Query the frame and get frame total (since this is only valid for reading from files) - tempImage = cvQueryFrame(localCapture); - this->m_FrameTotal = - static_cast(cvGetCaptureProperty(localCapture, CV_CAP_PROP_FRAME_COUNT)); + localCapture >> tempFrame; + this->m_FrameTotal = static_cast(localCapture.get(cv::CAP_PROP_FRAME_COUNT)); // Try to figure out if there are I-Frame issues we need to worry about // and compensate accordingly if (this->m_FrameTotal > 0) { // Try setting frame to 1 and see what actually gets set - cvSetCaptureProperty(localCapture, CV_CAP_PROP_POS_FRAMES, 1); - tempImage = cvQueryFrame(localCapture); + localCapture.set(cv::CAP_PROP_POS_FRAMES, 1); + localCapture >> tempFrame; - this->m_IFrameInterval = cvGetCaptureProperty(localCapture, CV_CAP_PROP_POS_FRAMES); + this->m_IFrameInterval = static_cast(localCapture.get(cv::CAP_PROP_POS_FRAMES)); if (this->m_IFrameInterval == 0) { @@ -245,21 +220,20 @@ OpenCVVideoIO::ReadImageInformation() { // Open the camera capture - localCapture = cvCaptureFromCAM(this->m_CameraIndex); + localCapture.open(this->m_CameraIndex); // Make sure it opened right - if (!localCapture) + if (!localCapture.isOpened()) { itkExceptionMacro("Cannot read from camera " << this->m_CameraIndex); } // Query the frame - tempImage = cvQueryFrame(localCapture); + localCapture >> tempFrame; // Make sure the image is not empty - if (!tempImage) + if (tempFrame.empty()) { - cvReleaseCapture(&localCapture); itkExceptionMacro("Empty image got from camera " << this->m_CameraIndex); } @@ -274,14 +248,14 @@ OpenCVVideoIO::ReadImageInformation() } // Populate member variables - this->m_FramesPerSecond = static_cast(cvGetCaptureProperty(localCapture, CV_CAP_PROP_FPS)); + this->m_FramesPerSecond = localCapture.get(cv::CAP_PROP_FPS); // Set width, height this->m_Dimensions.clear(); - this->m_Dimensions.push_back(cvGetCaptureProperty(localCapture, CV_CAP_PROP_FRAME_WIDTH)); - this->m_Dimensions.push_back(cvGetCaptureProperty(localCapture, CV_CAP_PROP_FRAME_HEIGHT)); + this->m_Dimensions.push_back(static_cast(localCapture.get(cv::CAP_PROP_FRAME_WIDTH))); + this->m_Dimensions.push_back(static_cast(localCapture.get(cv::CAP_PROP_FRAME_HEIGHT))); - this->m_NumberOfComponents = tempImage->nChannels; + this->m_NumberOfComponents = tempFrame.channels(); // Set the pixel type if (this->m_NumberOfComponents == 1) @@ -300,9 +274,6 @@ OpenCVVideoIO::ReadImageInformation() { itkExceptionStringMacro("OpenCV IO only supports Mono, RGB, and RGBA input"); } - - // Release the local capture and image - cvReleaseCapture(&localCapture); } void @@ -326,27 +297,34 @@ OpenCVVideoIO::Read(void * buffer) // doesn't need to be called before Read is called again unless you want to // skip to a different location. Be warned, though. SetNextFrameToRead can // only skip to I-Frames, so there can be unexpected behavior - IplImage * tempIm = cvQueryFrame(this->m_Capture); - if (tempIm == nullptr) + cv::Mat tempIm; + m_Capture >> tempIm; + if (tempIm.empty()) { itkExceptionMacro("Error reading frame " << this->m_CurrentFrame << ". May be out of bounds"); } - // Convert to RGB rather than BGR - if (this->m_CVImage == nullptr) + // Convert color format from OpenCV's native BGR to ITK's expected channel order + if (this->m_NumberOfComponents == 1) + { + m_CVImage = tempIm; + } + else if (this->m_NumberOfComponents == 3) { - this->m_CVImage = - cvCreateImage(cvSize(this->m_Dimensions[0], this->m_Dimensions[1]), IPL_DEPTH_8U, this->m_NumberOfComponents); + cv::cvtColor(tempIm, m_CVImage, cv::COLOR_BGR2RGB); + } + else + { + cv::cvtColor(tempIm, m_CVImage, cv::COLOR_BGRA2RGBA); } - cvCvtColor(tempIm, this->m_CVImage, CV_BGR2RGB); // Update the frame-dependent properties this->UpdateReaderProperties(); // Put the frame's buffer into the supplied output buffer - auto * tempBuffer = reinterpret_cast(this->m_CVImage->imageData); - size_t bufferSize = this->m_CVImage->imageSize; - memcpy(buffer, tempBuffer, bufferSize); + const auto * tempBuffer = m_CVImage.data; + const size_t bufferSize = m_CVImage.total() * m_CVImage.elemSize(); + std::copy_n(tempBuffer, bufferSize, static_cast(buffer)); } bool @@ -365,9 +343,9 @@ OpenCVVideoIO::SetNextFrameToRead(OpenCVVideoIO::FrameOffsetType frameNumber) return false; } - if (this->m_Capture != nullptr) + if (m_Capture.isOpened()) { - cvSetCaptureProperty(this->m_Capture, CV_CAP_PROP_POS_FRAMES, frameNumber); + m_Capture.set(cv::CAP_PROP_POS_FRAMES, frameNumber); this->UpdateReaderProperties(); this->Modified(); @@ -453,7 +431,7 @@ OpenCVVideoIO::SetWriterParameters(TemporalRatioType fps, this->m_Dimensions.push_back(dim[1]); this->m_FramesPerSecond = fps; - this->m_FourCC = CV_FOURCC(fourCC[0], fourCC[1], fourCC[2], fourCC[3]); + this->m_FourCC = cv::VideoWriter::fourcc(fourCC[0], fourCC[1], fourCC[2], fourCC[3]); this->m_NumberOfComponents = nChannels; if (nChannels == 1) { @@ -495,34 +473,25 @@ OpenCVVideoIO::Write(const void * buffer) this->OpenWriter(); } - // Place the contents of the buffer into an OpenCV image - if (this->m_CVImage == nullptr) - { - // The output image always has to be 3 components for the OpenCV writer - this->m_CVImage = cvCreateImage(cvSize(this->m_Dimensions[0], this->m_Dimensions[1]), IPL_DEPTH_8U, 3); - } - if (this->m_TempImage == nullptr) - { - this->m_TempImage = - cvCreateImage(cvSize(this->m_Dimensions[0], this->m_Dimensions[1]), IPL_DEPTH_8U, this->m_NumberOfComponents); - } + // Wrap the input buffer in a cv::Mat without copying (external ownership) + const int inputType = CV_MAKETYPE(CV_8U, static_cast(this->m_NumberOfComponents)); + cv::Mat tempMat(static_cast(this->m_Dimensions[1]), + static_cast(this->m_Dimensions[0]), + inputType, + const_cast(buffer)); - // Insert the buffer into TempImage - cvSetData(this->m_TempImage, reinterpret_cast(const_cast(buffer)), this->m_TempImage->widthStep); - - // Handle grayscale + // The video writer always needs a 3-channel BGR image; convert accordingly if (this->m_NumberOfComponents == 1) { - cvCvtColor(this->m_TempImage, this->m_CVImage, CV_GRAY2BGR); + cv::cvtColor(tempMat, m_CVImage, cv::COLOR_GRAY2BGR); } - // Guaranteed to be 3 channels else { - cvCvtColor(this->m_TempImage, this->m_CVImage, CV_RGB2BGR); + cv::cvtColor(tempMat, m_CVImage, cv::COLOR_RGB2BGR); } // Write the frame - cvWriteFrame(this->m_Writer, this->m_CVImage); + m_Writer.write(m_CVImage); // Update the current frame this->m_CurrentFrame++; @@ -532,11 +501,11 @@ void OpenCVVideoIO::UpdateReaderProperties() { // 0-based index of the frame to be decoded/captured next - this->m_CurrentFrame = cvGetCaptureProperty(this->m_Capture, CV_CAP_PROP_POS_FRAMES); - this->m_PositionInMSec = cvGetCaptureProperty(this->m_Capture, CV_CAP_PROP_POS_MSEC); - this->m_FramesPerSecond = static_cast(cvGetCaptureProperty(this->m_Capture, CV_CAP_PROP_FPS)); - this->m_Ratio = cvGetCaptureProperty(this->m_Capture, CV_CAP_PROP_POS_AVI_RATIO); - this->m_FourCC = cvGetCaptureProperty(this->m_Capture, CV_CAP_PROP_FOURCC); + this->m_CurrentFrame = static_cast(m_Capture.get(cv::CAP_PROP_POS_FRAMES)); + this->m_PositionInMSec = m_Capture.get(cv::CAP_PROP_POS_MSEC); + this->m_FramesPerSecond = m_Capture.get(cv::CAP_PROP_FPS); + this->m_Ratio = m_Capture.get(cv::CAP_PROP_POS_AVI_RATIO); + this->m_FourCC = static_cast(m_Capture.get(cv::CAP_PROP_FOURCC)); } void @@ -555,8 +524,8 @@ OpenCVVideoIO::OpenReader() // If neither reader nor writer is currently open, open the reader if (this->m_ReadFrom == ReadFromEnum::ReadFromFile) { - this->m_Capture = cvCaptureFromFile(this->GetFileName()); - if (this->m_Capture != nullptr) + m_Capture.open(this->GetFileName()); + if (m_Capture.isOpened()) { this->m_ReaderOpen = true; } @@ -567,8 +536,8 @@ OpenCVVideoIO::OpenReader() } else if (this->m_ReadFrom == ReadFromEnum::ReadFromCamera) { - this->m_Capture = cvCaptureFromCAM(this->m_CameraIndex); - if (this->m_Capture != nullptr) + m_Capture.open(this->m_CameraIndex); + if (m_Capture.isOpened()) { this->m_ReaderOpen = true; } @@ -593,18 +562,26 @@ OpenCVVideoIO::OpenWriter() } // If neither reader nor writer is currently open, open the writer - this->m_Writer = cvCreateVideoWriter( - this->GetFileName(), this->m_FourCC, this->m_FramesPerSecond, cvSize(this->m_Dimensions[0], this->m_Dimensions[1])); - this->m_WriterOpen = true; + m_Writer.open(this->GetFileName(), + this->m_FourCC, + this->m_FramesPerSecond, + cv::Size(static_cast(this->m_Dimensions[0]), static_cast(this->m_Dimensions[1]))); + if (m_Writer.isOpened()) + { + this->m_WriterOpen = true; + } + else + { + itkExceptionStringMacro("Video failed to open for writing"); + } } void OpenCVVideoIO::ResetMembers() { - this->m_CVImage = 0; - this->m_TempImage = 0; - this->m_Capture = 0; - this->m_Writer = 0; + m_CVImage = cv::Mat{}; + m_Capture.release(); + m_Writer.release(); this->m_WriterOpen = false; this->m_ReaderOpen = false; this->m_FramesPerSecond = 0; @@ -635,15 +612,11 @@ OpenCVVideoIO::PrintSelf(std::ostream & os, Indent indent) const { Superclass::PrintSelf(os, indent); - if (this->m_CVImage != nullptr) + if (!m_CVImage.empty()) { - os << indent << "Image dimensions : [" << this->m_CVImage->width << ',' << this->m_CVImage->height << ']' - << std::endl; - os << indent << "Origin : " << this->m_CVImage->origin << std::endl; - os << indent << "Image spacing (in bits) : " << this->m_CVImage->depth << std::endl; - os << indent << "Image Size : " << this->m_CVImage->imageSize << std::endl; - os << indent << "Color model : " << this->m_CVImage->colorModel << " (" << this->m_NumberOfComponents - << " channels)" << std::endl; + os << indent << "Image dimensions : [" << m_CVImage.cols << ',' << m_CVImage.rows << ']' << std::endl; + os << indent << "Image Size : " << (m_CVImage.total() * m_CVImage.elemSize()) << std::endl; + os << indent << "Color channels : " << m_CVImage.channels() << std::endl; } } diff --git a/Modules/Video/BridgeOpenCV/test/itkOpenCVVideoCaptureTest.cxx b/Modules/Video/BridgeOpenCV/test/itkOpenCVVideoCaptureTest.cxx index ee5f7f3e21c..e56c7d498f1 100644 --- a/Modules/Video/BridgeOpenCV/test/itkOpenCVVideoCaptureTest.cxx +++ b/Modules/Video/BridgeOpenCV/test/itkOpenCVVideoCaptureTest.cxx @@ -23,12 +23,7 @@ #include "itkOpenCVVideoIOFactory.h" #include "itkTestingMacros.h" -#include "opencv2/core/version.hpp" -#if !defined(CV_VERSION_EPOCH) -// OpenCV 3.x -# include "opencv2/videoio/videoio_c.h" -# include "opencv2/imgproc/imgproc_c.h" // cvCvtColor, CV_RGB2BGR, ... -#endif +#include "opencv2/videoio.hpp" // ITK type alias using ScalarPixelType = unsigned char; @@ -68,8 +63,8 @@ itkOpenCVVideoCaptureTest(int argc, char * argv[]) scalarCap->open(scalarReader->GetOutput()); // Check FourCC - scalarCap->set(CV_CAP_PROP_FOURCC, CV_FOURCC('M', 'P', '4', '2')); - if (static_cast(scalarCap->get(CV_CAP_PROP_FOURCC)) != CV_FOURCC('M', 'P', '4', '2')) + scalarCap->set(cv::CAP_PROP_FOURCC, cv::VideoWriter::fourcc('M', 'P', '4', '2')); + if (static_cast(scalarCap->get(cv::CAP_PROP_FOURCC)) != cv::VideoWriter::fourcc('M', 'P', '4', '2')) { std::cerr << "FourCC not reporting correctly" << std::endl; return EXIT_FAILURE; @@ -77,18 +72,18 @@ itkOpenCVVideoCaptureTest(int argc, char * argv[]) // Check FpS double eps = 0.0001; - if (scalarCap->get(CV_CAP_PROP_FPS) > 24 + eps || scalarCap->get(CV_CAP_PROP_FPS) < 24 - eps) + if (scalarCap->get(cv::CAP_PROP_FPS) > 24 + eps || scalarCap->get(cv::CAP_PROP_FPS) < 24 - eps) { std::cerr << "FpS not reporting correctly" << std::endl; return EXIT_FAILURE; } // Check width and height - if (static_cast(scalarCap->get(CV_CAP_PROP_FRAME_WIDTH)) != std::stoi(argv[4]) || - static_cast(scalarCap->get(CV_CAP_PROP_FRAME_HEIGHT)) != std::stoi(argv[5])) + if (static_cast(scalarCap->get(cv::CAP_PROP_FRAME_WIDTH)) != std::stoi(argv[4]) || + static_cast(scalarCap->get(cv::CAP_PROP_FRAME_HEIGHT)) != std::stoi(argv[5])) { - std::cerr << "Frame dimensions not reporting correctly. Got [" << scalarCap->get(CV_CAP_PROP_FRAME_WIDTH) << ',' - << scalarCap->get(CV_CAP_PROP_FRAME_HEIGHT) << "] Expected: [" << std::stoi(argv[4]) << ',' + std::cerr << "Frame dimensions not reporting correctly. Got [" << scalarCap->get(cv::CAP_PROP_FRAME_WIDTH) << ',' + << scalarCap->get(cv::CAP_PROP_FRAME_HEIGHT) << "] Expected: [" << std::stoi(argv[4]) << ',' << std::stoi(argv[5]) << ']' << std::endl; return EXIT_FAILURE; } @@ -96,9 +91,9 @@ itkOpenCVVideoCaptureTest(int argc, char * argv[]) // Set up OpenCV VideoWriter cv::VideoWriter scalarWriter( argv[2], - static_cast(scalarCap->get(CV_CAP_PROP_FOURCC)), - scalarCap->get(CV_CAP_PROP_FPS), - cv::Size(scalarCap->get(CV_CAP_PROP_FRAME_WIDTH), scalarCap->get(CV_CAP_PROP_FRAME_HEIGHT)), + static_cast(scalarCap->get(cv::CAP_PROP_FOURCC)), + scalarCap->get(cv::CAP_PROP_FPS), + cv::Size(scalarCap->get(cv::CAP_PROP_FRAME_WIDTH), scalarCap->get(cv::CAP_PROP_FRAME_HEIGHT)), false); // Loop through the frames and write @@ -124,14 +119,14 @@ itkOpenCVVideoCaptureTest(int argc, char * argv[]) rgbCap->open(rgbReader->GetOutput()); // Check FourCC - if (static_cast(rgbCap->get(CV_CAP_PROP_FOURCC)) != CV_FOURCC('M', 'P', '4', '2')) + if (static_cast(rgbCap->get(cv::CAP_PROP_FOURCC)) != cv::VideoWriter::fourcc('M', 'P', '4', '2')) { std::cerr << "FourCC not reporting correctly" << std::endl; return EXIT_FAILURE; } // Check FpS - if (rgbCap->get(CV_CAP_PROP_FPS) > 24 + eps || rgbCap->get(CV_CAP_PROP_FPS) < 24 - eps) + if (rgbCap->get(cv::CAP_PROP_FPS) > 24 + eps || rgbCap->get(cv::CAP_PROP_FPS) < 24 - eps) { std::cerr << "FpS not reporting correctly" << std::endl; return EXIT_FAILURE; @@ -139,9 +134,9 @@ itkOpenCVVideoCaptureTest(int argc, char * argv[]) // Set up OpenCV VideoWriter cv::VideoWriter rgbWriter(argv[3], - static_cast(rgbCap->get(CV_CAP_PROP_FOURCC)), - rgbCap->get(CV_CAP_PROP_FPS), - cv::Size(rgbCap->get(CV_CAP_PROP_FRAME_WIDTH), rgbCap->get(CV_CAP_PROP_FRAME_HEIGHT)), + static_cast(rgbCap->get(cv::CAP_PROP_FOURCC)), + rgbCap->get(cv::CAP_PROP_FPS), + cv::Size(rgbCap->get(cv::CAP_PROP_FRAME_WIDTH), rgbCap->get(cv::CAP_PROP_FRAME_HEIGHT)), true); // Loop through the frames and write diff --git a/Modules/Video/BridgeOpenCV/test/itkOpenCVVideoIOFactoryTest.cxx b/Modules/Video/BridgeOpenCV/test/itkOpenCVVideoIOFactoryTest.cxx index 65e939cdcfc..6ebbe834740 100644 --- a/Modules/Video/BridgeOpenCV/test/itkOpenCVVideoIOFactoryTest.cxx +++ b/Modules/Video/BridgeOpenCV/test/itkOpenCVVideoIOFactoryTest.cxx @@ -21,14 +21,7 @@ #include "itkVideoIOFactory.h" #include "itkOpenCVVideoIOFactory.h" -#include "opencv2/core/version.hpp" -#if defined(CV_VERSION_EPOCH) -// OpenCV 2.4.x -# include "highgui.h" -#else -// OpenCV 3.x -# include "opencv2/videoio/videoio_c.h" -#endif +#include "opencv2/videoio.hpp" using SizeValueType = itk::SizeValueType; @@ -71,13 +64,13 @@ test_OpenCVVideoIOFactory(char * input, char * output, SizeValueType cameraNumbe ////// // Use openCV to see if we can even try to open the camera - CvCapture * cameraCapture = cvCaptureFromCAM(cameraNumber); - if (cameraCapture != nullptr) + cv::VideoCapture cameraCapture(static_cast(cameraNumber)); + if (cameraCapture.isOpened()) { std::cout << "Trying to create IO for reading from camera " << cameraNumber << "..." << std::endl; // Release the OpenCV capture - cvReleaseCapture(&cameraCapture); + cameraCapture.release(); std::stringstream ss; ss << cameraNumber; diff --git a/Modules/Video/BridgeOpenCV/test/itkOpenCVVideoIOTest.cxx b/Modules/Video/BridgeOpenCV/test/itkOpenCVVideoIOTest.cxx index 756a8d5a2ce..fdf1164340a 100644 --- a/Modules/Video/BridgeOpenCV/test/itkOpenCVVideoIOTest.cxx +++ b/Modules/Video/BridgeOpenCV/test/itkOpenCVVideoIOTest.cxx @@ -24,6 +24,9 @@ #include "itkImageFileWriter.h" #include "itkOpenCVVideoIOFactory.h" +#include "opencv2/videoio.hpp" +#include "opencv2/imgproc.hpp" + // ITK type alias using PixelType = itk::RGBPixel; using ImportFilterType = itk::ImportImageFilter; @@ -63,7 +66,7 @@ itkImageFromBuffer(itk::OpenCVVideoIO::Pointer opencvIO, void * buffer, size_t b // Note: opencvIO should already have called ReadImageInformation // bool -readCorrectly(itk::OpenCVVideoIO::Pointer opencvIO, CvCapture * capture, FrameOffsetType frameNumber) +readCorrectly(itk::OpenCVVideoIO::Pointer opencvIO, cv::VideoCapture & capture, FrameOffsetType frameNumber) { bool ret = true; // Check meta data @@ -93,30 +96,29 @@ readCorrectly(itk::OpenCVVideoIO::Pointer opencvIO, CvCapture * capture, FrameOf // Read the frame data opencvIO->Read(static_cast(buffer)); - // Open the frame directly with OpenCV - IplImage * cvFrameBGR = cvQueryFrame(capture); - IplImage * cvFrameRGB = cvCreateImage( - cvSize(opencvIO->GetDimensions(0), opencvIO->GetDimensions(1)), IPL_DEPTH_8U, opencvIO->GetNumberOfComponents()); - cvCvtColor(cvFrameBGR, cvFrameRGB, CV_BGR2RGB); + // Read the corresponding frame directly with OpenCV and convert BGR -> RGB + cv::Mat cvFrameBGR; + capture >> cvFrameBGR; + cv::Mat cvFrameRGB; + cv::cvtColor(cvFrameBGR, cvFrameRGB, cv::COLOR_BGR2RGB); // Make sure buffers are same sized - if (cvFrameRGB->imageSize != static_cast(bufferSize)) + const size_t cvBufferSize = cvFrameRGB.total() * cvFrameRGB.elemSize(); + if (cvBufferSize != bufferSize) { - std::cerr << "Frame buffer sizes don't match. Got: " << bufferSize << ", Expected: " << cvFrameRGB->imageSize - << std::endl; + std::cerr << "Frame buffer sizes don't match. Got: " << bufferSize << ", Expected: " << cvBufferSize << std::endl; ret = false; } // Compare buffer contents - if (memcmp(reinterpret_cast(buffer), reinterpret_cast(cvFrameRGB->imageData), bufferSize)) + if (cvFrameRGB.isContinuous() && + memcmp(reinterpret_cast(buffer), reinterpret_cast(cvFrameRGB.data), bufferSize)) { std::cerr << "Frame buffers don't match for frame " << frameNumber << std::endl; ret = false; } delete[] buffer; - // Return - cvReleaseImage(&cvFrameRGB); return ret; } @@ -279,8 +281,8 @@ test_OpenCVVideoIO(char * input, std::cout << "OpenCVVideoIO::Read..." << std::endl; std::cout << "Comparing all " << opencvIO->GetFrameTotal() << " frames" << std::endl; - // Set up OpenCV capture - CvCapture * capture = cvCaptureFromFile(opencvIO->GetFileName()); + // Set up OpenCV capture for cross-validation + cv::VideoCapture capture(opencvIO->GetFileName()); // Loop through all frames for (FrameOffsetType i = 0; i * opencvIO->GetIFrameInterval() < opencvIO->GetFrameTotal(); ++i) { @@ -292,8 +294,7 @@ test_OpenCVVideoIO(char * input, } } - // Release capture - cvReleaseCapture(&capture); + capture.release(); // // SetNextFrameToRead