Open CV Haarcascades not working properly - c++

I've written a code for face and eye detection that worked fine previously but now due to unknwon reasons, the program is having problems and a message is displayed that Your Project has stopped working... Please have a look at the following code and the commented line number has the problem and the program stops there
#include <opencv2/core/core.hpp>
#include "opencv2/objdetect/objdetect.hpp"
#include <opencv2/highgui/highgui.hpp>
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
/*Mat image=imread("im.jpg");
namedWindow( "Display window", WINDOW_AUTOSIZE );// Create a window for display.
imshow( "Display window", image ); // Show our image inside it.
//imwrite("im2.jpg",image);// write the image stored in object image as im2.jpg
waitKey(0); // Wait for a keystroke in the window
return 0;*/
/*VideoCapture capture;
Mat frame;
capture.open(0);
if(capture.isOpened())
{
cout<<"success"<<endl;
while(1)
{
bool flag=capture.read(frame);
namedWindow( "Display window", WINDOW_AUTOSIZE );
if(flag)
imshow( "Display window", frame );
else
cout<<"failed";
waitKey(300);
}
}*/
//face detection
cout<<"i'm here";
CascadeClassifier face_cascade("C:\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml");
CascadeClassifier eye_cascade("C:\\opencv\\sources\\data\\haarcascades\\haarcascade_eye.xml");
Mat image=imread("subject3.jpg");
cout<<"i'm here";
Mat res;
resize(image, res, Size(800, 600), 0, 0, INTER_LINEAR);
Mat gray;
cvtColor(res,gray,COLOR_BGR2GRAY);
equalizeHist(gray, gray);
std::vector<Rect> faces;
std::vector<Rect> eyes;
face_cascade.detectMultiScale(gray,faces, 1.1, 2,0 | CASCADE_SCALE_IMAGE, Size(30, 30));//problem
Rect roi;
cout<<faces.size();
Mat crop;
Mat grayEye;
for(int i=0;i<faces.size();i++)
{
cout<<"flag2";
roi.x=faces[i].x;
roi.y=faces[i].y;
roi.width=faces[i].width;
roi.height=faces[i].height;
Point pt1(faces[i].x, faces[i].y);
Point pt2((faces[i].x + faces[i].height), (faces[i].y + faces[i].width));
crop=res(roi);
resize(crop, crop, Size(300, 300), 0, 0, INTER_LINEAR);
cvtColor(crop, grayEye, CV_BGR2GRAY);
equalizeHist(grayEye, grayEye);
eye_cascade.detectMultiScale(grayEye,eyes, 1.1, 2,0 | CASCADE_SCALE_IMAGE, Size(30, 30));
cout<<endl<<eyes.size();
for(int j=0;j<eyes.size();j++)
{
Point pnt1(eyes[j].x, eyes[j].y);
Point pnt2((eyes[j].x + eyes[j].height), (eyes[j].y + eyes[j].width));
rectangle(crop, pnt1, pnt2, Scalar(0, 255, 0), 2);
}
rectangle(res, pt1, pt2, Scalar(0, 255, 0), 2);
}
namedWindow( "detected", WINDOW_AUTOSIZE );
imshow("detected",res);
waitKey(300);
imshow("detected",crop);
waitKey(0);
}

The following modifications made the program to work correctly (strange)
Previous Code :
CascadeClassifier face_cascade("C:\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml");
Replaced with :
CascadeClassifier face_cascade;
face_cascade.load("C:\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml");
I was loading the xml file in constructor previously (still don't know why it happened) but it is working now.

Related

How to detect triangle accurately in OpenCv using C++

I am detecting red triangle objects in real time video using OpenCv c++. But my program is not working properly. Whether I cannot use findContours or approxPolyDP not much well. Here is my code
#include "opencv2/opencv.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
#include <raspicam/raspicam_cv.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
using namespace std;
int thresh = 100;
int number_pixels;
void drawAllTriangles(Mat&, const vector< vector<Point> >&);
int main(){
//Vectors
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
Mat canny_output,drawing;
//Initialise the image as a matrix container
Mat bgr;
raspicam::RaspiCam_Cv capture; // initialise the raspicam object
capture.open(); // activate the raspicam object
while (1)
{
capture.grab(); //grab the scene using raspicam
capture.retrieve(bgr); // retrieve the captured scene as an image and store it in matrix container
Mat gray,hsv; //Initialise the matrix container for gray color image
resize(bgr, bgr, Size(), .25, 0.25, CV_INTER_AREA);
//cvtColor(bgr, gray, COLOR_BGR2GRAY); //OpenCV code line for converting COLOR to GRAY scale image
//
cvtColor(bgr, hsv, COLOR_BGR2HSV);
//Gaussian Noice
Mat blure;
GaussianBlur(hsv,blure,Size(9,9),1.0);
//Gaussian Noice End
Mat mask1, mask2;
inRange(blure, Scalar(0,70,50), Scalar(10, 255, 255), mask1);
inRange(blure, Scalar(170, 70, 50), Scalar(180, 255, 255), mask2);
Mat mask3 = mask1 | mask2;
//Mat mask3 = mask1;
//
number_pixels = countNonZero(mask3);
Canny(mask3, canny_output, thresh, thresh*2, 3 );
findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
imshow("Original frame", bgr); //displaying original frame
imshow("Gray frame", mask3); //displaying original frame
drawAllTriangles(drawing,contours);
imshow("Triangles",drawing);
if (cvWaitKey(20) == 'q') // waitkey
break;
}
capture.release(); // release the raspicam frame grabbing
return 0;
}
void drawAllTriangles(Mat& img, const vector< vector<Point> >& contours){
vector<Point> approxTriangle;
for(size_t i = 0; i < contours.size(); i++){
approxPolyDP(contours[i], approxTriangle, arcLength(Mat(contours[i]), true)*0.05, true);
if(approxTriangle.size() == 3 and number_pixels>200){
drawContours(img, contours, i, Scalar(0, 255, 255), CV_FILLED); // fill GREEN
vector<Point>::iterator vertex;
for(vertex = approxTriangle.begin(); vertex != approxTriangle.end(); ++vertex){
circle(img, *vertex, 3, Scalar(0, 0, 255), 1);
}
printf("Triangle \n");
}
else {
printf("None \n");
}
}
}
My program should detect any red triangle shaped objects in video. Where I am going wrong. Thank you for answer
THese are the images, but it cannot detect triangles and confusing.

proximate contour to rectagle

I'm trying to detect and extract playing cards from an image. The plan is to detect the contours of the cards and then extract them using the area of the contours. (Is there a more efficient way of doing it?)
The problem is that I was having trouble with non-closed contours:
With this contours I'm not able to calculate the area of the rectangles. Hence, I performed morphological transformations to close the contours, producing this:
And after edge extracting:
Leaving me with these "rectangles" with twisted corners in the edges. How can I approximate these pseudo-rectangles to perfect geometric rectangles?
Is there a more efficient way of doing this?
Here is my code so far:
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdlib.h>
#include <stdio.h>
using namespace cv;
using namespace std;
#define BKG_THRESH 60 // preProcessImg
Mat src;
void preProcessImg(Mat* _img){
Mat aux_gray;
cvtColor(*_img, aux_gray, CV_BGR2GRAY );
GaussianBlur(aux_gray, *_img, Size(5,5), 0);
}
int main( int argc, char** argv ){
vector<vector<Point>> contours;
/// Load an image
src = imread("img.jpg");
preProcessImg(&src);
Canny(src, src, 30, 200);
//Mostrar imagem
namedWindow( "canny_output", CV_WINDOW_NORMAL); // Create a window
imshow( "canny_output", src);
waitKey(0);
Mat structuringElement = getStructuringElement(MORPH_ELLIPSE, Size(7, 7));
morphologyEx(src, src, MORPH_CLOSE, structuringElement);
//Mostrar imagem
namedWindow( "morph_transf", CV_WINDOW_NORMAL); // Create a window
imshow( "morph_transf", src);
waitKey(0);
findContours(src, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
Mat drawing = Mat::zeros( src.size(), CV_8UC3 );
for( int i = 0; i< contours.size(); i++){
Scalar color( rand()&255, rand()&255, rand()&255 );
drawContours( drawing, contours, i, color );
}
//Mostrar imagem
namedWindow( "contours", CV_WINDOW_NORMAL); // Create a window
imshow( "contours", drawing);
waitKey(0);
return 0;
}
The more robust way is to find lines (Hough lines) afer Canny, intersect they and find rectangles. Contours are not robust for noise.

How can I get the color histogram inside the circle in the image or the gradient distribution in the circle?

I have detected circular objects in the image with OpenCV and C++ and using houghcircle function. But I would like to filter out only those circle that have dark color (it should be the airplane door window). So I thought to use the color histogram inside the detected circle in the image or the gradient distribution in those circle to filter out .It works on some images like in the image provided. But when there are more circles in the image does not find the dark circle. Also I played with canny threshold but I would like it do happened automatically. So basically how to make the program more robust?
Firstly here is the code in C++ using OpenCV and C++
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
using namespace cv;
using namespace std;
#include <vector>
int thresh = 200;
int max_thresh = 400;
Mat src;
void thresh_callback(int, void* );
int main()
{
cv::Mat src = cv::imread("d4.png");
resize(src, src, Size(640,480), 0, 0, INTER_CUBIC);
char* source_window = "Source";
namedWindow( source_window, CV_WINDOW_AUTOSIZE );
imshow( source_window, src );
createTrackbar( " Canny thresh:", "Source", &thresh, max_thresh, thresh_callback );
thresh_callback( 0, 0 );
waitKey(0);
return(0);
}
void thresh_callback(int, void* ) {
Mat src_gray;
cv::Mat bgr_image = cv::imread( "d4.png");
cv::Mat orig_image = bgr_image.clone();
cvtColor( bgr_image, src_gray, COLOR_BGR2HSV );
medianBlur(src_gray, src_gray, 3);
Mat canny_output;
Canny( src_gray, canny_output, thresh, thresh*3.5, 3 );
// Threshold the HSV image, keep only the black pixels
cv::Mat lower_black_hue_range;
cv::Mat upper_black_hue_range;
cv::inRange(canny_output, cv::Scalar(0, 0, 0), cv::Scalar(10, 10, 40), lower_black_hue_range);
cv::inRange(canny_output, cv::Scalar(0,0, 41), cv::Scalar(10, 15, 50), upper_black_hue_range);
// Combine the above two images
cv::Mat black_hue_image;
cv::addWeighted(lower_black_hue_range, 1.0, upper_black_hue_range, 1.0, 0.0, black_hue_image);
cv::GaussianBlur(black_hue_image, black_hue_image, cv::Size(9, 9), 2, 2);
// Use the Hough transform to detect circles in the combined threshold image
std::vector<cv::Vec3f> circles;
cv::HoughCircles(black_hue_image, circles, CV_HOUGH_GRADIENT, 1, black_hue_image.rows/1, 10, 100, 10, 0);
// Loop over all detected circles and outline them on the original image
if(circles.size() == 0) std::exit(-1);
for(size_t current_circle = 0; current_circle < circles.size(); ++current_circle) {
Point center(cvRound(circles[current_circle][0]), cvRound(circles[current_circle][1]));
int radius = cvRound(circles[current_circle][2]);
cv::circle(orig_image, center, radius, cv::Scalar(0, 255, 0), 5);
}
// Show images
resize(lower_black_hue_range, lower_black_hue_range, Size(640,480), 0, 0, INTER_CUBIC);
char* source_window1 = "Threshold lower image";
namedWindow( source_window1, CV_WINDOW_AUTOSIZE );
imshow( source_window1, lower_black_hue_range );
//cv::namedWindow("Threshold lower image", cv::INTER_CUBIC);
//cv::imshow("Threshold lower image", lower_black_hue_range);
resize(upper_black_hue_range, upper_black_hue_range, Size(640,480), 0, 0, INTER_CUBIC);
char* source_window2 = "Threshold upper image";
namedWindow( source_window2, CV_WINDOW_AUTOSIZE );
imshow( source_window2, lower_black_hue_range );
//cv::namedWindow("Threshold upper image", cv::INTER_CUBIC);
//cv::imshow("Threshold upper image", upper_black_hue_range);
resize(black_hue_image, black_hue_image, Size(640,480), 0, 0, INTER_CUBIC);
char* source_window3 = "Combined threshold images";
namedWindow( source_window3, CV_WINDOW_AUTOSIZE );
imshow( source_window3, black_hue_image );
//cv::namedWindow("Combined threshold images", cv::INTER_CUBIC);
//cv::imshow("Combined threshold images", black_hue_image);
resize(orig_image, orig_image, Size(640,480), 0, 0, INTER_CUBIC);
char* source_window4 = "Detected black circles on the input image";
namedWindow( source_window4, CV_WINDOW_AUTOSIZE );
imshow( source_window4, orig_image );
//cv::namedWindow("Detected black circles on the input image", cv::INTER_CUBIC);
//cv::imshow("Detected black circles on the input image", orig_image);
}
Input image of good detected circle
The output is correct
Second image with more circles
The output is wrong, wrong detected circle
Any help?

OpenCV FindContours Causes stop working

I'm using OpenCV 2.4.9 on VisualStudio V10.0.30319.1 RTMRel trying to compile this sample code:
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace cv;
using namespace std;
Mat src; Mat src_gray;
int thresh = 100;
int max_thresh = 255;
RNG rng(12345);
/// Function header
void thresh_callback(int, void* );
/** #function main */
int main( int argc, char** argv )
{
/// Load source image and convert it to gray
VideoCapture capture;
capture.open(0);
capture.set(CV_CAP_PROP_FRAME_WIDTH,1280);
capture.set(CV_CAP_PROP_FRAME_HEIGHT,960);
char qq=0;
while(qq!=32)
{
qq = waitKey(30);
capture.read(src);
if(!src.empty())
imshow("Space",src);
}
/// Convert image to gray and blur it
cvtColor( src, src_gray, CV_BGR2GRAY );
blur( src_gray, src_gray, Size(3,3) );
/// Create Window
char* source_window = "Source";
namedWindow( source_window, CV_WINDOW_AUTOSIZE );
imshow( source_window, src );
createTrackbar( " Canny thresh:", "Source", &thresh, max_thresh, thresh_callback );
thresh_callback( 0, 0 );
waitKey(0);
return(0);
}
/** #function thresh_callback */
void thresh_callback(int, void* )
{
Mat canny_output;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
/// Detect edges using canny
Canny( src_gray, canny_output, thresh, thresh*2, 3 );
/// Find contours
findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
/// Draw contours
Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
for( int i = 0; i< contours.size(); i++ )
{
Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() );
}
/// Show in a window
namedWindow( "Contours", CV_WINDOW_AUTOSIZE );
imshow( "Contours", drawing );
}
It's a sample code and should work just find but when I try to run the code just after pressing Space to capture the image the program just crashes and says "Ashkan.exe has stopped working" without any error at all!
I know the problem is with the FindContours line because as i comment that line the program runs just fine.
In debug mode when passing findContours line it says: Unhandled exception at 0x76f2320e in Ashkan.exe: 0xC0000005: Access violation reading location 0xffffffffffffffff.
Does anyone know any possible cause for this problem?!

OpenCV Skin Detection

I've been doing some skin detection but can't get a smooth one. The image below contains the input (left) and output (right) using the code also attached below. Now, the desired output should have been the bottom most image (the one that is smooth on the edges and doesn't have holes within). How do I achieve this output? A sample code on where to start would be of great help.
Input (left) and Incorrect output (right):
Desired output:
Code to generate the Incorect output:
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
int main(){
Mat src = imread("qq.jpg");
if (src.empty())
return -1;
blur( src, src, Size(3,3) );
Mat hsv;
cvtColor(src, hsv, CV_BGR2HSV);
Mat bw;
inRange(hsv, Scalar(0, 10, 60), Scalar(20, 150, 255), bw);
imshow("src", src);
imshow("dst", bw);
waitKey(0);
return 0;
}
Modified Code (after Astor's suggestion):
(the problem now is: how do you smoothen the output?)
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
int findBiggestContour(vector<vector<Point> >);
int main(){
Mat src = imread("qq.jpg");
if (src.empty())
return -1;
blur( src, src, Size(3,3) );
Mat hsv;
cvtColor(src, hsv, CV_BGR2HSV);
Mat bw;
inRange(hsv, Scalar(0, 10, 60), Scalar(20, 150, 255), bw);
imshow("src", src);
imshow("dst", bw);
Mat canny_output;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours( bw, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
int s = findBiggestContour(contours);
Mat drawing = Mat::zeros( src.size(), CV_8UC1 );
drawContours( drawing, contours, s, Scalar(255), -1, 8, hierarchy, 0, Point() );
imshow("drw", drawing);
waitKey(0);
return 0;
}
int findBiggestContour(vector<vector<Point> > contours){
int indexOfBiggestContour = -1;
int sizeOfBiggestContour = 0;
for (int i = 0; i < contours.size(); i++){
if(contours[i].size() > sizeOfBiggestContour){
sizeOfBiggestContour = contours[i].size();
indexOfBiggestContour = i;
}
}
return indexOfBiggestContour;
}
You should use findContours to detect the biggest contour and after this draw founded contour with fill parameter -1 using method drawContours. Here's useful link: http://docs.opencv.org/doc/tutorials/imgproc/shapedescriptors/find_contours/find_contours.html
To improve the smoothness of the output, or in other words to reduce the black holes in the detected area try performing morphological operations on the resulting image.
Following documentation explains the eroding and dilating functions in opencv.
http://docs.opencv.org/doc/tutorials/imgproc/erosion_dilatation/erosion_dilatation.html