built-in webcam, opencv: sometimes works, sometimes not - c++

I am working on visual studio 2010 C++ and Opencv 2.3.1. Using HP laptop windows 7 32 bit. I really have tried many times to solve this problem but it still happening. My built-in webcam with some codes (some times works and some times not ) and with some other codes it always displays a gray window instead of camera feed?
could anyone help?
Thanks in advance.
For Example The first code sometimes display cam feed and the second one always display gray window
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace std;
int main(int, char**)
{
VideoCapture cap(0); // open the default camera
if (!cap.isOpened()) // check if we succeeded
return -1;
Ptr<BackgroundSubtractor> pMOG = new BackgroundSubtractorMOG2();
Mat fg_mask;
Mat frame;
int count = -1;
for (;;)
{
// Get frame
cap >> frame; // get a new frame from camera
// Update counter
++count;
// Background subtraction
pMOG->operator()(frame, fg_mask);
imshow("frame", frame);
imshow("fg_mask", fg_mask);
// Save foreground mask
string name = "mask_" + std::to_string(static_cast<long long>(count)) + ".png";
imwrite("D:\\SO\\temp\\" + name, fg_mask);
if (waitKey(1) >= 0) break;
}
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;
}
////////////////////////
second code:
// WriteVideo.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char* argv[])
{
VideoCapture cap(0); // open the video camera no. 0
if (!cap.isOpened()) // if not success, exit program
{
cout << "ERROR: Cannot open the video file" << endl;
return -1;
}
namedWindow("MyVideo",CV_WINDOW_AUTOSIZE); //create a window called "MyVideo"
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
cout << "Frame Size = " << dWidth << "x" << dHeight << endl;
Size frameSize(static_cast<int>(dWidth), static_cast<int>(dHeight));
VideoWriter oVideoWriter ("D:/visual outs/mix/WriteVideo.avi", CV_FOURCC('P','I','M','1'), 20, frameSize, true); //initialize the VideoWriter object
if ( !oVideoWriter.isOpened() ) //if not initialize the VideoWriter successfully, exit the program
{
cout << "ERROR: Failed to write the video" << endl;
return -1;
}
while (1)
{
Mat frame;
bool bSuccess = cap.read(frame); // read a new frame from video
if (!bSuccess) //if not success, break loop
{
cout << "ERROR: Cannot read a frame from video file" << endl;
break;
}
oVideoWriter.write(frame); //writer the frame into the file
imshow("MyVideo", frame); //show the frame in "MyVideo" window
if (waitKey(10) == 27) //wait for 'esc' key press for 30ms. If 'esc' key is pressed, break loop
{
cout << "esc key is pressed by user" << endl;
break;
}
}
return 0;
}

Without the actual code, there's nothing we can really do in order to pinpoint the issue. Could you reformulate your question please? Anyway, in order to instantiate a VideoCapture object in OpenCV, the C++ code would be pretty much something like this
#include "opencv2/opencv.hpp"
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_BGR2GRAY);
GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5);
Canny(edges, edges, 0, 30, 3);
imshow("edges", edges);
if(waitKey(30) >= 0) break; // Wait 30 ms for a key feed, then break out of the code if a keypress is found in the message queue
}
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;
}
As for the standard C version, you'd have to leverage the old yet still reliable CvCapture struct which is contained in the old OpenCV API. In this case, you'd act upon the cvCreateCameraCapture(0) which simply returns a pointer to the newly created camera instance (CvCapture). In the latter case, the code would evaluate to the snipper hereunder.
# include "highgui.h"
# include "cv.h"
int main( int argc, char** argv )
{
CvCapture* capture;
capture = cvCreateCameraCapture(0);
if (!capture)
return -1;
IplImage* bgr_frame = cvQueryFrame(capture); // Query the next frame
CvSize size = cvSize(
(int)cvGetCaptureProperty(capture,
CV_CAP_PROP_FRAME_WIDTH),
(int)cvGetCaptureProperty(capture,
CV_CAP_PROP_FRAME_HEIGHT)
);
cvNamedWindow("OpenCV via CvCapture", CV_WINDOW_AUTOSIZE); // Create a window and assign it a title
/* Open a CvVideoWriter to save the video to a file. Think of it as a stream */
CvVideoWriter *writer = cvCreateVideoWriter(argv[1],
CV_FOURCC('D','I','V','X'),
30,
size
);
while((bgr_frame = cvQueryFrame(capture)) != NULL)
{
cvWriteFrame(writer, bgr_frame);
cvShowImage("OpenCV via CvCapture", bgr_frame);
char c = cvWaitKey(30); // Same as the snippet above. Wait for 30 ms
if(c == 27) break; // If the key code is 0x27 (ESC), break
}
cvReleaseVideoWriter(&writer); // Dispose the CvVideoWriter instance
cvReleaseCapture(&capture); // Dispose the CvCapture instance
cvDestroyWindow("OpenCV via CvCapture"); // Destroy the window
return 0;
}

Related

OpenCV change colors in real time camera feed

I am using openCV 2.4.9. I open camera using OpenCV run camera in a new window. I want to change colors of camera feed whith a key press. For example, when I click '1' camera feed change to gray scale, '2' -> black and white, '3' -> HSV, and when I press 'ESC' return(0). This what I've came up so far:
#include <iostream>
#include <conio.h>
using namespace std;
#include<opencv\cv.h>
#include<opencv\highgui.h>
#include "opencv2\core\core.hpp"
#include "opencv2\imgproc\imgproc.hpp"
void main(){
CvCapture *capture = cvCaptureFromCAM(CV_CAP_ANY);
IplImage *frame = 0, *image = 0;
int key = 0, last = 0;
cvNamedWindow("WebCamera", CV_WINDOW_AUTOSIZE);
while(key != 27) {
frame = cvQueryFrame(capture);
image = cvCloneImage(frame);
// i try to use swich and case for this but i can't get it work
// when using cvtColor need to use Mat image but when use cvShowImage need IplImage
// switch(last)
// {
// case '1':
// cvtColor(image,HSVimage,CV_BGR2HSV);
// case '2':
// cvtColor(image,HSVimage,CV_BGR2GRAY);
// case '3':
// .
// .
// default: break;
// }
cvShowImage("WebCamera", image);
cvReleaseImage(&image);
key = cvWaitKey(1);
if (key != -1) last = key;
}
cvDestroyWindow("WebCamera");
cvReleaseCapture(&capture);
exit(0);
}
I want change colors again and again in same window or (if it is not possible) open and close windows for each color filter. Thank You. Sorry for bad English
It should work with the code below. Got it from this OpenCV tutorial and from the OpenCV documentation.
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
int key = 0, last = 0;
VideoCapture cap(0); // open the default camera
if(!cap.isOpened()) // check if we camera is opened
{
cout << "Cannot open selected camera" << endl;
return -1;
}
namedWindow("Capture",1);
Mat convertedImage;
for(;;) //Loop until user hit "esc"
{
Mat frame;
cap >> frame; // get a new frame from camera
switch(last)
{
case '1':
{
cvtColor(frame,convertedImage,CV_BGR2GRAY);
break;
}
case '2': //Binarization to generate Black/White image
{
Mat img_gray;
cvtColor(frame,img_gray,CV_BGR2GRAY); //First convert to gray
//Binarization. Use your parameters here or try adaptiveThreshold
threshold(img_gray, convertedIamge, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);
}
case '3':
{
cvtColor(frame,convertedImage,CV_BGR2HSV);
break;
}
default: //use to prevent ecxeption at program start or use case '0' to show original image
{
convertedImage = frame;
}
}
imshow("Capture", convertedImage); //show converted image
key = waitKey(1);
if (key != -1)
last = key;
if(key == 27)
break;
// the camera will be deinitialized automatically in VideoCapture destructor
}
return 0;
}
I not checked this(compileted).. But I think it can help you.
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main() {
VideoCapture stream1(0);
if (!stream1.isOpened()) { cout << "cannot open camera"; }
while (true) {
Mat cameraFrame;
stream1.read(cameraFrame);
switch(last)
{
case '1':
cvtColor(image,HSVimage,CV_BGR2HSV);
break;
case '2':
cvtColor(image,HSVimage,CV_BGR2GRAY);
break;
case '3':
...}
imshow("cam", cameraFrame);
key = cvWaitKey(1);
if (key != -1) last = key;
}
return 0;
}

OpenCV Unable to detect circles

I am pretty new to OpenCV, but I wrote a programm that detects circles in a video for a school project. The Problem: In my video (.avi) there are some circles that are not being detected and some "things" that are definetely not circles but they ARE detected. I am using OpenCV 3.0.0 on Windows 7 and my programming language is C++. Below you can find the code.
Any ideas how I could share the video file with you (maybe send e-mail on request)?
I think the problems are the parameters in the HoughCircles method.
Any suggestions how I can find the wanted circles? (I also posted a screenshot from a frame in the video (gray)).
As you can see I want to track the circles on the start/landing lane for planes.
#include <iostream>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
VideoCapture cap("C:/Users/Julian Büchel/Documents/Screen Video/Circle_Rotenburg.avi"); // open the video file for reading
if (!cap.isOpened()) // if not success, exit program
{
cout << "Cannot open the video file" << endl;
return -1;
}
double fps = cap.get(CV_CAP_PROP_FPS); //get the frames per seconds of the video
cout << "Frame per seconds : " << fps << endl;
namedWindow("MyVideo", CV_WINDOW_NORMAL); //create a window called "MyVideo"
namedWindow("Trackbar", CV_WINDOW_NORMAL); //create a window called "Trackbar"
resizeWindow("MyVideo", 1200, 700);
resizeWindow("Trackbar", 1200, 200);
//These are the parameters for my HoughCircles method. I added sliders to be able to adjust them.
int iSliderValue1 = 1;
createTrackbar("dp", "Trackbar", &iSliderValue1, 4);
int iSliderValue2 = 200;
createTrackbar("Min. Distance", "Trackbar", &iSliderValue2, 500);
int iSliderValue3 = 200;
createTrackbar("P1", "Trackbar", &iSliderValue3, 500);
int iSliderValue4 = 100;
createTrackbar("P2", "Trackbar", &iSliderValue4, 500);
int iSliderValue5 = 0;
createTrackbar("Min.R", "Trackbar", &iSliderValue5, 40);
int iSliderValue6 = 15;
createTrackbar("Max.R", "Trackbar", &iSliderValue6, 50);
while (1)
{
Mat frame, gray;
bool bSuccess = cap.read(frame); // read a new frame from video
if (!bSuccess) //if not success, break loop
{
cout << "Cannot read the frame from video file" << endl;
waitKey(10000);
break;
}
//Should I add the GaussianBlur? Right now you can see the circles more clear, but it takes up more CPU.
cvtColor(frame, gray, CV_RGB2GRAY);
//GaussianBlur(gray, gray, Size(9, 9), 2, 2);
vector<Vec3f> circles; //Store the circles
// Apply the Hough Transform to find the circles
// src vector method dp dist p1 p2 miR maR
//HoughCircles(gray, circles, CV_HOUGH_GRADIENT, 2, 200, 200, 100, 25, 35);
HoughCircles(gray, circles, CV_HOUGH_GRADIENT, iSliderValue1, iSliderValue2, iSliderValue3, iSliderValue4, iSliderValue5, iSliderValue6);
//Draw circles
for (size_t i = 0; i < circles.size(); i++)
{
Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
int radius = cvRound(circles[i][2]);
circle(gray, center, 3, Scalar(0, 255, 0), -1, 8, 0);// circle center
circle(gray, center, radius, Scalar(0, 0, 255), 3, 8, 0);// circle outside
cout << "center : " << center << "\nradius : " << radius << endl;
}
imshow("MyVideo", gray); //show the frame in "MyVideo" window
waitKey(25);//Make video slower/back to normal speed
if (waitKey(30) == 27) //wait for 'esc' key press for 30 ms. If 'esc' key is pressed, break loop
{
cout << "esc key is pressed by user" << endl;
break;
}
}
return 0;
}

OpenCV cpp motion detection

I'm trying to figure out how motion detection work in opencv.
I can see there the video analysis reference but I don't find enough information about how this is used.
I've also seen some people using absdiff I tried it like this, but It gives me an exception at memore errors
OpenCV Error: Sizes of input arguments do not match (The operation is neither 'a
rray op array' (where arrays have the same size and the same number of channels)
, nor 'array op scalar', nor 'scalar op array') in cv::arithm_op, file C:\builds
\2_4_PackSlave-win32-vc12-shared\opencv\modules\core\src\arithm.cpp, line 1287
the code is
#include <iostream>
#include <sstream>
#include <string>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
int main()
{
//create matrix for storage
Mat image;
Mat image2;
Mat image3;
Mat image4;
//initialize capture
VideoCapture cap;
cap.open(0);
//create window to show image
namedWindow("window", 1);
while (1){
//copy webcam stream to image
cap >> image;
cap >> image2;
absdiff(image, image2, image3);
threshold(image3, image4, 128, 255, THRESH_BINARY);
//print image to screen
if (!image.empty()) {
imshow("window", image3);
}
//delay33ms
waitKey(10);
//
}
}
im obviously not using it right
You need to confirm the VideoCapture was successful before using the images. Also, you want to test if the image was captured successfully before using it. Try this:
VideoCapture cap(0);
if(!cap.isOpened()) {
std::cerr << "Failed to open video capture" << std::endl;
return -1;
}
namedWindow("window");
while(true) {
cap >> image;
cap >> image2;
if(image.empty() || image2.empty()) {
std::cerr << "failed to capture images\n";
return -1;
}
absdiff(image, image2, image3);
threshold(image3, image4, 128, 255, THRESH_BINARY);
imshow("window", image);
int k = waitKey(30) & 0xff;
if('q' == k || 27 == k)
break;
}

Overlay Image in OpenCV

I am trying to overlay an image over the video capture of my program with OpenCV but I am having trouble getting it to work. I set the a region of interest in the original frame taken from the webcam in the form of a rectangle. Then i copy it to the original frame. However it never shows up on the new frame captured by the webcam. I tested it and the image is loading correctly but it is not being copied to the new frame for some reason.
Code Below in C++:
#include<opencv2/core/core.hpp>
#include<opencv2/contrib/contrib.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<iostream>
#include<vector>
using namespace std;
using namespace cv;
int main(){
VideoCapture cap;
cap.open(0);
if(!cap.isOpened()){
cerr << "Error opening the webcam!" << endl;
return -1;
}
for(;;){
Mat frame;
cap>>frame;
Mat newFrame;
frame.copyTo(newFrame);
Mat image = imread("C:\\User\\Desktop\\images\\image.png");
int cx = (newFrame.cols - 70) / 2;
if (image.data) {
// Get a BGR version of the face, since the output is BGR color
Mat srcBGR = Mat(face.size(), CV_8UC3);
cvtColor(image, srcBGR, CV_GRAY2BGR);
// Get the destination ROI (and make sure it is within the image)
Rect dstRC = Rect(cx, newFrame.rows/2, 70, 70);
Mat dstROI = newFrame(dstRC);
// Copy the pixels from src to dst.
srcBGR.copyTo(dstROI);
}
imshow("frame", newFrame);
char key = (char) waitKey(30);
// Exit this loop on escape:
if(key == 27)
break;
}
return 0;
}
Any suggestions or help would be appreciated. Thanks.
You converted image to BGR by using not converted one:
change this: image.copyTo(dstROI); to this srcBGR.copyTo(dstROI);
#include<opencv2/core/core.hpp>
#include<opencv2/contrib/contrib.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<iostream>
#include<vector>
using namespace std;
using namespace cv;
int main(){
VideoCapture cap;
cap.open(0);
if(!cap.isOpened()){
cerr << "Error opening the webcam!" << endl;
return -1;
}
Mat image = imread("D:\\ImagesForTest\\Lena.jpg",0);
cv::resize(image,image,Size(70,70));
Mat frame;
for(;;){
cap>>frame;
Mat newFrame=frame.clone();
int cx = (newFrame.cols - 70) / 2;
if (!image.empty()) {
// Get a BGR version of the face, since the output is BGR color
Mat srcBGR = Mat(image.size(), CV_8UC3);
cvtColor(image, srcBGR, CV_GRAY2BGR);
// Get the destination ROI (and make sure it is within the image)
Rect dstRC = Rect(cx, newFrame.rows/2, 70, 70);
Mat dstROI = newFrame(dstRC);
// Copy the pixels from src to dst.
srcBGR.copyTo(dstROI);
}
imshow("frame", newFrame);
char key = (char) waitKey(30);
// Exit this loop on escape:
if(key == 27)
break;
}
return 0;
}

How to extract Frames from AVI video

Hey peeps so far i manage OpenCV to play a video.avi but what should i do now to extract frames...?
below is the code i written so far that got my video playing:
#include<opencv\cv.h>
#include<opencv\highgui.h>
#include<opencv\ml.h>
#include<opencv\cxcore.h>
int main( int argc, char** argv ) {
cvNamedWindow( "DisplayVideo", CV_WINDOW_AUTOSIZE );
CvCapture* capture = cvCreateFileCapture( argv[1] );
IplImage* frame;
while(1) {
frame = cvQueryFrame( capture );
if( !frame ) break;
cvShowImage( "DisplayVideo", frame );
char c = cvWaitKey(33);
if( c == 27 ) break;
}
cvReleaseCapture( &capture );
cvDestroyWindow("DisplayVideo" );
}
frame is the frame you are extracting. If you want to convert that to a cv::Mat you can do that by creating a mat with that IplImage:
Mat myImage(IplImage);
There is a nice tutorial on it here.
However, you are doing it the old way. The newest version of OpenCV has the latest camera capture abilities, and you should do something like this:
#include "cv.h"
#include "highgui.h"
using namespace cv;
int main()
{
VideoCapture cap(0); // open the default camera
if(!cap.isOpened()) // check if we succeeded
return -1;
namedWindow("Output",1);
while(true)
{
Mat frame;
cap >> frame; // get a new frame from camera
//Do your processing here
...
//Show the image
imshow("Output", frame);
if(waitKey(30) >= 0) break;
}
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;
}