I'm trying to compile the given OpenCV - C++ source code using g++ compiler the compiling command being:
g++ `pkg-config --cflags opencv` vehicleDetection.cpp `pkg-config --libs opencv`
I've also tried compiling the code by explicitly mentioning the libraries using
g++ -I/usr/local/include/opencv -I/usr/local/include/opencv2 -L/usr/local/lib/ -g -o vehicleDetection vehicleDetection.cpp -lopencv_core -lopencv_highgui -lopencv_video -lopencv_videoio -lopencv_videostab
It returns the error:
vehicleDetection.cpp: In function ‘int main()’:
vehicleDetection.cpp:96:2: error: ‘CascadeClassifier’ was not declared in this scope
CascadeClassifier vehicleCascade;
^
vehicleDetection.cpp:101:7: error: ‘vehicleCascade’ was not declared in this scope
if (!vehicleCascade.load (VEHICLE_CASCADE_NAME)) {
^
vehicleDetection.cpp:117:3: error: ‘vehicleCascade’ was not declared in this scope
vehicleCascade.detectMultiScale (grayscaleSampleVideo, vehicles,
^
vehicleDetection.cpp:118:22: error: ‘CV_HAAR_SCALE_IMAGE’ was not declared in this scope
1.1, 2, 0|CV_HAAR_SCALE_IMAGE,
^
vehicleDetection.cpp:121:3: error: ‘vehicleCount’ was not declared in this scope
vehicleCount = 0;
^
vehicleDetection.cpp:124:42: error: conversion from ‘int’ to non-scalar type ‘cv::Point {aka cv::Point_<int>}’ requested
vehicles[i].y + vehicles[i].height);
^
vehicleDetection.cpp:126:45: error: conversion from ‘int’ to non-scalar type ‘cv::Point {aka cv::Point_<int>}’ requested
Point pt2 = (vehicles[i].x, vehicles[i].y);`
May someone enlighten me with the errors.
I beg pardon for disturbing with such trifle issues.
The source code is given herein-
#include <iostream>
#include <string>
#include "opencv2/core/core.hpp"
#include "opencv2/core/core_c.h"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/highgui/highgui_c.h"
#include "opencv2/video/video.hpp"
#include "opencv2/videoio/videoio.hpp"
#include "opencv2/videoio/videoio_c.h"
using namespace std;
using namespace cv;
#define VEHICLE_CASCADE_NAME "path to cascade.xml"
#define SAMPLE_VIDEO_NAME "path to sample video"
#define WINDOW_NAME "Vehicle Detector"
int main () {
int timeCount = 0;
CascadeClassifier vehicleCascade;
Mat captureSampleVideo, grayscaleSampleVideo;
cout << "\nVehicle Detection" << endl << "NOTE: Press <Esc> to quit" << endl;
if (!vehicleCascade.load (VEHICLE_CASCADE_NAME)) {
cout << "ERROR: Classifier loading unsuccessful!!" << endl;
}
VideoCapture sampleVideo (SAMPLE_VIDEO_NAME);
if (!sampleVideo.isOpened ()) {
cout << "ERROR: Sample video loading unsuccessful!!" << endl;
}
while (1) {
sampleVideo >> captureSampleVideo;
cvtColor (captureSampleVideo, grayscaleSampleVideo, CV_BGR2GRAY);
equalizeHist (grayscaleSampleVideo, grayscaleSampleVideo);
vector<Rect> vehicles;
vehicleCascade.detectMultiScale (grayscaleSampleVideo, vehicles,
1.1, 2, 0|CV_HAAR_SCALE_IMAGE,
Size(30, 30));
vehicleCount = 0;
for (int i = 0; i < vehicles.size(); i++) {
Point pt1 = (vehicles[i].x + vehicles[i].width,
vehicles[i].y + vehicles[i].height);
Point pt2 = (vehicles[i].x, vehicles[i].y);
rectangle (captureSampleVideo, pt1, pt2,
CvScalar(255, 0, 0), 1, 8, 0);
vehicleCount += 1;
}
namedWindow (WINDOW_NAME, WINDOW_NORMAL);
imshow (WINDOW_NAME, captureSampleVideo);
if (waitKey(1) == 27) {
destroyWindow (WINDOW_NAME);
cout << timeCount << " ms" << endl;
break;
return 0;
}
}
}
Related
Recently I have decided to store my data into hdf5 binary instead of ASCII files. I would like to use hdf5 format. Basically the thought is have the header and the data in the same file (header ASCII not binary format and then binary format). Something like this:
----------------------------------------
Dataname : testdata
ref_ell : wgs84
bmin :
etc.
and here are the data in hdf5 format
The armadillo library (http://arma.sourceforge.net/docs.html#save_load_mat) do have the function to append data to the existing file (hdf5_opts::append). But I have reached the problem much sooner. I have followed the manual but apparently I did something wrong. Lets say I have:
#include <iomanip>
#include <iostream>
#include <fstream>
#include <map>
#include <cmath>
#include <algorithm>
#include <vector>
#define ARMA_USE_HDF5
#include <hdf5.h>
#include <armadillo>
// g++ -O3 -lhdf5 -larmadillo -DARMA_DONT_USE_WRAPPER -DARMA_USE_BLAS -DARMA_USE_LAPACK -DARMA_USE_HDF5 - hdf5.cpp -o hdf5.o
// g++ -O3 -lhdf5 -larmadillo hdf5.cpp -o hdf5.o
// g++ -O3 -larmadillo -lhdf5 hdf5.cpp -o hdf5.o
using namespace std;
int main() {
arma::mat amat = arma::randu<arma::mat>(5,6);
cout << amat << endl;
amat.save( arma::hdf5_name("A.h5", "my_data"));
arma::mat bmat;
bool t = bmat.load( arma::hdf5_name("A.h5", "my_data"));
cout << bmat << endl;
if(t == false)
cout << "problem with loading" << endl;
return 0;
}
I tried to compile this exercise but I get only errors:
Either this:
hdf5.cpp: In function ‘int main()’:
hdf5.cpp:28:43: error: ‘hdf5_name’ was not declared in this scope
amat.save( hdf5_name("A.h5", "my_data"));
Or:
g++ -O3 -lhdf5 -larmadillo hdf5.cpp -o hdf5.o
hdf5.cpp: In function ‘int main()’:
hdf5.cpp:27:16: error: ‘hdf5_name’ is not a member of ‘arma’
amat.save( arma::hdf5_name("A.h5", "my_data"), arma::hdf5_binary);
What am I missing? (Solved - an update of the armadillo lib was required !)
Proceeding to second part of the problem: To save the header first and then add the data in hdf5 format. This way it works. But the header is added after the matrix is stored.
#include <iomanip>
#include <iostream>
#include <fstream>
#include <map>
#include <cmath>
#include <algorithm>
#include <vector>
#define ARMA_USE_HDF5
#define ARMA_DONT_USE_WRAPPER
#include <hdf5.h>
#include <armadillo>
// g++ -O3 -larmadillo -lhdf5 hdf5.cpp -o hdf5.o
using namespace std;
int main() {
arma::mat amat = arma::randu<arma::mat>(5,6);
cout << amat << endl;
amat.save( arma::hdf5_name("A.hdf5", "gmodel", arma::hdf5_opts::append ) );
ofstream f_out; f_out.open( "A.hdf5", ios::app );
f_out << "\nbegin_of_head ================================================\n";
f_out << "model name : " << "model_name" << endl;
f_out << "model type : " << "model_type" << endl;
f_out << "units : " << "units" << endl;
f_out << "ref_ell : " << "ref_ell" << endl;
f_out << "ISG format = " << "isg_format" << endl;;
f_out << "end_of_head ==================================================\n";
f_out.close();
return 0;
}
When i switch the order, the amat.save() function just rewrites the content of the A.hdf5 file.
For me the code worked (in Ubuntu 17.10) using
g++ hdf5.cpp `pkg-config --cflags --libs hdf5` -DARMA_DONT_USE_WRAPPER -I/home/claes/armadillo-8.500/include -o hdf5.o -lblas -llapack
where
`pkg-config --cflags --libs hdf5`
expands to
-I/usr/include/hdf5/serial -L/usr/lib/x86_64-linux-gnu/hdf5/serial -lhdf5
I am compiling an example for OpenCV with the following code:
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main( int argc, char** argv )
{
if( argc != 2)
{
cout <<" Usage: display_image ImageToLoadAndDisplay" << endl;
return -1;
}
Mat image;
image = imread(argv[1], CV_LOAD_IMAGE_COLOR); // Read the file
if(! image.data ) // Check for invalid input
{
cout << "Could not open or find the image" << std::endl ;
return -1;
}
namedWindow( "Display window", WINDOW_AUTOSIZE );// Create a window for display.
imshow( "Display window", image ); // Show our image inside it.
waitKey(0); // Wait for a keystroke in the window
return 0;
}
The compilation code is:
g++ -I/usr/local/include/opencv2 `pkg-config --cflags --libs opencv` -L /usr/local/share/OpenCV/3rdparty/lib/ opencv.cpp -o opencv -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_features2d -lopencv_imgcodecs
If I omit one of the libraries I add additionally, I get linking errors. When trying to run the program, I get an"Invalid machine code" error. How can that be solved?
I have written a small program to prepare an image which is later processed by a FPGA-Board. I need to have it run on any windows machine, even if opencv is not installed. I have read a lot of tutorials and answers on stack overflow, but none of that seems to work for me. I compiled opencv myself using Cmake and MinGW to build the static libraries (.a files). How do I get those in my project, which ones do I need and how do I link them? It seems like everytime I try to link the libraries I used before (when using dlls) seems to have some kind of dependency to other ones.
Thanks in advance,
Brillow
The error message is:
g++ "-LE:\\opencv\\staticlibs\\lib" -static-libgcc -static-libstdc++ -mwindows -o img_prep.exe main.o -lIlmImf -ljasper -lpng -ltiff -ljpeg -lz -lopencv_highgui249 -lopencv_imgproc249 -lopencv_core249
E:\opencv\staticlibs\lib/libopencv_highgui249.a(grfmt_jpeg.cpp.obj):grfmt_jpeg.cpp:(.text.unlikely._ZN2cvL16my_jpeg_load_dhtEP22jpeg_decompress_structPhPP9JHUFF_TBLS5_.constprop.52+0xce): undefined reference to `jpeg_alloc_huff_table'
E:\opencv\staticlibs\lib/libopencv_highgui249.a(grfmt_jpeg.cpp.obj):grfmt_jpeg.cpp:(.text$_ZN2cv11JpegEncoder5writeERKNS_3MatERKSt6vectorIiSaIiEE+0xe2): undefined reference to `jpeg_CreateCompress'
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: E:\opencv\staticlibs\lib/libopencv_highgui249.a(grfmt_jpeg.cpp.obj): bad reloc address 0xe2 in section `.text$_ZN2cv11JpegEncoder5writeERKNS_3MatERKSt6vectorIiSaIiEE'
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: final link failed: Invalid operation
collect2.exe: error: ld returned 1 exit status
I have linked the following libraries in the MinGW linker:
Here's my code:
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <fstream>
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
if (argc != 2) {
cout << "Usage: img_prep InputImage" << endl;
return -1;
}
Mat img, img_gray;
Size size(800,600);
img = imread(argv[1], CV_LOAD_IMAGE_COLOR);
if (!img.data) {
cout << "Could not read the image!" << endl;
return -1;
}
cvtColor(img, img_gray, CV_RGB2GRAY);
resize(img_gray, img, size);
cout << "Image successfully converted!" << endl;
ofstream output;
output.open("output.img", ios::binary);
output.write((char *) img.data, img.rows * img.cols);
output.close();
imwrite("output.bmp", img);
cout << "Image saved!" << endl;
//Ergebnis anzeigen:
namedWindow("Display", WINDOW_AUTOSIZE);
imshow("Display", img);
waitKey(0);
return 0;
}
I have a problem under Qt, Actually I want to use opencv under it (ubuntu) and there is a crash.
If I compile under the terminal :
g++ pkg-config --cflags opencv example.cc -o output_file pkg-config --libs opencv
All is all right but under QT there is a crashed problem and I just read this message error :
Starting /home/quentin/build-test_opencv-Desktop_Qt_5_2_1_GCC_64bit-Release/test_opencv...
The program has unexpectedly finished.
/home/quentin/build-test_opencv-Desktop_Qt_5_2_1_GCC_64bit-Release/test_opencv crashed
This is my .pro :
QT += core
QT -= gui
TARGET = test_opencv
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
CONFIG += link_pkgconfig
PKGCONFIG += opencv
SOURCES += main.cpp
INCLUDEPATH += -I /usr/local/include/opencv
LIBS += `pkg-config opencv --libs`
and this is my main.cpp :
#include <QCoreApplication>
#include <iostream>
#include "cv.h"
#include "highgui.h"
using namespace std;
int main(int argc, char *argv[])
{
IplImage* img = cvLoadImage( "lena.png" );
cout << "Image WIDTH = " << img->width << endl;
cout << "Image HEIGHT = " << img->height << endl;
cvReleaseImage( &img );
return 0;
}
Most likely cvLoadImage fails and returns nullptr. You never bother checking for that.
What version of openCV do you use? What berak means is that IplImage is not used in the newer versions of openCV. Use Mat instead of IplImage. Try this code and tell me what happens:
#include <QCoreApplication>
#include <iostream>
#include <stdio.h>
#include <opencv2/core/core.hpp>
#include "opencv2/highgui/highgui.hpp"
int main(int argc, char *argv[])
{
Mat* img = new cv::Mat(cv::imread("lena.png",CV_LOAD_IMAGE_COLOR));
if(img == NULL){
perror("Could not load image");
}
std::cout << "Image WIDTH = " << img->cols << std::endl;
std::cout << "Image HEIGHT = " << img->rows << std::endl;
img->release();
return 0;
}
This will work in opencv 2.4.X. Also make sure your image is in the same folder as your program. Please tell me of any error.
when training my classifier, i get this error:
Image step is wrong (The matrix is not continuous, thus its number of rows can not be changed) in reshape, file /home/denn/Downloads/opencv-2.4.6.1/modules/core/src/matrix.cpp, line 802
terminate called after throwing an instance of 'cv::Exception'
what(): /home/denn/Downloads/opencv-2.4.6.1/modules/core/src/matrix.cpp:802: error: (-13) The matrix is not continuous, thus its number of rows can not be changed in function reshape
Aborted (core dumped)
I'm working on an Automatic Number Plate Recognition project in C++. all that is left now is train the my SVM.
I resized all my images to a 450 by 450 after researching this but the error persists.
I have studied and looked around but none of the solutions works for me.
any help accorded will be highly appreciated.
// Main entry code OpenCV
#include <cv.h>
#include <highgui.h>
#include <cvaux.h>
#include <iostream>
#include <vector>
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=450; //144
int imageHeight=450; //33
//Check if user specify image to process
if(argc >= 5 )
{
numPlates= atoi(argv[1]);
numNoPlates= atoi(argv[2]);
path_Plates= argv[3];
path_NoPlates= argv[4];
}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=0; i< numPlates; i++)
{
stringstream ss(stringstream::in | stringstream::out);
ss << path_Plates << i << ".jpg";
Mat img=imread(ss.str(), 0);
img= img.reshape(1, 1);
trainingImages.push_back(img);
trainingLabels.push_back(1);
}
for(int i=0; i< numNoPlates; i++)
{
stringstream ss(stringstream::in | stringstream::out);
ss << path_NoPlates << i << ".jpg";
Mat img=imread(ss.str(), 0);
img= img.reshape(1, 1);
trainingImages.push_back(img);
trainingLabels.push_back(0);
}
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;
}
I edited the code and made it like this:
// Main entry code OpenCV
#include <cv.h>
#include <highgui.h>
#include <cvaux.h>
#include <iostream>
#include <vector>
#include <iostream>
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=450; //144
int imageHeight=450; //33
//Check if user specify image to process
if(argc >= 5 )
{
numPlates= atoi(argv[1]);
numNoPlates= atoi(argv[2]);
path_Plates= argv[3];
path_NoPlates= argv[4];
}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;
Mat classes = new Mat();
Mat trainingData = new Mat();
Mat trainingImages = new Mat();
Mat trainingLabels = new Mat();
for(int i=0; i< numPlates; i++)
{
stringstream ss(stringstream::in | stringstream::out);
ss << path_Plates << i << ".png";
Mat img=imread(ss.str(), 0);
img= img.reshape(1, 1);
trainingImages.push_back(img);
trainingLabels.push_back(1);//trainingLabels.push_back(Mat.ones(new Size(1, 1), CvType.CV_32FC1));//trainingLabels.push_back(1);
}
for(int i=0; i< numNoPlates; i++)
{
stringstream ss(stringstream::in | stringstream::out);
ss << path_NoPlates << i << ".png";
Mat img=imread(ss.str(), 0);
img= img.reshape(1, 1); //img= img.clone().reshape(1, 1);
trainingImages.push_back(img);
trainingLabels.push_back(0);//trainingLabels.push_back(Mat.zeros(new Size(1, 1), CvType.CV_32FC1));//trainingLabels.push_back(0);
}
trainingImages.copyTo(trainingData);
//trainingData = trainingData.reshape(1,trainingData.rows);
trainingData.convertTo(trainingData, CV_32FC1);
trainingLabels.copyTo(classes);
FileStorage fs("SVM.xml", FileStorage::WRITE);
fs << "TrainingData" << trainingData;
fs << "classes" << classes;
fs.release();
return 0;
}
but I get this error on compilation:
/home/denn/Desktop/NumberPlateRecognition/trainSVM.cpp:52:27: error: conversion from ‘cv::Mat*’ to non-scalar type ‘cv::Mat’ requested
/home/denn/Desktop/NumberPlateRecognition/trainSVM.cpp:52:27: error: conversion from ‘cv::Mat*’ to non-scalar type ‘cv::Mat’ requested
/home/denn/Desktop/NumberPlateRecognition/trainSVM.cpp:53:32: error: conversion from ‘cv::Mat*’ to non-scalar type ‘cv::Mat’ requested
/home/denn/Desktop/NumberPlateRecognition/trainSVM.cpp:55:34: error: conversion from ‘cv::Mat*’ to non-scalar type ‘cv::Mat’ requested
/home/denn/Desktop/NumberPlateRecognition/trainSVM.cpp:56:34: error: conversion from ‘cv::Mat*’ to non-scalar type ‘cv::Mat’ requested
make[2]: *** [CMakeFiles/trainSVM.dir/trainSVM.cpp.o] Error 1
make[1]: *** [CMakeFiles/trainSVM.dir/all] Error 2
make: *** [all] Error 2
I any advice?
As berak pointed out in the comments above, your cv::Mat can become discontinuous in the following instances:
if you extract a part of the matrix using Mat::col(), Mat::diag() , and so on, or construct a matrix header for externally allocated data, such matrices may no longer have [the iscontinuous()] property.
As they point out in the above reference, create your matrices using Mat::create and you won't have this issue.
Update:
So, the function Mat::clone, as our friend berak pointed out in the comments above, will do the trick for you. It calls the function Mat::create. I just tried out the following code, and it worked like a charm.
Mat trainingImages;
vector<int> trainingLabels;
for(int i=0; i< numPlates; i++)
{
stringstream ss;
ss << path_Plates << "grumpy" << i << ".jpg";
std::cout << ss.str() << std::endl;
Mat img =imread(ss.str(), CV_LOAD_IMAGE_GRAYSCALE);
if(! img.data ) {
cout << "Could not open or find the image" << std::endl ;
return -1;
}
else {
img = img.clone().reshape(0,1);
trainingImages.push_back(img);
trainingLabels.push_back(i);
}
}
However, a few notes, it looks like you might not have the right header file names. I used the following with OpenCV 2.4.8 on Ubuntu 12.04:
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/ml/ml.hpp>
Also, make sure to compile it with the OpenCV libraries (i.e. opencv_core and opencv_ml). Hope that helps you in your quest for plate recognition.