I am trying to read data from an industrial camera using the V4l linux driver and C++. I would like to display the result using the OpenCV. I read the buffer, create an Mat object, which actually contains values in range 0...255.
The problem seems to be the imshow() call. When commenting this line out, an actual window without an image is displayed. Once uncommented no window is diplayed and also no output in terminal after this line is shown. I am not able to find a solution on my own, all examples I found look the same as my code to me.
Here is the code:
#include <fcntl.h>
#include "opencv/cv.h"
#include "opencv/highgui.h"
#include <libv4l2.h>
#include <libv4l1.h>
#include <linux/videodev2.h>
#include <sys/ioctl.h>
#define BUFFERSIZE 357120 // 744 * 480
using namespace cv;
using namespace std;
int main(int argc, char **argv) {
int cameraHandle, i;
unsigned char pictureBuffer[BUFFERSIZE];
char cameraDevice[] = "/dev/video0";
struct v4l2_control V4L2_control;
/* open camera device */
if (( cameraHandle = v4l1_open(cameraDevice, O_RDONLY)) == -1 ){
printf("Unable to open the camera");
return -1;
}
// disable auto exposure
V4L2_control.id = V4L2_CID_EXPOSURE_AUTO;
V4L2_control.value = V4L2_EXPOSURE_SHUTTER_PRIORITY;
ioctl(cameraHandle, VIDIOC_S_CTRL, &V4L2_control);
// set exposure time
V4L2_control.id = V4L2_CID_EXPOSURE_ABSOLUTE;
V4L2_control.value = 2;
ioctl(cameraHandle, VIDIOC_S_CTRL, &V4L2_control);
// get 5 pictures to warm up the camera
for (i = 0; i <= 5; i++){
v4l1_read(cameraHandle, pictureBuffer, BUFFERSIZE);
}
// show pictures
Mat mat = Mat(744, 480, CV_8UC3, (void*)pictureBuffer);
cout << "M = " << endl << " " << mat << endl << endl; // display the image data
namedWindow("imagetest", CV_WINDOW_AUTOSIZE );
imshow("imagetest", mat);
waitKey(30);
cout << "test output" << endl;
//clenup
v4l1_close(cameraHandle);
destroyWindow("imagetest");
return 0;
}
EDIT:
Well, after running the code in terminal instead of ecipse I saw a segmentation fault Even commenting everything behind the
cout << "M = " << endl << " " << mat << endl << endl;
line gives me this error.
Solved. The problem lied in the wrong file format. CV_8UC1 or CV_8U instead of CV_8UC3 brought and an output. The difference between those formats is described here: In OpenCV, what's the difference between CV_8U and CV_8UC1?
Related
I downloaded a project which allows to get frames from Pi camera module with OpenCV. When I try to run the downloaded code, It works without a problem. I just want to apply simple trheshold operation on frames but I got the error shown below.
I check the frames' type and channel. image.channels() returns 1 and image.type() returns 0. I can't see any reason for the threshold operation error.
What is the problem here?
The error:
The Code:
#include "cap.h"
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
int main() {
namedWindow("Video");
// Create capture object, similar to VideoCapture
// PiCapture(width, height, color_flag);
// color_flag = true => color images are captured,
// color_flag = false => greyscale images are captured
PiCapture cap(320, 240, false);
Mat image,binary;
double time = 0;
unsigned int frames = 0;
cout << "Press 'q' to quit" << endl;
while(char(waitKey(1)) != 'q') {
double t0 = getTickCount();
image = cap.grab();
std::cout<<image.channels()<< endl;//check for channel
cout<<image.type()<< endl;//check for type
threshold(image,binary,150,255,THRESH_BINARY);//threshold operation
frames++;
if(!image.empty()) imshow("Hello", image);
else cout << "Frame dropped" << endl;
time += (getTickCount() - t0) / getTickFrequency();
cout << frames / time << " fps" << endl;
}
return 0;
}
Assertion m.ndims >= 2 is to check that the matrix in question is a valid two dimensional image. While you have a conditional to show the image only if it's not empty. But the assertion must be failing before the program reaches that conditional. So you shouldn't be seeing any image window pop up.
I am trying to write a program that captures video from a webcam using this code:
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
Mat frame;
VideoCapture cap(1);
char key;
String outputName = "output.avi";
VideoWriter outputVideo;
Size size = Size(cap.get(CV_CAP_PROP_FRAME_WIDTH), cap.get(CV_CAP_PROP_FRAME_HEIGHT));
outputVideo.open(outputName, CV_FOURCC('D', 'I', 'V', 'X'), cap.get(CV_CAP_PROP_FPS), size, true);
if (!outputVideo.isOpened())
{
cout << "Could not open the output video for write: " << outputName << endl;
return -1;
}
cout << "size " << size.width << " x " << size.height << endl;
namedWindow("Display window", WINDOW_AUTOSIZE); // Create a window for display.
cap.set(CV_CAP_PROP_EXPOSURE, -8);
while (true){
bool success = cap.read(frame);
if (!success){
cout << "Cannot read frame from file" << endl;
return -2;
}
outputVideo.write(frame);
imshow("Display window", frame);
key = waitKey(1);
if (key == ' '){
cout << "Video ended due to key stroke" << endl;
return 1;
}
}
return 0;
}
The program doesn't seem to be able to open outputVideo since it always returns -1. I thought that I might not have the codec divx installed, but I have installed it from k-lite codec pack and divx and it still does not work.
Could anybody please tell me how to install codecs such that opencv recognizes them?
I am using OpenCV 2.4.10 on Windows 7 with Visual studio 2013.
this code is suppose to display a webcam feed and when you press the s key save the image to a file in the path selected. It is not working. imwrite crashes the program with this error code.
Unspecified error (could not find a writer for the specified extension) in cv::imwrite_, file ........\opencv\modules\highgui\src\loadsave.cpp, line 275
here is my code it crashes at line 99 imwrite(buffer, imgh); if you can think of any way I can make it save this image I'd be very grateful.
#include <opencv/cv.h>
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
#include <cstdlib>
#include <windows.h>
using namespace cv;
using namespace std;
double Brightness;
double Contrast;
double Saturation;
double Gain;
double Exposure;
char buffer[100];
int i = 0;
int c = 1;
int main(int argc, char* argv[])
{
VideoCapture cap(0); // open the video camera no. 0
if (!cap.isOpened()){
cout << "Cannot open the video cam" << endl;
return -1;
}
double dWidth = cap.get(CV_CAP_PROP_FRAME_WIDTH); //get the width of frames of the video
double dHeight = cap.get(CV_CAP_PROP_FRAME_HEIGHT); //get the height of frames of the video
cap.set(CV_CAP_PROP_AUTO_EXPOSURE,0.0 ); // turn off auto exposure
// Get fixed Cam Properties
Brightness = cap.get(CV_CAP_PROP_BRIGHTNESS);
Contrast = cap.get(CV_CAP_PROP_CONTRAST );
Saturation = cap.get(CV_CAP_PROP_SATURATION);
Gain = cap.get(CV_CAP_PROP_GAIN);
Exposure = cap.get(CV_CAP_PROP_AUTO_EXPOSURE );
// Display Them
cout<<"===================================="<<endl;
cout<<"Default Brightness -------> "<<Brightness<<endl;
cout<<"Default Contrast----------> "<<Contrast<<endl;
cout<<"Default Saturation--------> "<<Saturation<<endl;
cout<<"Default Gain--------------> "<<Gain<<endl;
cout<<"Default exp --------------> "<<Exposure<<endl;
cout<<"===================================="<<endl;
// console adjustment for testing
cout << "\nFrame size : " << dWidth << " x " << dHeight << endl;
int bright;
cout<< "\nbrightness level -100 - 100 " << endl;
cin>> bright;
cout <<"\nbrightness level: " <<bright <<endl;
namedWindow("Video"); //create a window called "MyVideo"
for(;;)
{
Mat frame;
cap >> frame;
int x = 200;
Sleep(x);
Mat imgH = frame + Scalar(0.0722*bright, 0.7152*bright, 0.7152*bright); // convert BGR to Luminance set to color space
char ch =waitKey(30);
sprintf(buffer, "C:\\pics\\image%d.jpg" ,c);
cvWaitKey(10);
//save image frmae
if (ch == 's'){
cvWaitKey(10);
cout<< "new frame in window " <<buffer<<endl;
imshow("Video", imgH );
imwrite(buffer, imgH); // <-- this is not working die in a hole!!!
c++ ;
}
// Camera Properties
if (ch == 'p'){
cap.set(CV_CAP_PROP_SETTINGS , 1 );
}
//Exit
if (ch == 27){
cout << "esc key is pressed by user" << endl;
return 0;
}
}
return 0;
}
It works fine. The issue was in the version of visual studio I was using. I switched to 2010 and linked the libraries dynamically and the code works.
how to install opencv and link libraries in visual studio 2010
https://www.youtube.com/watch?v=cgo0UitHfp8&list=PLvwB65U8V0HHCEyW2UTyOJym5FsdqfbHQ
thanks for looking at it.
I am reading in an image sequence from a file using an OpenCV VidoeCapture - I believe I am doing this part correctly - and then putting them in a c++ vector, for processing at a later point.
To test this, I wrote the following that would read in images, put them in a vector, and then display those images from the vector one by one. However, when I run this, no images appear.
What's wrong?
I am using a raspberry pi, I don't know if that makes any difference.
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <vector>
#include <iostream>
using namespace cv;
using namespace std;
vector<Mat> imageQueue;
int main(int argc, char** argv)
{
string arg = ("/home/pi/pictures/ceilingSequence/%02d.jpg");
VidoeCapture sequence(arg);
if(!sequence.isOpened()) {
cout << "Failed to open image sequence" << endl;
return -1;
}
Mat image;
for(;;)
{
sequence >> image;
if(image.empty()) {
cout << "End of sequence" << endl;
break;
}
imageQueue.push_back(image);
}
for(int i = 0; i < 10; i++)
{
//display 10 images
Mat readImage;
readImage = imageQueue[i];
namedWindow("Current Image", CV_WINDOW_AUTOSIZE);
imshow("Current Image", readImage);
sleep(2);
}
return 0;
}
please replace the sleep(2) with a waitKey(2000). // assuming you want to wait for 2 seconds
even if you're not interested in keypresses in general, it is needed to update the opencv / highgui graphics loop correctly.
I'm trying to display a video file at 25fps smoothly without any lag. The code below does this, but only achieves about 10fps, taking about 0.1ms to execute. With cvWaitKey(1) I get around 0.03 to 0.04ms, which would be perfect, but the named window just stays grey and doesn't show the video!
Is this because cvShowImage() is too slow? Is there any other way to speed up the code and output the video smoothly?
See my code below.
Thanks a lot in advance,
Adrian
#include <cv.h>
#include <iostream>
#include <highgui.h>
#include <cxcore.h>
#include <cvaux.h>
#include <sstream>
#include <time.h>
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
CvCapture* vid = 0;
IplImage* input; //Input image
int fps;
int i=0;
clock_t start, end;
/*Creates the GUI to output the processed images*/
cvNamedWindow("Video input", 0);
/*Open input video*/
if (argc!=2)
{
cout << "Please specify an input video." << endl;
return -1;
}
else
{
vid=cvCreateFileCapture(argv[1]);
if (!vid)
{
cout << "Could not extract frame." << endl;
return -1;
}
}
input = cvQueryFrame(vid);
fps = (int)cvGetCaptureProperty(vid, CV_CAP_PROP_FPS);
cout << fps << endl;
cout << "Video found." << endl;
/*Extraction loop */
while (input)
{
start = clock();
cout << flush;
cout << i << "\r";
i++;
/*Show image*/
cvShowImage("Video input", input);
cvWaitKey(2); //Wait is needed or else we see a grey box
input = cvQueryFrame(vid); //Read next frame from video
end = clock();
cout << (double)(end-start)/CLOCKS_PER_SEC << " s" << endl;
};
/*Release the allocated memory for the frames */
cvReleaseImage(&input);
cvDestroyWindow("Video input");
return 1;
}
Have you tried this without all the cout stuff?
The debug build of the Microsoft STL has cout handling which is almost unbelievably slow.
Try calling cvWaitKey with 1000 / fps wanted, in your case :
cvWaitKey(1000/25)
You could try something like:
char key = cvWaitKey(10); //waits 10 milliseconds
if (key == 27) //and if ESC is pressed, get out of the loop
break;