OpenCV haarcascades loading is NOT working at all - c++

I'm using visual studio 2019 with OpenCV 4.4.0
every thing was great but when i want to start face detection the cascade classifiar doesn't load the haarcascade
you also have to know that i installed openCV in the c partition and this is a simple code
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <opencv2\opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <Windows.h>
#include <vector>
#include <stdio.h>
using namespace std;
using namespace cv;
int main()
{
VideoCapture cam(0);
Mat img;
CascadeClassifier detector;
vector<Rect> faces;
Point p[2];
bool cap = false;
if (!detector.load("c:\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_default.xml"))
{
cout << "Image Detector Doesn't work\n";
return EXIT_FAILURE;
}
if (!cam.isOpened())
{
cout << "Can't Open Camera\n";
return EXIT_FAILURE;
}
while (!cap)
{
cam.read(img);
imshow("Cam", img);
waitKey(0);
if (GetAsyncKeyState(VK_ESCAPE))
cap = true;
}
destroyWindow("Cam");
cout << "Detecting Face...\n";
detector.detectMultiScale(img, faces);
for (int i = 0; i < faces.size(); i++)
{
p[0] = Point(faces[i].x,faces[i].y);
p[1] = Point(faces[i].x + faces[i].height,faces[i].y + faces[i].width);
rectangle(img,p[0],p[1],Scalar(0,0,255),3);
}
imwrite("Result.jpg",img);
return EXIT_SUCCESS;
}
this code doesn't load the haarcascade and it returns "can't load" in the cmd
so i really need help with and thanks for all

\ is used as escape sequence in C++ string literals.
Therefore, you should use \\ to put a character \ in them.
if (!dec.load("c:\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_default.xml"))

Related

opencv c++ change ipl to mat accumulate

i tried to change code ipl to mat
but failed
i use opencv 4.1.2
this sample uses opencv 2.4.13
https://jadeshin.tistory.com/entry/cvAcc에-의한-배경-영상-계산
i can't use ipl
so i changed
#include <opencv2\opencv.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\core\mat.hpp>
#include <opencv2\imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
VideoCapture cap("ball.avi");
if (!cap.isOpened())
{
cout << "file not found." << endl;
return 0;
}
Mat image;
Size size = Size((int)CAP_PROP_FRAME_WIDTH, (int)CAP_PROP_FRAME_HEIGHT);
Mat grayImage(size, CV_8UC1);
Mat sumImage(size, CV_32FC1);
sumImage.setTo(Scalar::all(0));
int nFrameCount = 0;
for (;;)
{
cap.read(image);
if (image.empty())
{
cout << "could'nt capture" << endl;
break;
}
cvtColor(image, grayImage, COLOR_BGR2GRAY);
accumulate(grayImage, sumImage, NULL); //here is error
imshow("grayImage", grayImage);
char chKey = waitKey(50);
if (chKey == 27)
break;
nFrameCount++;
}
convertScaleAbs(sumImage, sumImage, 1.0 / nFrameCount);
imwrite("ballBkg.jpg", sumImage);
destroyAllWindows();
return 0;
}
nothing wrong to compile but wrong to excute
i did also try, catch
but also failed
what's wrong with accumulate?
C++ version of accumulate void accumulate(InputArray src, InputOutputArray dst, InputArray mask=noArray() )
your are passing NULL instead of noArray() . so just do :
accumulate(grayImage, sumImage);
cv::noArray() is an empty Mat not NULL.
Edit :
Also change
Size size = Size((int)CAP_PROP_FRAME_WIDTH, (int)CAP_PROP_FRAME_HEIGHT);
to
Size size = Size((int)cap.get(CV_CAP_PROP_FRAME_WIDTH), (int)cap.get(CV_CAP_PROP_FRAME_HEIGHT));

Converting webcam program to process one image

I am currently trying to modify a program that takes in a webcam stream as input. The problem is, when I try to alter the program to use a single image, it doesn't display the output that I am expecting e.g. with video stream (code below)
#include "opencv2/opencv.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/videoio.hpp"
#include <opencv2/highgui.hpp>
#include <opencv2/video.hpp>
#include "BackgroundRemover.h"
#include "SkinDetector.h"
#include "FaceDetector.h"
#include "FingerCount.h"
using namespace cv;
using namespace std;
int main(int, char**) {
VideoCapture videoCapture(0);
videoCapture.set(CV_CAP_PROP_SETTINGS, 1);
if (!videoCapture.isOpened()) {
cout << "Can't find camera!" << endl;
return -1;
}
Mat frame, frameOut, handMask, foreground, fingerCountDebug;
BackgroundRemover backgroundRemover;
SkinDetector skinDetector;
FaceDetector faceDetector;
FingerCount fingerCount;
for (int i = 0; i < 2; i++)
{
videoCapture >> frame;
frameOut = frame.clone();
skinDetector.drawSkinColorSampler(frameOut);
foreground = backgroundRemover.getForeground(frame);
faceDetector.removeFaces(frame, foreground);
handMask = skinDetector.getSkinMask(foreground);
fingerCountDebug = fingerCount.findFingersCount(handMask, frameOut);
imshow("output", frameOut);
imshow("foreground", foreground);
imshow("handMask", handMask);
imshow("handDetection", fingerCountDebug);
if (i == 0)
{
backgroundRemover.calibrate(frame);
skinDetector.calibrate(frame);
}
}
waitKey(0);
}
The output shows a detection. Whereas, if I modify the code so that frame doesn't read from the video stream, the output shows nothing at all. Can anybody help to fix this? EDIT: Due to confusion from some members of the community, the modified code is below that reads in a single image:
#include "opencv2/opencv.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/videoio.hpp"
#include <opencv2/highgui.hpp>
#include <opencv2/video.hpp>
#include "BackgroundRemover.h"
#include "SkinDetector.h"
#include "FaceDetector.h"
#include "FingerCount.h"
using namespace cv;
using namespace std;
int main(int, char**) {
string imageName("C:/Users/whoever/Desktop/hand_test.jpg"); // by default
Mat image;
image = imread(imageName.c_str(), IMREAD_COLOR); // Read the file
Mat frame, frameOut, handMask, foreground, fingerCountDebug;
BackgroundRemover backgroundRemover;
SkinDetector skinDetector;
FaceDetector faceDetector;
FingerCount fingerCount;
for (int i = 0; i < 2; i++)
{
frame = image;
frameOut = frame.clone();
skinDetector.drawSkinColorSampler(frameOut);
foreground = backgroundRemover.getForeground(frame);
faceDetector.removeFaces(frame, foreground);
handMask = skinDetector.getSkinMask(foreground);
fingerCountDebug = fingerCount.findFingersCount(handMask, frameOut);
imshow("output", frameOut);
imshow("foreground", foreground);
imshow("handMask", handMask);
imshow("handDetection", fingerCountDebug);
if (i == 0)
{
cout << "Calibrating...";
backgroundRemover.calibrate(frame);
skinDetector.calibrate(frame);
}
}
waitKey(0);
}
The original code processes different images captured from the camera each time it goes round the loop and outputs the differences. Since you are now using the same image every time round there are never any differences hence the output is completely blank. (Note that it will still be playing the output as a video, just a constantly blank one)
The first line in the for loop is where it grabs a new image from the camera:
videoCapture >> frame;
As you can see in your updated code you are removing this and just using the same image again:
frame = image;
Try saving 2 different images instead and have the program load in a different one each time round the loop.
Here is a fairly brute force way to do it which you could improve to load a different file each time it loops, use arrays and so on:
string imageName1("C:/Users/whoever/Desktop/hand_test_1.jpg"); // by default
string imageName2("C:/Users/whoever/Desktop/hand_test_2.jpg"); // by default
Mat image1;
Mat image2;
image1 = imread(imageName1.c_str(), IMREAD_COLOR); // Read the file
image2 = imread(imageName2.c_str(), IMREAD_COLOR); // Read the file
Mat frame, frameOut, handMask, foreground, fingerCountDebug;
BackgroundRemover backgroundRemover;
SkinDetector skinDetector;
FaceDetector faceDetector;
FingerCount fingerCount;
for (int i = 0; i < 2; i++)
{
if (i = 0) { frame = image1 } else { frame = image2 };
...

How to get the Chain Code xml file in OpenCV 3.0 c++

I'm using Freeman Chain Code as Feature Extraction for an image.
I'm not able to read the image and I need to obtain a chain code xml file.
How can i retrieve the chain code xml file and save it?
Below is my c++ code in OpenCV 3.0
Can someone help..
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/opencv.hpp>
#include "opencv2/imgcodecs.hpp"
#include <opencv2/highgui.hpp>
#include <opencv2/ml.hpp>
#include <fstream>
#include<string.h>
using namespace std;
using namespace cv;
int main() {
Mat img = imread("test.jpg")
imshow("Test", img);
vector<vector<Point>> contours; // Vector for storing contour
vector<Vec4i> hierarchy;
cv::findContours(img, contours, RETR_EXTERNAL,CV_CHAIN_CODE);
cout << Mat(contours[0]) << endl;
findContours(img, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
cout << "CHAIN_APPROX_SIMPLE" << endl;
cout << Mat(contours[0]) << endl;
CvChain* chain = 0;
CvMemStorage* storage = 0;
storage = cvCreateMemStorage();
cvFindContours(&IplImage(img), storage, (CvSeq**)(&chain), sizeof(*chain), CV_RETR_TREE, CV_CHAIN_CODE);
int total = chain->total;
cv::Mat hist(1, 8, CV_32F, Scalar(0));
int totalCount = 0;
for (; chain != NULL; chain = (CvChain*)chain->h_next)
{
int numChain = 0;
CvSeqReader reader;
int i, total = chain->total;
cvStartReadSeq((CvSeq*)chain, &reader, 0);
cout<<"--------------------chain\n";
for (i = 0; i<total; i++)
{
char code;
CV_READ_SEQ_ELEM(code, reader);
int Fchain = (int)code;
hist.at<float>(0, Fchain)++;
totalCount++;
cout<<"%d"<<code;
}
}
Mat prob = hist / totalCount;
cout << prob << endl;
waitKey(0);
return 0;
}
Whenever the code is being run,I'm having this error.Have I used a wrong format?? Can anyone please help?
OpenCV Error: Unsupported format or combination of formats ([Start]FindContours supports only CV_8UC1 images when mode != CV_RETR_FLOODFILL otherwise supports CV_32SC1 images only) in cvStartFindContours, file C:\buildslave64\win64_amdocl\master_PackSlave-win64-vc14-shared\opencv\modules\imgproc\src\contours.cpp, line 198
I have updated my code.I'm able to save the xml file but but I'm getting the data in only 1 row.
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc/imgproc_c.h"
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/opencv.hpp>
#include "opencv2/imgcodecs.hpp"
#include <opencv2/highgui.hpp>
#include <opencv2/ml.hpp>
#include <fstream>
#include<string.h>
using namespace std;
using namespace cv;
vector<String> files;
int main() {
double totalCount = 0;
cv::glob("C:/Users//Videos/Database/Frames/*.jpg", files);
for (size_t i = 0; i < files.size(); i++) {
Mat image = imread(files[i]);
//Mat image = imread("Outline.jpg");
Canny(image, image, 100, 100 * 2, 3, false);
CvChain* chain;
CvMemStorage* storage = 0;
storage = cvCreateMemStorage();
cvFindContours(&IplImage(image), storage, (CvSeq**)(&chain), sizeof(*chain), CV_RETR_EXTERNAL, CV_CHAIN_CODE);
int total = chain->total;
// 1 row, 8 cols, filled with zeros, (float type, because we want to normalize later):
cv::Mat hist(1, 8, CV_32F, Scalar(0));
for (; chain != NULL; chain = (CvChain*)chain->h_next)
{
CvSeqReader reader;
int i, total = chain->total;
cvStartReadSeq((CvSeq*)chain, &reader, 0);
for (i = 0; i < total; i++)
{
char code;
CV_READ_SEQ_ELEM(code, reader);
int Fchain = (int)code;
// increase the counter for the respective bin:
hist.at<float>(0, Fchain)++;
totalCount++;
}
}
// print the raw histogram:
cout << "Histo: " << hist << endl;
cout << "Total: " << totalCount << endl;
// normalize it:
Mat prob = hist / totalCount;
cout << "Proba: " << prob << endl;
FileStorage fs("freeman.xml", FileStorage::WRITE);
fs << "chain" << prob;
waitKey(0);
return 0;
}
}
As shown below i'm having my chain code xml like this.Why am i getting this? Can anyone help me please?
<?xml version="1.0"?>
<opencv_storage>
<chain type_id="opencv-matrix">
<rows>1</rows>
<cols>8</cols>
<dt>f</dt>
<data>
5.00000000e-01 0. 0. 0. 5.00000000e-01 0. 0. 0.</data></chain>
</opencv_storage>
The error message says exactly and unambiguously what is wrong - it's enough to read it. cv::findContours() accepts only images of CV_8UC1 pixel type or only CV_32SC1 if you use CV_RETR_FLOODFILL mode. In your particular case, you need to convert your img object to CV_8UC1 after loading - you are probably loading an RGB image.

Object Detection using SVM

I am new to SVM. I used to do object detection using HAAR Cascading. Now I am trying to implement SVM for object detection. I searched online and got to know about the basics.
I wanted to use libsvm while coding for c++. I am getting lots of problems.
Can anyone please explain step by step process of using it for object detection.
BTW I looked into opencv documentation of svm. But I am not able to do anything further.
Also I got this code for training my SVM and saving it into an xml file.
Now I want a code which can take this xml and detect objects in test cases.
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <cv.h>
#include <highgui.h>
#include <cvaux.h>
#include <iostream>
#include <vector>
#include<string.h>
using namespace std;
using namespace cv;
int main ( int argc, char** argv )
{
cout << "OpenCV Training SVM Automatic Number Plate Recognition\n";
cout << "\n";
char* path_Plates;
char* path_NoPlates;
int numPlates;
int numNoPlates;
int imageWidth=150;
int imageHeight=150;
//Check if user specify image to process
if(1)
{
numPlates= 11;
numNoPlates= 90 ;
path_Plates= "/home/kaushik/opencv_work/Manas6/Pics/Positive_Images/";
path_NoPlates= "/home/kaushik/opencv_work/Manas6/Pics/Negative_Images/i";
}else{
cout << "Usage:\n" << argv[0] << " <num Plate Files> <num Non Plate Files> <path to plate folder files> <path to non plate files> \n";
return 0;
}
Mat classes;//(numPlates+numNoPlates, 1, CV_32FC1);
Mat trainingData;//(numPlates+numNoPlates, imageWidth*imageHeight, CV_32FC1 );
Mat trainingImages;
vector<int> trainingLabels;
for(int i=1; i<= numPlates; i++)
{
stringstream ss(stringstream::in | stringstream::out);
ss<<path_Plates<<i<<".jpg";
try{
const char* a = ss.str().c_str();
printf("\n%s\n",a);
Mat img = imread(ss.str(), CV_LOAD_IMAGE_UNCHANGED);
img= img.clone().reshape(1, 1);
//imshow("Window",img);
//cout<<ss.str();
trainingImages.push_back(img);
trainingLabels.push_back(1);
}
catch(Exception e){;}
}
for(int i=0; i< numNoPlates; i++)
{
stringstream ss(stringstream::in | stringstream::out);
ss << path_NoPlates<<i << ".jpg";
try
{
const char* a = ss.str().c_str();
printf("\n%s\n",a);
Mat img=imread(ss.str(), 0);
//imshow("Win",img);
img= img.clone().reshape(1, 1);
trainingImages.push_back(img);
trainingLabels.push_back(0);
//cout<<ss.str();
}
catch(Exception e){;}
}
Mat(trainingImages).copyTo(trainingData);
//trainingData = trainingData.reshape(1,trainingData.rows);
trainingData.convertTo(trainingData, CV_32FC1);
Mat(trainingLabels).copyTo(classes);
FileStorage fs("SVM.xml", FileStorage::WRITE);
fs << "TrainingData" << trainingData;
fs << "classes" << classes;
fs.release();
return 0;
}
Any help would be greatly appreciated.
Also I would love to have suggestions on how to implement libsvm for object detection.
This is a simple code which you could take a test with your xml file:
#include "highgui.h"
#include "opencv2/imgproc/imgproc.hpp"
#include "cv.h"
#include <vector>
#include <string.h>
#include <ml.h>
#include <iostream>
#include <io.h>
using namespace cv;
using namespace std;
int main()
{
FileStorage fs;
fs.open("SVM.xml", FileStorage::READ);
Mat trainingData;
Mat classes;
fs["TrainingData"] >> trainingData;
fs["classes"] >> classes;
CvSVMParams SVM_params;
SVM_params.svm_type = CvSVM::C_SVC;
SVM_params.kernel_type = CvSVM::LINEAR; //CvSVM::LINEAR;
SVM_params.degree = 1;
SVM_params.gamma = 1;
SVM_params.coef0 = 0;
SVM_params.C = 1;
SVM_params.nu = 0;
SVM_params.p = 0;
SVM_params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 1000, 0.01);
CvSVM svm(trainingData, classes, Mat(), Mat(), SVM_params);
Mat src = imread("D:\\SVM\\samples\\\pos\\10.jpg");
Mat gray;
cvtColor(src, gray, CV_BGR2GRAY);
Mat p = gray.reshape(1, 1);
p.convertTo(p, CV_32FC1);
int response = (int)svm.predict( p );
if(response ==1 )
{
cout<<"this is a object!"<<endl;
cout<<endl;
}
else
{
cout<<"no object detected!"<<endl;
cout<<endl;
}
return 0;
}
by the way,it seems that there is little problem when runing your offered code,the result shows that:"opencv errror,Image step is wrongin cv::Mat::reshape".Had you met such situation before?Thank you.

Change resolution of extracted frame in Opencv

I have an H.264 video stream and I need to extract frames from it. However when I extract the frames,the quality is really poor since I need to perform color segmentation!I want to know how can i extract the frame and convert it to B G R so as to have a better quality picture.
Here is the code I have so far:
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main(){
VideoCapture capture("1.dv4");
if(!capture.isOpened())
return 1;
double rate=capture.get(CV_CAP_PROP_FPS);
bool stop(false);
Mat frame;
namedWindow("Extracted Frame",CV_WINDOW_NORMAL);
cout <<"Rate is="<<rate;
int delay=1000/rate;
while(!stop){
if(!capture.read(frame))
break;
imshow("Extracted Frame",frame);
imwrite("C:/Users/DELL/Documents/Visual Studio 2010/Projects/VideoFrameCapture/VideoFrameCapture/frame.jpg",frame);
if(waitKey(delay)>=0)
stop=true;
}
capture.release();
waitKey(0);
return 1;
}
Once you have opened the VideoCapture, add this:
capture.set(CV_CAP_PROP_CONVERT_RGB, 1);