I came across functions used like this:
void func(int, void*);
int main()
{
func(0,0);
}
void func(int, void*)
{
//content
}
And I have no idea, what does it mean. But for some reason, if I copied content from func straight into main, it doesn't work.
I found it used with OpenCV, but no explanation of it.
So I would appreciate, if someone could explain to me what does it mean or why is it used.
So, in my case:
#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;
/// Function header
void thresh_callback(int, void* );
/** #function main */
int main( int argc, char** argv )
{
/// Load source image and convert it to gray
src = imread( "test.png", 1 );
/// 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 );
thresh_callback( 0, 0 );
waitKey(0);
return(0);
}
/** #function thresh_callback */
void thresh_callback(int, void* )
{
Mat threshold_output;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
/// Detect edges using Threshold
threshold( src_gray, threshold_output, thresh, 255, THRESH_BINARY );
/// Find contours
findContours( threshold_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
/// Approximate contours to polygons + get bounding rects
vector<vector<Point> > contours_poly( contours.size() );
vector<Rect> boundRect( contours.size() );
for( int i = 0; i < contours.size(); i++ ) {
approxPolyDP( Mat(contours[i]), contours_poly[i], 3, true );
boundRect[i] = boundingRect( Mat(contours_poly[i]) );
}
/// Draw bonding rects
Mat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 );;
for( int i = 0; i< contours.size(); i++ ) {
rectangle( drawing, boundRect[i].tl(), boundRect[i].br(), Scalar::all(255), 2, 8, 0 );
}
/// Show in a window
namedWindow( "Contours", CV_WINDOW_AUTOSIZE );
imshow( "Contours", drawing );
}
This is code, that I get from the internet. It works well, it detects edges and draw rectangle around them and i can understand it, except declaration of function thresh_callback.
So, my main question is, why it doesn't work without it?
And what does parameters without names mean or why are they there?
1.
void func(int, void*);
declares that there will be a void function called func with two parameters, the first being an int and the second being a void*.
2.
void func(int, void*)
{
//content
}
This is the definition of the function declared in 1. So, if you call func, this function will be executed.
3.
int main()
{
func(0,0);
}
Here you execute func and pass 0 as the first parameter and 0 as the second parameter as well.
4.
If you paste the content of func into main, then it will not work, since the content of func assumes the existence of the two parameters, which do not exist in main.
Related
I wrote this program by C++ using OpenCV to detect pedestrians.xml file that I have. The program should read all of the input images and display blue rectangles on the output images where pedestrians are located. But the code is giving me errors. Is there anyone who can tell me why these errors come?
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/features2d/features2d.hpp>
#include<iostream>
#include <stdio.h>
#include <string>
#include <vector>
using namespace std;
using namespace cv;
void detectAndDisplay( Mat frame );
/** Global variables */
String pedestrians_name = "hogcascade_pedestrians.xml";
//CascadeClassifier pedestrians;
string window_name = "Capture - pedestrians detection";
RNG rng(12345);
/** #function main */
int main( int argc, const char** argv )
{
CvCapture* capture;
Mat frame;
//-- 1. Load the cascades
//if( !pedestrians.load( pedestrians_name ) ){ printf("--(!)Error loading\n"); return -1; };
Mat image = imread("ped1.jpg");
Mat image_keypoints;
cvtColor(image, image_keypoints, CV_BGR2GRAY);
return 0;
}
/** #function detectAndDisplay */
void detectAndDisplay( Mat frame )
{
std::vector<Rect> pedestrians;
Mat frame_gray;
cvtColor( frame, frame_gray, CV_BGR2GRAY );
equalizeHist( frame_gray, frame_gray );
//-- Detect faces
pedestrians.detectMultiScale( frame_gray, pedestrians, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );
void CascadeClassifier::detectMultiScale(const Mat& image, vector<Rect>& objects, double scaleFactor=1.1, int minNeighbors=3, int flags=0, Size minSize=Size(), Size maxSize=Size());
for( int i = 0; i < pedestrians.size(); i++ )
{
Point center( pedestrians[i].x + pedestrians[i].width*0.5, pedestrians[i].y + pedestrians[i].height*0.5 );
ellipse( frame, center, Size( pedestrians[i].width*0.5, pedestrians[i].height*0.5), 0, 0, 360, Scalar( 255, 0, 255 ), 4, 8, 0 );
Mat faceROI = frame_gray( pedestrians[i] );
std::vector<Rect> eyes;
//-- In each face, detect eyes
/*eyes_cascade.detectMultiScale( faceROI, eyes, 1.1, 2, 0 |CV_HAAR_SCALE_IMAGE, Size(30, 30) );
for( size_t j = 0; j < eyes.size(); j++ )
{
Point center( faces[i].x + eyes[j].x + eyes[j].width*0.5, faces[i].y + eyes[j].y + eyes[j].height*0.5 );
int radius = cvRound( (eyes[j].width + eyes[j].height)*0.25 );
circle( frame, center, radius, Scalar( 255, 0, 0 ), 4, 8, 0 );
}*/
}
//-- Show what you got
imshow( window_name, frame );
}
these are the errors:
cascade.cpp: In function âvoid detectAndDisplay(cv::Mat)â:
cascade.cpp:46: error: âclass std::vector<cv::Rect_<int>, std::allocator<cv::Rect_<int> > >â has no member named âdetectMultiScaleâ
cascade.cpp:46: error: âCV_HAAR_SCALE_IMAGEâ was not declared in this scope
cascade.cpp:47: error: âCascadeClassifierâ has not been declared
cascade.cpp:47: error: invalid use of qualified-name â<declaration error>::detectMultiScaleâ
You need to add opencv_objdetect library. And include "opencv2/objdetect.hpp".
create a Cascade classifier object and load the xml file obj.load(xml file path)
First of all, in main() you never called detectAndDisplay() right? You need to call it if you want to execute it...
Second of all, you need to declare and load a cascade classifier in detectAndDisplay() before you use detectMultiScale.
CascadeClassifier pedestrians;
if( !pedestrians.load( pedestrians_name ) ){
printf("--(!)Error loading\n");
return;}
//.....
pedestrians.detectMultiScale( frame_gray, pedestrians, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );
so I am working on an assignment in which I have to classify road signs based on input images. So naturally I used the canny function, and findContours, followed by approxPolyPD in order to get the corners of the image that I will be transforming.
However for some reason, I keep getting an error when I attempt to use getPerspectiveTransform for the next step. Please help.
Error:
OpenCV Error: Assertion failed (0 <= i && i < (int)vv.size()) in getMat_, file /home/path_to_opencv/opencv/modules/core/src/matrix.cpp, line 1192
terminate called after throwing an instance of 'cv::Exception'
what(): /home/path_to_opencv/opencv/modules/core/src/matrix.cpp:1192: error: (-215) 0 <= i && i < (int)vv.size() in function getMat_
Aborted (core dumped)
Code used:
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#define WARPED_XSIZE 200
#define WARPED_YSIZE 300
using namespace cv;
using namespace std;
Mat src; Mat src_gray, warped_result; Mat dst;
Mat speed_80, speed_40;
int canny_thresh = 154;
#define VERY_LARGE_VALUE 100000
#define NO_MATCH 0
#define STOP_SIGN 1
#define SPEED_LIMIT_40_SIGN 2
#define SPEED_LIMIT_80_SIGN 3
RNG rng(12345);
/** #function main */
int main(int argc, char** argv)
{
int sign_recog_result = NO_MATCH;
speed_40 = imread("speed_40.bmp", 0);
speed_80 = imread("speed_80.bmp", 0);
// you run your program on these three examples (uncomment the two lines below)
//string sign_name = "stop4";
string sign_name = "speedsign12";
//string sign_name = "speedsign3";
//string sign_name = "speedsign4";
string final_sign_input_name = sign_name + ".jpg";
string final_sign_output_name = sign_name + "_result" + ".jpg";
/// Load source image and convert it to gray
src = imread(final_sign_input_name, 1);
/// Convert image to gray and blur it
cvtColor(src, src_gray, COLOR_BGR2GRAY);
blur(src_gray, src_gray, Size(3, 3));
warped_result = Mat(Size(WARPED_XSIZE, WARPED_YSIZE), src_gray.type());
// here you add the code to do the recognition, and set the variable
// sign_recog_result to one of STOP_SIGN, SPEED_LIMIT_40_SIGN, SPEED_LIMIT_80_SIGN, or NO_MATCH
// PART 1 of Assignment 2
Mat canny_output;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
Canny(src_gray, canny_output, canny_thresh, canny_thresh*2, 3);
findContours(canny_output, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_NONE, Point(0, 0));
vector<vector<Point> > contours_poly(contours.size());
for (unsigned int i = 0; i < contours.size(); ++i) {
approxPolyDP(Mat(contours[i]), contours_poly[i], contours_poly[i].size()*.02, true);
}
// Part 2 of Assignment 2
vector<vector<Point> > transform_result(contours_poly.size());
warped_result = getPerspectiveTransform(contours_poly, transform_result);
warpPerspective(src, dst, warped_result, dst.size());
//imshow("input", src);
//imshow("output", dst);
/*
Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
for(unsigned int i = 0; i< contours_poly.size(); i++ ) {
Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
drawContours( drawing, contours_poly, i, color, 2, 8, hierarchy, 0, Point() );
}
// Show in a window
namedWindow( "Contours", CV_WINDOW_AUTOSIZE );
imshow( "Contours", drawing );
//*/
// Returning to the predetermined code.
string text;
if (sign_recog_result == SPEED_LIMIT_40_SIGN) text = "Speed 40";
else if (sign_recog_result == SPEED_LIMIT_80_SIGN) text = "Speed 80";
else if (sign_recog_result == STOP_SIGN) text = "Stop";
else if (sign_recog_result == NO_MATCH) text = "Fail";
int fontFace = FONT_HERSHEY_SCRIPT_SIMPLEX;
double fontScale = 2;
int thickness = 3;
cv::Point textOrg(10, 130);
cv::putText(src, text, textOrg, fontFace, fontScale, Scalar::all(255), thickness, 8);
/// Create Window
char* source_window = "Result";
namedWindow(source_window, WINDOW_AUTOSIZE);
imshow(source_window, src);
imwrite(final_sign_output_name, src);
waitKey(0);
return(0);
}
I want any advice how to solve this Error
I'm trying a sample code to check the opencv_contrib Extra modules using CMake
This is the error message:
And this is the sample code which I used
#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
src = imread("Baraya.jpg", 1);
/// 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(" Threshold:", "Source", &thresh, max_thresh, thresh_callback);
thresh_callback(0, 0);
waitKey(0);
return(0);
}
/** #function thresh_callback */
void thresh_callback(int, void*)
{
Mat threshold_output;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
/// Detect edges using Threshold
threshold(src_gray, threshold_output, thresh, 255, THRESH_BINARY);
/// Find contours
findContours(threshold_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
/// Approximate contours to polygons + get bounding rects and circles
vector<vector<Point> > contours_poly(contours.size());
vector<Rect> boundRect(contours.size());
vector<Point2f>center(contours.size());
vector<float>radius(contours.size());
for (int i = 0; i < contours.size(); i++)
{
approxPolyDP(Mat(contours[i]), contours_poly[i], 3, true);
boundRect[i] = boundingRect(Mat(contours_poly[i]));
minEnclosingCircle((Mat)contours_poly[i], center[i], radius[i]);
}
/// Draw polygonal contour + bonding rects + circles
Mat drawing = Mat::zeros(threshold_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_poly, i, color, 1, 8, vector<Vec4i>(), 0, Point());
rectangle(drawing, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0);
circle(drawing, center[i], (int)radius[i], color, 2, 8, 0);
}
/// Show in a window
namedWindow("Contours", CV_WINDOW_AUTOSIZE);
imshow("Contours", drawing);
}
There is no error in the code you posted. It works well if you installed OpenCV properly. This error is because you didn't build with any windowing system .
This error is from here:
#if defined (HAVE_WIN32UI) // see window_w32.cpp
#elif defined (HAVE_GTK) // see window_gtk.cpp
#elif defined (HAVE_COCOA) // see window_carbon.cpp
#elif defined (HAVE_CARBON)
#elif defined (HAVE_QT) // see window_QT.cpp
#elif defined (WINRT) && !defined (WINRT_8_0) // see window_winrt.cpp
#else
// No windowing system present at compile time ;-(
//
// We will build place holders that don't break the API but give an error
// at runtime. This way people can choose to replace an installed HighGUI
// version with a more capable one without a need to recompile dependent
// applications or libraries.
void cv::setWindowTitle(const String&, const String&)
{
CV_Error(Error::StsNotImplemented, "The function is not implemented. "
"Rebuild the library with Windows, GTK+ 2.x or Carbon support. "
"If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script");
}
So re-run CMAKE with WITH_WIN32UI, since you are on Windows, and eventually with WITH_QT.
I am trying to make this OOP, so I made a class that implements the callback function for the trackbar.
This is my class
class Contours
{
public:
static Mat src_gray;
static int thresh;
Contours(Mat, int);
~Contours(void);
static void callback(int, void* );
private:
};
Contours::Contours(Mat src_gray,int thresh){
this->src_gray=src_gray;
this->thresh=thresh;
}
Contours::~Contours(void){}
void Contours::callback(int, void*)
{int largest_area=0;
int largest_contour_index=0;
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 );
cout<<contours.size()<<endl;
for( int i = 0; i< contours.size(); i++ )
{
double a=contourArea( contours[i],false); // Find the area of contour
if(a>largest_area){
largest_area=a;
largest_contour_index=i; } //Store the index of largest contour
//Scalar color = Scalar(255,255,255 );
//drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() );
}
cout<<"cnt maxim: "<<largest_contour_index<<endl;
Scalar color = Scalar(255,255,255 );
drawContours( drawing, contours, largest_contour_index, color, 2, 8, hierarchy, 0, Point() );
/// Show in a window
namedWindow( "Contours", CV_WINDOW_AUTOSIZE );
imshow( "Contours", drawing );
//imwrite("sada.png",drawing);
}
And calling the function
createTrackbar( " Canny thresh:", "Source", &thresh, max_thresh, &Contours::callback );
I get
Error 5 error LNK2001: unresolved external symbol "public: static class cv::Mat Contours::src_gray" (?src_gray#Contours##2VMat#cv##A) D:\Licenta\Hand sign recognition\Algoritmi.obj Hand sign recognition
Error 6 error LNK2001: unresolved external symbol "public: static int Contours::thresh" (?thresh#Contours##2HA) D:\Licenta\Hand sign recognition\Algoritmi.obj Hand sign recognition
Any ideas why?
maybe use a different approach to the 'static callback' problem:
class Contours
{
public:
Mat src_gray; // non-static
int thresh;
Contours(Mat, int);
void callback(int, void* ); // non-static
};
void callback(int value, void*ptr) // static global
{
Contours* cnt = (Contours*)ptr; // cast 'this'
cnt->callback(value,0); // call non-static member
}
int main()
{
Mat gray = ...
Contours cnt(gray,17);
// now pass the address of cnt as additional void* Ptr:
createTrackbar( " Canny thresh:", "Source", &thresh, max_thresh, callback, &cnt );
...
I'm trying to iterate over the points i get from cv::goodFeaturesToTrack.
I retrieve my points using this code:
std::vector<std::vector<cv::Point2f> > corners;
cv::goodFeaturesToTrack(image,corners, 500, 0.01, 10);
My idea, which doesn't work:
for (size_t idx = 0; idx < corners.size(); idx++) {
cv::circle(image,corners.at(idx),radius,color,thickness);
}
Any ideas?
The detector goodFeaturesToTrack (indeed all feature detectors) populate a vector of features, while you are trying to pass it a vector of a vector of features. The remainder of your code looks fine but you should change the line
std::vector<std::vector<cv::Point2f>> corners;
to
std::vector<cv::Point2f> corners;
and hopefully all will be well.
Not sure what you mean by "doesn't work". But, you might try looking at the goodFeaturesToTrack_Demo.cpp to see if that usage will fix your problem.
Update with code:
/**
* #function goodFeaturesToTrack_Demo.cpp
* #brief Demo code for detecting corners using Shi-Tomasi method
* #author OpenCV team
*/
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace cv;
using namespace std;
/// Global variables
Mat src, src_gray;
int maxCorners = 23;
int maxTrackbar = 100;
RNG rng(12345);
const char* source_window = "Image";
/// Function header
void goodFeaturesToTrack_Demo( int, void* );
/**
* #function main
*/
int main( int, char** argv )
{
/// Load source image and convert it to gray
src = imread( argv[1], 1 );
cvtColor( src, src_gray, COLOR_BGR2GRAY );
/// Create Window
namedWindow( source_window, WINDOW_AUTOSIZE );
/// Create Trackbar to set the number of corners
createTrackbar( "Max corners:", source_window, &maxCorners, maxTrackbar, goodFeaturesToTrack_Demo );
imshow( source_window, src );
goodFeaturesToTrack_Demo( 0, 0 );
waitKey(0);
return(0);
}
/**
* #function goodFeaturesToTrack_Demo.cpp
* #brief Apply Shi-Tomasi corner detector
*/
void goodFeaturesToTrack_Demo( int, void* )
{
if( maxCorners < 1 ) { maxCorners = 1; }
/// Parameters for Shi-Tomasi algorithm
vector<Point2f> corners;
double qualityLevel = 0.01;
double minDistance = 10;
int blockSize = 3;
bool useHarrisDetector = false;
double k = 0.04;
/// Copy the source image
Mat copy;
copy = src.clone();
/// Apply corner detection
goodFeaturesToTrack( src_gray,
corners,
maxCorners,
qualityLevel,
minDistance,
Mat(),
blockSize,
useHarrisDetector,
k );
/// Draw corners detected
cout<<"** Number of corners detected: "<<corners.size()<<endl;
int r = 4;
for( size_t i = 0; i < corners.size(); i++ )
{ circle( copy, corners[i], r, Scalar(rng.uniform(0,255), rng.uniform(0,255), rng.uniform(0,255)), -1, 8, 0 ); }
/// Show what you got
namedWindow( source_window, WINDOW_AUTOSIZE );
imshow( source_window, copy );
}