I want to show a live stream of the camera connected to raspberry in qt application (OS Linux). After googling it, I found out I must display the video inside QLabel. When displaying an image there's no problem and everything works fine, but when I want to display the live stream inside QLabel, the live stream window opens separately (not inside QLabel). would you tell me how to solve this problem? here's my code :
void Dialog::on_Preview_clicked()
{
command = "raspistill";
args<<"-o"<<"/home/pi/Pictures/Preview/"+Date1.currentDateTime().toString()+".jpg"<<"-t"<<QString::number(20000);
Pic.start(command,args,QIODevice::ReadOnly);
QPixmap pix("//home//pi//Pictures//Preview//test.jpg");
ui->label_2->setPixmap(pix);
ui->label_2->setScaledContents(true);
}
This code opens video capturing screen and captures an image after 20 seconds. the only problem is that the capture screen (which could be used as a live stream). isn't being displayed inside the "Lable_2". Is there anyway to do this without using OpenCV library? If not, tell me how to do it using OpenCV.
Thanks
It is pretty simple in opencv
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
VideoCapture cap(0); // open the default camera
if(!cap.isOpened()) // check if we succeeded
return -1;
Mat edges;
namedWindow("edges",1);
for(;;)
{
Mat frame;
cap >> frame; // get a new frame from camera
imshow("edges", frame);
if(waitKey(30) >= 0) break;
}
return 0;
}
Stream the camera using OpenCV, and show it in QLabel is possible.
When QCamera not working, and also use OpenCV in the project, could use VideoCapture to stream the video instead of QCamera.
The problem can be decomposed into several steps. Basically, We need:
Create a QThread for streaming(Don't let the GUI thread blocked).
In the sub-thread, using cv::VideoCapture to capture the frame into a cv::Mat.
Convert the cv::Mat to QImage(how to convert an opencv cv::Mat to qimage).
Pass QImage frame from sub-thread to the main GUI thread.
Paint the QImage on the QLabel.
I put the complete demo code in Github. it could paint the frame on the QLabel and QML VideoOutput.
Related
I am taking my first steps with OpenCV and I am trying to run this piece of code. It is supposed to open the specified video in a new window and wait for the user to press ESC. I tried passing both the relative and absolute path to VideoCapture but VideoCapture::isOpened() always fails. Why is this happening?
If I pass 0 to VideoCapture and do NOT call isOpened(), then I get a nice little window.
Note that I am using VS15 and OpenCV 2.4 (with the x86 libs)
#include "opencv2/opencv.hpp"
using namespace cv;
int main(int, char**)
{
VideoCapture cap(path_to_video); // open the video file
// VideoCapture cap(0);
if(!cap.isOpened()) // check if we succeeded
return -1;
namedWindow("Video",1);
for(;;)
{
Mat frame;
cap >> frame; // get a new frame from camera
imshow("Video", frame);
if(waitKey(30) >= 0) break;
}
return 0;
}
EDIT: I solved this by reinstalling OpenCV and creating a new Visual Studio project. The above code miraculously started working.
If I pass 0 to VideoCapture and do NOT call isOpened(), then I get a
nice little window. Why is this happening?
Because the VideoCapture class has two different constructors. The one that takes a string attempts to read from a file. The one that takes an integer attempts to read from a device. Passing 0 to the second version specifies the default device / camera.
VideoCapture::open¶ Open video file or a capturing device for video
capturing
C++: bool VideoCapture::open(const string& filename)
C++: bool VideoCapture::open(int device)
Parameters:
filename – name of the opened video file (eg. video.avi)
or image sequence (eg. img_%02d.jpg, which will read samples like
img_00.jpg, img_01.jpg, img_02.jpg, ...)
device – id of the opened video capturing device (i.e. a camera index).
I am using console linux and I have a camera capture application. I need to capture an image without GUI(The camera should start and capture some images, save it to disk and close). The following code works well on my laptop but doesn't start on console. Any suggestions?
#include "cv.h"
#include "highgui.h"
using namespace cv;
int main(int, char**)
{
VideoCapture cap(0); // open the default camera
Mat frame;
namedWindow("feed",1);
for(;;)
{
Mat frame;
cap >> frame; // get a new frame from camera
imshow("feed", frame);
imwrite("/home/zaif/output.png", frame);
if(waitKey(1) >= 0) break;
}
return 0;
}
After the release of OpenCV 2.4.6 there were bug fixes for video capture on Linux. Go straight to 2.4.6.2 and you should get the fixes. Specifically, this revision is probably the relevant fix for you, although there were a number of other revisions pertaining to video capture on android that might effect Linux compilation too.
Good day everyone! So currently I'm working on a project with video processing, so I decided to give a try to OpenCV. As I'm new to it, I decided to find few sample codes and test them out. First one, is C OpenCV and looks like this:
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <stdio.h>
int main( void ) {
CvCapture* capture = 0;
IplImage *frame = 0;
if (!(capture = cvCaptureFromCAM(0)))
printf("Cannot initialize camera\n");
cvNamedWindow("Capture", CV_WINDOW_AUTOSIZE);
while (1) {
frame = cvQueryFrame(capture);
if (!frame)
break;
IplImage *temp = cvCreateImage(cvSize(frame->width/2, frame->height/2), frame->depth, frame->nChannels); // A new Image half size
cvResize(frame, temp, CV_INTER_CUBIC); // Resize
cvSaveImage("test.jpg", temp, 0); // Save this image
cvShowImage("Capture", frame); // Display the frame
cvReleaseImage(&temp);
if (cvWaitKey(5000) == 27) // Escape key and wait, 5 sec per capture
break;
}
cvReleaseImage(&frame);
cvReleaseCapture(&capture);
return 0;
}
So, this one works perfectly well and stores image to hard drive nicely. But problems begin with next sample, which uses C++ OpenCV:
#include "opencv2/opencv.hpp"
#include <string>
using namespace cv;
int main(int, char**)
{
VideoCapture cap(0); // open the default camera
if(!cap.isOpened()) // check if we succeeded
return -1;
Mat edges;
//namedWindow("edges",1);
for(;;)
{
Mat frame;
cap >> frame; // get a new frame from camera
cvtColor(frame, edges, CV_RGB2XYZ);
imshow("edges", edges);
//imshow("edges2", frame);
//imwrite("test1.jpg", frame);
if(waitKey(1000) >= 0) break;
}
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;
}
So, yeah, generally, in terms of showing video (image frames) there is practically no changes, but when it comes to using im** functions, some problems arise.
Using cvSaveImage() works out nicely, but the moment I try to use imwrite(), unhandled exception arises in regards of 'access violation reading location'. Same goes for imread(), when I'm trying to load image.
So, the thing I wanted to ask, is it possible to use most of the functionality with C OpenCV? Or is it necessary to use C++ OpenCV. If yes, is there any solution for the problem I described earlier.
Also as stated here, images initially are in BGR-format, so conversion needed. But doing BGR2XYZ conversion seems to invert colors, while RGB2XYZ preserve them. Examples:
images
Or is it necessary to use C++ OpenCV?
No, there is no necessity whatsoever. You can use any interface you like and you think you are good with it (OpenCV offers C, C++, Python interfaces).
For your problem about imwrite() and imread() :
For color images the order channel is normally Blue, Green, Red , this
is what imshow() , imread() and imwrite() expect
Quoted from there
I'm trying to set the camera parameters using the following codeand it is not working at all.
using namespace cv;
int main(int argc,char *argv[])
{
VideoCapture cap(0); // open the default camera
if(!cap.isOpened()) // check if we succeeded
return -1;
bool value = cap.set(CV_CAP_PROP_FRAME_WIDTH,10);
for(;;)
{
Mat frame;
cap >> frame; // get a new frame from camera
imshow("frame", frame);
unsigned char *dad = (unsigned char*)frame.data;
if(waitKey(30) >= 0) break;
}
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;
}
OpenCV tries to set this size directly in the camera, so it doesn't need to resize the frame.
The problem with this approach is that if your camera doesn't support this size natively, OpenCV will fail setting the value, leaving you the task to resize the frame after it is retrieved.
cap.set() seems to return the success of the function, I suggest you check it.
I recommend taking a look at another thread: how to change the capture resolution in OpenCV.
from opencv is using directshow for video capture. however, your camera only support a few of the resolution settings like, 480*320, 640*480, 720p, 1080p. if you set something else, it would not work at all.
if you want to check what kinds of resolution your camera support.
download the graphedt and check in the capture pin property.
the above code is not using for changing the camera parameters. I think it usu full for showing the video in your machine. May be this link is useful to you http://opencv.willowgarage.com/wiki/CameraCapture
I am using OpenCV and trying to apply a Gaussian Blur to an incoming video stream. I basically use cvQueryFrame to remove a frame, blur it and display the frame onto the screen. The thing is though, my video gets stuck on the first frame after I apply the blur....anyone know why? its basically showing one frame instead of a video. The second I remove the blur it starts outputting video again.
#include "cv.h"
#include "highgui.h"
#include "cvaux.h"
#include <iostream>
using namespace std;
int main()
{
//declare initial data
IplImage *grabCapture= 0; //used for inital video frame capture
IplImage *process =0; //used for processing
IplImage *output=0; //displays final output
CvCapture* vidStream= cvCaptureFromCAM(0);
cvNamedWindow ("Output", CV_WINDOW_AUTOSIZE);
int createimage=1;
while (1)
{
grabCapture= cvQueryFrame (vidStream);
if (createimage==1)
{
process= cvCreateImage (cvGetSize(grabCapture), IPL_DEPTH_16U, 3);
createimage=0;
}
*process=*grabCapture;
cvSmooth (process,process,CV_GAUSSIAN,7,7); //line that makes it display frame instead of video
cvShowImage("Output",process);
}
//clean up data
cvReleaseImage (&grabCapture);
cvReleaseImage (&process);
cvReleaseImage (&output);
cvReleaseCapture (&vidStream);
return 0;
}
You are missing a call to cvWaitKey. This is the only way to tell OpenCV to process events and thus prevent the GUI from freezing.
Try adding this line:
cvWaitKey(10);
after cvShowImage("Output",process);.
Edit: here is the documentation for cvWaitKey