I am trying out face detection using OpenCV and am pretty new to OpenCV.
Here's my code:
#include <opencv2/core/core.hpp>
#include <opencv2/contrib/contrib.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <iostream>
#include <fstream>
#include <sstream>
using namespace cv;
using namespace std;
static void read_csv(const string& filename, vector<Mat>& images, vector<int>& labels, char separator = ';') {
std::ifstream file(filename.c_str(), ifstream::in);
if (!file) {
string error_message = "No valid input file was given, please check the given filename.";
CV_Error(CV_StsBadArg, error_message);
}
string line, path, classlabel;
while (getline(file, line)) {
stringstream liness(line);
getline(liness, path, separator);
getline(liness, classlabel);
if (!path.empty() && !classlabel.empty()) {
images.push_back(imread(path, 0));
labels.push_back(atoi(classlabel.c_str()));
}
}
}
int main(int argc, const char *argv[]) {
string fn_haar = "haarcascade_frontalface_alt2.xml";
string fn_csv = "reader.txt";
int deviceId = 0;
// These vectors hold the images and corresponding labels:
vector<Mat> images;
vector<int> labels;
try {
read_csv(fn_csv, images, labels);
}
catch (cv::Exception& e) {
cerr << "Error opening file \"" << fn_csv << "\". Reason: " << e.msg << endl;
// nothing more we can do
exit(1);
}
int im_width = images[0].cols;
int im_height = images[0].rows;
Ptr<FaceRecognizer> model = createFisherFaceRecognizer();
model->train(images, labels);
CascadeClassifier haar_cascade;
haar_cascade.load(fn_haar);
VideoCapture cap(deviceId);
if (!cap.isOpened()) {
cerr << "Capture Device ID " << deviceId << "cannot be opened." << endl;
return -1;
}
Mat frame;
while (true) {
cap >> frame;
Mat original = frame.clone();
Mat gray;
cvtColor(original, gray, CV_BGR2GRAY);
vector< Rect_<int> > faces;
haar_cascade.detectMultiScale(gray, faces);
for (int i = 0; i < faces.size(); i++) {
Rect face_i = faces[i];
Mat face = gray(face_i);
Mat face_resized;
cv::resize(face, face_resized, Size(im_width, im_height), 1.0, 1.0, INTER_CUBIC);
int prediction = model->predict(face_resized);
rectangle(original, face_i, CV_RGB(0, 255, 0), 1);
string box_text = format("Prediction = %d", prediction);
int pos_x = std::max(face_i.tl().x - 10, 0);
int pos_y = std::max(face_i.tl().y - 10, 0);
putText(original, box_text, Point(pos_x, pos_y), FONT_HERSHEY_PLAIN, 1.0, CV_RGB(0, 255, 0), 2.0);
}
namedWindow("face_recognizer", 1);
imshow("face_recognizer", original);
char key = (char)waitKey(20);
if (key == 27)
break;
}
return 0;
}
And here's my reader.txt file
C:\Users\Hitanshu Dhawan\Documents\Visual Studio 2013\Projects\ConsoleApplication21\ConsoleApplication21\obama\obama1.jpg;0
C:\Users\Hitanshu Dhawan\Documents\Visual Studio 2013\Projects\ConsoleApplication21\ConsoleApplication21\obama\obama2.jpg;0
Now, the problem is my code is not working and it shows some error "Exception at memory location" and "Integer division by zero" and "opencv_core2410d.pdb not loaded"...
I've tried many ways such as adding different lib in Linker > Input.
Also I've checked the Microsoft Symbol Servers.
Also my .xml and .csv files are properly copied into the application folder!
Here are some screenshots:
Related
I am developing a face detection algorithm in c++ visual studio with haar cascade method.
At the below line application quits while the same application works perfectly in linux environment.
Is there any opencv configuration which might cause this?
Any help would be really great.
frontfaceCascade.detectMultiScale(grey_image, faces, 1.1, 0, 0 |
CV_HAAR_SCALE_IMAGE, cv::Size(30, 30));
Thanks.
#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include <iostream>
#include <thread>
#include <stdlib.h>
#include <corecrt_math_defines.h>
using namespace std;
using namespace cv;
vector<Mat> Frames;
void getFrames(char* fileName);
cv::CascadeClassifier frontfaceCascade;
cv::CascadeClassifier sidefaceCascade;
int main(int argc, char *argv[]) {
if (argc < 2) {
cout << " enter file name: \n";
exit(1);
}
char* fileName = argv[1];
// if( !frontfaceCascade.load("lbpcascade_frontalface.xml")){
if (!frontfaceCascade.load("haarcascade_frontalface_default.xml")) {
std::cout << "Error Loading frontface haarcascade" << std::endl;
}
if (!sidefaceCascade.load("haarcascade_profileface.xml"))
{
std::cout << "Error Loading sideface haarcascade" << std::endl;
}
namedWindow("Faces", WINDOW_NORMAL);
resizeWindow("Faces", 100, 400);
moveWindow("Faces", 30, 100);
getFrames(fileName);
return 0;
}
void getFrames(char* fileName) {
cv::VideoCapture vcap(fileName);
if (!vcap.isOpened()) {
cout << "Error opening video stream or file" << endl;
return;
}
cv::Mat grey_image;
Mat img;
namedWindow("Frames", CV_WINDOW_AUTOSIZE);
resizeWindow("Frames", 640, 360);
moveWindow("Frames", 130, 100);
int init = 0;
while (1)
{
vcap >> img;
// If the frame is empty, break immediately
if (img.empty())
break;
unsigned int prevSize = 0;
resize(img, img, cv::Size(640, 360));
cv::cvtColor(img, grey_image, CV_RGB2GRAY);
//cv::equalizeHist(grey_image, grey_image);
std::vector<cv::Rect> faces;
frontfaceCascade.detectMultiScale(grey_image, faces, 1.1, 0, 0 | CV_HAAR_SCALE_IMAGE, cv::Size(30, 30)); // Minimum size of obj
//sidefaceCascade.detectMultiScale(grey_image, faces, 1.1, 4, 0 | 1, Size(40, 40), Size(100, 100)); // Minimum size of obj
/****/
}
destroyAllWindows();
vcap.release();
}
I am new to Realsense & C++. I know this question might be easy on.
However, I cannot solve this even I searched half of day.
I am trying to use Realsense with OpenCV face detection(Haarcascade).
But when I use 'face_cascade,detectMultiScale', the project gets access violation error.
(just like the picture underneath)
and my codes are this :
// License: Apache 2.0.See LICENSE file in root directory.
// Copyright(c) 2017 Intel Corporation. All Rights Reserved.
#include <rs.hpp> // Include RealSense Cross Platform API
#include <opencv2/opencv.hpp> // Include OpenCV API
#include "opencv2/objdetect.hpp"
#include "opencv2/videoio.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
using namespace std;
using namespace cv;
//String face_cascade_name;
CascadeClassifier face_cascade;
string window_name = "Face detection";
void detectAndDisplay(Mat frame)
{
std::vector<Rect> faces;
Mat frame_gray;
cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
equalizeHist(frame_gray, frame_gray);
if (frame.empty()) {
printf("error, no data");
}
else {
printf("no problem");
}
//face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));
face_cascade.detectMultiScale(frame_gray, faces , 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(500, 500));
for (size_t i = 0; i < faces.size(); i++)
{
Point center(faces[i].x + faces[i].width / 2, faces[i].y + faces[i].height / 2);
ellipse(frame, center, Size(faces[i].width / 2, faces[i].height / 2),
0, 0, 360, Scalar(0, 0, 255), 4, 8, 0);
}
imshow(window_name, frame);
}
int main(int argc, char * argv[]) try
{
// Declare depth colorizer for pretty visualization of depth data
rs2::colorizer color_map;
// Declare RealSense pipeline, encapsulating the actual device and sensors
rs2::pipeline pipe;
face_cascade.load("C:\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml");
//if (!face_cascade.load(face_cascade_name)) { printf("--(!)Error loading face cascade\n"); };
// Start streaming with default recommended configuration
pipe.start();
const auto window_name = "Display Image";
namedWindow(window_name, WINDOW_AUTOSIZE);
while (waitKey(1) < 0 && cvGetWindowHandle(window_name))
{
rs2::frameset data = pipe.wait_for_frames(); // Wait for next set of frames from the camera
//rs2::frame depth = color_map(data.get_depth_frame());
rs2::frame color = data.get_color_frame();
// Query frame size (width and height)
//const int w = depth.as<rs2::video_frame>().get_width();
//const int h = depth.as<rs2::video_frame>().get_height();
const int color_w = color.as<rs2::video_frame>().get_width();
const int color_h = color.as<rs2::video_frame>().get_height();
// Create OpenCV matrix of size (w,h) from the colorized depth data
//Mat image(Size(w, h), CV_8UC3, (void*)depth.get_data(), Mat::AUTO_STEP);
Mat image(Size(color_w, color_h), CV_8UC3, (void*)color.get_data(), Mat::AUTO_STEP);
// Update the window with new data
//imshow(window_name, image);
detectAndDisplay(image);
}
return EXIT_SUCCESS;
}
catch (const rs2::error & e)
{
std::cerr << "RealSense error calling " << e.get_failed_function() << "(" << e.get_failed_args() << "):\n " << e.what() << std::endl;
return EXIT_FAILURE;
}
catch (const std::exception& e)
{
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
enter code here
I'm trying to use solvePnP in a C++ program that detects a chessboard in a video stream. Every time the calibration finishes, I try to run solvePnP, but I keep getting errors that I think are related to the translation and rotation vectors.
This is the error:
The error
This is my code:
#include <cstdio>
#include <cstdlib>
#include <string>
#include <iostream>
#include <fstream>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
//Global variables
vector<vector<Point2f> > corner_list;
vector<vector<Point3f> > point_list;
vector<Mat> rotation_vecs, translation_vecs;
int i = 0;
bool calibMode = true, drawMode = false, drawMode2 = false, camMatrixInit = false, calibrated = false;
Mat originalCameraMatrix, cameraMatrix, distCoefficients, frame, gray, rvec, tvec;
//Function declarations
vector<Point3f> genWorldPoints(int cols, int rows);
void printCameraMatrix();
void printDistCoeff();
void printRotVecs();
/*Generates the world points (0, 0, 0), (1, 0, 0), etc. for the camera calibration.*/
vector<Point3f> genWorldPoints(int cols, int rows){
vector<Point3f> ret;
for (int i=0; i<rows; i++) {
for (int j=0; j<cols; j++) {
int tempi = i*(-1);
ret.push_back(Point3f((float)j, (float)tempi, 0.0));
}
}
return ret;
}
/*Print the camera matrix*/
void printCameraMatrix(){
cout << "Original Camera Matrix" << endl << originalCameraMatrix << endl;
cout << "Current Camera Matrix" << endl << cameraMatrix << endl;
}
/*Prints the distortion coefficients*/
void printDistCoeff(){
cout << "Distortion Coefficients:"<< endl << distCoefficients << endl;
}
int main(int argc, char *argv[]){
VideoCapture *capdev;
cameraMatrix = Mat::eye(3, 3, CV_64F);
distCoefficients = Mat::zeros(8, 1, CV_64F);
// open the video device
capdev = new VideoCapture(0);
if (!capdev->isOpened()) {
printf("Unable to open video device\n");
return(-1);
}
namedWindow("Video", 1);
bool found;
*capdev >> frame;
rvec = Mat::zeros(3, 1, CV_64F);
tvec = Mat::zeros(3, 1, CV_64F);
//Initialize camera matrix
cameraMatrix.at<double>(0,2) = (frame.size().width)/2;
cameraMatrix.at<double>(1,2) = (frame.size().height)/2;
cameraMatrix.copyTo(originalCameraMatrix);
printCameraMatrix();
for(;;){
*capdev >> frame;
if (!found) {
imshow("Video", frame);
}
Size patternsize(9,6);
vector<Point2f> corner_set;
vector<Point3f> point_set;
int code = waitKey(10);
cvtColor(frame, gray, CV_BGR2GRAY);
found = findChessboardCorners(gray, patternsize, corner_set, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS);
//Code to add a calibration frame
if (found && calibMode) {
cornerSubPix(gray, corner_set, Size(11, 11), Size(-1, -1), TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));
drawChessboardCorners(frame, patternsize, Mat(corner_set), found);
//s key press
if (code == 115){
printf("Adding calibration frame\n");
printf("Number of corners found: %lu\n", corner_set.size());
printf("Point 0 x: %f\ty: %f\n", corner_set[0].x, corner_set[1].y);
//Add the corner set
corner_list.push_back(corner_set);
//Generate point set
vector<Point3f> point_set = genWorldPoints(9,6);
//Add point set to point set list
point_list.push_back(point_set);
//Save the image
string filename = "../data/images/p4_calib_image_"+to_string(i)+".jpeg";
imwrite(filename, frame);
//if there are more than 5 saved calibration images, run calibration procedure
if (i>4) {
//Calculate the reprojection error by running calibrateCamera
double rpe = calibrateCamera(point_list, corner_list, frame.size(), cameraMatrix,
distCoefficients, rotation_vecs, translation_vecs,
CV_CALIB_FIX_ASPECT_RATIO | CV_CALIB_FIX_K4);
//Print the camera matrix
printCameraMatrix();
printDistCoeff();
//Print the reprojection error
cout << "Reprojection error: " << rpe << endl;
calibrated = true;
}
//Increment i
i++;
}
imshow("Video", frame);
}
else if (found && drawMode){
cout << "Draw mode" << endl;
bool solved = solvePnP(point_list, corner_list, cameraMatrix, distCoefficients,
rvec, tvec);
//rotation_vecs.front(), translation_vecs.front());
}
else if (found && drawMode2){
cout << "Draw mode 2" << endl;
bool solved = solvePnP(point_list, corner_list, cameraMatrix, distCoefficients,
rvec, tvec);
//rotation_vecs.front(), translation_vecs.front());
}
//Switching between drawing modes
if (calibrated && code == 49) {
calibMode = false;
drawMode2 = false;
drawMode = true;
}
else if (calibrated && code == 50){
calibMode = false;
drawMode = false;
drawMode2 = true;
}
//Switch back to calibration mode
else if (calibrated && code == 51){
drawMode = false;
drawMode2 = false;
calibMode = true;
}
if (code == 27) {
printf("Terminating\n");
delete capdev;
return(0);
}
}
capdev = new VideoCapture(0);
printf("Terminating\n");
delete capdev;
return(0);
}
Please excuse the indentation...
The problem is that sovlePnP requires vector<Point2/3f> as input, instead of vector<vector<Point2/3f> >. In your code, "point_list" is vector<vector<Point3f> >, and "corner_list" is vector<vector<Point2f> >.
The documentation of solvePnP can be found here: http://docs.opencv.org/3.0-beta/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html
I want to do eigen face by opencv ,and this is my code.
#include "opencv2/core/core.hpp"'
#include "opencv2/contrib/contrib.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include <iostream>
#include <fstream>
#include <sstream>
using namespace cv;
using namespace std;
static void read_csv(const string& filename, vector<Mat>& images,vector<int>& labels, char separator = ';') {
ifstream file(filename.c_str(), ifstream::in);
if (!file) {
string error_message = "No valid input file was given, please check the given filename.";
CV_Error(CV_StsBadArg, error_message);
}
string line, path, classlabel;
while (getline(file, line)) {
stringstream liness(line);
getline(liness, path, separator);
getline(liness, classlabel);
if(!path.empty() && !classlabel.empty()) {
images.push_back(imread(path, 0));
labels.push_back(atoi(classlabel.c_str()));
}
}
}
int main(int argc, const char *argv[]) {
string fn_haar = string("C:/opencv/sources/data/haarcascades/haarcascade_frontalface_alt_tree.xml");
string fn_csv = string("C:/Users/faho0odywbas/Desktop/csv.ext");
int deviceId = atoi("0");
vector<Mat> images;
vector<int> labels;
try {
read_csv(fn_csv, images, labels);
} catch (cv::Exception& e) {
cerr << "Error opening file \"" << fn_csv << "\". Reason: " << e.msg << endl;
exit(1);
}
int im_width = images[0].cols;
int im_height = images[0].rows;
Ptr<FaceRecognizer> model = createEigenFaceRecognizer(23,2500.0);
CascadeClassifier haar_cascade;
haar_cascade.load(fn_haar);
VideoCapture cap(deviceId);
namedWindow("face_recognizer", CV_WINDOW_AUTOSIZE);
if(!cap.isOpened()) {
cerr << "Capture Device ID " << deviceId << "cannot be opened." << endl;
return -1;
}
vector< Rect_<int> > faces;
Mat frame;
waitKey(1500);
for(;;) {
cap >> frame;
Mat original = frame.clone();
Mat gray;
cvtColor(original, gray, CV_BGR2GRAY);
haar_cascade.detectMultiScale(gray, faces);
for(int i = 0; i < faces.size(); i++) {
Rect face_i = faces[i];
Mat face = gray(face_i);
Mat face_resized;
cv::resize(face, face_resized, Size(im_width, im_height), 1.0, 1.0, INTER_CUBIC);
int prediction = model->predict(face_resized);
rectangle(original, face_i, CV_RGB(255, 0,0), 1);
string box_text = format("Sujeto = %d", prediction);
int pos_x = std::max(face_i.tl().x - 10, 0);
int pos_y = std::max(face_i.tl().y - 10, 0);
putText(original, box_text, Point(pos_x, pos_y), FONT_HERSHEY_PLAIN, 1.0, CV_RGB(0,255,0), 2.0);
}
imshow("face_recognizer", original);
char key = (char) waitKey(1);
if(key == 27){
destroyAllWindows();
break;
}
}
return 0;
}
I'm sure it's right because it was work with my friend's computer, so I think the problem with my visual studio or the windows.
The error that comes to me is
" First-chance exception at 0x74C44598 in Project3.exe: Microsoft C++ exception: cv::Exception at memory location 0x00D7ED2C.
If there is a handler for this exception, the program may be safely continued. "
and when I click break, it shows also to me this error
wkernelbase.pdb not loaded
so, what I have to do ?
I have done this Tools->Options->Debugging->Symbols->Select “Microsoft Symbol Servers”.
but also same error
I have another question which is if I want hit "s" to start recording face for every frame, and hit "d" to end the recording, how can I do that ?
Thanks a lot
I have a code that detects faces and saves multiple cropped area images of them to a file path. My code doesn't stop saving images of detected faces until I physically close the program. For every one second a face is detected on a webcam, my code saves 6 images of the face.
Is it possible to have it save just one image per face detected? For example, if there is one face, only one image, if two faces, an image of both faces are saved etc. My code is below. Can anyone help me?
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace cv;
void detectAndDisplay(Mat frame);
string face_cascade_name = "C:\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt2.xml";
CascadeClassifier face_cascade;
string window_name = "Window";
int filenumber;
string filename;
int main(void)
{
VideoCapture capture(0);
if (!capture.isOpened())
return -1;
if (!face_cascade.load(face_cascade_name))
{
cout << "error" << endl;
return (-1);
};
Mat frame;
for (;;)
{
capture >> frame;
if (!frame.empty())
{
detectAndDisplay(frame);
}
else
{
cout << "error2" << endl;
break;
}
int c = waitKey(10);
if (27 == char(c))
{
break;
}
}
return 0;
}
void detectAndDisplay(Mat frame)
{
std::vector<Rect> faces;
Mat frame_gray;
Mat crop;
Mat res;
Mat gray;
string text;
stringstream sstm;
cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
equalizeHist(frame_gray, frame_gray);
face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));
cv::Rect roi_b;
cv::Rect roi_c;
size_t ic = 0;
int ac = 0;
size_t ib = 0;
int ab = 0;
for (ic = 0; ic < faces.size(); ic++)
{
roi_c.x = faces[ic].x;
roi_c.y = faces[ic].y;
roi_c.width = (faces[ic].width);
roi_c.height = (faces[ic].height);
ac = roi_c.width * roi_c.height;
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, CV_BGR2GRAY);
filename = "C:\\Users\\Desktop\\Faces\\face";
stringstream ssfn;
ssfn << filename.c_str() << filenumber << ".jpg";
filename = ssfn.str();
cv::imwrite(filename, res);
filenumber++;
Point pt1(faces[ic].x, faces[ic].y);
Point pt2((faces[ic].x + faces[ic].height), (faces[ic].y + faces[ic].width));
rectangle(frame, pt1, pt2, Scalar(0, 255, 0), 2, 8, 0);
}
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");
}