Related
I am a newbie to c++ and the IDE I am using is Visual Studio '22. I have written a code to detect a face (eyes and mouth too) and save the roi to a folder on the pc. Now what it does can be thought of as an auto-capture of the roi as soon as the face is detected.
I now want to create the function for "force capture", for which I will need to have a button and add pretty much the same code I wrote for auto-capture to give it functionality.
How do I add the button and make it perform its task?
I found related answers but they use Qt not sure how to apply that here.
Thanks a ton! Really need help.
#include <opencv2/opencv.hpp>
#include <opencv2/dnn/dnn.hpp>
//(1) include face header
#include "opencv2/face.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
//(2) include face header
#include "opencv2/objdetect.hpp"
#include <iostream>
#include <opencv2/imgproc/types_c.h>
//file handling
#include <fstream>
#include <sstream>
using namespace cv;
using namespace std;
using namespace ml;
using namespace cv::face;
//(3) Global variables
Ptr<Facemark> facemark; //mark detection
CascadeClassifier faceDetector, mouth, eye, eye1; //face detection
string name, filename;
void process(Mat img, Mat imgcol) {
vector<Rect> faces;
faceDetector.detectMultiScale(img, faces);
Mat imFace;
if (faces.size() != 0) {
for (size_t i = 0; i < faces.size(); i++)
{
cv::rectangle(imgcol, faces[i], Scalar(255, 0, 0));
imFace = imgcol(faces[i]);
resize(imFace, imFace, Size(imFace.cols * 5, imFace.rows * 5));
faces[i] = Rect(faces[i].x = 0, faces[i].y = 0, faces[i].width * 5,
(faces[i].height) * 5);
}
vector< vector<Point2f> > shapes;
//vector < Rect > measures;
if (facemark->fit(imFace, faces, shapes)) //fiiting predef shapes in faces// // imface is the size of faces
{
for (unsigned long i = 0; i < faces.size(); i++) {
for (unsigned long k = 0; k < shapes[i].size(); k++) {
cv::circle(imFace, shapes[i][k], 5, cv::Scalar(0, 0, 255), FILLED);
}
}
}
namedWindow("Detected_shape");
imshow("Detected_shape", imFace);
waitKey(5);
}
else {
cout << "Faces not detected." << endl;
}
}
int main()
{
facemark = FacemarkLBF::create();
facemark->loadModel("C:/Dev/HeadPose/HeadPose/lbfmodel.yml");
faceDetector.load("D:/opencv/build/install/etc/haarcascades/haarcascade_frontalface_alt2.xml");
mouth.load("D:/opencv/build/install/etc/haarcascades/haarcascade_smile.xml");
eye.load("D:/opencv/build/install/etc/haarcascades/haarcascade_eye.xml");
cout << "Loaded model" << endl;
Mat frame, grayframe, testframe, faceROI;
int x_axis, y_axis;
namedWindow("Detecting");
VideoCapture cap(0); //1 for diff cam
while (1)
{
cap.read(frame);
if (!cap.read(frame))
{
cout << "an error while taking the frame from cap" << endl;
}
//face
vector<Rect> faces;
Mat frame_gray;
Mat crop;
Mat res;
Mat gray;
string text;
stringstream sstm;
cvtColor(frame, grayframe, CV_BGR2GRAY);
equalizeHist(grayframe, testframe);
faceDetector.detectMultiScale(testframe, faces, 1.1, 3, CASCADE_SCALE_IMAGE, Size(30, 30));
Rect roi_b;
Rect roi_c;
size_t ic = 0;
int ac = 0;
size_t ib = 0;
int ab = 0;
for (int ic = 0; ic < faces.size(); ic++)
{
roi_b.x = faces[ib].x;
roi_b.y = faces[ib].y;
roi_b.width = (faces[ib].width);
roi_b.height = (faces[ib].height);
crop = frame(roi_b);
resize(crop, res, Size(128, 128), 0, 0, INTER_LINEAR);
cvtColor(crop, gray, COLOR_BGR2GRAY);
stringstream ssfn;
filename = "C:\\Users\\Hp\\Desktop\\Faces\\";
ssfn << filename.c_str() << name <<"_"<< roi_b.width<<"_"<< roi_b.height << ".jpg";
filename = ssfn.str();
imwrite(filename, res);
rectangle(frame, faces[ic], Scalar(255, 0, 255), 2, 8, 0);
Mat face = frame(faces[ic]);
cvtColor(face, face, CV_BGR2GRAY);
//mouth
vector <Rect> mouthi;
mouth.detectMultiScale(face, mouthi);
for (int k = 0; k < mouthi.size(); k++)
{
Point pt1(mouthi[0].x + faces[ic].x, mouthi[0].y + faces[ic].y);
Point pt2(pt1.x + mouthi[0].width, pt1.y + mouthi[0].height);
rectangle(frame, pt1, pt2, Scalar(255, 0, 0), 1, 8, 0);
}
//eyes
faceROI = frame(faces[ic]);//Taking area of the face as Region of Interest for eyes//
vector<Rect>eyes;//declaring a vector named eyes//
eye.detectMultiScale(faceROI, eyes, 1.1, 3, 0 | CASCADE_SCALE_IMAGE, Size(5, 5)); //detect eyes in every face//
/*eye1.detectMultiScale(faceROI, eyes, 1.1, 3, 0 | CASCADE_SCALE_IMAGE, Size(5, 5));*/
for (size_t j = 0; j < eyes.size(); j++)
{ //for locating eyes//
Point center(faces[ic].x + eyes[j].x + eyes[j].width * 0.5, faces[ic].y + eyes[j].y + eyes[j].height * 0.5);//getting the centers of both eyes//
int radius = cvRound((eyes[j].width + eyes[j].height) * 0.25); //declaring radius of the eye enclosing circles//
// cout << "radius" << radius << endl;
circle(frame, center, radius, Scalar(255, 0, 0), 1, 8, 0);//drawing circle around both eyes//
x_axis = eyes[j].x;//storing x axis location of eyes in x_axis//
y_axis = eyes[j].y;//storing y axis location of eyes in y_axis//
cout << "Position of the eyes is:" << "(" << x_axis << "," << y_axis << ")" << endl;//showing co-ordinate values//
}
}
sstm << "Crop area size: " << roi_b.width << "x" << roi_b.height << " Filename: " << filename;
text = sstm.str();
if (!crop.empty()) {
imshow("detected", crop);
}
else destroyWindow("detected");
cout << "Name\n";
cin >> name;
Mat img; //image containers
Mat imgbw;
cap >> img; //image from webcam
resize(img, img, Size(460, 460), 0, 0, INTER_LINEAR_EXACT);
cvtColor(img, imgbw, COLOR_BGR2GRAY);
process(imgbw, img);
imshow("Detecting", frame);
if (waitKey(30) == 27) {
break;
}
}
return 0;
}
I have downloaded a program from a YouTube video, it should be able to detect a red rectangle and calculate the distance.
(https://www.youtube.com/watch?v=3Xl8yWvMPl8)
I've never used C++ so that's why I actually need some help.
The error I get when I launch the console is the following:;
"OpenCV Error: Assertion failed (scn == 3 || scn == 4) in cv::cvtColor, file C:\builds\2_4_PackSlave-win64-vc12-shared\opencv\modules\imgproc\src\color.cpp, line 3739"
I'm not sure what it means, and I don't know how I should fix it.
I've managed to include all the files and using the correct libraries but it won't work. Personally I don't have a webcam, but I asked a friend of mine, which has one, to try out the program but he gets the same error.
So here is the code:
#include "stdafx.h"
#include "cv.h"
#include "highgui.h"
#include "opencv2\imgproc\imgproc_c.h"
#include <fstream>
#include "math.h"
int _tmain(int argc, _TCHAR* argv[])
{
using namespace std;
using namespace cv;
Mat img, img_gray, channel[3];
VideoCapture cam(1);
double distance = 0;
//FILE *data;
//data = fopen("data320.csv","a");
cam.set(CV_CAP_PROP_FRAME_WIDTH, 1280);
cam.set(CV_CAP_PROP_FRAME_HEIGHT, 720);
cam.set(CV_CAP_PROP_CONVERT_RGB, 1);
namedWindow("Frame", WINDOW_AUTOSIZE);
while (waitKey(10) != 'a')
{
cam >> img;
cvtColor(img, img_gray, COLOR_RGB2GRAY);
split(img, channel);
subtract(channel[2], img_gray, img_gray);
//convertScaleAbs(img, img);
threshold(img_gray, img_gray, 90, 255, THRESH_BINARY);
erode(img_gray, img_gray, Mat(), Point(-1, -1), 4);
dilate(img_gray, img_gray, Mat(), Point(-1, -1), 4);
vector<vector<Size>> contors;
vector<Vec4i> heirarcy;
findContours(img_gray, contors, heirarcy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
vector<Rect> boundRect(contors.size());
vector<vector<Point>> contor_poly(contors.size());
for (int i = 0; i< contors.size(); i++)
{
approxPolyDP(Mat(contors[i]), contor_poly[i], 3, true);
boundRect[i] = boundingRect(Mat(contor_poly[i]));
}
int max_index = 0, max_area = 0;
for (int i = 0; i< boundRect.size(); i++)
{
int a = boundRect[i].area();
rectangle(img, boundRect[i].tl(), boundRect[i].br(), Scalar(255, 255, 0), 2, 8, 0);
if (a > max_area)
{
max_area = a;
max_index = i;
}
}
int confidence = 0;
for (int i = 0; i< boundRect.size(); i++)
{
if ((boundRect[i].x < boundRect[max_index].x + boundRect[max_index].width && boundRect[i].x > boundRect[max_index].x - int(0.1*boundRect[max_index].width)) && (boundRect[i].y > boundRect[max_index].y))
confidence += 45;
}
if (boundRect.size() > 0)
{
if (confidence > 99)
confidence = 0;
//try{
//Mat sub_image = Mat(img, Rect(max(boundRect[max_index].x-30, 0), max(boundRect[max_index].y-30, 0), min(int(boundRect[max_index].width*1.75), img.cols - boundRect[max_index].x+30), min(boundRect[max_index].height*3, img.rows - boundRect[max_index].y+30)));
//imshow("Frame", sub_image);
//}catch(int e){
// cout<<"Error occured"<<endl;
//}
rectangle(img, boundRect[max_index].tl(), boundRect[max_index].br(), Scalar(0, 255, 0), 2, 8, 0);
//fprintf(data,"%d , %d , %d\n", boundRect[max_index].width, boundRect[max_index].height, boundRect[max_index].area());
distance = 8414.7*pow(boundRect[max_index].area(), -0.468);
cout << distance << " cm." << " Confidence: " << confidence << endl;
imshow("Frame", img);
}
else
imshow("Frame", img);
}
//fflush(data);
//fclose(data);
cam.release();
return 0;
}
Check shape of image before calling cvtColor, it work only if image shape greater than 2
if(img.size>2)
cvtColor(img, img_gray, COLOR_RGB2GRAY)
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
I'm using Opencv2.4.6 and Netbeans IDE for C++.
I'm trying to do a program to detect a face with the CascadeClassifier, and then pass the Rect of the face to the Camshift function to track this face.
To do that, I took the sample code "Camshiftdemo.cpp" that comes in the samples folder of opencv and I've modified. In my code instead of use the mouse to select the region over which you want to do tracking, is the cascade classifier which passes that information.
#include "opencv2/video/tracking.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include <iostream>
#include <ctype.h>
using namespace cv;
using namespace std;
Mat image;
int trackObject = 0;
Rect selection;
int main()
{
VideoCapture cap;
Rect trackWindow;
int hsize = 16;
float hranges[] = {0,180};
const float* phranges = hranges;
int matchesNum = 0;
CascadeClassifier cascade;
if (!cascade.load("C:/opencv/data/haarcascades/haarcascade_frontalface_default.xml")) {
cout << "Cannot load face xml!" << endl;
return -1;
}
cap.open("D:/Videos_Proy/ProgramacionII/CAMERA3_clase1.MP4");
if (!cap.isOpened()) {
cout << "***Could not initialize capturing...***\n";
return -1;
}
namedWindow( "Result", 1 );
Mat frame, hsv, hue, hist, mask, backproj;
for(;;)
{
cap >> frame;
if( frame.empty() )
break;
frame.copyTo(image);
if ( !trackObject )
{
Mat grayframe;
vector <Rect> facesBuf;
int detectionsNum = 0;
cvtColor(image, grayframe, CV_BGR2GRAY);
cascade.detectMultiScale(grayframe, facesBuf, 1.2, 4, CV_HAAR_FIND_BIGGEST_OBJECT |
CV_HAAR_SCALE_IMAGE, cvSize(0, 0));
detectionsNum = (int) facesBuf.size();
Rect *faceRects = &facesBuf[0];
//It must found faces in three consecutives frames to start the tracking to discard false positives
if (detectionsNum > 0)
matchesNum += 1;
else matchesNum = 0;
if ( matchesNum == 3 )
{
trackObject = -1;
selection = faceRects[0];
}
for (int i = 0; i < detectionsNum; i++)
{
Rect r = faceRects[i];
rectangle(image, Point(r.x, r.y), Point(r.x + r.width, r.y + r.height), CV_RGB(0, 255, 0));
}
}
if( trackObject )
{
cvtColor(image, hsv, CV_BGR2HSV);
inRange(hsv, Scalar(0, 69, 53),
Scalar(180, 256, 256), mask);
int ch[] = {0, 0};
hue.create(hsv.size(), hsv.depth());
mixChannels(&hsv, 1, &hue, 1, ch, 1);
if( trackObject < 0 )
{
Mat roi(hue, selection), maskroi(mask, selection);
calcHist(&roi, 1, 0, maskroi, hist, 1, &hsize, &phranges);
normalize(hist, hist, 0, 255, CV_MINMAX);
trackWindow = selection;
trackObject = 1;
}
calcBackProject(&hue, 1, 0, hist, backproj, &phranges);
backproj &= mask;
RotatedRect trackBox = CamShift(backproj, trackWindow,
TermCriteria( CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1 ));
if( trackWindow.area() <= 1 )
{
int cols = backproj.cols, rows = backproj.rows, r = (MIN(cols, rows) + 5)/6;
trackWindow = Rect(trackWindow.x - r, trackWindow.y - r,
trackWindow.x + r, trackWindow.y + r) &
Rect(0, 0, cols, rows);
}
ellipse( image, trackBox, Scalar(0,0,255), 3, CV_AA );
}
imshow( "Result", image );
if(waitKey(30) >= 0) break;
}
return 0;
}
This code makes sense to me, and when I Build it in Netbeans do not get any error, the problem is that don't run and Netbeans don't give any clue, only says: RUN FAILED (exit value -1.073.741.819, total time: 5s)
Anyone could help me and give any idea about what is happening. Thanks!!
Base from this here.
I got this error and this is the only one left for almost 3 days of my trial and error in debugging:
Unhandled exception at 0x000007FEEC6315A4 (opencv_imgproc242.dll) in PCA.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
Please can someone here who can help me with this. Im currently using VS2012 and my os is win7 64-bit. I configure my opencv 2.4.2 following this blog.
Please help!
I've corrected some minor bugs (and now it works perfect for me):
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
double getOrientation(vector<Point> &pts, Mat &img)
{
if (pts.size() == 0) return false;
//Construct a buffer used by the pca analysis
Mat data_pts = Mat(pts.size(), 2, CV_64FC1);
for (int i = 0; i < data_pts.rows; ++i)
{
data_pts.at<double>(i, 0) = pts[i].x;
data_pts.at<double>(i, 1) = pts[i].y;
}
//Perform PCA analysis
PCA pca_analysis(data_pts, Mat(), CV_PCA_DATA_AS_ROW);
//Store the position of the object
Point pos = Point(pca_analysis.mean.at<double>(0, 0),
pca_analysis.mean.at<double>(0, 1));
//Store the eigenvalues and eigenvectors
vector<Point2d> eigen_vecs(2);
vector<double> eigen_val(2);
for (int i = 0; i < 2; ++i)
{
eigen_vecs[i] = Point2d(pca_analysis.eigenvectors.at<double>(i, 0),
pca_analysis.eigenvectors.at<double>(i, 1));
eigen_val[i] = pca_analysis.eigenvalues.at<double>(i);
}
// Draw the principal components
circle(img, pos, 3, CV_RGB(255, 0, 255), 2);
line(img, pos, pos + 0.02 * Point(eigen_vecs[0].x * eigen_val[0], eigen_vecs[0].y * eigen_val[0]) , CV_RGB(255, 255, 0));
line(img, pos, pos + 0.02 * Point(eigen_vecs[1].x * eigen_val[1], eigen_vecs[1].y * eigen_val[1]) , CV_RGB(0, 255, 255));
return atan2(eigen_vecs[0].y, eigen_vecs[0].x);
}
int main()
{
// Read the image
Mat bw, img = imread("pca_test1.jpg",1); // "pca_test2.jpg"
// Convert it to greyscale
cvtColor(img, bw, COLOR_BGR2GRAY);
// Apply thresholding
threshold(bw, bw, 150, 255, cv::THRESH_BINARY);
// Find all objects of interest
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours(bw, contours, hierarchy, cv::RETR_LIST, cv::CHAIN_APPROX_NONE);
// For each object
for (size_t i = 0; i < contours.size(); ++i)
{
// Calculate its area
double area = contourArea(contours[i]);
// Ignore if too small or too large
if (area < 1e2 || 1e5 < area) continue;
// Draw the contour
drawContours(img, contours, i, CV_RGB(255, 0, 0), 2, 8, hierarchy, 0);
// Get the object orientation
getOrientation(contours[i], img);
}
imshow("Image", img);
char key;
while (true)
{
key = waitKey(1);
if (key == 'q') break;
}
cv::destroyAllWindows();
return 0;
}