How to convert videostream data to cv::gpumat? - c++

I need to convert videostream data to cv::gpumat. Initially I tried copying to cv::Mat and then use upload to load it to gpumat. This process is very slow(20ms for a 640*480 frame).
I need a method to convert from openni videostream to gpumat directly. I tried the following code but it gives run time error
I am using opencv3.1, cuda-8.0, gtx titanx on ubuntu 16.04
#include "opencv2/opencv_modules.hpp"
#include <opencv2/core.hpp>
#include <opencv2/cudacodec.hpp>
#include <opencv2/highgui.hpp>
int main(int argc, const char* argv[])
{
const std::string fname = argv[1];
cv::cuda::GpuMat d_frame;
cv::Ptr<cv::cudacodec::VideoReader> d_reader = cv::cudacodec::createVideoReader(fname);
for (;;)
{
if (!d_reader->nextFrame(d_frame))
break;
cv::Mat frame;
d_frame.download(frame);
cv::imshow("GPU", frame);
if (cv::waitKey(3) > 0)
break;
}
return 0;
}
OpenCV Error: The function/feature is not implemented (The called functionality is disabled for current build or platform) in throw_no_cuda, file /home/krr/softwares/opencv-3.1.0/modules/core/include/opencv2/core/private.cuda.hpp, line 101
terminate called after throwing an instance of 'cv::Exception'
what(): /home/krr/softwares/opencv-3.1.0/modules/core/include/opencv2/core/private.cuda.hpp:101: error: (-213) The called functionality is disabled for current build or platform in function throw_no_cuda

Take a look into the source code. The framework called "throw_no_cuda()" (lines are different, version?). Also the error seems to be a duplicate of this one on github.
alalek:
https://developer.nvidia.com/nvidia-video-codec-sdk:
Note: For Video Codec SDK 7.0 and later, NVCUVID has been renamed to NVDECODE API.
OpenCV has no support for new API and there are no plans to add this.
The latest CUDA version with NVCUVID is ~ CUDA 6.5.
Consider using ffmpeg with enabled CUDA features (via normal cv::VideoCapture - but it can't work with CUDA's cv ::GpuMat).
And further:
dapicard:
I found a way to define the codec used by the FFMpeg backend :
export OPENCV_FFMPEG_CAPTURE_OPTIONS="video_codec|h264_cuvid"
More generally, it is possible to define theses parameters, using the syntax parameter_name|value;parameter_name2|value2
That is, to use the hardware capabilities to decode videos (which you tried). Sidenote: ffmpeg also offers options to transcode videos directly on the gpu (i.e. without moving fromes away from gpu memory).
Frankly, using the proposed method will not result in the matrix being delivered to your gpu memory directly, but only solve the error. I don't think it is possible to grab the memory directly from ffmpeg directly, so you are stuck with moving it.

Related

OpenCV, can't release CAP_OPENCV_MJPEG VideoWriter for long records

Hi stackoverflow community,
I recently had a problem with the performance of the opencv VideoWriter (see here), and I am now using cv::CAP_OPENCV_MJPEG as a backend instead of cv::CAP_FFMPEG.
Now I am running in another issue, so my code looks like this:
cv::VideoWriter videoWriter(path, cv::CAP_OPENCV_MJPEG, fourcc, fps, *size);
videoWriter.set(cv::VIDEOWRITER_PROP_QUALITY, 100);
int id = metaDataWriter.insertNow(path);
while (this->isRunning) {
while (!this->stackFrames.empty()) {
cv:Mat m = this->stackFrames.pop();
videoWriter << m;
}
}
videoWriter.release();
This loop runs in a separate thread and "isRunning" will be switched from outside. There is a stack with cv::Mat (stackFrames) which is filled by another thread that captures the images by a video capture card. This works fine, but if the file size is too big, several GB, I get the following error when the videoWriter.release() is called:
terminate called after throwing an instance of 'cv::Exception'
what(): OpenCV(4.4.0) /home/michael-gary/opencv/opencv/modules/videoio/src/container_avi.cpp:27: error: (-211:One of the arguments' values is out of range) Failed to write AVI file: chunk size is out of bounds in function 'safe_int_cast'
I tried to change the video container from .avi to .mkv, .mp4, .mpg but none of them is working, it does not even create the file. Only .avi is working, but fails by the release.
For now I will try to write multiple files, so I don't run in this problem, but I would like to face the problem itself.
Open for any suggestions
BR Michael
AVI files are practically limited in size.
when you force it to use OPENCV_MJPEG, it will only use OpenCV's own writing methods, which can only do AVI and MJPEG.
if you need a different container, you have to use a different backend, such as FFMPEG. you can still have MJPG for a codec (fourcc).

OpenCV C++ Xcode on Mac Mojave error NSCameraUsageDescription

I have installed the opencv on MacPro and am trying to write a program which allow me to activate the cam, it is only to test opencv it build successfully, however, the cam is not on and I receive this message
saved enable noise cancellation setting is the same as the default(=1) pentest[30782:364297] [access] This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSCameraUsageDescription key with a string value explaining to the user how the app uses this data
my code is:
#include <iostream>
#include<opencv2/opencv.hpp>
using namespace cv;
int main(int argc, const char * argv[]) {
// insert code here...
VideoCapture cap(0);
while(true){
Mat Webcam;
cap.read(Webcam);
imshow("webcam",Webcam);
}
return 0;
}
I recently posted another answer that addresses this situation:
Put the Info.plist file with the desired NSCameraUsageDescription, NSMicrophoneUsageDescription (or others) with the assembled file from XCode (See screenshots below). For the Release and Debug versions.

How do I dynamically select an available codec for OpenCV's VideoWriter?

I am writing an image processing application to align a set of images, and I would like there to be functionality to write those images into a video. The image processing part is done in OpenCV 3.2.0 (C++), and currently outputs still images that aren't stitched together.
I have successfully used the VideoWriter with one of the codecs available to my machine to write the output images to an .avi, but to my knowledge there is no guarantee that any codec will be available on different platforms. As I would like to be able to share this application, this is a problem.
If it matters, the GUI is built in wxWidgets 3.1.0, so if there is something that can help me there that I didn't find, I would love to know.
My assumption is that there is no way of guaranteeing a successful video without somehow shipping a codec with the app, but is there a way of browsing available codecs at run time?
I know that on some platforms the following brings up a dialog of additional codecs, which would be perfect if I could automatically interpret it:
cv::Size outputSize = myImage.size();
cv::VideoWriter("output.avi", -1, 30, outputSize);
But this also doesn't work on every platform. So is there any way of scrubbing available codecs from the machine at run time or do I have to supply a codec somehow in order to write videos cross platform?
There is no such function in OpenCV to list all the available codecs. However, if you've ffmpeg or LibAV on your machine - as you should've while building/installing OpenCV - then you can use ffmpeg/LibAV to list all the available codecs. Following is code that does that:
#include <iostream>
extern "C" {
#include <libavcodec/avcodec.h>
}
int main(int argc, char **argv)
{
/* initialize libavcodec, and register all codecs and formats */
avcodec_register_all();
// struct to hold the codecs
AVCodec* current_codec = NULL;
// initialize the AVCodec* object with first codec
current_codec = av_codec_next(current_codec);
std::cout<<"List of codecs:"<<std::endl;
// loop over all codecs
while (current_codec != NULL)
{
if(av_codec_is_encoder(current_codec) | av_codec_is_decoder(current_codec))
{
std::cout<<current_codec->name<<std::endl;
}
current_codec = av_codec_next(current_codec);
}
}
Compile with:
g++ listcodecs.cpp -o listcodecs `pkg-config libavcodec --cflags --libs`

OpenCV gives an error when trying to get images from an axis camera

I am trying to write a program in OpenCV that just displays the video from an axis camera, which is a type of ip camera. My problem is that OpenCV gives me an error and crashes.
The error is:
OpenCV Error: Bad flag (parameter or structure field) (Unrecognized or unsupported array type) in cvGetMat, file /home/pi/opencv-2.4.5/modules/core/src/array.cpp, line 2482
terminate called after throwing an instance of 'cv::Exception'
what(): /home/pi/opencv-2.4.5/modules/core/src/array.cpp:2482: error: (-206)
Unrecognized or unsupported array type in function cvGetMat
Aborted
My code is:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
Mat img;
namedWindow("IMG", CV_WINDOW_AUTOSIZE);
while(true)
{
img = imread("http://10.17.14.11/jpg/image.jpg");
if(img.empty())cout<<"The image is empty\n";//This cout is printed
imshow("IMG", img);
if(waitkey(1) >=0)break;
}
}
I have tried using a VideoCapture with the address
"http://10.17.14.11/mjpg/video.mjpg"
but I got the same error. I also put both of these URLs into my web browser and they were valid.
Thank you.
EDIT
Could the reason for VideoCapture not working be that I don't have ffmpeg installed?
I guess the function 'imread' only search for files in the current host. You should download the file by other means and then open it using imread.
The error is probably because neither imread or VideoCapture can open remote images. It is easy to check if you try to read a local image instead. At least, I couldn't find anything in the VideoCapture documentation that suggest that remote paths are valid.
If you saw some example, maybe it was using some extended class. It can be very useful to future readers if you find the URL of the example.

Effective way to get into image processing with C++?

Recently I was turned on to the opencv programming library for image and data processing, and over the course of trying to get the software to work I've decided I'm simply fed up with how complicated it is to get the libraries onto my computer. Is there another library or framework that allows a user to interact with cameras and image processing in c++ but doesn't require such tedious work to obtain and install as OpenCV?
Edit: The reason I am having a hard time with opencsv is because I do not wish to use an IDE to develop any of my programs, I am trying to learn to use gdb from the cmd line and vim to edit
Could you specify which platform you are using and what problems you encountered?
I suspect that many of your problems are not related to OpenCV per se, but instead are general problems you would have with any C++ lib. E.g. getting a 64-bit compiler, a decent IDE, compiling OpenCV and if needed some of its dependencies. That can actually indeed become a nuissance. What platform are you using? I find that a Linux distribution with a good package repository makes this way easier, since you can very easily setup the required tools and often install many build dependencies via the repository without having to compile them yourself.
If indeed you are having strictly OpenCV-related issues, ITK (http://www.itk.org/) may well be a good alternative.
Best,
You can use this in 8-steps
#include <cv.h>
#include <highgui.h>
using namespace cv;
int main( int argc, char** argv )
{
Mat image;
image = imread( argv[1], 1 );
if( argc != 2 || !image.data )
{
printf( "No image data \n" );
return -1;
}
namedWindow( "Display Image", CV_WINDOW_AUTOSIZE );
imshow( "Display Image", image );
waitKey(0);
return 0;
}
in Linux.
Windows also needs 8-steps.
You can call MATLAB engine from C/C++ . Matlab has image-processing too!
When I did a lot of image processing I would deal with Bitmaps. Read the file into memory and make note of the BITMAPFILEHEADER. There is more information but you could just look up the offset into the pixel data. You could use Directshow as well to get frames from a webcam.
Create a wrapper to expose some user friendly functions like getPixel() etc.
Then I would look up papers + blogs etc to see if I can write the algorithms myself, sometimes it's all too easy passing some image to say a FaceTracking(ImageData data) function.