Detecting SURF points on real time video - c++

I am looking to detect SURF feature points in a live video feed, however, I can't seem to find any tutorials on how to achieve this.
I am able to detect them on still images:
int minHessian = 400;
cv::SurfFeatureDetector detector(minHessian);
std::vector<cv::KeyPoint> keypoints_1;
detector.detect(img_1, keypoints_1);
cv::Mat img_keypoints_1;
drawKeypoints(img_1, keypoints_1, img_keypoints_1);
But I am not sure how you apply this to a video feed using cvCaptureFromCAM()?

The frame grabbed by your webcam is nothing but a single image. Therefore, whatever you can do with your single image, you can do the same thing on that frame too using the same method.
Following is the code where you receive a frame through your webcam in an infinite for loop. Basically, you just need to read the frame and then do the same thing which you did at your single image.
Mat frame;
VideoCapture cap(0); // open the default camera
if (!cap.isOpened()) // check if we succeeded
return -1;
for (;;)
{
cap.read(frame); // get a new frame from camera
if (frame.empty()) continue;
//Now do the same thing with each frame which you did with your single image.
}

Related

OpenCV cheap stereo camera can't load both streams at once

I have purchased an ELP-1MP2CAM001 which shows up as two webcam devices on Windows. If I open the Windwos default "Camera" app and Skype I can display the feeds from both the left and right camera at the same time. I don't think therefore it is a USB Bandwidth issue with two cameras coming into the same port
I'm using fairly standard code (shown below) to open both of these feeds and it works successfully if I use two standard Microsoft HD3000 webcams instead of the single stereo camera.
I've tried a range of numbers inside the cap2() arguments so I don't think it's hiding at number 10 or anything weird like that.
My questions are:
There must be some sort of on board hub for the ELP cameras, do I need to do something different in OpenCV?
Could it be that both frames are accessible through cap(0)? This seems unlikely to me.
This questions says I don't need to do anything special? but obviously I'm missing something.
Any help on this would be great.
Code:
#include <opencv2/opencv.hpp>
using namespace cv;
int main(int, char**)
{
VideoCapture cap(0); // open the default camera
VideoCapture cap2(1); // open the default camera
cap.set(CV_CAP_PROP_FRAME_WIDTH, 240);
cap.set(CV_CAP_PROP_FRAME_HEIGHT, 120);
cap2.set(CV_CAP_PROP_FRAME_WIDTH, 240);
cap2.set(CV_CAP_PROP_FRAME_HEIGHT, 120);
if (!cap.isOpened()) // check if we succeeded
return -1;
if (!cap2.isOpened()) // check if we succeeded
return -1;
Mat frame;
Mat frame2;
namedWindow("Frame", 1);
namedWindow("Frame2", 1);
for (;;)
{
Mat frame;
cap >> frame; // get a new frame from camera
imshow("Frame", frame);
Mat frame2;
cap2 >> frame2;
imshow("Frame2", frame2);
if (waitKey(30) >= 0) break; // Finish on "esc" key
}
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;
}
I have the same camera as this, and I ran into the same problem before. Try change the order of your code as below:
VideoCapture cap(0);
cap.set(CV_CAP_PROP_FRAME_WIDTH, 240);
cap.set(CV_CAP_PROP_FRAME_HEIGHT, 120);
VideoCapture cap2(1);
cap2.set(CV_CAP_PROP_FRAME_WIDTH, 240);
cap2.set(CV_CAP_PROP_FRAME_HEIGHT, 120);
I think it's a problem with USB bandwidth. In your code, you opened two cameras in full resolution at the beginning, then you change the resolution of two cameras.
When you call VideoCapture cap(0); // open the default camera, cap has resolution 1280*720. cap already occupied the bandwidth. Thereby, VideoCapture cap2(1); won't open camera cap2 sucessfully.
Hope it helps.
According to VideoCapture documentation, there is a function called cv::VideoCapture::grab:
The primary use of the function is in multi-camera environments, especially when the cameras do not have hardware synchronization. That is, you call VideoCapture::grab() for each camera and after that call the slower method VideoCapture::retrieve() to decode and get frame from each camera
You can try that, with:
cap.grab();
cap.retrieve(...);

OpenCV Black and White video empty

I have some code to record a video using openCV. It works fine for recording colour video, but I'd like to record black and white.
When I call cvtColor to black and white I get an empty video. I'd really like to know what I'm doing wrong.
VideoCapture cap(1); // open the default camera
cap.set(CV_CAP_PROP_FPS, fps);
cap.set(CV_CAP_PROP_FRAME_WIDTH, 1280);
cap.set(CV_CAP_PROP_FRAME_HEIGHT, 720);
if(!cap.isOpened()) // check if we succeeded
return -1;
VideoWriter writer(filename, CV_FOURCC('M','P','4','2'), fps, Size(1280, 720), true);
int count = 0;
for(;;)
{
count++;
Mat frame;
cap >> frame;
//cvtColor(frame, frame, CV_BGR2GRAY);
writer.write(frame);
}
The above code produces a perfectly fine video, but when cvtColor is uncommented the file is empty.
I was trying to make b/w video with XVID codec and got empty film too (5kB length), until I made FFMPEG libraries available to program (put them together with program or in PATH-ed directory, Windows OS).
OpenCV checks for FFMPEG presence and uses it if available.
And aside remark - use the second Mat for b/w frame - it will save computer time (with single object every capture causes two reallocations/reinitializations)
cvtColor(frame, bwframe, CV_BGR2GRAY);

Split frames obtained from video into separate channels

I am trying to read a video (mp4) frame by frame and then convert the frames from BGR to HSV.
I then want to split the HSV Mats into different channels (Hue, Saturation, Value).
this, however, does not work:
void colorize () {
VideoCapture cap("myFile.mp4");
Mat frame;
Mat frame2;
while (true) {
cap>>frame;
cvtColor(frame, frame2, CV_BGR2HSV);
Vector<Mat> channels;
split(frame2, channels);
}
}
The split-function gives the following error:
no matching function for call to ‘split(cv::Mat&, cv::Vector<cv::Mat>&)’
split(frame2, channels);
I have tried the exact same code outside of a loop with another image I had before transformed to hsv and it worked fine, so I assume the problem must be the looping.
Any ideas?
You're using cv::Vector, while instead you should use std::vector (note the lowercase v).
std::vector<Mat> channels; // std::vector, not cv::Vector
split(frame2, channels);

Compare two image in real time with predefined image with real time capture image in Opencv c++

I am doing a project of Automatic fabric defect detection. In this i developed the algorithm using the [FFT][1] (Fast Fourier Transform) and its working fine in my Ubuntu 14.04 opencv c++. But now i want to develop this to real time there i have to capture image every 2s and have to process that image with my developed algorithm. I need ideas on how to capture images using webcam in opencv c++ and to process withat same image which is being captured. Please do help me if anyone knows of this. Thank you in advance.
You can follow the guidance which has given by OpenCV - They have provided enough examples such as following sample code. Following code is provided by OpenCV Dev team as sample.
#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;
}
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;
}

Modifying a video stream in real time

I need to access the pixel data from a video camera attached to my Windows PC in real time. Once accessed, I will modify it and output it as part of the video stream. In other words, I need to find the easiest way to modify a video stream in real time. I know about OpenCV and Matlab functionality, but I am wondering if anyone has found a simpler way to do this.
If you want to do this with C++, OpenCV, as long as it works with your camera, is one of the simplest ways there is. The code below is from the OpenCV documentation VideoCapture. The only trick is instantiating the VideoCapture instance. How much simpler can it be?
#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, COLOR_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;
}
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;
}
There is even a python version at Capture Video from Camera that looks very similar to the C++ version above.