Displaying video using opencv - c++

Hi I am trying to play a video using the following code:
//#include <stdio.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
//#include <iostream>
using namespace cv;
int main(int argc, char** argv)
{
string filename = "anime.avi";
VideoCapture capture(filename);
Mat frame;
if( !capture.isOpened() )
throw "Error when reading steam_avi";
namedWindow( "w", 1);
for( ; ; )
{
capture >> frame;
if(!frame)
break;
imshow("w", frame);
waitKey(20); // waits to display frame
}
waitKey(0); // key press to close window
// releases and window destroy are automatic in C++ interface
}
When I run it though, I get the following errors:
project.cpp: In function ‘int main(int, char**)’:
project.cpp:23:13: error: no match for ‘operator!’ in ‘!frame’
project.cpp:23:13: note: candidates are:
project.cpp:23:13: note: operator!(bool) <built-in>
project.cpp:23:13: note: no known conversion for argument 1 from ‘cv::Mat’ to ‘bool’
/usr/local/include/opencv2/core/operations.hpp:2220:20: note: bool cv::operator!(const cv::Range&)
/usr/local/include/opencv2/core/operations.hpp:2220:20: note: no known conversion for argument 1 from ‘cv::Mat’ to ‘const cv::Range&’
Could you possibly help. I've been on this for hours without success :(

Because there is no operator! overloaded for class cv::Mat. In the documentation, it not said clearly, what should happen with the image in case of acquisition failed. That's the implementation of cv::VideoCapture::operator>> from cap.cpp:
VideoCapture& VideoCapture::operator >> (Mat& image)
{
if(!grab())
image.release();
else
retrieve(image);
return *this;
}
Now go to documentation on cv::Mat:release. And let's double check it's implementation from the mat.hpp:
inline void Mat::release()
{
if( refcount && CV_XADD(refcount, -1) == 1 )
deallocate();
data = datastart = dataend = datalimit = 0;
size.p[0] = 0;
refcount = 0;
}
Hence, finally, you can check the data pointer to find out, whether the grab was successful:
if (!frame.data) break;
However, I recommend to use function-style call cv::VideoCapture::read in this case, since it explicitly returns whether it was successful, or not:
if (!capture.read(frame)) break;
HTH

Related

Trying to Locate Aruco Fiducials with USB camera Ubuntu 18.04

I have some code I think should be working using open CV to detect a set of fiducials. For some reason, I cant get my code to run. It gives the error "Unable to stop the stream: Invalid argument"
#include "opencv2/opencv.hpp"
using namespace cv;
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/aruco.hpp>
int main(int argc, char** argv)
{
Mat markerImage;
VideoCapture cap;
// open the default camera, use something different from 0 otherwise;
// Check VideoCapture documentation.
if(!cap.open(1))
return 0;
for(;;)
{
Mat frame;
cap >> frame;
if( frame.empty() ) break; // end of video stream
std::vector<int> markerIds;
std::vector<std::vector<cv::Point2f>> markerCorners, rejectedCandidates;
cv::Ptr<cv::aruco::DetectorParameters> parameters = cv::aruco::DetectorParameters::create();
cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_5X5_50);
cv::aruco::detectMarkers(frame, dictionary, markerCorners, markerIds, parameters, rejectedCandidates);
cv::aruco::drawDetectedMarkers(frame, markerCorners, markerIds);
imshow("Camera)", frame);
if( waitKey(10) == 27 ) break; // stop capturing by pressing ESC
}
// the camera will be closed automatically upon exit
// cap.close();
return 0;
}

How do you stream raspberry pi camera V2 footage via netcat to OpenCV C++

Edit: I rewrote the code I copied and now it receives the stream successfully however when the code reaches namedWindow I get no output or sometimes "Aborted" at the end of my string
error: (-215:Assertion failed) size.width>0 && size.height>0 in function 'imshow'
My PC: a debian virtualbox machine
note: Thee stuff in < > is replaced with my ip address
#include <stdio.h>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main(int argc, char** argv )
{
VideoCapture vcap;
Mat image;
const string videoStreamAddress = "udp://<myIp>:<port>";
vcap.open("udp://<myIp>:<port>");
if(!vcap.isOpened())
{
printf("nope");
}
else
{
printf("sucsess");
namedWindow("stuff", WINDOW_NORMAL);
imshow("stuff", image);
}
}
what my raspberry pi executes:
/opt/vc/bin/raspivid -t 0 -w 300 -h 300 -hf -fps 20 -o - | nc IpAddressInCode PortInCode
Ok so apparently the problem was
1.ImShow Requires a frame to show and No where in my code did I assign "image" a value
In order to recieve output from a stream I have to get it frame by frame, I cant just show the whole stream
error: (-215:Assertion failed) size.width>0 && size.height>0 in function 'imshow'
#include <stdio.h>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main(int argc, char** argv )
{
VideoCapture vcap;
const string videoStreamAddress = "udp://<myIp>:<myPort>";
vcap.open(videoStreamAddress);
if(!vcap.isOpened())
{
printf("nope");
}
else
{
for(;;)
{
Mat frame;
vcap >> frame;
imshow("stuff", frame);
if( waitKey(10) == 27) break;
}
printf("Sucsess!");
}
return 0;
}

Visual Studio Error: name must be a namespace name

This is the 3rd question for today as I am still struggling. The problem is: Visual Studio is giving the error on line 2. It says:
Error: name must be a namespace name
This is my code, this should open the webcam and it should take frames.
What is wrong here?
#include "opencv.hpp"
using namespace cv;
int main(int argc, char** argv)
{
VideoCapture cap;
// open the default camera, use something different from 0 otherwise;
// Check VideoCapture documentation.
if (!cap.open(0))
return 0;
for (;;)
{
Mat frame;
cap >> frame;
if (frame.empty()) break; // end of video stream
imshow("this is you, smile! :)", frame);
if (waitKey(1) == 27) break; // stop capturing by pressing ESC
}
// the camera will be closed automatically upon exit
// cap.close();
return 0;
}

Opencv: Null pointer (NULL array pointer is passed) in cvGetMat

I'm getting this error when trying to capture video from webcam using opencv. This is the code I'm using:
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace std;
int main( int argc, const char** argv ) {
CvCapture *capture = cvCaptureFromCAM(0);
IplImage *frame;
cvNamedWindow("test");
while ( 1)
{
frame = cvQueryFrame(capture) ;
cvShowImage("test", frame);
int key = cvWaitKey(1);
if ( key == 27 ) break; // ESC key was pressed
}
// Memory deallocation
cvReleaseCapture(&capture);
cvDestroyWindow("test");
return 0;
}
The error occur at cvShowImage("text", frame):
OpenCV Error: Null pointer (NULL array pointer is passed) in cvGetMat,
file
/opt/local/var/macports/build/_opt_mports_dports_graphics_opencv/opencv/work/opencv-2.4.6.1/modules/core/src/array.cpp,
line 2382 libc++abi.dylib: terminate called throwing an exception
(lldb)
What is it error about and how can I fix it?
First you should check that whether there is a device at index 0, like this
if (!capture)
{
// print error and exit
cout << "ERROR: Capture is null!\n";
return -1;
}
Secondly, :
while ( capture)
{
frame = cvQueryFrame(capture) ;
cvShowImage("test", frame);
int key = cvWaitKey(1);
if ( key == 27 ) break; // ESC key was pressed
}
Hope this helps

error with gpumat and mat

When I compile this example:
#include <iostream>
#include "opencv2/opencv.hpp"
#include "opencv2/gpu/gpu.hpp"
int main (int argc, char* argv[])
{
try
{
cv::Mat src_host = cv::imread("file.png", CV_LOAD_IMAGE_GRAYSCALE);
cv::gpu::GpuMat dst, src;
src.upload(src_host);
cv::gpu::threshold(src, dst, 128.0, 255.0, CV_THRESH_BINARY);
cv::Mat result_host = dst;
cv::imshow("Result", result_host);
cv::waitKey();
}
catch(const cv::Exception& ex)
{
std::cout << "Error: " << ex.what() << std::endl;
}
return 0;
}
I got the following error:
threshold.cpp: In function ‘int main(int, char**)’:
threshold.cpp:19: error: conversion from ‘cv::gpu::GpuMat’ to non-scalar type ‘cv::Mat’ requested
Does anybody knows why?
In the current versions of OpenCV, the cv::Mat class has no overloaded assignment operator or copy constructor which takes argument of type cv::gpu::GpuMat. So the following line of your code will not compile.
cv::Mat result_host = dst;
There are 2 alternatives to this.
First you can pass the dst as the argument of the constructor of result_host.
cv::Mat result_host(dst);
Second is that you can call the download function of dst
cv::Mat result_host;
dst.download(result_host);
It seems that you should use download method of gpuMat to convert it to cv::Mat:
//! downloads data from device to host memory. Blocking calls.
void download(cv::Mat& m) const;
See this doc.