I'm using opencv with visual studio 2010 in Windows 7 with 32 bit OS.... While running the sample program of People detection, it shows the output video playing in a window... But I'm unable to open the output video, stored in a particular location... Kindly help me... Thankyou...
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <opencv2/core/core.hpp>
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
Mat img; char _filename[1024];
HOGDescriptor hog;
hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());
namedWindow("people detector", 1);
CvCapture *cap=cvCaptureFromFile("E:/Phase_I_output/2.walk.avi");
img=cvQueryFrame(cap);
for(;;)
{
img=cvQueryFrame(cap);
if(img.empty())
break;
fflush(stdout);
vector<Rect> found, found_filtered;
double t = (double)getTickCount();
int can = img.channels();
hog.detectMultiScale(img, found, 0, Size(8,8), Size(32,32), 1.05, 2);
t = (double)getTickCount() - t;
printf("tdetection time = %gms\n", t*1000./cv::getTickFrequency());
size_t i, j;
for( i = 0; i < found.size(); i++ )
{
Rect r = found[i];
for( j = 0; j < found.size(); j++ )
if( j != i && (r & found[j]) == r)
break;
if( j == found.size() ) found_filtered.push_back(r);
}
for( i = 0; i < found_filtered.size(); i++ )
{
Rect r = found_filtered[i];
r.x += cvRound(r.width*0.1);
r.width = cvRound(r.width*0.8);
r.y += cvRound(r.height*0.07);
r.height = cvRound(r.height*0.8);
rectangle(img, r.tl(), r.br(), cv::Scalar(0,255,0), 3);
}
Size size2 = Size(640,480);
int codec = CV_FOURCC('M', 'J', 'P', 'G');
VideoWriter writer2("E:/Phase_I_output/video_.avi",codec,50.0,size2,true);
writer2.open("E:/Phase_I_output/video_.avi",codec,15.0,size2,true);
writer2.write(img);
imshow("people detector", img);
if(waitKey(1) == 27)
break;
}
std::cout << "Completed" << std::endl ;
waitKey();
return 0;
}
You should initialize the videowriter before the infinite loop, and release the videowriter (not necessary with the C++ API) and the videocapture once there are no more frame to grab :
Size size2 = Size(640,480);
int codec = CV_FOURCC('M', 'J', 'P', 'G');
VideoWriter writer2("E:/Phase_I_output/video_.avi",codec,50.0,size2,true);
writer2.open("E:/Phase_I_output/video_.avi",codec,50.0,size2,true);
for(;;){
//do your stuff
//write the current frame
writer2.write(img);
}
cvReleaseVideoWriter( writer2 );
cvReleaseCapture( &cap );
You should also use the C++ API of openCV. I believe every function beginning with 'cv' is part of the C API (and no longer supported). Check the openCV documentation to find the corresponding C++ function.
For example :
img=cvQueryFrame(cap);
Will become :
cap >> img;
Edit
I corrected your code to use the C++ API of openCV, and it's working fine (the people detection seems to give false positive though). Here is the code :
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <opencv2/core/core.hpp>
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
Mat img;
string _filename;
_filename = "path/to/video.avi";
HOGDescriptor hog;
hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());
namedWindow("people detector", WND_PROP_AUTOSIZE);
VideoCapture cap = VideoCapture(_filename);
if(!cap.isOpened()){
cout<<"error opening : "<<_filename<<endl;
return 1;
}
Size size2 = Size(640,480);
int codec = static_cast<int>(cap.get(CV_CAP_PROP_FOURCC));
double fps = cap.get(CV_CAP_PROP_FPS);
VideoWriter writer2("../outputVideo_.avi",codec,fps,size2,true);
for(;;)
{
cap >> img;
if(img.empty()){
cout<<"frame n° "<<cap.get(CV_CAP_PROP_FRAME_COUNT)<<endl;
break;
}
fflush(stdout);
vector<Rect> found, found_filtered;
double t = (double)getTickCount();
int can = img.channels();
hog.detectMultiScale(img, found, 0, Size(8,8), Size(32,32), 1.05, 2);
t = (double)getTickCount() - t;
printf("tdetection time = %gms\n", t*1000./cv::getTickFrequency());
size_t i, j;
for( i = 0; i < found.size(); i++ )
{
Rect r = found[i];
for( j = 0; j < found.size(); j++ )
if( j != i && (r & found[j]) == r)
break;
if( j == found.size() ) found_filtered.push_back(r);
}
for( i = 0; i < found_filtered.size(); i++ )
{
Rect r = found_filtered[i];
r.x += cvRound(r.width*0.1);
r.width = cvRound(r.width*0.8);
r.y += cvRound(r.height*0.07);
r.height = cvRound(r.height*0.8);
rectangle(img, r.tl(), r.br(), Scalar(0,255,0), 3);
}
//writer2.write(img);
writer2 << img;
imshow("people detector", img);
if(waitKey(1) == 27)
{
break;
}
}
writer2.release();
cap.release();
cout << "Completed" << endl ;
waitKey();
destroyAllWindows();
return 0;
}
Related
Namespace "torch::jit" is missing member "load"
The official reference says it is there, but I can't use it.
It's not just an intelligence problem, but when I run it, it throws an error saying that there is no "jit::load".
Why?
source code
#include <torch/torch.h>
#include <iostream>
#include <Windows.h>
#include <gdiplus.h>
#include <gdipluspixelformats.h> // PixelFormat24bppRGB
#include <vector>
#include <cstdlib>
#pragma comment(lib, "gdiplus.lib")
int main()
{
Gdiplus::GdiplusStartupInput input;
ULONG_PTR token;
Gdiplus::GdiplusStartup(&token, &input, NULL);
std::vector<uint8_t> pixels;
Gdiplus::BitmapData bmpData;
LARGE_INTEGER freq, start, end;
QueryPerformanceFrequency(&freq);
std::wstring path = L"C:\\Users\\baiji\\Documents\\triggerBot\\data2\\0.jpg";
std::wstring path2 = L"D:\\screenshot\\result\\output.bmp";
auto image = Gdiplus::Bitmap::FromFile(path2.c_str());
QueryPerformanceCounter(&start);
int bWidth = image->GetWidth();
int bHeight = image->GetHeight();
std::cout << bWidth << std::endl;
std::cout << bHeight << std::endl;
auto stride = 3 * bWidth;
pixels.resize(stride * bHeight);
Gdiplus::Rect rect(0, 0, bWidth, bHeight);
image->LockBits(&rect, Gdiplus::ImageLockModeRead, PixelFormat24bppRGB, &bmpData);
for (int y = 0; y < bHeight; ++y) {
memcpy(pixels.data() + y * stride, (byte*)bmpData.Scan0 + y * bmpData.Stride, stride);
}
image->UnlockBits(&bmpData);
Gdiplus::GdiplusShutdown(token);
uint8_t buf1, buf2;
for (int i = 2;i < pixels.size(); i += 3) {
buf1 = pixels[i - 2];
buf2 = pixels[i];
pixels[i-2] = buf2;
pixels[i] = buf1;
}
std::cout << "要素数: " << pixels.size() << "\n";
torch::Tensor tsr = torch::tensor(torch::ArrayRef<uint8_t>(pixels)).to(torch::kFloat64) / 256;
torch::Tensor input = torch::reshape(tsr, { bWidth,bHeight,3 });
torch::jit::script::Module module;
module = torch::jit::load("model to path/traced_model.pt");
QueryPerformanceCounter(&end);
double time = static_cast<double>(end.QuadPart - start.QuadPart) * 1000.0 / freq.QuadPart;
std::cout << time << "ms\n";
//system("PAUSE");
return 1;
}
How can I run torch::jit::load?
I tried to call an OpenBlas function from an OpenMP thread while the Blas parallelisation is set to a value unequal to one. I am using OpenBlas 0.3.9, after downloading the source I untared it and called
make USE_OPENMP=1
make PREFIX=/someFolder/ install
However I always get the following error message from my executeable
OpenBLAS Warning : Detect OpenMP Loop and this application may hang. Please rebuild the library with USE_OPENMP=1 option.
Does anyone know, why this is the case and how I can change it? Here is a minimal example of my code:
#include <complex>
#include <vector>
#include <random>
#include <iostream>
#include <algorithm>
#include <omp.h>
#include <cblas.h>
#include <lapacke.h>
int main(int, char**) {
int const blas_threads = 2,
omp_threads = 2,
matrix_size = 100;
openblas_set_num_threads(blas_threads);
omp_set_max_active_levels(2);
double alpha = 1.,
beta = 0.;
std::vector<std::vector<double>> as(omp_threads,
std::vector<double>(matrix_size*matrix_size));
std::vector<std::vector<double>> bs(omp_threads,
std::vector<double>(matrix_size*matrix_size));
std::vector<std::vector<double>> cs(omp_threads,
std::vector<double>(matrix_size*matrix_size));
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_real_distribution<double> dis;
for(int i = 0; i < omp_threads; ++i) {
std::generate(as[i].begin(),
as[i].end(),
[&dis,&gen]() { return dis(gen); });
std::generate(bs[i].begin(),
bs[i].end(),
[&dis,&gen]() { return dis(gen); });
}
// for(int i = 0; i < matrix_size*matrix_size; ++i) {
// std::cout << as[0][i] << " " << bs[0][i] << std::endl;
// }
#pragma omp parallel for num_threads(omp_threads), schedule(static, 1)
for(int i = 0; i < omp_threads; ++i) {
cblas_dgemm(CblasColMajor,
CblasNoTrans,
CblasNoTrans,
matrix_size,
matrix_size,
matrix_size,
alpha,
as[i].data(),
matrix_size,
bs[i].data(),
matrix_size,
beta,
cs[i].data(),
matrix_size);
}
// for(int i = 0; i < matrix_size*matrix_size; ++i) {
// std::cout << cs[0][i] << std::endl;
// }
return 0;
}
I do not why, but in Windows (with MinGW) this code generates for 3/4 time the same pseudo-random number.
I think that is because I set badly the seed, but I can not correct it.
Thank you for your help.
Here there is the code:
#include <iostream>
#include <random>
#include <chrono>
int main()
{
double Nprove = 50.0;
double p = 0.2;
const int Ncampioni = 100; // number of samples
int cappa = 0;
double sample[Ncampioni];
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::mt19937 gen(seed);
std::binomial_distribution<> d(Nprove, 0.9);
for(cappa = 0; cappa < Ncampioni; cappa = cappa +1){
sample[cappa] = d(gen);
std::cout << cappa << "," << sample[cappa] << std::endl;
}
}
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
int main()
{
string token = "000000:::AAAA:::000011:::Hello 8:::::::D Jay!";
string * stringArray = new string[token.size()];
string interim;
int r = 0;
int arrayCounter = 0;
for(int x = 0; x < token.length(); x++)
{
if(token[x] != ':')
{
interim[r] = token[x];
r++;
}
}
for (int x = 0; x < r; x++)
{
cout << interim[x] << endl;
}
system("pause");
return 0;
}
I am new and learning, and have narrowed it down to the line:
interim[r] = token[x];
..But i don't know why it crashes. Advice? I am coding in Visual C++ VSE2012
The string interim has a size of zero. Setting interim[r] = token[x] modifies the string at location r without changing its size. With a size of zero this is undefined behavior.
interim += token[x] is probably what you want.
Example:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string token = "000000:::AAAA:::000011:::Hello 8:::::::D Jay!";
string interim;
for(int x = 0; x < token.length(); x++)
{
if(token[x] != ':')
{
interim += token[x];
}
}
cout << interim << endl;
system("pause");
return 0;
}
Output:
000000AAAA000011Hello 8D Jay!
Press any key to continue . . .
I am updating some older OpenCV code that was written in (I guess) an OpenCV 1.1 manner (i.e. using IplImages).
What I want to accomplish right now is to simply load a series of images (passed as command line arguments) as Mats. This is part of a larger task. The first code sample below is the old code's image loading method. It loads 5 images from the command line and displays them in sequence, pausing for a key hit after each, then exits.
The second code sample is my updated version using Mat. It works fine so far, but is this the best way to do this? I've used an array of Mats. Should I use an array of pointers to Mats instead? And is there a way to do this such that the number of images is determined at run time from argc and does not need to be set ahead of time with IMAGE_NUM.
Basically, I'd like to be able to pass any number (within reason) of images as command line arguments, and have them loaded into some convenient array or other similar storage for later reference.
Thanks.
Old code:
#include <iostream>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
using namespace std;
using namespace cv;
// the number of input images
#define IMAGE_NUM 5
int main(int argc, char **argv)
{
uchar **imgdata;
IplImage **img;
int index = 0;
char *img_file[IMAGE_NUM];
cout << "Loading files" << endl;
while(++index < argc)
if (index <= IMAGE_NUM)
img_file[index-1] = argv[index];
// malloc memory for images
img = (IplImage **)malloc(IMAGE_NUM * sizeof(IplImage *)); // Allocates memory to store just an IplImage pointer for each image loaded
imgdata = (uchar **)malloc(IMAGE_NUM * sizeof(uchar *));
// load images. Note: cvLoadImage actually allocates the memory for the images
for (index = 0; index < IMAGE_NUM; index++) {
img[index] = cvLoadImage(img_file[index], 1);
if (!img[index]->imageData){
cout << "Image data not loaded properly" << endl;
return -1;
}
imgdata[index] = (uchar *)img[index]->imageData;
}
for (index = 0; index < IMAGE_NUM; index++){
imshow("myWin", img[index]);
waitKey(0);
}
cvDestroyWindow("myWin");
cvReleaseImage(img);
return 0;
}
New code:
#include <iostream>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include <time.h>
using namespace std;
using namespace cv;
// the number of input images
#define IMAGE_NUM 5
int main(int argc, char **argv)
{
Mat img[IMAGE_NUM];
int index = 0;
for (index = 0; index < IMAGE_NUM; index++) {
img[index] = imread(argv[index+1]);
if (!img[index].data){
cout << "Image data not loaded properly" << endl;
cin.get();
return -1;
}
}
for (index = 0; index < IMAGE_NUM; index++) {
imshow("myWin", img[index]);
waitKey(0);
}
cvDestroyWindow("myWin");
return 0;
}
you can use a vector instead of an array:
for example
#include <iostream>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include <time.h>
#include <vector>
using namespace std;
using namespace cv;
int main(int argc, char **argv)
{
vector<Mat> img;
//Mat img[IMAGE_NUM];
int index = 0;
for (index = 0; index < IMAGE_NUM; index++) {
//img[index] = imread(argv[index+1]);
img.push_back(imread(argy[index+1]));
if (!img[index].data){
cout << "Image data not loaded properly" << endl;
cin.get();
return -1;
}
}
vector<Mat>::iterator it;
for (it = img.begin(); it != img.end() ; it++) {
imshow("myWin", (*it));
waitKey(0);
}
cvDestroyWindow("myWin");
return 0;
}
It took me a while to get back around to this, but what I've ended up doing is as follows, which is probably functionally the same as Gootik's suggestion. This has worked well for me. Notice that for functions that take Mat& (i.e. a single cv::Mat), you can just de-ref the array of Mats and pass that, which is a notation I'm more comfortable with after doing a lot of image processing work in Matlab.
#include <iostream>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
using namespace std;
using namespace cv;
int main(int argc, char **argv)
{
if (argc==1){
cout << "No images to load!" << endl;
cin.get();
return 0;
}
int index = 0;
int image_num = argc-1;
Mat *img = new Mat[image_num]; // allocates table on heap instead of stack
// Load the images from command line:
for (index = 0; index < image_num; index++) {
img[index] = imread(argv[index+1]);
if (!img[index].data){
cout << "Image data not loaded properly" << endl;
cin.get();
return -1;
}
}
for (index = 0; index < image_num; index++) {
imshow("myWin", img[index]);
waitKey(0);
}
cvDestroyWindow("myWin");
delete [] img; // notice the [] when deleting an array.
return 0;
}