Displaying Images from file using OpenCV VideoCapture, and C++ vectors - c++

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.

Related

"Cannot open file 'opencv_calib3d320d.lib'" Error

I'm trying to get OpenCV to work with visual studio. After following the official OpenCV installation instructions down to the letter, I tried building a sample program. I got the error in the title. The odd part is that the namespace 'cv' works fine - there are no errors for the rest of the code. Here's the sample program I tried to build:
#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
if (argc != 2)
{
cout << " Usage: display_image ImageToLoadAndDisplay" << endl;
return -1;
}
Mat image;
image = imread(argv[1], IMREAD_COLOR); // Read the file
if (image.empty()) // Check for invalid input
{
cout << "Could not open or find the image" << std::endl;
return -1;
}
namedWindow("Display window", WINDOW_AUTOSIZE); // Create a window for display.
imshow("Display window", image); // Show our image inside it.
waitKey(0); // Wait for a keystroke in the window
return 0;
}
In addition, here's my list of additional dependencies that I put in the project properties:
opencv_calib3d320d.lib
opencv_core320d.lib
opencv_features2d320d.lib
opencv_flann320d.lib
opencv_highgui320d.lib
opencv_imgcodecs320d.lib
opencv_imgproc320d.lib
opencv_ml320d.lib
opencv_objdetect320d.lib
opencv_photo320d.lib
opencv_shape320d.lib
opencv_stitching320d.lib
opencv_superres320d.lib
opencv_ts320d.lib
opencv_video320d.lib
opencv_videoio320d.lib
opencv_videostab320d.lib
I badly need this work :( . It should be noted that I have quadruple-checked the instructions to make this work, so I don't think it has to do with the header files or something.

Taking multiple pictures in opencv

This seems fairly straightforward, but for the life of me, I cannot figure out why this will not work. I have similar code that writes an image everytime it reads an image, and that works fine saving the last image seen. I am seriously puzzled as to why this is saving the same image to both img0 and img1. If you guys could shed some light, that would be amazing! Thanks so much for taking the time to read this.
#include "highgui.hpp"
#include "imgproc.hpp"
#include "opencv.hpp"
#include <iostream>
#include <string>
#include <unistd.h>
using namespace std;
using namespace cv;
int main(){
VideoCapture stream(0);
if(!stream.isOpened()){
cout << "No camera :(\n";
}
stream.set(CV_CAP_PROP_FRAME_WIDTH, 640);
stream.set(CV_CAP_PROP_FRAME_HEIGHT, 480);
int img_num = 0;
int num_pics;
cout << "How many images do you want to take?\n";
cin >> num_pics;
Mat image;
while(img_num < num_pics){
cout << "Picture in...\n";
cout << "3...\n";
sleep(1);
cout << "2...\n";
sleep(1);
cout << "1...\n";
sleep(1);
stream.read(image);
imshow("pic",image);
imwrite(format("img_%d.jpg",img_num),image);
waitKey(3000);
img_num += 1;
}
return 0;
}
Edit to add simple code for saving every frame captured (into the same file, so should ultimately be the last image seen):
#include "/home/sarah/opencv-2.4.9/modules/highgui/include/opencv2/highgui/highgui.hpp"
#include "/home/sarah/opencv-2.4.9/modules/imgproc/include/opencv2/imgproc/imgproc.hpp"
#include "/home/sarah/opencv-2.4.9/include/opencv2/opencv.hpp"
#include <iostream>
using namespace std;
using namespace cv;
int main(){
VideoCapture stream(0);
//stream.set(CV_CAP_PROP_FPS,1);
if(!stream.isOpened()){
cout << "No camera :(\n";
}
cout << "After\n";
stream.set(CV_CAP_PROP_FRAME_WIDTH, 640);
stream.set(CV_CAP_PROP_FRAME_HEIGHT, 480);
Mat cameraFrame;
while(1){
stream.read(cameraFrame);
imshow("camera",cameraFrame);
imwrite("img.jpg",cameraFrame);
if(waitKey(30) == 13){
break;
}
}
return 0;
}
here's the culprit:
imwrite(filename,image);
atm, it will save any image to the same filename(thus overwriting any previos ones). what you want is probably more similar to:
imwrite( format("img_%d.jpg",img_num) ,image );

OpenCV: Debug Assertion Fail (pHead->nBlockUse)

My program is getting an input from the webcam and outputting the Gaussian Pyramid in real time. The program runs fine, but when I exit (by pressing a key to trigger the waitKey()), I get an error:
Debug Assertion Failed!
_BLOCK_TYPE_IS_VALID(pHead->nBlockUse))
Line 52: dbgdel.cpp
I suspect this is related to the buildPyramid() function I am using to create the Gaussian Pyramid. The output requires an Array of Mat. The number of mats that are output depends on the number of levels, so the output needs to be a pointer. I don't know if the problem is with initializing the variable or if it doesn't get deleted at the end. I could also just be completely off about the cause.
I am making the Array of Arrays with this:
std::vector<cv::Mat> GPyr;
and I am making the Gaussian Pyramid with this:
buildPyramid(imgMatNew, GPyr, levels, BORDER_DEFAULT);
Any ideas for what is causing the error?
Full Source:
#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include "opencv2/core/core.hpp"
#include "opencv2/flann/miniflann.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/photo/photo.hpp"
#include "opencv2/video/video.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/ml/ml.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/contrib/contrib.hpp"
#include "opencv2/core/core_c.h"
#include "opencv2/highgui/highgui_c.h"
#include "opencv2/imgproc/imgproc_c.h"
#include "opencv2\objdetect\objdetect.hpp"
using namespace cv;
using namespace std;
int main()
{
CvCapture* capture = 0;
// imgMatNew, imgMatOut were used to grab the current frame
Mat frame, frameCopy, image, imgMatNew, imgMatOut;
std::vector<cv::Mat> GPyr;
int levels = 4;
capture = cvCaptureFromCAM(CV_CAP_ANY); //0=default, -1=any camera, 1..99=your camera
if (!capture)
{
cout << "No camera detected" << endl;
}
//cvNamedWindow("result", CV_WINDOW_AUTOSIZE);
namedWindow("GPyrOut", WINDOW_AUTOSIZE);
namedWindow("imageNew", WINDOW_AUTOSIZE);
if (capture)
{
cout << "In capture ..." << endl;
for (;;)
{
// capture frame from video camera
IplImage* iplImg = cvQueryFrame(capture);
frame = iplImg;
// convert ilpImg into Mat format for easy processing
imgMatNew = cvarrToMat(iplImg, 1);
// Start Image Processing Here
buildPyramid(imgMatNew, GPyr, levels, BORDER_DEFAULT);
// Show Window
imshow("GPyrOut", GPyr[levels]); //show G Pyr, at a certain level, mex index = levels
imshow("imageNew", imgMatNew); //show window
if (waitKey(10) >= 0)
break;
}
// waitKey(0);
}
cvReleaseCapture(&capture);
return 0;
}
so, there's 2 things wrong here.
a) you must not use opencv's outdated c-api, mixing c and c++ calls is the straight road to hell.
b) c++ starts indexing at 0, and the last valid index is size-1, so for 4 levels, levels[4] is out of bounds. please run a debug build to get proper exceptions in this case !
here's the corrected code:
Mat frame, frameCopy, image, imgMatNew, imgMatOut;
std::vector<cv::Mat> GPyr;
int levels = 4;
VideoCapture capture(0);
if (!capture.isOpened())
{
cout << "No camera detected" << endl;
return -1;
}
//cvNamedWindow("result", CV_WINDOW_AUTOSIZE);
namedWindow("GPyrOut", WINDOW_AUTOSIZE);
namedWindow("imageNew", WINDOW_AUTOSIZE);
cout << "In capture ..." << endl;
for (;;)
{
// capture frame from video camera
capture.read(frame);
// Start Image Processing Here
buildPyramid(frame, GPyr, levels, BORDER_DEFAULT);
// Show Window
imshow("GPyrOut", GPyr[levels-1]); //show last level
imshow("imageNew", frame); //show window
if (waitKey(10) >= 0)
break;
}

create a video from image sequence in open cv

I am working on open cv with c++.I have around 30 frames of images .I need to combine these frames to obtain a video.Can anyone suggest me method?Is it like reading each frames and storing in videowriter?Please suggest
I would suggest using ffmpeg. You can do it programmatically or using the command line. An example of doing this on the command line is:
ffmpeg -start_number n -i image%d.jpg -vcodec mpeg4 test.avi
Where n is the first image number.
Tutorial how to do Videooutput
You will be asked for the codec you want to use. It's a bit complicated, but there are already many codec related questions on SO.
This code should work (not tested):
#include <iostream> // for standard I/O
#include <string> // for strings
#include <vector>
#include <opencv2/core/core.hpp> // Basic OpenCV structures (cv::Mat)
#include <opencv2/highgui/highgui.hpp> // Video write
using namespace std;
using namespace cv;
int main(int argc, char *argv[], char *window_name){
vector<Mat> images; //fill this somehow
Size S = vector[0].getSize();
VideoWriter outputVideo; // Open the output
outputVideo.open(NAME , ex=-1, 30), S, true); //30 for 30 fps
if (!outputVideo.isOpened()){
cout << "Could not open the output video for write: "<< endl;
return -1;
}
for(int i=0; i<images.size(); i++){
outputVideo << res;
}
cout << "Finished writing" << endl;
return 0;
}

How to get the average output of two consecutive frames?

I am working on the following code
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
int main()
{
VideoCapture *camera = new VideoCapture();
camera->open(0);
if(!camera->isOpened())
{
cout << "No Camera" << endl;
return -1;
}
Mat image,blur,image2;
namedWindow("Video");
while(true)
{
*camera>>image;
*camera>>image2;
//Show default image
imshow("Video",image);
if(waitKey(30)>=0)
{
break;
}
}
return 0;
}
I got to know I can reduce the video of real time web camera output by 70% if I manage to get the average output of two consecutive frames. I got the two consecutive frames using
*camera>>image;
*camera>>image2;
Now, how can I get the average of this and display it?
For cv::Mat, you can do it like this:
Mat img_mean=0.5*image+0.5*image2;
imshow("Average",img_mean);