opencv (SVM) - the parameter nu is out of range - opencv

The following code generates an exception saying:
One of arguments' values is out of range- the parameter nu must be between 0 and 1
I wonder why this is happening when I've already set it to something between 0 and 1.
CvSVM svm;
CvParamGrid CvParamGrid_C(pow(2.0,-5), pow(2.0,15), pow(2.0,2));
CvParamGrid CvParamGrid_gamma(pow(2.0,-15), pow(2.0,3), pow(2.0,2));
CvParamGrid CvParamGrid_nu(0.4, 0.8,0.1);
const cv::Mat labelsMat(250, 1, CV_32FC1, labels);
const cv::Mat trainingDataMat(250,35, CV_32FC1, trainingData);
CvSVMParams paramz;
paramz.kernel_type = CvSVM::RBF; paramz.svm_type = CvSVM::NU_SVR;
paramz.term_crit = cvTermCriteria(CV_TERMCRIT_ITER,100,0.000001);
svm.train_auto(trainingDataMat, labelsMat, cv::Mat(), cv::Mat(), paramz, 5,
CvParamGrid_C, CvParamGrid_gamma, CvSVM::get_default_grid(CvSVM::P),
CvParamGrid_nu,vSVM::get_default_grid(CvSVM::COEF),
CvSVM::get_default_grid(CvSVM::DEGREE), true);
paramz = svm.get_params();
Can someone help?

From opencv documentation: The grid is logarithmic, so step must always be greater then 1.

Related

OpenCV fisheye::projectpoints assertion faild

I want to project a single point (-1450,-1660) on an image
I am using opencv 4.0.1 c++
I have the camera matrix and distortion coefficient
and my code is
vector <Point3f> inputpoints;
Point3f myPoint;
myPoint.x = -1450;
myPoint.y = -1660;
myPoint.z = 0;
inputpoints.push_back(myPoint);
vector<Point2f> outputpoints;
vector<Point3f> tvec;
tvec.push_back(Point3f(0, 0, 0));
vector<Point3f> rvec;
rvec.push_back(Point3f(0, 0, 0));
double mydata[9] = { 3.3202343554882879e+02, 1., 6.4337059696010670e+02, 0, 3.3196938477610536e+02, 5.3844814394773562e+02, 0., 0., 1. };
Mat mycameraMatrix = Mat(3, 3, CV_64F, mydata);
double mydata2[4] = { -1.1129472191078109e-03, 4.9443845791693870e-02,
-7.2244333582166609e-03, -1.7309984187889034e-03 };
Mat mydiscoff = Mat{ 4,1, CV_64F ,mydata2 };
Mat newCamMat1= Mat(3, 3, CV_64F);
cv::fisheye::projectPoints(inputpoints, rvec, tvec, mycameraMatrix, mydiscoff, outputpoints);
when I run the program I get this exception
OpenCV(4.0.1) Error: Assertion failed (mtype == type0 || (CV_MAT_CN(mtype) == CV_MAT_CN(type0) && ((1 << type0) & fixedDepthMask) != 0)) in cv::debug_build_guard::_OutputArray::create, file c:\build\master_winpack-build-win64-vc15\opencv\modules\core\src\matrix_wrap.cpp, line 1395
I changed the type of camera matrix and distortion coefficient to CV_32f but I still got the same error , I am a very beginner in openCV ..so can any one tell me what caused this exception?
I know the rvec should be 3*3 but I just followed someone else code who wrote that can be written in this way
okay the problem was that projectpoints and fisheye::projectpoints differ in the order of parameters ..so I was putting the order which belongs to projectpoints

cvCalibrateCamera2 - how to properly define rotation matrix?

I try to use cvCalibrateCamera2, but I get error that rotation matrix is not properly defined:
...calibration.cpp:1495: error: (-5) the output array of rotation vectors must be 3-channel 1xn or nx1 array or 1-channel nx3 or nx9 array, where n is the number of views
I have already tried all possibilities from that info but I still get this error.
My code:
CvMat *object_points = cvCreateMat((int)pp.object_points.size(), 1, CV_32FC3);
CvMat *image_points = cvCreateMat((int)pp.image_points.size(), 1, CV_32FC2);
const CvMat point_counts = cvMat((int)pp.point_counts.size(), 1, CV_32SC1, &pp.point_counts[0]);
for (size_t i=0; i<pp.object_points.size(); i++)
{
object_points->data.fl[i*3+0] = (float)pp.object_points[i].x;
object_points->data.fl[i*3+1] = (float)pp.object_points[i].y;
object_points->data.fl[i*3+2] = (float)pp.object_points[i].z;
image_points->data.fl[i*2+0] = (float)pp.image_points[i].x;
image_points->data.fl[i*2+1] = (float)pp.image_points[i].y;
}
CvMat* tempR = cvCreateMat(1, 3, CV_32F);
cvCalibrateCamera2(object_points, image_points, &point_counts,
cvSize(pp.width, pp.height), camera->m_calib_K,
camera->m_calib_D, tempR, &tempData->m_calib_T,
CV_CALIB_USE_INTRINSIC_GUESS)
// camera->calib_T is defined as:
// double m_calib_T_data[3];
// cvMat(3, 1, CV_64F, camera->m_calib_T_data);
I thought that rotation matrix used in cvCalibrateCamera2 should be 1x3 (then I want to use Rodrigues function to get 3x3 matrix) but it doesn't work as any other combination mentioned in error.
Any ideas?
And I use opencv 2.4.0 (maybe there is bug in that method, but for some reasons I can't use later version of opencv)
I think the statement is clear. I am not confident with C# but I know it requires a strong initialization.
The problem in line
CvMat* tempR = cvCreateMat(1, 3, CV_32F);
is that tempR should have a line 1x3 for every N objects point you use. In this sense, the statement becomes clear
...calibration.cpp:1495: error: (-5) the output array of rotation
vectors must be 3-channel 1xn or nx1 array or 1-channel nx3 or nx9
array, where n is the number of views
You must create a tempR like that (more or less, I do not know how to calculate N in C#)
CvMat* tempR = cvCreateMat(N, 3, CV_32F);
Try to extract N from dimensions of object.point.size. If it does not work, try image.point.size

Get values from OpenCV Histogram

I have what should be a simple exercise in OpenCV, but can't seem to get it working. I'm trying to determine the density of edges in a section of an image. This is the process I follow:
1. pull subimage from image
2. use Canny to find edges in subImage
3. threshold to create binary image
4. create histogram for binary image
5. get number of pixels in binary image that are "on" (255)
6. calculate "edge density" as numPixelsOn/totalPixels
I've checked the results of 1,2,and 3 above, and results seem ok. Steps 4 and 5 seem to be giving me trouble.
Here's my code for calculating the histogram:
int histSize = 256; // bin size
float range[] = { 0, 256} ;
const float* histRange = { range };
bool uniform = true;
bool accumulate = false;
Mat hist;
/// Compute the histograms:
calcHist( &gray, 1, 0, Mat(), hist, 1, &histSize, &histRange, uniform, accumulate );
This doesn't seem to be working. When I check hist after calling calcHist, it has no data (i.e. data == 0)... or maybe I don't understand what I'm looking at.
Now for accessing the "bins" in the histogram, I've tried a number of things. First I tried this:
uchar* p;
p = hist.ptr<uchar>(0);
double edgePixels = p[255];
I also tried to use:
cvQueryHistValue_1D(hist,255); // #include <opencv2/legacy/compat.hpp>
This wouldn't compile. Gave 2 errors: 'cv::Mat' does not have an overloaded member 'operator ->', and 'bins': is not a member of 'cv::Mat'
I guess I need some help on this.
There is an error in your 3rd param - channels, that should be an array so you should call it like this
int histSize = 256; // bin size
float range[] = { 0, 256} ;
const float* histRange = { range };
bool uniform = true;
bool accumulate = false;
Mat hist;
int channels[] = {0};
/// Compute the histograms:
calcHist( &gray, 1, channels, Mat(), hist, 1, &histSize, &histRange, uniform, accumulate );
You should also call:
hist.at<float>(0);
to get your value, OpenCV stores them as floats, this is the reason you're getting 0 when using uchar as uchar is smaller than float and the numbers stores as small enough to not fill the first bites.

Using cvReshape after convertion from IplImage to CvMat by cvGetImage

I need to get 1D vectors from input grayscale images in order to calculate covariance matrix. So I'm trying to convert IplImage to CvMat and then reshape it.
At the first time I used the following code:
CvMat *image_matrix = cvCreateMat(image->width, image->height, CV_32FC1);
cvConvert(image, image_matrix);
CvMat iv_p, *image_vector = cvCreateMat(image->widht * image->height, 1, CV_32FC1);
image_vector = cvReshape(image_matrix, &iv_p, 1, image->widht * image->height);
But it gave me
Assertion failed (src.size == dst.size && src.channels<> ==
dst.channels<> in cvConvertScale)
So I find here another way:
CvMat i_p, *image_matrix;
image_matrix = cvGetMat(image, &i_p, 0, 0);
CvMat iv_p, *image_vector = cvCreateMat(image->widht * image->height, 1, CV_32FC1);
image_vector = cvReshape(image_matrix, &iv_p, 1, image->widht * image->height);
But this time I get
Image step is wrong (The matrix is not continuous, thus the number of rows can not be changed> in cvReshape.
Could anybody please suggest any solution to my problem?

Learning of SVM Code

Well its a forum for posting the question in which you feel difficulty , well the same thing happen to me so i post the question here , i need to learn the code , understand it , what its doing and what we can do more with it
// Data for visual representation
int width = 512, height = 512;
Mat image = Mat::zeros(height, width, CV_8UC3);
// Set up training data
float labels[4] = {1.0, -1.0, -1.0, -1.0};
Mat labelsMat(3, 1, CV_32FC1, labels);
float trainingData[4][2] = { {501, 10}, {255, 10}, {501, 255}, {10, 501} };
Mat trainingDataMat(3, 2, CV_32FC1, trainingData);
// Set up SVM’s parameters
CvSVMParams params;
params.svm_type = CvSVM::C_SVC;
params.kernel_type = CvSVM::LINEAR;
params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6);
// Train the SVM
CvSVM SVM;
SVM.train(trainingDataMat, labelsMat, Mat(), Mat(), params);
Vec3b green(0,255,0), blue (255,0,0);
// Show the decision regions given by the SVM
for (int i = 0; i <2; ++i)
for (int j = 0; j <2; ++j)
{
Mat sampleMat = (Mat_<float>(1,2) << i,j);
float response = SVM.predict(sampleMat);
if (response == 1)
image.at<Vec3b>(j, i) = green;
else if (response == -1)
image.at<Vec3b>(j, i) = blue;
}
I know this code is for training data , but i want to know about its basic things , its basic understanding , which i think i didn't found on opencv documentation like why and when we use CV_8UC3 , and with which things this code is training
Thanks
image is an empty 3 channel matrix data, i.e. 512x512; R-G-B channels. At the end, this code draws the responses (predictions of SVM) onto that image - image at somewhere = green = (0,255,0). it is done in a for loop to create the lines from pointwise assigning.
the SVM model training is an internal process of this method, in which opencv uses a learning algorithm that can be found only looking at the source code. however, it is declared and described in the documentation that the parameters like svm_type, kernel_type, k_fold, grid, balanced, ... changes the behaviour of the method.

Resources