imshow function doesn't update image - c++

The below code captures the given video and outputs the frames using imshow() function only when the statement calling the function detectMultiScale() is commented. Is it only to me? If no, then why so?
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main() {
VideoCapture cap("test.mp4");
cap.set(CV_CAP_PROP_FRAME_WIDTH, 640);
cap.set(CV_CAP_PROP_FRAME_HEIGHT, 480);
if (!cap.isOpened()) {
cout << "\nCould not open video file\n";
return -1;
}
Mat img;
HOGDescriptor hog;
hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());
namedWindow("video capture", CV_WINDOW_AUTOSIZE);
while (true) {
cap >> img;
if (!img.data)
continue;
vector<Rect> found, found_filtered;
// hog.detectMultiScale(img, found, 0, Size(4, 4), Size(8, 8), 1.05, 2);
imshow("video capture", img);
waitKey(30);
}
return 0;
}

Related

Track bar is not working properly in opencv

I have written a program in opencv(c++) to manipulate camera property. I am trying to blur my camera display using "track bar". The code is working but in certain condition. It works, when i change the position of "track bar" using mouse click. But if i tried to slide the track bar it gives me an error as mention below.
Here is my code
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
Mat image, image_blurred;
int slider=5;
float sigma=0.3 *((slider - 1)*0.5 - 1) +0.8;
void on_Trackbar(int,void *)
{
int k_size = max(1,slider);
//k_size = k_size%2 == 0 ? k_size+1 : k_size;
setTrackbarPos("kernel","Blur window",3);
sigma=0.3 *((slider - 1)*0.5 - 1) +0.8;
GaussianBlur(image,image_blurred,Size(3,3),sigma);
}
int main()
{
Mat img;
VideoCapture cap(0);
if(!cap.isOpened())
{
cout<<"Camera is not successfully opened"<<endl;
return -1;
}
namedWindow("original image",CV_WINDOW_AUTOSIZE);
namedWindow("Blur Image",CV_WINDOW_AUTOSIZE);
while(!char(waitKey(30)=='q') && cap.isOpened())
{
cap>>img;
GaussianBlur(img,image_blurred,Size(slider,slider),sigma);
createTrackbar("kernel","Blur Image",&slider,21,on_Trackbar);
imshow("Blur Image",image_blurred);
imshow("original image",img);
}
destroyAllWindows();
return 0;
}
Please give your valuable views. Thanks in advance!!.
In the while loop, you're passing an invalid value to GaussianBlur, since slider can also be an even number.
You can correct this introducing a new variable int kernel_size = 2*slider+1. slider now is the radius of the kernel, and kernel_size is guaranteed to be odd.
Also you don't need to call GaussianBlur in the callback function, since it's already called in the main loop. The only goal of the callback is to update the values of kernel_size and sigma.
This code will work as expected:
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
Mat image, image_blurred;
int slider = 0;
int kernel_size = 3;
float sigma = 0.3 *((kernel_size - 1)*0.5 - 1) + 0.8;
void on_Trackbar(int, void *)
{
kernel_size = 2 * slider + 1;
sigma = 0.3 *((kernel_size - 1)*0.5 - 1) + 0.8;
}
int main()
{
Mat img;
VideoCapture cap(0);
if (!cap.isOpened())
{
cout << "Camera is not successfully opened" << endl;
return -1;
}
namedWindow("original image", CV_WINDOW_AUTOSIZE);
namedWindow("Blur Image", CV_WINDOW_AUTOSIZE);
createTrackbar("kernel", "Blur Image", &slider, 21, on_Trackbar);
while (!char(waitKey(30) == 'q') && cap.isOpened())
{
cap >> img;
GaussianBlur(img, image_blurred, Size(kernel_size, kernel_size), sigma);
imshow("Blur Image", image_blurred);
imshow("original image", img);
}
destroyAllWindows();
return 0;
}

Playing a video file in opencv c++

I'm trying to play a video file using the following code.
When run it only shows a black screen with the window name (Video), can anyone help me fix it.
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <opencv2\core\core.hpp>
#include "opencv2/opencv.hpp"
using namespace cv;
int main( int argc, char** argv )
{
CvCapture* capture = cvCreateFileCapture( "1.avi" );
Mat frame= cvQueryFrame(capture);
imshow("Video", frame);
waitKey();
cvReleaseCapture(&capture);
}
Try this if you only want to play a video ::::::::::::::::::::::::::
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <opencv2\core\core.hpp>
#include "opencv2/opencv.hpp"
int main(int argc, char** argv)
{
cvNamedWindow("Example3", CV_WINDOW_AUTOSIZE);
//CvCapture* capture = cvCreateFileCapture("20051210-w50s.flv");
CvCapture* capture = cvCreateFileCapture("1.wmv");
/* if(!capture)
{
std::cout <<"Video Not Opened\n";
return -1;
}*/
IplImage* frame = NULL;
while(1) {
frame = cvQueryFrame(capture);
//std::cout << "Inside loop\n";
if (!frame)
break;
cvShowImage("Example3", frame);
char c = cvWaitKey(33);
if (c == 27) break;
}
cvReleaseCapture(&capture);
cvDestroyWindow("Example3");
std::cout << "Hello!";
return 0;
}
Actually the code you posted won't even compile.
Just have a look at OpenCV documentation: Reading and Writing images and video
#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;
}

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;
}

Slow Video in Object Tracking Script using OpenCV

I wrote a short routine in openCV and C++ to track objects with a webcam. The webcam formulation was speedy with no lag, but before leaving work for the weekend, I recorded a typical sequence to use as a test template while I work until Monday. This and the corresponding change in code somehow make the video play back in really slow motion. Here is the code, opening "Test.avi", ~20 seconds long instead of running a constant stream off of the webcam:
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <vector>
using namespace cv;
using namespace std;
Mat drawBoundingBoxes (Mat canvasImage, vector<vector<Point>> contours);
int main(int argc, char** argv[])
{
Mat frame;
Mat back;
Mat fGround;
BackgroundSubtractorMOG2 bGround;
bGround.nmixtures = 3;
//bGround.nShadowDetection = 0;
bGround.fTau = .5;
VideoCapture cap;
cap.open("Test.avi");
if (!cap.isOpened())
{
cout << "Can't open video" << endl;
return -1;
}
vector<vector<Point>> contours;
namedWindow("video", CV_WINDOW_AUTOSIZE);
while (true)
{
static int count = 1;
cap >> frame;
if (frame.empty())
break;
bGround.operator()(frame, fGround);
bGround.getBackgroundImage(back);
erode(fGround, fGround, Mat(), Point(-1,-1), 2, BORDER_DEFAULT);
dilate(fGround, fGround, Mat(), Point(-1,-1), 10, BORDER_DEFAULT);
if (count > 50)
{
findContours(fGround, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
drawContours(frame, contours, -1, Scalar(239,255,0), 2);
drawBoundingBoxes(frame, contours);
}
imshow("video", frame);
if(waitKey(30) >= 0)
break;
count++;
}
return 0;
}
Mat drawBoundingBoxes (Mat canvasImage, vector<vector<Point>> contours)
{
vector<Rect> boundRect(contours.size());
for (int i=0; i<contours.size(); i++)
{
boundRect[i] = boundingRect(contours[i]);
rectangle(canvasImage, boundRect[i], Scalar(153,0,76), 2, 8, 0);
}
return canvasImage;
}
Any ideas? Memory Leak somewhere? Thanks,
-Tony
I believe your recorded video has a higher framerate than that your PC can process real time. It's not a problem with a webcam as it just drops the frames. You could try to decrease the delay in the waitKey() procedure and see if that helps.