I'm new for using HOG detector to detect humans on the road, and I've already write the code and try to run it, but it always have the error on the this line: "hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());" this line, can any one tell me what's wrong with my code?
#include < stdio.h>
#include < iostream>
#include < opencv2\opencv.hpp>
#include < opencv2/core/core.hpp>
#include < opencv2/highgui/highgui.hpp>
#include < opencv2/video/background_segm.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/objdetect.hpp>
#include <peopledetect.cpp>
using namespace cv;
using namespace std;
int main(int argc, const char * argv[])
{
VideoCapture cap(0);
cap.set(CV_CAP_PROP_FRAME_WIDTH, 320);
cap.set(CV_CAP_PROP_FRAME_HEIGHT, 240);
if (!cap.isOpened())
return -1;
Mat img;
namedWindow("opencv", CV_WINDOW_AUTOSIZE);
HOGDescriptor hog;
hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());
while (true)
{
cap >> img;
if (img.empty())
continue;
vector<Rect> found, found_filtered;
hog.detectMultiScale(img, found, 0, Size(8, 8), Size(32, 32), 1.05, 2);
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);
}
imshow("opencv", img);
waitKey(1);
}
return 0;
}
In general, you should never include .cpp files in a C++ program. There are .h and .hpp headers for that.
Now, for your particular problem, if we're talking about the same peopledetect.cpp, the function you want is not defined there but in a header included there... You probably already have the right header (objdetect.hpp) so just remove the #include <peopledetect.cpp> line
Related
I'm writing a program to recognize the numbers on the image.
I do not see an error in the code. You receive a runtime exception. Indicates Mat.
I use Visual Studio 2015 Community and OpenCV 3.1.
Kmeans segmentation code found on stackoverflow.
Exeption:
test_opencv_nuget.exe!cv::Mat::at >(int i0, int i1)Строка 918 C++
mat.inl.hpp file
line:
CV_DbgAssert((unsigned)(i1 * DataType<_Tp>::channels) < (unsigned)(size.p[1] * channels()));
#include "opencv2/opencv.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/core.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
VideoCapture cap;
if (!cap.open(0))
return 0;
Mat camera_image;
Mat gray_scale_image;
Mat binary_image;
Mat otsu_binary_image;
Mat laplas_circuit_image;
for (;;)
{
cap >> camera_image;
cvtColor(camera_image, gray_scale_image, cv::COLOR_RGB2GRAY);
threshold(gray_scale_image, otsu_binary_image, 0, 255, CV_THRESH_OTSU);
Mat laplas_kernel = (Mat_<float>(3, 3) << 0, 1, 0,
1, -4, 1,
0, 1, 0);
filter2D(otsu_binary_image, laplas_circuit_image, -1, laplas_kernel);
Mat samples(otsu_binary_image.rows * otsu_binary_image.cols, 3, CV_32F);
for (int y = 0; y < otsu_binary_image.rows; y++)
for (int x = 0; x < otsu_binary_image.cols; x++)
for (int z = 0; z < 3; z++)
samples.at<float>(y + x*otsu_binary_image.rows, z) = otsu_binary_image.at<Vec3b>(y, x)[z];
int clusterCount = 5;
Mat labels;
int attempts = 5;
Mat centers;
kmeans(samples, clusterCount, labels, TermCriteria(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 10000, 0.0001), attempts, KMEANS_PP_CENTERS, centers);
Mat kmeans_image(otsu_binary_image.size(), otsu_binary_image.type());
for (int y = 0; y < otsu_binary_image.rows; y++)
for (int x = 0; x < otsu_binary_image.cols; x++)
{
int cluster_idx = labels.at<int>(y + x*otsu_binary_image.rows, 0);
kmeans_image.at<Vec3b>(y, x)[0] = centers.at<float>(cluster_idx, 0);
kmeans_image.at<Vec3b>(y, x)[1] = centers.at<float>(cluster_idx, 1);
kmeans_image.at<Vec3b>(y, x)[2] = centers.at<float>(cluster_idx, 2);
}
imshow("original", camera_image);
imshow("gray_scale", gray_scale_image);
imshow("otsu", otsu_binary_image);
imshow("laplas_circuit", laplas_circuit_image);
imshow("clusters", kmeans_image);
char c = cvWaitKey(33);
if (c == 27) break; // press ESC
}
return 0;
}
I'm a novice programmer. My experience is very small. Now I have a code to detected people. I use SVM classifier and a HOG descriptor. Video is very long to be loaded and processed. Please help me with this problem.
#include <assert.h>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <conio.h>
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace std;
int main()
{
string filename = "Street.MP4";
VideoCapture capture(filename);
Mat frame;
//namedWindow("w", 1);
while (true)
{
capture >> frame;
if (frame.empty())
break;
Mat img, res;
Mat framecopy = frame.clone();
resize(framecopy, img, Size(2 * framecopy.cols, 2 * framecopy.rows));
int nbins = 9;
Size cellSize(8, 8);
Size blockSize(16, 16);
Size blockStride(8, 8);
Size winSize(64, 128);
Size winStride(4, 4);
HOGDescriptor hog(winSize, blockSize, blockStride, cellSize, nbins);
hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());
assert(hog.checkDetectorSize());
vector<Rect> locations;
vector<double> weights;
hog.detectMultiScale(img, locations, weights, 0.0, winStride, Size(), 1.05, 2., true);
resize(img, res, Size(framecopy.cols / 2, framecopy.rows / 2));
for (size_t i = 0; i < locations.size(); ++i)
{
Rect detection = locations[i];
detection.x /= 2;
detection.y /= 2;
detection.width /= 2;
detection.height /= 2;
rectangle(res, detection, Scalar(0, 0, 255), 2);
}
imshow("w", res);
waitKey(20); // waits to display frame
}
waitKey();
return 0;
}
Don't create the hog detector in each iteration.
try:
#include <assert.h>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <conio.h>
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace std;
int main()
{
string filename = "Street.MP4";
VideoCapture capture(filename);
Mat frame;
//namedWindow("w", 1);
int nbins = 9;
Size cellSize(8, 8);
Size blockSize(16, 16);
Size blockStride(8, 8);
Size winSize(64, 128);
Size winStride(4, 4);
HOGDescriptor hog(winSize, blockSize, blockStride, cellSize, nbins);
hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());
assert(hog.checkDetectorSize());
while (true)
{
capture >> frame;
if (frame.empty())
break;
Mat img, res;
Mat framecopy = frame.clone();
resize(framecopy, img, Size(2 * framecopy.cols, 2 * framecopy.rows));
vector<Rect> locations;
vector<double> weights;
hog.detectMultiScale(img, locations, weights, 0.0, winStride, Size(), 1.05, 2., true);
resize(img, res, Size(framecopy.cols / 2, framecopy.rows / 2));
for (size_t i = 0; i < locations.size(); ++i)
{
Rect detection = locations[i];
detection.x /= 2;
detection.y /= 2;
detection.width /= 2;
detection.height /= 2;
rectangle(res, detection, Scalar(0, 0, 255), 2);
}
imshow("w", res);
waitKey(1); // waits to display frame
}
waitKey();
return 0;
}
But keep in mind that HoG detection is a quite expensive operation. What's the resolution of your images?
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main ()
{
VideoCapture cap("/opencv/images/people.avi");
if (!cap.isOpened())
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(8,8), Size(32,32), 1.05, 2);
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];
Point textOrg(r.x,r.y);
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);
putText(img, "human", textOrg,
FONT_HERSHEY_COMPLEX_SMALL, 0.8, Scalar::all(000), 1, CV_AA);
}
imshow("video capture", img);
if (waitKey(20) >= 0)
{ break;}
}
return 0;
}
above code can used to detect people in every frame using hog. But I want to track those people for action recognition.I hope to use dense optical flow for action recognition.Can I us hog descriptor for tracking or is there any other good method.
I want to use the fitLine function to come up with a line to draw on my source image src_crop. I load the frame in my main() and call the drawLine().
But the code aborts with the following error :
Code:
#include "stdafx.h"
#include <fstream>
#include <iostream>
#include <vector>
#include <stdlib.h>
#include <stdio.h>
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
using namespace std;
using namespace cv;
/// Global variables
Mat src_gray;
Mat src_crop;
Mat dst, detected_edges;
int edgeThresh = 1;
int lowThreshold = 27;
int const max_lowThreshold = 100;
int ratio = 3;
int kernel_size = 3;
char* window_name = "Edge Map";
int i,j;
void drawLine(int, void*)
{
vector<Vec4f> outline;
vector<Point2f> ssline;
int flag2 = 0;
/// Reduce noise with a kernel 3x3
blur(src_gray, detected_edges, Size(3, 3));
/// Canny detector
Canny(detected_edges, detected_edges, lowThreshold, lowThreshold*ratio, kernel_size);
/// Using Canny's output as a mask, we display our result
dst.create(detected_edges.size(), detected_edges.type());
dst = Scalar::all(0);
src_crop.copyTo(dst, detected_edges);
//namedWindow("Detected Edges", CV_WINDOW_AUTOSIZE);
//imshow("Detected Edges", detected_edges);
cvtColor(dst, dst, CV_BGR2GRAY);
for (j = 0; j < dst.cols; j++)
{
for (i = 0; i < dst.rows; i++)
{
if (Scalar(dst.at<uchar>(i,j)).val[0] >= 90)
{
//cout << "Hi";
flag2 = 1;
break;
}
}
if (flag2 == 1)
break;
}
int k = j;
int l = i;
for (j = k; j < dst.cols; j++)
{
Point2f ss = Point2f(l,j);
ssline.push_back(ss);
}
fitLine(ssline, outline, CV_DIST_L1, 0, 0.01, 0.01);
//imshow("Result", src_crop);
}
int main(int argc, char** argv)
{
/// Load an image
src = imread(s);
if (!src.data)
{
return -1;
}
/// Create a matrix of the same type and size as src (for dst)
//dst.create(src.size(), src.type());
src_crop = src;
/// Convert the image to grayscale
cvtColor(src_crop, src_gray, CV_BGR2GRAY);
/// Create a window
namedWindow(window_name, CV_WINDOW_AUTOSIZE);
/// Create a Trackbar for user to enter threshold
createTrackbar("Min Threshold:", window_name, &lowThreshold, max_lowThreshold, drawLine);
/// Show the image
drawLine(0, 0);
if (waitKey(30) >= 0) break;
return 0;
}
The code stops working at the point fitLine() is called. This I found by testing the code with printf statements.
Can anyone kindly help me solve the issue?
Aside the fact the your code won't compile, the issue is that you're passing to fitLine the parameter outline as a vector<Vec4f>, while it should be a Vec4f.
Change outline declaration as:
Vec4f outline;
The Hog based multi scale detector is not able to detect any of the faces or even any human. According to the peopledetect.cpp in OpenCV examples, I am trying to detect the people but not getting what I am missing here. Following the code that I am trying:
#include "cvaux.h"
#include "highgui.h"
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <ctype.h>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
Mat img;
FILE* f = 0;
char _filename[1024];
if( argc == 1 )
{
printf("Usage: peopledetect (<image_filename>\n");
return 0;
}
img = imread(argv[1]);
if( img.data )
{
strcpy(_filename, argv[1]);
}
HOGDescriptor hog;
hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());
for(;;)
{
char* filename = _filename;
printf("%s:\n", filename);
if(!img.data)
continue;
fflush(stdout);
vector<Rect> found, found_filtered;
double t = (double)getTickCount();
hog.detectMultiScale(img, found, 0, Size(8,8), Size(32,32), 1.05, 2);
cout<<found.size()<<endl; // To check how many faces detected.
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];cout<<i<<endl;
for( j = 0; j < found.size(); j++ )
if( j != i && (r & found[j]) == r)
break;
if( j == found.size() )
found_filtered.push_back(r);
cout<<found_filtered.size()<<endl;
}
imshow("people detector", img);
int c = waitKey(0) & 255;
}
return 0;
}
Any picture is not being detected for anything. What might be the issue? Am I not linking something ?