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;
}
Related
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;
}
I am currently trying to modify a program that takes in a webcam stream as input. The problem is, when I try to alter the program to use a single image, it doesn't display the output that I am expecting e.g. with video stream (code below)
#include "opencv2/opencv.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/videoio.hpp"
#include <opencv2/highgui.hpp>
#include <opencv2/video.hpp>
#include "BackgroundRemover.h"
#include "SkinDetector.h"
#include "FaceDetector.h"
#include "FingerCount.h"
using namespace cv;
using namespace std;
int main(int, char**) {
VideoCapture videoCapture(0);
videoCapture.set(CV_CAP_PROP_SETTINGS, 1);
if (!videoCapture.isOpened()) {
cout << "Can't find camera!" << endl;
return -1;
}
Mat frame, frameOut, handMask, foreground, fingerCountDebug;
BackgroundRemover backgroundRemover;
SkinDetector skinDetector;
FaceDetector faceDetector;
FingerCount fingerCount;
for (int i = 0; i < 2; i++)
{
videoCapture >> frame;
frameOut = frame.clone();
skinDetector.drawSkinColorSampler(frameOut);
foreground = backgroundRemover.getForeground(frame);
faceDetector.removeFaces(frame, foreground);
handMask = skinDetector.getSkinMask(foreground);
fingerCountDebug = fingerCount.findFingersCount(handMask, frameOut);
imshow("output", frameOut);
imshow("foreground", foreground);
imshow("handMask", handMask);
imshow("handDetection", fingerCountDebug);
if (i == 0)
{
backgroundRemover.calibrate(frame);
skinDetector.calibrate(frame);
}
}
waitKey(0);
}
The output shows a detection. Whereas, if I modify the code so that frame doesn't read from the video stream, the output shows nothing at all. Can anybody help to fix this? EDIT: Due to confusion from some members of the community, the modified code is below that reads in a single image:
#include "opencv2/opencv.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/videoio.hpp"
#include <opencv2/highgui.hpp>
#include <opencv2/video.hpp>
#include "BackgroundRemover.h"
#include "SkinDetector.h"
#include "FaceDetector.h"
#include "FingerCount.h"
using namespace cv;
using namespace std;
int main(int, char**) {
string imageName("C:/Users/whoever/Desktop/hand_test.jpg"); // by default
Mat image;
image = imread(imageName.c_str(), IMREAD_COLOR); // Read the file
Mat frame, frameOut, handMask, foreground, fingerCountDebug;
BackgroundRemover backgroundRemover;
SkinDetector skinDetector;
FaceDetector faceDetector;
FingerCount fingerCount;
for (int i = 0; i < 2; i++)
{
frame = image;
frameOut = frame.clone();
skinDetector.drawSkinColorSampler(frameOut);
foreground = backgroundRemover.getForeground(frame);
faceDetector.removeFaces(frame, foreground);
handMask = skinDetector.getSkinMask(foreground);
fingerCountDebug = fingerCount.findFingersCount(handMask, frameOut);
imshow("output", frameOut);
imshow("foreground", foreground);
imshow("handMask", handMask);
imshow("handDetection", fingerCountDebug);
if (i == 0)
{
cout << "Calibrating...";
backgroundRemover.calibrate(frame);
skinDetector.calibrate(frame);
}
}
waitKey(0);
}
The original code processes different images captured from the camera each time it goes round the loop and outputs the differences. Since you are now using the same image every time round there are never any differences hence the output is completely blank. (Note that it will still be playing the output as a video, just a constantly blank one)
The first line in the for loop is where it grabs a new image from the camera:
videoCapture >> frame;
As you can see in your updated code you are removing this and just using the same image again:
frame = image;
Try saving 2 different images instead and have the program load in a different one each time round the loop.
Here is a fairly brute force way to do it which you could improve to load a different file each time it loops, use arrays and so on:
string imageName1("C:/Users/whoever/Desktop/hand_test_1.jpg"); // by default
string imageName2("C:/Users/whoever/Desktop/hand_test_2.jpg"); // by default
Mat image1;
Mat image2;
image1 = imread(imageName1.c_str(), IMREAD_COLOR); // Read the file
image2 = imread(imageName2.c_str(), IMREAD_COLOR); // Read the file
Mat frame, frameOut, handMask, foreground, fingerCountDebug;
BackgroundRemover backgroundRemover;
SkinDetector skinDetector;
FaceDetector faceDetector;
FingerCount fingerCount;
for (int i = 0; i < 2; i++)
{
if (i = 0) { frame = image1 } else { frame = image2 };
...
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;
}
I am using this piece of code to grab frames off a video :
#include <stdio.h>
#include <stdlib.h>
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <iostream>
using namespace cv;
using namespace std;
int main (int argc, char** argv)
{
//initializing capture from file
CvCapture * capture = cvCaptureFromAVI ("/home/<some_file>.avi");
//Capturing a frame
IplImage* img = 0;
if(!cvGrabFrame(capture)) //capture a frame
{
cout << Could not grab a frame\n\7";
exit(0);
}
img=cvRetrieveFrame(capture); //retrieve the captured frame
//free resources
cvReleaseCapture(&capture);
}
Which is returning :
Could not grab a frame
Additional details :
I had used code to save webcam video feed to the file from which i want to grab frames .
I used this code :
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
int main( int argc, char** argv ) {
CvCapture* capture;
capture = cvCreateCameraCapture(0);
assert( capture != NULL );
IplImage* bgr_frame = cvQueryFrame( capture );
CvSize size = cvSize(
(int)cvGetCaptureProperty( capture,
CV_CAP_PROP_FRAME_WIDTH),
(int)cvGetCaptureProperty( capture,
CV_CAP_PROP_FRAME_HEIGHT)
);
cvNamedWindow( "Webcam", CV_WINDOW_AUTOSIZE );
CvVideoWriter *writer = cvCreateVideoWriter( "/Users/user/Desktop/OpenCV_trial/OpenCV_trial/vidtry.AVI",
CV_FOURCC('D','I','V','X'),
30,
size
);
while( (bgr_frame = cvQueryFrame( capture )) != NULL )
{
cvWriteFrame(writer, bgr_frame );
cvShowImage( "Webcam", bgr_frame );
char c = cvWaitKey( 33 );
if( c == 27 ) break;
}
cvReleaseVideoWriter( &writer );
cvReleaseCapture( &capture );
cvDestroyWindow( "Webcam" );
return( 0 );
}
Does anyone know where I might be going wrong ? I am running OpenCV-2.4.3 on a Beagleboard -xM with Ubuntu Quantal.
I am not quite sure what your exactly question is, but if you want to grab frames from a video, you should at least have a loop.
A reason for your error could be, that your video file is not available. Have you tried another one? The full path of the file? Or put the file directly into your working directory and check it.
Another reason could be a problem with the first frame (this sometimes happens). So try to remove your exit and enclose your code with a loop over all frames.
Here is an example that shows the given video file (Consider to use the C++-interface):
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <iostream>
using namespace cv;
using namespace std;
int main (int argc, char** argv)
{
//initializing capture from file
Mat img;
VideoCapture capture("a.avi");
if(!capture.isOpened())
{
cout<<"Could not open video!\n";
return 1;
}
while(true)
{
//Capturing a frame
capture >> img;
if(!img.empty())
{
imshow("Video",img);
}
else
{
cout <<"Could not grab a frame\n";
break;
}
if(waitKey(5) >= 0)
break;
}
return 0;
}
This program runs on my PC if the file "a.avi" is in the current working directory of the program.
I am using OpenCV 2.4.6. I have found over the Internet some example of getting frame from a camera. It works well (it displays my ugly face onto the screen). However, I absolutely cannot get pixel data from the frames. I've found some topic here: http://answers.opencv.org/question/1934/reading-pixel-values-from-a-frame-of-a-video/ but it doesn't work for me.
Here is the code - in the commented parts I pointed out what is wrong.
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
int main() {
int c;
IplImage* img;
CvCapture* capture = cvCaptureFromCAM(1);
cvNamedWindow("mainWin", CV_WINDOW_AUTOSIZE);
while(1) {
img = cvQueryFrame(capture);
uchar* data = (uchar*)img->imageData; // access violation
// this does not work either
//Mat m(img);
//uchar a = m.data[0]; // access violation
cvShowImage("mainWin", img);
c = cvWaitKey(10);
if(c == 27)
break;
}
}
Could you give me some suggestions, please?
I suggest using the newer Mat structure instead of IplImage since your question is tagged with C++ tag. For your task you can use a data member of Mat - it points to internal Mat storage. For example Mat img; uchar* data = img.data;. Here's a full example
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
int main() {
int c;
Mat img;
VideoCapture capture(0);
namedWindow("mainWin", CV_WINDOW_AUTOSIZE);
bool readOk = true;
while(capture.isOpened()) {
readOk = capture.read(img);
// make sure we grabbed the frame successfully
if (!readOk) {
std::cout << "No frame" << std::endl;
break;
}
uchar* data = img.data; // this should work
imshow("mainWin", img);
c = waitKey(10);
if(c == 27)
break;
}
}