Unable to read video file in OpenCV - c++

I am trying to capture a video and store it in a file and then read the same video file. I am able to write it but not able to read the same file. On pressing escape, the program is supposed to quit the webcam and play the recorded video but displays the following error instead:
mpeg1video # 0x2a16f40] ac-tex damaged at 14 28
[mpeg1video # 0x2a16f40] Warning MVs not available
OpenCV Error: Bad flag (parameter or structure field) (Unrecognized or unsupported array type) in cvGetMat, file /home/ujjwal/Downloads/OpenCV-2.4.0/modules/core/src/array.cpp, line 2482
terminate called after throwing an instance of 'cv::Exception'
what(): /home/ujjwal/Downloads/OpenCV-2.4.0/modules/core/src/array.cpp:2482: error: (-206) Unrecognized or unsupported array type in function cvGetMat
The code is:
#include <sstream>
#include <string>
#include <iostream>
#include <opencv/highgui.h>
#include <opencv/cv.h>
using namespace cv;
int main(int argc, char* argv[])
{
Mat inputVideo;
Mat frame;
Mat HSV;
Mat tracking;
char checkKey;
VideoCapture capture;
capture.open(0);
capture.set(CV_CAP_PROP_FRAME_WIDTH, 640);
capture.set(CV_CAP_PROP_FRAME_HEIGHT,480);
VideoWriter writer("OutputFile.mpeg", CV_FOURCC('P','I','M','1'), 50, Size(640, 480));
while(1){
capture.read(inputVideo);
imshow("Original Video",inputVideo);
writer.write(inputVideo);
checkKey = cvWaitKey(20);
if(checkKey == 27)
break;
}
capture.open("OutputFile.mpeg");
capture.set(CV_CAP_PROP_FRAME_WIDTH, 640);
capture.set(CV_CAP_PROP_FRAME_HEIGHT,480);
while(1){
capture.read(inputVideo);
imshow("Tracking Video", inputVideo);
}
return 0;
}
Can someone please help me? Thanks!

You need to correct several things to make it work:
You have to create the window before showing images in the window.
You have to close the writer to finish writing before open it later.
You need to add cvWaitKey(20) for the second image showing (check out here for why this is essential).
The whole fixed code is as follows:
#include <sstream>
#include <string>
#include <iostream>
#include <opencv/highgui.h>
#include <opencv/cv.h>
using namespace cv;
int main(int argc, char* argv[])
{
Mat inputVideo;
Mat frame;
Mat HSV;
Mat tracking;
char checkKey;
VideoCapture capture;
capture.open(0);
capture.set(CV_CAP_PROP_FRAME_WIDTH, 640);
capture.set(CV_CAP_PROP_FRAME_HEIGHT,480);
VideoWriter writer("OutputFile.mpeg", CV_FOURCC('P','I','M','1'), 50, Size(640, 480));
namedWindow("Original Video", WINDOW_AUTOSIZE );
while(1){
capture.read(inputVideo);
imshow("Original Video",inputVideo);
writer.write(inputVideo);
checkKey = cvWaitKey(20);
if(checkKey == 27)
break;
}
writer.release();
capture.open("OutputFile.mpeg");
capture.set(CV_CAP_PROP_FRAME_WIDTH, 640);
capture.set(CV_CAP_PROP_FRAME_HEIGHT,480);
namedWindow("Tracking Video", WINDOW_AUTOSIZE );
while(1){
capture.read(inputVideo);
if (!inputVideo.empty())
{
imshow("Tracking Video", inputVideo);
checkKey = cvWaitKey(20);
}
else
break;
}
return 0;
}

Related

How to get frames from webcam using OpenCV C++

I'm trying to get frames form a Logitech C920 camera
and show them.
The camera seems to be working but nothing is being shown on the display window.
I tried to configure all the camera settings but nothing.
What am I missing???
#include "pch.h"
#include <iostream>
#include "opencv2\imgcodecs.hpp"
#include "opencv2\core.hpp"
#include "opencv2\highgui.hpp"
#include "opencv2\videoio.hpp"
using namespace std;
using namespace cv;
int main()
{
VideoCapture camera(CAP_ANY);
Mat frame;
namedWindow("x", WINDOW_AUTOSIZE);
camera.set(CAP_PROP_FOURCC, VideoWriter::fourcc('M', 'J', 'P', 'G'));
camera.set(CAP_PROP_FRAME_WIDTH, 1920);
camera.set(CAP_PROP_FRAME_HEIGHT, 1080);
while (1)
{
camera.read(frame);
imshow("x", frame);
}
waitKey(0);
return 0;
}
You have to put waitKey(int delay) after each frame. Your while loop should look like this:
while (1)
{
camera.read(frame);
imshow("x", frame);
waitKey(1);
}

Visual Studio 2010 console window closes immediately using opencv

I'm developing a project with visual studio 2010 and opencv. Here is my problem: i acquire a video from webcam, analize it, do some operation on it and then i show the result in another window (Object Tracking). The code is ok, no compiling errors but as soon as i start the program the console windows it closes immediately and i cannot see both the original and the modified video. If i debug the code i can see the webcam works and acquire images but obviously i ned to do this in real time. Any suggestion?
Can you give any code?
Are you write and compile any video player program like this?
#include "opencv2/opencv.hpp"
using namespace cv;
int main(int, char**)
{
VideoCapture cap(0); // open the default camera
//Video Capture cap(path_to_video); // open the video file
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;
}
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;
}
Try this:
#include <iostream>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;
using namespace std;
int main() {
VideoCapture cap(0);
while (true)
{
Mat imgOriginal;
Mat imgHSV;
bool bSuccess = cap.read(imgOriginal);
cvtColor(imgOriginal, imgHSV, COLOR_BGR2HSV); //Convert the captured frame from BGR to HSV
imshow("Thresholded Image", imgHSV);
imshow("Original", imgOriginal);
waitKey(33);
}
return 0;
}

OpenCV: record footage in one window and Display the same video in 2nd window but with contours only

I want to capture a video and display it on one window and have second window in which contours are displayed simultaneous. I am struggling with how to have the processed video displayed in the second window. Please analyze my code and suggest a solution or indicate where am going wrong maybe give me some directions to an online tutorial or sources. Thanks.
#include "iostream"
#include<opencv\cv.h>
#include<opencv\highgui.h>
#include<opencv\ml.h>
#include<opencv\cxcore.h>
#include <iostream>
#include <vector>
#include <string>
#include <opencv2/core/core.hpp> // Basic OpenCV structures (cv::Mat)
#include <opencv2/highgui/highgui.hpp> // Video write
using namespace cv;
using namespace std;
Mat image; Mat image_gray; Mat image_gray2; Mat threshold_output;
Mat frame;
int thresh=100, max_thresh=255;
int main(int argc, char** argv) {
//Capture Video
VideoCapture capCam(1);
if (!capCam.isOpened()){
cout<<"ERROR: Failed to Initialize Camera"<<endl;
return 1;
}
else{
cout<<"Camera Initialized"<<endl;
}
//Create Window
char* ImputFootage = "Source";
namedWindow(ImputFootage, CV_WINDOW_AUTOSIZE);
imshow(ImputFootage, frame);
char* OutputFootage = "Processed";
namedWindow(OutputFootage, CV_WINDOW_AUTOSIZE);
imshow(OutputFootage, frame);
while(1){
capCam>> frame;
imshow("Source", frame);
return(1);
if(capCam.read(ImputFootage)){
//Convert Image to gray & blur it
cvtColor( image,
image_gray,
CV_BGR2GRAY );
blur( image_gray,
image_gray2,
Size(3,3) );
//Threshold Gray&Blur Image
threshold(image_gray2,
threshold_output,
thresh,
max_thresh,
THRESH_BINARY);
//2D Container
vector<vector<Point>> contours;
//Fnd Countours Points, (Imput Image, Storage, Mode1, Mode2, Offset??)
findContours(threshold_output,
contours, // a vector of contours
CV_RETR_EXTERNAL,// retrieve the external contours
CV_CHAIN_APPROX_NONE,
Point(0, 0)); // all pixels of each contours
// Draw black contours on a white image
Mat result(threshold_output.size(),CV_8U,Scalar(255));
drawContours(result,contours,
-1, // draw all contours
Scalar(0), // in black
2); // with a thickness of 2
}
}
char CheckForEscKey = waitKey(10);
return 1;
}
You should call imshow("Processed", result); after calling drawContours
You were trying to show frames even before they were captured with camera. Compiler was not giving you error because Mat were declared ,but they were without value (null), Moreover you were trying to display Mat image, but what you capture from camera is Mat frame. Also, you lack exit (esc sequence, and your wait key was OUT of camera loop.
Anyway, here is your code (rewritten), I hope this is what you wanted.
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <cstdio>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
using namespace cv;
Mat image;
Mat image_gray;
Mat image_gray2;
Mat threshold_output;
Mat frame;
int thresh = 100, max_thresh = 255;
int main(int argc, char** argv)
{
//Capture Video
VideoCapture capCam(0);
if (!capCam.isOpened())
{
cout << "ERROR: Failed to Initialize Camera" << endl;
return 1;
}
else
{
cout << "Camera Initialized" << endl;
}
//Create Window
char* ImputFootage = "Source";
namedWindow(ImputFootage, CV_WINDOW_AUTOSIZE);
char* OutputFootage = "Processed";
namedWindow(OutputFootage, CV_WINDOW_AUTOSIZE);
while (1)
{
capCam >> frame;
imshow(ImputFootage, frame);
if (capCam.read(frame))
{
//Convert Image to gray & blur it
cvtColor(frame, image_gray, CV_BGR2GRAY);
blur(image_gray, image_gray2, Size(3, 3));
//Threshold Gray&Blur Image
threshold(image_gray2, threshold_output, thresh, max_thresh, THRESH_BINARY);
//2D Container
vector<vector<Point> > contours;
//Fnd Countours Points, (Imput Image, Storage, Mode1, Mode2, Offset??)
findContours(threshold_output, contours, // a vector of contours
CV_RETR_EXTERNAL, // retrieve the external contours
CV_CHAIN_APPROX_NONE, Point(0, 0)); // all pixels of each contours
// Draw black contours on a white image
Mat result(threshold_output.size(), CV_8U, Scalar(255));
drawContours(result, contours, -1, // draw all contours
Scalar(0), // in black
2); // with a thickness of 2
imshow(OutputFootage, result);
char CheckForEscKey = waitKey(10);
//If the key pressed by user is Esc(ASCII is 27) then break out of the loop
if (CheckForEscKey == 27)
{
break;
}
}
}
return 0;
}

How can I convert a cv::Mat to a gray scale in OpenCv?

How can I convert a cv::Mat to a gray scale?
I am trying to run drawKeyPoints func from opencv, however I have been getting an Assertion Filed error. My guess is that it needs to receive a gray scale image rather than a color image in the parameter.
void SurfDetector(cv::Mat img){
vector<cv::KeyPoint> keypoints;
cv::Mat featureImage;
cv::drawKeypoints(img, keypoints, featureImage, cv::Scalar(255,255,255) ,cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
cv::namedWindow("Picture");
cv::imshow("Picture", featureImage);
}
Using the C++ API, the function name has slightly changed and it writes now:
#include <opencv2/imgproc/imgproc.hpp>
cv::Mat greyMat, colorMat;
cv::cvtColor(colorMat, greyMat, CV_BGR2GRAY);
The main difficulties are that the function is in the imgproc module (not in the core), and by default cv::Mat are in the Blue Green Red (BGR) order instead of the more common RGB.
OpenCV 3
Starting with OpenCV 3.0, there is yet another convention.
Conversion codes are embedded in the namespace cv:: and are prefixed with COLOR.
So, the example becomes then:
#include <opencv2/imgproc/imgproc.hpp>
cv::Mat greyMat, colorMat;
cv::cvtColor(colorMat, greyMat, cv::COLOR_BGR2GRAY);
As far as I have seen, the included file path hasn't changed (this is not a typo).
May be helpful for late comers.
#include "stdafx.h"
#include "cv.h"
#include "highgui.h"
using namespace cv;
using namespace std;
int main(int argc, char *argv[])
{
if (argc != 2) {
cout << "Usage: display_Image ImageToLoadandDisplay" << endl;
return -1;
}else{
Mat image;
Mat grayImage;
image = imread(argv[1], IMREAD_COLOR);
if (!image.data) {
cout << "Could not open the image file" << endl;
return -1;
}
else {
int height = image.rows;
int width = image.cols;
cvtColor(image, grayImage, CV_BGR2GRAY);
namedWindow("Display window", WINDOW_AUTOSIZE);
imshow("Display window", image);
namedWindow("Gray Image", WINDOW_AUTOSIZE);
imshow("Gray Image", grayImage);
cvWaitKey(0);
image.release();
grayImage.release();
return 0;
}
}
}

opencv cvblob render issue

I just installed cvblob for object detection.
When I tried to run the program, the image would not show up and it gives me an error:
"VIDIOC_QUERYMENU: Invalid argument"
Here is the code.
#include "highgui.h"
#include "cv.h"
#include "cvaux.h"
#include "iostream"
#include <stdio.h>
#include <ctype.h>
#include <cvblob.h>
using namespace cv;
using namespace std;
using namespace cvb;
int main(int argc, char** argv) {
CvTracks tracks;
namedWindow("frame", CV_WINDOW_AUTOSIZE);
cvMoveWindow("frame", 50, 100);
CvCapture* capture;
IplImage* frame = 0;
// frame = cvLoadImage("fruits.jpg", 1);
capture = cvCreateCameraCapture( 1 ); //capture frames from cam on index 0: /dev/video0/
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 240);
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 320);
frame = cvQueryFrame(capture);
while(capture) {
IplImage *gray = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 1);
cvCvtColor(frame, gray, CV_BGR2GRAY);
cvThreshold(gray, gray, 150, 255, CV_THRESH_BINARY);
IplImage *labelImg=cvCreateImage(cvGetSize(gray), IPL_DEPTH_LABEL, 1);
CvBlobs blobs;
unsigned int result=cvLabel(gray, labelImg, blobs);
cvFilterByArea(blobs, 500, 1000000);
cvRenderBlobs(labelImg, blobs, frame, frame, CV_BLOB_RENDER_BOUNDING_BOX);
cvUpdateTracks(blobs, tracks, 200., 5);
cvRenderTracks(tracks, frame, frame, CV_TRACK_RENDER_ID|CV_TRACK_RENDER_BOUNDING_BOX);
// for (CvBlobs::const_iterator it=blobs.begin(); it!=blobs.end(); ++it) {
// cout << "Blob #" << it->second->label << ": Area=" << it->second->area << ", Centroid=(" << it->second->centroid.x << ", " << it->second->centroid.y << ")" << endl;
// }
cvShowImage("frame", frame);
frame = cvQueryFrame(capture);
}
}
If I uncomment the commented part, the blob information will be shown.
Can anyone help me find out why the image is not showing?
Thanks,
Milo
That error is coming from the video capture system, not cvBlob.
I see a few issues:
You must test capture after creating it to make sure you have successfully opened a camera.
Your while loop should be testing frame, not capture to make sure you've successfully received a frame of video.
Are you sure you have a camera at index 1?
Try this simplified version and see if it works. Note that I'm testing capture, looping while frame is not 0, and opening the camera at index 0. This works on my system.
int main(int argc, char** argv) {
namedWindow("frame", CV_WINDOW_AUTOSIZE);
cvMoveWindow("frame", 50, 100);
CvCapture* capture;
IplImage* frame = 0;
capture = cvCreateCameraCapture( 0 ); //capture frames from cam on index 0: /dev/video0/
if (!capture) {
return -1;
}
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 240);
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 320);
frame = cvQueryFrame(capture);
while(frame) {
cvShowImage("frame", frame);
frame = cvQueryFrame(capture);
}
}
If this works for you, try changing the cvCreateCameraCapture argument to 1. Then try adding back your code a little at a time.