I'm trying to train SVM and use it inside HOGDescrpitor from OpenCV.
The xml file was succesfully generated and loaded by HOGDescriptor but when I try to detect some object, then assertion is occurred:
OpenCV Error: Assertion failed (dsize.area() || (inv_scale_x > 0 &&
inv_scale_y > 0)) in resize, file
/build/buildd/opencv-2.4.8+dfsg1/modules/imgproc/src/imgwarp.cpp, line
1825 terminate called after throwing an instance of
'tbb::captured_exception' what():
/build/buildd/opencv-2.4.8+dfsg1/modules/imgproc/src/imgwarp.cpp:1825:
error: (-215) dsize.area() || (inv_scale_x > 0 && inv_scale_y > 0) in
function resize
To implement SVM trainer I used hints from using OpenCV and SVM with images
Generated XML file has about 144Kbytes. For positive and negative samples I used images of size 64x128 (2000 for positive and 2000 for negative)
Parameter for SVM trainer:
CvSVMParams svmParams;
svmParams.svm_type = CvSVM::C_SVC;
svmParams.kernel_type = CvSVM::LINEAR;
svmParams.term_crit = cvTermCriteria( CV_TERMCRIT_ITER, 10000, 1e-6 );
Code for detection:
int main()
{
HOGDescriptor hog();
if(!hog.load("/home/bin/hogdescriptor.xml"))
{
std::cout << "Failed to load file!" << std::endl;
return -1;
}
VideoCapture cap(0);
if(!cap.isOpened())
{
std::cout << "Error opening camera!" << std::endl;
return 1;
}
Mat testImage;
while ((cvWaitKey(30) & 255) != 27)
{
cap >> testImage;
detectTest(hog, testImage);
imshow("HOG custom detection", testImage);
}
return EXIT_SUCCESS;
}
void showDetections(const vector<Rect>& found, Mat& imageData) {
for (const Rect& rect : found)
{
Point rectPoint1;
rectPoint1.x = rect.x;
rectPoint1.y = rect.y;
Point rectPoint2;
rectPoint2.x = rect.x + rect.width;
rectPoint2.y = rect.y + rect.height;
std::cout << "detection x: " << rect.x << ", y: " << rect.y << std::endl;
rectangle(imageData, rectPoint1, rectPoint2, Scalar(0, 255, 0));
}
}
void detectTest(const HOGDescriptor& hog, Mat& imageData)
{
std::cout << "Trying to detect" << std::endl;
vector<Rect> found;
int groupThreshold = 2;
Size padding(Size(32, 32));
Size winStride(Size(8, 8));
double hitThreshold = 0.; // tolerance
hog.detectMultiScale(imageData, found, hitThreshold, winStride, padding, 1.05, groupThreshold);
// hog.detectMultiScale(imageData, found);
std::cout << "Trying to show detections" << std::endl;
showDetections(found, imageData);
}
XML:
<?xml version="1.0"?>
<opencv_storage>
<my_svm type_id="opencv-ml-svm">
<svm_type>C_SVC</svm_type>
<kernel><type>LINEAR</type></kernel>
<C>1.</C>
<term_criteria><epsilon>2.2204460492503131e-16</epsilon>
<iterations>10000</iterations></term_criteria>
<var_all>8192</var_all>
<var_count>8192</var_count>
<class_count>2</class_count>
<class_labels type_id="opencv-matrix">
<rows>1</rows>
<cols>2</cols>
<dt>i</dt>
<data>
-1 1</data></class_labels>
<sv_total>1</sv_total>
<support_vectors>
<_>
-9.25376153e-05 -9.25376153e-05 -9.25376153e-05 -9.25376153e-05 ...and many, many...</_></support_vectors>
<decision_functions>
<_>
<sv_count>1</sv_count>
<rho>-1.</rho>
<alpha>
1.</alpha>
<index>
0</index></_></decision_functions></my_svm>
</opencv_storage>
Can someone explain me this assertion or maybe can provide some solution for this problem? I spent almost 3 days to fix this but without any success... Thanks in advance!
this is the closer what i got... still trying to use this xml
private static void buscar_hog_svm() {
if (clasificador == null) {
clasificador = new CvSVM();
clasificador.load(path_vectores);
}
Mat img_gray = new Mat();
//gray
Imgproc.cvtColor(imag, img_gray, Imgproc.COLOR_BGR2GRAY);
//Extract HogFeature
hog = new HOGDescriptor(
_winSize //new Size(32, 16)
, _blockSize, _blockStride, _cellSize, _nbins);
MatOfFloat descriptorsValues = new MatOfFloat();
MatOfPoint locations = new MatOfPoint();
hog.compute(img_gray,
descriptorsValues,
_winSize,
_padding, locations);
Mat fm = descriptorsValues;
System.out.println("tamano fm: " + fm.size());
//Classification whether data is positive or negative
float result = clasificador.predict(fm);
System.out.println("resultado= " + result);
}
if you have more clues, please share
Related
This question already has answers here:
imread returns None, violating assertion !_src.empty() in function 'cvtColor' error
(22 answers)
Closed 8 months ago.
I am trying to convert frames from a video to Tensors as the video is playing. This is my code:
#include <iostream>
#include "src/VideoProcessing.h"
#include <opencv2/opencv.hpp>
#include <opencv2/videoio.hpp>
typedef cv::Point3_<float> Pixel;
const uint WIDTH = 224;
const uint HEIGHT = 224;
const uint CHANNEL = 3;
const uint OUTDIM = 128;
void normalize(Pixel &pixel){
pixel.x = (pixel.x / 255.0 - 0.5) * 2.0;
pixel.y = (pixel.y / 255.0 - 0.5) * 2.0;
pixel.z = (pixel.z / 255.0 - 0.5) * 2.0;
}
int main() {
int fps = VideoProcessing::getFPS("trainer.mp4");
unsigned long size = VideoProcessing::getSize("trainer.mp4");
cv::VideoCapture cap("trainer.mp4");
//Check if input video exists
if(!cap.isOpened()){
std::cout<<"Error opening video stream or file"<<std::endl;
return -1;
}
//Create a window to show input video
cv::namedWindow("input video", cv::WINDOW_NORMAL);
//Keep playing video until video is completed
while(true){
cv::Mat frame;
frame.convertTo(frame, CV_32FC3);
cv::cvtColor(frame, frame, cv::COLOR_BGR2RGB); // convert to float; BGR -> RGB
// normalize to -1 & 1
auto* pixel = frame.ptr<Pixel>(0,0);
const Pixel* endPixel = pixel + frame.cols * frame.rows;
for (; pixel != endPixel; pixel++){normalize(*pixel);}
// resize image as model input
cv::resize(frame, frame, cv::Size(WIDTH, HEIGHT));
//Capture frame by frame
bool success = cap.read(frame);
//If frame is empty then break the loop
if (!success){
std::cout << "Found the end of the video" << std::endl;
break;
}
//Show the current frame
cv::imshow("input video", frame);
if (cv::waitKey(10) == 27){
std::cout << "Esc key is pressed by user. Stopping the video" << std::endl;
break;
}
}
//Close window after input video is completed
cap.release();
//Destroy all the opened windows
cv::destroyAllWindows();
std::cout << "Video file FPS: " << fps << std::endl;
std::cout << "Video file size: " << size << std::endl;
return 0;
}
My goal (down the road) is to run inference on each frame to get landmarks. However, at this stage, I see this error:
terminate called after throwing an instance of 'cv::Exception'
what(): OpenCV(4.1.0) /home/onur/opencv/modules/imgproc/src/color.cpp:182: error: (-215:Assertion failed) !_src.empty() in function 'cvtColor'
Aborted (core dumped)
Where am I going wrong?
You will have to read the frame before performing any conversion.
Move the part
//Capture frame by frame
bool success = cap.read(frame);
//If frame is empty then break the loop
if (!success){
std::cout << "Found the end of the video" << std::endl;
break;
}
Just after
cv::Mat frame;
I'm trying to use OpenCV's calcOpticalFlowPyrLK() function and I can't seem to get past this error:
OpenCV Error: Assertion failed (mtype == type0 || (CV_MAT_CN(mtype) == CV_MAT_CN(type0) && ((1 << type0) & fixedDepthMask) != 0)) in create, file /tmp/opencv20160107-21708-lubvml/opencv-2.4.12/modules/core/src/matrix.cpp, line 1486
libc++abi.dylib: terminating with uncaught exception of type cv::Exception: /tmp/opencv20160107-21708-lubvml/opencv-2.4.12/modules/core/src/matrix.cpp:1486: error: (-215) mtype == type0 || (CV_MAT_CN(mtype) == CV_MAT_CN(type0) && ((1 << type0) & fixedDepthMask) != 0) in function create
I checked the input parameters and both images are:
Size:[1280 x 720]
Depth:(CV_8U)
Here is the code:
Mat frame;
Mat back;
Mat fore;
Mat temp;
Mat prevImage;
Mat currImage;
// for floodfill
Point seed = Point(0,0);
VideoCapture cap("./Sequence2/Sequence_03_%03d.jpg");
// Background subtraction
BackgroundSubtractorMOG2 bg;
bg.set("nmixtures",5);
bg.set("detectShadows", true);
bg.set("fTau", 0.5);
//
bool foundpoints = false;
vector<uchar> status, err;
// Blob Detector
SimpleBlobDetector::Params params;
//params.filterByColor = true;
//params.blobColor = 255; // use if bitwise not statement used
// // Filter by Area.
params.filterByArea = true; //size
params.minArea = 25;
params.maxArea = 300;
params.filterByCircularity = true; // circle or not
params.minCircularity = 0.15;
params.filterByConvexity = true; // closed or not
params.minConvexity = 0.92;
params.filterByInertia = true; // elongated or not
params.minInertiaRatio = 0.40;
SimpleBlobDetector detector(params);
//
std::vector<std::vector<Point> > contours;
std::vector<KeyPoint> keypoints;
std::vector<Point2f> pKeypoints, prevKeypoints;
namedWindow("Video");
//namedWindow("Background");
for (int i = 0; i < 623; i++) {
file << "./Output3/image" << i << ".jpg";
cap >> frame;
// CONVERT TO GRAY
cvtColor(frame, temp, CV_RGB2GRAY);
//adaptiveThreshold(frame,temp,1,ADAPTIVE_THRESH_MEAN_C,THRESH_BINARY,3,1);
bg.operator ()(temp,fore);
//bg.getBackgroundImage(back);
// THREHOLD THE IMAGE
threshold(fore,fore,80,150,THRESH_TOZERO);
erode(fore,fore,cv::Mat());
dilate(fore,fore,cv::Mat());
findContours(fore,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_NONE);
// REMOVE SOME NOISE
cv::floodFill(fore, seed,(255));
erode(fore,fore,cv::Mat());
dilate(fore,fore,cv::Mat());
//bitwise_not(fore,fore);
erode(fore,fore,cv::Mat());
dilate(fore,fore,cv::Mat());
detector.detect(fore, keypoints);
//std::cout << keypoints.size() << "\n";
if (keypoints.size() > 0){
if (foundpoints == false)
foundpoints = true;
else{
cv::Size winsize = fore.size();
KeyPoint::convert(keypoints,pKeypoints);
// std::cout << pKeypoints.size() << " , " << prevKeypoints.size() << " , " << prevImage.depth() << " , "<< fore.depth();
calcOpticalFlowPyrLK(prevImage,fore,prevKeypoints,pKeypoints,status,err,winsize);
prevImage.pop_back();
}
prevImage.push_back(fore);
KeyPoint::convert(keypoints,prevKeypoints);
}
imshow("Frame",fore); // frame
// imshow("Background",back);
if(cv::waitKey(30) >= 0) break;
imwrite(file.str(), fore);
file.str("");
}
Change vector<uchar> err to Mat err.
I've trained a BOW codebook (vocabulary) using a A-KAZE feature descriptors and am trying to use a BFMatcher with knnMatch to compare newly extracted features to the codebook.
Instead, I get the following error,
OpenCV Error: Assertion failed (_queryDescriptors.type() == trainDescType) in knnMatchImpl, file /home/cecilia/opencv-3.0.0/modules/features2d/src/matchers.cpp, line 722 terminate called after throwing an instance of 'cv::Exception' what(): /home/cecilia/opencv-3.0.0/modules/features2d/src/matchers.cpp:722: error: (-215) _queryDescriptors.type() == trainDescType in function knnMatchImpl
I've using the following examples
BoW in OpenCV using precomputed features
How to train and predict using bag of words?
My intuition is that I am adding the codebook to the matcher incorrectly, but I can't find any documentation or examples that support another method. How can I use my codebook with new examples.
MCVE
/* BOWTest.cpp*/
#include <opencv2/imgcodecs.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/opencv.hpp>
#include <iostream>
#include <string>
#include <stdio.h>
#include <dirent.h>
using namespace cv;
using namespace std;
std::string outputFile = "test_codebook.png";
std::string trainingDir = "dataset/";
std::string outputPrefix = "output/res_custom_";
void train(Mat codebook, int codebook_n, Ptr<Feature2D> akaze);
void test(Mat codebook, Ptr<Feature2D> akaze);
int main(int ac, char** av) {
Ptr<Feature2D> feature = AKAZE::create();
Mat codebook;
int codebook_n = 100;
//train(codebook, codebook_n, feature);
test(codebook, feature);
}
//I included the train method to show how the codebook is trained, but it is not actually called in this example
void train(Mat codebook, int codebook_n, Ptr<Feature2D> akaze){
//defining terms for bowkmeans trainer
TermCriteria tc(TermCriteria::MAX_ITER + TermCriteria::EPS, 10, 0.001);
int retries = 1;
int flags = KMEANS_PP_CENTERS;
BOWKMeansTrainer bowTrainer(codebook_n, tc, retries, flags);
int i = 0;
unsigned long numPoints = 0;
DIR *d;
struct dirent *dir;
d = opendir(trainingDir.c_str());
if (d) {
while ((dir = readdir(d)) != NULL){
try {
Mat img;
std::string imgName = trainingDir + dir->d_name;
i = i + 1;
printf("%d, %lu: %s ...", i,numPoints, imgName.c_str());
img = imread(imgName, CV_LOAD_IMAGE_COLOR);
if(img.empty()){ //not image
printf("bad.\n");
continue;
}
printf("loaded.\n");
resize(img, img, Size(200, 200));
Mat features;
vector<KeyPoint> keypoints;
akaze->detectAndCompute(img, Mat(), keypoints, features);
features.convertTo(features, CV_32F);
bowTrainer.add(features);
Mat res;
drawKeypoints(img, keypoints, res);
std::string output_img = outputPrefix + dir->d_name;
imwrite(output_img, res);
numPoints += features.rows;
}catch(int e){
cout << "An exception occurred. Nr. " << e << '\n';
}
}
printf("Read images!");
closedir(d);
codebook = bowTrainer.cluster();
imwrite(outputFile, codebook);
}
}
void test(Mat codebook, Ptr<Feature2D> akaze){
codebook = imread(outputFile);
int codebook_n = codebook.rows;
BFMatcher matcher(NORM_L2);
matcher.add(std::vector<cv::Mat>(1, codebook));
Mat res(Size(codebook_n * 10, 3*10), CV_8UC3, Scalar(0));
vector<int> res_idx(codebook_n, 0);
try {
Mat img;
String imgName = trainingDir + "dog1.jpeg";
img = imread(imgName, CV_LOAD_IMAGE_COLOR);
if(img.empty()){ //not image
printf("bad.\n");
}else{
printf("loaded.\n");
resize(img, img, Size(200, 200));
Mat features;
vector<KeyPoint> keypoints;
akaze->detectAndCompute(img, noArray(), keypoints, features);
features.convertTo(features, CV_32F);
vector< vector< DMatch > > nn_matches;
matcher.knnMatch(features, nn_matches, 1);
printf("%d matched keypoints", nn_matches.size());
}
}catch(int e){
cout << "An exception occurred. Nr. " << e << '\n';
}
}
test_codebook.png
dog1.jpeg
Output
loaded.
OpenCV Error: Assertion failed (_queryDescriptors.type() == trainDescType) in knnMatchImpl, file /home/cecilia/opencv-3.0.0/modules/features2d/src/matchers.cpp, line 722
terminate called after throwing an instance of 'cv::Exception'
what(): /home/cecilia/opencv-3.0.0/modules/features2d/src/matchers.cpp:722: error: (-215) _queryDescriptors.type() == trainDescType in function knnMatchImpl
You shouldn't save the codebook as an image. imwrite will eventually scale and convert the values of the codebook. And imread with default parameters will load it as a 3 channel image CV_8UC3. To store matrices that are not strictly images, you should use FileStorage.
Save:
FileStorage fs(outputFile, FileStorage::WRITE);
// Store codebook
fs << "codebook" << codebook;
Load:
FileStorage fs(outputFile, FileStorage::READ);
fs["codebook"] >> codebook;
You should use BOWImgDescriptorExtractor to compute the BoW image descriptor starting from your features, AKAZE in this case:
Ptr<DescriptorMatcher> matcher = BFMatcher::create("BruteForce");
BOWImgDescriptorExtractor bow(akaze, matcher);
bow.setVocabulary(codebook);
// Mat img = ...
// AKAZE features
Mat features;
vector<KeyPoint> keypoints;
akaze->detectAndCompute(img, noArray(), keypoints, features);
features.convertTo(features, CV_32F);
// BoW descriptor
Mat bowFeatures;
vector<vector<int>> pointsIdxsOfCluster;
bow.compute(features, bowFeatures, &pointsIdxsOfCluster);
You can use builtin glob to read images from a folder, avoiding dirent.
vector<String> fileNames;
glob(trainingDir, fileNames);
for (int i=0; i<fileNames.size(); ++i)
{
Mat img = imread(fileNames[i]);
...
You can use iostream with cout, instead of printf.
This is how the code looks like:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
std::string outputFile = "test_codebook.yml";
std::string trainingDir = "path_to_train_folder/";
std::string outputPrefix = "path_to_output_folder/";
void train(Mat codebook, int codebook_n, Ptr<Feature2D> akaze);
void test(Mat codebook, Ptr<Feature2D> akaze);
int main(int ac, char** av) {
Ptr<Feature2D> feature = AKAZE::create();
Mat codebook;
int codebook_n = 100;
train(codebook, codebook_n, feature);
test(codebook, feature);
}
//I included the train method to show how the codebook is trained, but it is not actually called in this example
void train(Mat codebook, int codebook_n, Ptr<Feature2D> akaze){
//defining terms for bowkmeans trainer
TermCriteria tc(TermCriteria::MAX_ITER + TermCriteria::EPS, 10, 0.001);
int retries = 1;
int flags = KMEANS_PP_CENTERS;
BOWKMeansTrainer bowTrainer(codebook_n, tc, retries, flags);
int i = 0;
unsigned long numPoints = 0;
vector<String> fileNames;
glob(trainingDir, fileNames);
for (int i=0; i<fileNames.size(); ++i)
{
try {
Mat img;
std::string imgName = fileNames[i];
std::string filename = imgName.substr(trainingDir.length());
cout << i << ", " << numPoints << " : " << imgName;
img = imread(imgName, CV_LOAD_IMAGE_COLOR);
if (img.empty()){ //not image
cout << " bad" << endl;
continue;
}
cout << " loaded" << endl;
resize(img, img, Size(200, 200));
Mat features;
vector<KeyPoint> keypoints;
akaze->detectAndCompute(img, Mat(), keypoints, features);
features.convertTo(features, CV_32F);
bowTrainer.add(features);
Mat res;
drawKeypoints(img, keypoints, res);
std::string output_img = outputPrefix + filename;
imwrite(output_img, res);
numPoints += features.rows;
}
catch (int e){
cout << "An exception occurred. Nr. " << e << '\n';
}
}
cout << "Read images!" << endl;
codebook = bowTrainer.cluster();
{
FileStorage fs(outputFile, FileStorage::WRITE);
// Store codebook
fs << "codebook" << codebook;
// You can also store additional info, like the list of images
//// Store train images filenames
//fs << "train" << "[";
//for (int i = 0; i < fileNames.size(); ++i)
//{
// fs << fileNames[i];
//}
//fs << "]";
}
}
void test(Mat codebook, Ptr<Feature2D> akaze)
{
vector<String> trainFileNames;
{
FileStorage fs(outputFile, FileStorage::READ);
fs["codebook"] >> codebook;
/*FileNode trainingImages = fs["train"];
FileNodeIterator it = trainingImages.begin(), it_end = trainingImages.end();
int idx = 0;
for (; it != it_end; ++it, idx++)
{
trainFileNames.push_back(*it);
}*/
}
int codebook_n = codebook.rows;
Ptr<DescriptorMatcher> matcher = BFMatcher::create("BruteForce");
BOWImgDescriptorExtractor bow(akaze, matcher);
bow.setVocabulary(codebook);
try {
Mat img;
String imgName = "path_to_test_image";
img = imread(imgName, CV_LOAD_IMAGE_COLOR);
if (img.empty()){ //not image
cout << "bad" << endl;
}
else{
cout << "loaded" << endl;
resize(img, img, Size(200, 200));
Mat features;
vector<KeyPoint> keypoints;
akaze->detectAndCompute(img, noArray(), keypoints, features);
features.convertTo(features, CV_32F);
Mat bowFeatures;
vector<vector<int>> pointsIdxsOfCluster;
bow.compute(features, bowFeatures, &pointsIdxsOfCluster);
// bowFeatures is the descriptor you're looking for
// pointsIdxsOfCluster contains the indices of keypoints that belong to the cluster.
}
}
catch (int e){
cout << "An exception occurred. Nr. " << e << endl;
}
}
i am trying to use the code given in the tutorial but it is not working. i am sure all the dependencies are there and the program is compiling but it giving me some errors related that some functions can not be found.
here is the code:
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/face.hpp"
#include <iostream>
#include <fstream>
#include <sstream>
using namespace cv;
using namespace std;
static Mat norm_0_255(InputArray _src){
Mat src = _src.getMat();
Mat dst;
switch(src.channels()){
case 1:
cv::normalize(_src, dst, 0, 255, NORM_MINMAX, CV_8UC1);
break;
case 3:
cv::normalize(_src, dst, 0, 255, NORM_MINMAX, CV_8UC3);
break;
default:
src.copyTo(dst);
break;
}
return dst;
}
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[]){
if(argc < 2){
cout << "usage: " << argv[0] << " <csv.ext> <output_folder> " << endl;
exit(0);
}
string output_folder = ".";
if(argc == 3){
output_folder = string(argv[2]);
}
string fn_csv = string(argv[1]);
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);
}
if(images.size() <= 1){
string error_message = "This demo needs at least 2 images to work. please add more images to your data set!";
CV_Error(CV_StsError, error_message);
}
int height = images[0].rows;
Mat testSample = images[images.size() - 1];
int testLabel = labels[labels.size() - 1];
images.pop_back();
labels.pop_back();
Ptr<cv::face::FaceRecognizer> model = cv::face::createEigenFaceRecognizer();
model->train(images, labels);
int predictedLabel = model->predict(testSample);
string result_message = format("Predicted class = %d / Actual class = %d ", predictedLabel, testLabel);
cout << result_message << endl;
Mat eigenvalues = model->getMat("eigenvalues");
Mat W = model->getMat("eigenvectors");
Mat mean = model->getMat("mean");
if(argc == 2){
imshow("mean", norm_0_255(mean.reshape(1, images[0].rows)));
}else{
imwrite(format("%s/mean.png", output_folder.c_str()), norm_0_255(mean.reshape(1, images[0].rows)));
}
// Display or save the Eigenfaces:
for (int i = 0; i < min(10, W.cols); i++) {
string msg = format("Eigenvalue #%d = %.5f", i, eigenvalues.at<double>(i));
cout << msg << endl;
// get eigenvector #i
Mat ev = W.col(i).clone();
// Reshape to original size & normalize to [0...255] for imshow.
Mat grayscale = norm_0_255(ev.reshape(1, height));
// Show the image & apply a Jet colormap for better sensing.
Mat cgrayscale;
applyColorMap(grayscale, cgrayscale, COLORMAP_JET);
// Display or save:
if(argc == 2) {
imshow(format("eigenface_%d", i), cgrayscale);
} else {
imwrite(format("%s/eigenface_%d.png", output_folder.c_str(), i), norm_0_255(cgrayscale));
}
}
// Display or save the image reconstruction at some predefined steps:
for(int num_components = min(W.cols, 10); num_components < min(W.cols, 300); num_components+=15) {
// slice the eigenvectors from the model
Mat evs = Mat(W, Range::all(), Range(0, num_components));
Mat projection = subspaceProject(evs, mean, images[0].reshape(1,1));
Mat reconstruction = subspaceReconstruct(evs, mean, projection);
// Normalize the result:
reconstruction = norm_0_255(reconstruction.reshape(1, images[0].rows));
// Display or save:
if(argc == 2) {
imshow(format("eigenface_reconstruction_%d", num_components), reconstruction);
} else {
imwrite(format("%s/eigenface_reconstruction_%d.png", output_folder.c_str(), num_components), reconstruction);
}
}
// Display if we are not writing to an output folder:
if(argc == 2) {
waitKey(0);
}
return 0;
}
CMakeLists.txt file:
cmake_minimum_required(VERSION 2.8)
project(faceReco)
find_package(OpenCV REQUIRED)
add_executable(faceReco faceReco.cpp)
target_link_libraries(faceReco ${OpenCV_LIBS})
Errors:
/home/abdulaziz/workspace/OpenCV_Projects/FaceReco/faceReco.cpp: In function ‘int main(int, const char**)’:
/home/abdulaziz/workspace/OpenCV_Projects/FaceReco/faceReco.cpp:110:27: error: ‘class cv::face::FaceRecognizer’ has no member named ‘getMat’
Mat eigenvalues = model->getMat("eigenvalues");
^
/home/abdulaziz/workspace/OpenCV_Projects/FaceReco/faceReco.cpp:111:17: error: ‘class cv::face::FaceRecognizer’ has no member named ‘getMat’
Mat W = model->getMat("eigenvectors");
^
/home/abdulaziz/workspace/OpenCV_Projects/FaceReco/faceReco.cpp:112:20: error: ‘class cv::face::FaceRecognizer’ has no member named ‘getMat’
Mat mean = model->getMat("mean");
^
/home/abdulaziz/workspace/OpenCV_Projects/FaceReco/faceReco.cpp:130:46: error: ‘COLORMAP_JET’ was not declared in this scope
applyColorMap(grayscale, cgrayscale, COLORMAP_JET);
^
/home/abdulaziz/workspace/OpenCV_Projects/FaceReco/faceReco.cpp:130:58: error: ‘applyColorMap’ was not declared in this scope
applyColorMap(grayscale, cgrayscale, COLORMAP_JET);
^
/home/abdulaziz/workspace/OpenCV_Projects/FaceReco/faceReco.cpp:143:75: error: ‘subspaceProject’ was not declared in this scope
Mat projection = subspaceProject(evs, mean, images[0].reshape(1,1));
^
/home/abdulaziz/workspace/OpenCV_Projects/FaceReco/faceReco.cpp:144:71: error: ‘subspaceReconstruct’ was not declared in this scope
Mat reconstruction = subspaceReconstruct(evs, mean, projection);
^
few days I'm fighting with camera calibration with chessboard example. Everything is going fine (corners are found and displayed, then feed to arrays) till I call final function calibrateCamera. Than I get assertation error:
OpenCV Error: Assertion failed (nimages > 0) in calibrateCamera, file /home/ig/Downloads/opencv-2.4.8/modules/calib3d/src/calibration.cpp, line 3415
here is classic code:
#include <iostream>
#include <fstream>
#include <vector>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;
using namespace std;
int main(int argc, char* argv[])
{
VideoCapture captR(0); // open the video camera no. 0 (RIGHT)
if (!captR.isOpened()) // if not success, exit program
{
cout << "Cannot open the video cam 0" << endl;
return -1;
}
namedWindow("MyVideo (RIGHT)",CV_WINDOW_AUTOSIZE); //create a window called "MyVideo"
namedWindow("Grayscale",CV_WINDOW_AUTOSIZE); //create a window called "Grayscale"
int a = 0; // Frame counter
int numCornersHor = 7; // Chessboard dimensions
int numCornersVer = 5;
int numSquares = numCornersHor * numCornersVer;
Size boardSize = Size(numCornersHor, numCornersVer);
Mat frameR;
// Mat frameL;
Mat gray_frame;
vector<Point3f> obj;
vector<Point2f> corners; // output vectors of image points
for (int i=0; i<boardSize.height; i++) {
for (int j=0; j<boardSize.width; j++) {
obj.push_back(Point3f(i, j, 0.0f));
}
}
while (1){
int key = waitKey(30);
bool bCaptSuccessR = captR.read(frameR); // read a new frame from video
if (!bCaptSuccessR) //if capture not succeded, break loop
{
cout << "Cannot read a frame from video stream" << endl;
break;
}
vector<vector<Point3f> > object_points;
vector<vector<Point2f> > image_points;
// make grayscale frame version for conerSubPix
cvtColor(frameR, gray_frame, CV_BGR2GRAY);
// Get the chessboard corners
bool found = findChessboardCorners(frameR, boardSize, corners);
if (found) {
// Increase accuracy by subpixels
cornerSubPix(gray_frame, corners, Size(11, 11), Size(-1, -1), TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 30, 0.1));
drawChessboardCorners(gray_frame, boardSize, corners, found);
imshow("Grayscale", gray_frame);
////////////////////////////////////////////
if(key==32){ // Save good found by pressing [space]
image_points.push_back(corners);
object_points.push_back(obj);
cout << "Captured good calibration image, No " << a << endl;
cout << "corners: " << corners << endl;
//cout << "obj: " << obj << endl;
a++;
}
}
imshow("MyVideo (RIGHT)", frameR); //show right webcam frame in "MyVideo" window
if (key == 27) { //wait for 'esc' key press for 30ms. If 'esc' key is pressed, break loop
cout << "esc key is pressed by user" << endl;
break;
}
if (key == 115){ // If 'S' key pressed begin calibration
//////////// BEGIN CALIBRATION ////////////////////////
cout << "Callibration started..." << endl;
Mat cameraMatrix = Mat(3, 3, CV_64F);
cameraMatrix.at<double>(0,0) = 1.0;
Mat distCoeffs;
distCoeffs = Mat::zeros(8, 1, CV_64F);
vector<Mat> rvecs;
vector<Mat> tvecs;
Size imageSize = frameR.size();
calibrateCamera(object_points, image_points, imageSize, cameraMatrix, distCoeffs, rvecs, tvecs);
cout << "Callibration ended." << endl;
}//callibration
}
captR.release();
return 0;
}
And here is OpenCV file excerpt with line numbers:
3400 double cv::calibrateCamera( InputArrayOfArrays _objectPoints,
3401 InputArrayOfArrays _imagePoints,
3402 Size imageSize, InputOutputArray _cameraMatrix, InputOutputArray _distCoeffs,
3403 OutputArrayOfArrays _rvecs, OutputArrayOfArrays _tvecs, int flags, TermCriteria criteria )
3404 {
3405 int rtype = CV_64F;
3406 Mat cameraMatrix = _cameraMatrix.getMat();
3407 cameraMatrix = prepareCameraMatrix(cameraMatrix, rtype);
3408 Mat distCoeffs = _distCoeffs.getMat();
3409 distCoeffs = prepareDistCoeffs(distCoeffs, rtype);
3410 if( !(flags & CALIB_RATIONAL_MODEL) )
3411 distCoeffs = distCoeffs.rows == 1 ? distCoeffs.colRange(0, 5) : distCoeffs.rowRange(0, 5);
3412
3413 int i;
3414 size_t nimages = _objectPoints.total();
3415 CV_Assert( nimages > 0 );
3416 Mat objPt, imgPt, npoints, rvecM((int)nimages, 3, CV_64FC1), tvecM((int)nimages, 3, CV_64FC1);
3417 collectCalibrationData( _objectPoints, _imagePoints, noArray(),
3418 objPt, imgPt, 0, npoints );
3419 CvMat c_objPt = objPt, c_imgPt = imgPt, c_npoints = npoints;
3420 CvMat c_cameraMatrix = cameraMatrix, c_distCoeffs = distCoeffs;
3421 CvMat c_rvecM = rvecM, c_tvecM = tvecM;
3422
3423 double reprojErr = cvCalibrateCamera2(&c_objPt, &c_imgPt, &c_npoints, imageSize,
3424 &c_cameraMatrix, &c_distCoeffs, &c_rvecM,
3425 &c_tvecM, flags, criteria );
3426
3427 bool rvecs_needed = _rvecs.needed(), tvecs_needed = _tvecs.needed();
3428
3429 if( rvecs_needed )
3430 _rvecs.create((int)nimages, 1, CV_64FC3);
3431 if( tvecs_needed )
3432 _tvecs.create((int)nimages, 1, CV_64FC3);
3433
Using Linux Ubuntu 12.04, OpenCV 2.4.8, gcc 4.6.3, Eclipse, ...
You are declaring object_points and image_points within the while loop, but probably want to put declarations outside of the loop. Otherwise, the lists will (effectively) be cleared after each iteration.
The user presses the first key, to detect the checkerboards. Boards are written to object_points and image_points. Then the user presses the key to calibrate the camera. Processing of the first key ends, object_points and image_points loose scope (and are cleared), processing of the second key starts, calibrateCamera is called with an empty object_points array and fails.
You should also check whether object_points is not empty before calling calibrateCamera.
You may also find the source code in the samples/cpp/tutorial_code/calib3d/camera_calibration/ folder of the OpenCV source library