Drawing bounding boxes through a live feed - c++

I was recently assigned a school project to do some filtering on a live video feed. The Idea is that only the biggest object currently in camera view is shown, I am planning to do this through the use of bounding boxes (deleting all objects except for the biggest one).
However I have very limited coding experience with C++ & opencv, so Im basically just picking code off the net where I can and (attempting to) editing it to fit my purpose.
At the moment I have attempted to combine the bounding boxes tutorial code found here :http://docs.opencv.org/doc/tutorials/imgproc/shapedescriptors/bounding_rects_circles/bounding_rects_circles.html
And this code right here (to greyscale each frame caught from the camera) without any success (probably because its horrible).
#include <stdlib.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace std;
using namespace cv;
void thresh_callback(int, void* );
int main(int argc, char** argv)
{
VideoCapture cap(0); // open the default camera
if(!cap.isOpened()) // check if we succeeded
return -1;
Mat edges;
namedWindow("edges",1);
cout << "Hello Application\n" << endl;
for(;;)
{
Mat frame, GBlur;
cap >> frame; // get a new frame from camera
cvtColor(frame, edges, COLOR_BGR2GRAY);
GBlur : GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5);
Canny(edges, edges, 0, 30, 3);
imshow("edges", edges);
if(waitKey(30) >= 0) break;
}
return(0);
If you guys have any advice on how I should go about this then please tell! Im kind of in a desperate mood lol.

Related

How do I store the captured image in OpenCV (saving the picture to computer)

I am still quite new to OpenCV and c++ programming in general. I am doing on a project that stores image from my webcam. I was able to display camera image and detect faces somehow but I don't know how to save the images.
What should i do in order for the faces that my webcam detects gets captured and store into my computer?
Using my code below, how can i edit it to:
capture an image from the live cam 5 seconds after detecting face
save the images to a folder in jpg format
Thanks so much for any help you can provide!
my code:
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/objdetect.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
// capture from web camera init
VideoCapture cap(0);
cap.open(0);
Mat img;
// Initialize the inbuilt Harr Cascade frontal face detection
// Below mention the path of where your haarcascade_frontalface_alt2.xml file is located
CascadeClassifier face_cascade;
face_cascade.load("C:/OpenCV/sources/data/haarcascades/haarcascade_frontalface_alt2.xml");
// i tried changing this line to match my folder in C Drive
for (;;)
{
// Image from camera to Mat
cap >> img;
// Just resize input image if you want
resize(img, img, Size(1000, 640));
// Container of faces
vector<Rect> faces;
// Detect faces
face_cascade.detectMultiScale(img, faces, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(140, 140));
// error message appears here
//Show the results
// Draw circles on the detected faces
for (int i = 0; i < faces.size(); i++)
{
Point center(faces[i].x + faces[i].width*0.5, faces[i].y + faces[i].height*0.5);
ellipse(img, center, Size(faces[i].width*0.5, faces[i].height*0.5), 0, 0, 360, Scalar(255, 0, 255), 4, 8, 0);
}
// To draw rectangles around detected faces
/* for (unsigned i = 0; i<faces.size(); i++)
rectangle(img,faces[i], Scalar(255, 0, 0), 2, 1);*/
imshow("wooohooo", img);
int key2 = waitKey(20);
}
return 0;
}
Answering this so we can close this question
The function to use to save an image in C++ opencv is cv::imwrite('image_name.jpg', img).
Add this before or after you cv::imshow() if you want to save the image after every detection.

Background subtraction in OpenCV

I am trying to implement background subtraction in OpenCV 2.4.10 using mog2. My aim is to segment the hand using background subtraction. Unfortunately, the first frame that is used as foreground appear to be stuck during live capture from the webcam. Here is the code that I used for this simple project
#include "stdafx.h"
#include <opencv2\opencv.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\video\video.hpp>
#include <opencv2\core\core.hpp>
#include <iostream>
#include <sstream>
#include <string.h>
using namespace cv;
int main()
{
Mat frame, mask, gray;
BackgroundSubtractorMOG2 mog2;
VideoCapture cap(0);
if (cap.isOpened()){
while (true)
{
if (cap.read(frame))
{
imshow("frame", frame);
cvtColor(frame, gray, cv::COLOR_RGB2GRAY);
imshow("gray", gray);
mog2(gray, mask, 0.0);// 0.1 is learning rate
imshow("Background Subtraction", mask);
if (waitKey(30) >= 0)
break;
}
}
}
cap.release();
return 0;
}
Here is the output
This is because your fist happens to be in the very first frame, thus when you move your hand, you get 2 difference images- one from the new position of your palm, and the other from the old location of the fist, now occupied by the actual background behind it.
I would suggest that you shouldn't have your hand in the first frames

Learning background yet still showing static object through webcam

I am working on a university project where we have a table with glass surface, a webcam, and IR spots underneath.
We want to detect certain gestures such as:
1, 2, 3 fingers
3 fingertips
This is how a hand looks through the camera:
When the camera initialise it learns the background and subtracts it, going from
to this:
The hand, however, is also "learned" and disappears rather quickly.
We want to the program to learn the background, but will not store the hand as part of the background as it will be static.
Any suggestions on how to do this?
What we have tried: playing with the learning rate, blurring, morphology.
Code included below.
#include <opencv2/core/core.hpp>
#include "opencv2/opencv.hpp"
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/video/background_segm.hpp>
#include <opencv\cv.h>
#include <iostream>
#include <sstream>
using namespace cv;
using namespace std;
int main(int, char)
{
Mat frame; //current frame
Mat fgMaskMOG; //fg mask generated by MOG method
int frameNum = 0;
Ptr<BackgroundSubtractor> pMOG2; //MOG2 Background subtractor
//pMOG = new BackgroundSubtractorMOG(); //MOG approach
pMOG2 = createBackgroundSubtractorMOG2(20, 16, false); //MOG2 approach
VideoCapture cap(1); // open the default camera
if (!cap.isOpened()) // check if we succeeded
return -1;
for (;;)
{
cap >> frame; // get a new frame from camera
if (!cap.read(frame)) {
cerr << "Unable to read next frame." << endl;
continue;
}
imshow("orig", frame);
++frameNum;
pMOG2->apply(frame, fgMaskMOG, -1);
imshow("frame", fgMaskMOG);
if (waitKey(30) >= 0)
break;
}
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;
}

OpenCV C++ Mat to Integer

I'm pretty new to OpenCV, so bear with me. I'm running a Mac Mini with OSX 10.8. I have a program that recognizes colors and displays them in binary picture (black and white). However, I want to store the number of white pixels as an integer (or float, etc.) to compare with other number of pixels. How can I do this? Here is my current code-
#include <iostream>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/core/core.hpp"
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
VideoCapture cap(0); //capture the video from webcam
if ( !cap.isOpened() ) // if not success, exit program
{
cout << "Cannot open the web cam" << endl;
return -1;
}
namedWindow("HSVLeftRed", CV_WINDOW_AUTOSIZE);
namedWindow("HSVLeftGreen", CV_WINDOW_AUTOSIZE);
while (true) {
Mat image;
cap.read(image);
Mat HSV;
Mat leftgreen;
Mat leftred;
//Left Cropping
Mat leftimg = image(Rect(0, 0, 640, 720));
//Left Red Detection
cvtColor(leftimg,HSV,CV_BGR2HSV);
inRange(HSV,Scalar(0,0,150),Scalar(0,0,255), leftgreen);
//imshow("HSVLeftRed", leftgreen);
//print pixel type
//Left Green Detection
cvtColor(leftimg,HSV,CV_BGR2HSV);
inRange(HSV,Scalar(still need to find proper min values),Scalar(still need to find proper max values), leftgreen);
//imshow("HSVLeftGreen", leftgreen);
//compare pixel types
}
return 0;
}
Thanks in advance!
To count the non-zero pixels, OpenCV has this function cv::countNonZero. It takes input the image, whose number of non-zero pixels, we want to calculate and output is number of non-zero pixels(int). Here is the documentation.
In your case, since all the pixels are either black or white, all the non zero pixels will be white pixels.
This is how to use it,
int cal = countNonZero(image);
Change image, as per your code.

Capture a picture from multiple webcams, using C++

I need a program to capture pictures from multiple webcams and save them automatically in Windows Vista. I got the basic code from this link. The code runs in Window XP, but when I tried using it on Vista it says "failed." Different errors pop up every time it is executed. Would it help if I used the SDK platform? Does anyone have any suggestions?
I can't test this on multiple webcams since I only have one, but I'm sure OpenCV2.0 should be able to handle it. Here's some sample code (I use Vista) with one webcam to get you started.
#include <cv.h>
#include <highgui.h>
using namespace cv;
int main()
{
// Start capturing on camera 0
VideoCapture cap(0);
if(!cap.isOpened()) return -1;
// This matrix will store the edges of the captured frame
Mat edges;
namedWindow("edges",1);
for(;;)
{
// Acquire the frame from cap into frame
Mat frame;
cap >> frame;
// Now, find the edges by converting to grayscale, blurring and then Canny edge detection
cvtColor(frame, edges, CV_BGR2GRAY);
GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5);
Canny(edges, edges, 0, 30, 3);
// Display the edges and the frame
imshow("edges", edges);
imshow("frame", frame);
// Terminate by pressing a key
if(waitKey(30) >= 0) break;
}
return 0;
}
Note:
The matrix edges is allocated during
the first frame processing and unless
the resolution will suddenly change,
the same buffer will be reused for
every next frame’s edge map.
As you can see, the code is quite clean and readable! I lifted this from the OpenCV 2.0 documentation (opencv.pdf).
The code not only displays the image from the webcam (under frame) but also does real-time edge detection! Here's a screenshot when I pointed the webcam at my monitor :)
screenshot http://img245.imageshack.us/img245/5014/scrq.png
If you want code to just display the frames from one camera:
#include <cv.h>
#include <highgui.h>
using namespace cv;
int main()
{
VideoCapture cap(0);
if(!cap.isOpened()) return -1;
for(;;)
{
Mat frame;
cap >> frame;
imshow("frame", frame);
if(waitKey(30) >= 0) break;
}
return 0;
}
If the program works with UAC off or when running administrator, make sure the place you choose to save the results are in writable places like the user's my documents folder. Generally speaking root folders and the program files folder is read only for normal users.