KNN find nearest error - opencv

I'm doing KNN classification of static gestures and i get this error.
ERROR: Unhandled exception at 0x01213aa2 in NUIGHR.exe: 0xC0000005:
Access violation reading location 0x00000000.
CvMat* GetFeatures(CvSeq* contour, CvSeq* hull, double boundingRectArea){
CvMoments moments;
CvHuMoments humoments;
cvMoments(contour, &moments, cvGetHuMoments(&moments, &humoments);
int cCont;
double cArea, cPerimeter, cDiameter, cExtent, cCompactness, cEccentricity, cCircularity;
cCont = contour->total;
cArea = fabs(cvContourArea(contour));
cPerimeter = cvContourPerimeter(contour);
cDiameter = sqrt( 4 * cArea / CV_PI);
cExtent = cArea / (boundingRectArea * boundingRectArea);
cCompactness = (4 * cArea * CV_PI) / cPerimeter;
cEccentricity = pow( (moments.m20 - moments.m02), 2) - (4 * pow(moments.m11, 2)) / ( pow(moments.m20 + moments.m02, 2) );
cCircularity = pow(cPerimeter, 2) / cArea;
cvmSet( featureVector, 0, 0, boundingRectArea);
cvmSet( featureVector, 0, 1, cCont);
cvmSet( featureVector, 0, 2, cArea);
cvmSet( featureVector, 0, 3, cPerimeter);
cvmSet( featureVector, 0, 4, cDiameter);
cvmSet( featureVector, 0, 5, cExtent);
cvmSet( featureVector, 0, 6, cCompactness);
cvmSet( featureVector, 0, 7, cEccentricity);
cvmSet( featureVector, 0, 8, cCircularity);
cvmSet( featureVector, 0, 9, humoments.hu1);
cvmSet( featureVector, 0, 10, humoments.hu2);
cvmSet( featureVector, 0, 11, humoments.hu3);
cvmSet( featureVector, 0, 12, humoments.hu4);
cvmSet( featureVector, 0, 13, humoments.hu5);
cvmSet( featureVector, 0, 14, humoments.hu6);
cvmSet( featureVector, 0, 15, humoments.hu7);
return featureVector;
}
int main(){
...
const int K = 10;
CvKNearest *knn = NULL;
float resultNode = 0;
CvMat* featVector = cvCreateMat(1, NUMBER_OF_FEATURES, CV_32FC1 );
CvMat* nearest = cvCreateMat(1, K, CV_32FC1);
...
resultNode = knn->find_nearest(&featVector, K, 0, 0, nearest, 0);
}
I think i need to convert CvMat* to CvMat.
How do i do it?

You cannot pass 0 as 3rd and 4th argument to find_nearest function, not if you do pass something as 5th argument. OpenCV tries to populate the results and neighbourResponses (see doc), but cannot read/write the NULL pointer.

featureVector = NULL pointer
sorry guys... i'm a beginner :(

Related

Intel IPP Erode Access Violation Exception

I made a simple script using the ErodeBorder function in IPP, and I want to use ippiErode_1u_C1R_L. I am having trouble using ippiErode_1u_C1R_L I keep getting an AccessViolation Exception. First script shows a functioning code, second script shows an attempt to use ippiErode_1u_C1R_L.
Working Code:
int width = 1600;
int height = 594;
int binSize = 118800;
int binStep = ceil(width / 8);
IppiSize roi = { width, height };
Ipp8u* workBin = (Ipp8u*)ippsMalloc_8u(binSize);
Ipp8u* defectMask = (Ipp8u*)ippsMalloc_8u(binSize);
Ipp8u* origBin = GetMask(); //Same size as workBin
Ipp8u mask[9] = { 1, 1, 1,
1, 0, 1,
1, 1, 1 };
IppiSize maskSize = { 3, 3 };
int pSpecSize = 0, pBufferSize = 0;
ippiMorphologyBorderGetSize_1u_C1R(roi, maskSize, &pSpecSize, &pBufferSize);
Ipp8u* pBuffer = (Ipp8u*)ippsMalloc_8u(pBufferSize);
IppiMorphState* pSpec = (IppiMorphState*)ippsMalloc_8u(pSpecSize);
ippiMorphologyBorderInit_1u_C1R(roi, mask, maskSize, pSpec, pBuffer);
ippiErodeBorder_1u_C1R(origBin, binStep, 0, workBin, binStep, 0, roi, ippBorderRepl, 0, pSpec, pBuffer);
ippiErodeBorder_1u_C1R(workBin, binStep, 0, defectMask, binStep, 0, roi, ippBorderRepl, 0, pSpec, pBuffer);
ippiErodeBorder_1u_C1R(defectMask, binStep, 0, workBin, binStep, 0, roi, ippBorderRepl, 0, pSpec, pBuffer);
ippiErodeBorder_1u_C1R(workBin, binStep, 0, defectMask, binStep, 0, roi, ippBorderRepl, 0, pSpec, pBuffer);
Throws Exception when calling ippiErode_1u_C1R_L():
int width = 1600;
int height = 594;
int binSize = 118800;
int binStep = ceil(width / 8);
IppiSizeL roi_L = { width, height };
Ipp8u* workBin = (Ipp8u*)ippsMalloc_8u(binSize);
Ipp8u* defectMask = (Ipp8u*)ippsMalloc_8u(binSize);
Ipp8u* origBin = GetMask(); //Same size as workBin
Ipp8u mask[9] = { 1, 1, 1,
1, 0, 1,
1, 1, 1 };
IppiSizeL maskSize = { 3, 3 };
IppSizeL pSpecSize = 0, pBufferSize = 0;
ippiErodeGetBufferSize_L(roi_L, maskSize, ipp1u, 1, &pBufferSize);
ippiErodeGetSpecSize_L(roi_L, maskSize, &pSpecSize);
Ipp8u* pBuffer = (Ipp8u*)ippsMalloc_8u_L(pBufferSize);
IppiMorphStateL* pSpec = (IppiMorphStateL*)ippsMalloc_8u_L(pSpecSize);
IppStatus initSizeStat = ippiErodeInit_L(roi_L, mask, maskSize, pSpec);
ippiErode_1u_C1R_L(origBin, binStep, 0, workBin, binStep, 0, roi_L, ippBorderRepl, 0, pSpec, pBuffer);

How to understand the math behind the CTM(current transformation matrix)?

When I written some test code about modifying CTM, I found it can't be explain with The Math Behind the Matrices in Quartz 2D Programming Guide. The test code is as follow:
// {a, b, c, d, tx, ty}
NSLog(#"UIKit CTM:%#\n", NSStringFromCGAffineTransform(CGContextGetCTM(ctx)));
CGContextSaveGState(ctx);
CGContextTranslateCTM(ctx, 0, CGRectGetHeight(rect));// 1
NSLog(#"Quartz part 1 CTM:%#\n", NSStringFromCGAffineTransform(CGContextGetCTM(ctx)));
CGContextScaleCTM(ctx, 1, -1);// 2
NSLog(#"Quartz CTM:%#\n", NSStringFromCGAffineTransform(CGContextGetCTM(ctx)));
CGContextTranslateCTM(ctx, 0, CGRectGetHeight(rect)); // 3
NSLog(#"UIKit part 1 CTM:%#\n", NSStringFromCGAffineTransform(CGContextGetCTM(ctx)));
CGContextScaleCTM(ctx, 1, -1);// 4
NSLog(#"UIKit part 2 CTM:%#\n", NSStringFromCGAffineTransform(CGContextGetCTM(ctx)));
CGContextRestoreGState(ctx);
The output:
2017-09-29 09:51:27.166 QuartzDemo[53287:31120880] UIKit CTM:[2, 0, 0, -2, 0, 1136]
2017-09-29 09:51:27.167 QuartzDemo[53287:31120880] Quartz part 1 CTM:[2, 0, 0, -2, 0, 0]
2017-09-29 09:51:27.167 QuartzDemo[53287:31120880] Quartz CTM:[2, 0, -0, 2, 0, 0]
2017-09-29 09:51:27.167 QuartzDemo[53287:31120880] UIKit part 1 CTM:[2, 0, -0, 2, 0, 1136]
2017-09-29 09:51:27.167 QuartzDemo[53287:31120880] UIKit part 2 CTM:[2, 0, 0, -2, 0, 1136]
First, let's focus on UIKit CTM transforms to Quartz CTM, we use array express matrix, on line 1:
[2, 0, 0, 0, -2, 0, 0, 1136, 1] x [1, 0, 0, 0, 1, 0, tx1, ty1, 1] = [2, 0, 0, 0, -2, 0, 0, 0, 1]
then
[1, 0, 0, 0, 1, 0, tx1, ty1, 1] = [1, 0, 0, 0, 1, 0, -1136, 1]
so in this case CGContextTranslateCTM(ctx, 0, CGRectGetHeight(rect)); equal to [1, 0, 0, 0, 1, 0, -1136, 1], Question 1: Where is minus sign come from?
On line 2:
[2, 0, 0, 0, -2, 0, 0, 0, 1] x [sx1, 0, 0, 0, sy1, 0, 0, 0, 1] = [2, 0, 0, -0, 2, 0, 0, 0, 1]
then
[sx1, 0, 0, 0, sy1, 0, 0, 0, 1] = [1, 0, 0, 0, -1, 0, 0, 0, 1]
so CGContextScaleCTM(ctx, 1, -1); equal to [1, 0, 0, 0, -1, 0, 0, 0, 1], this result is the same as theory value.
On line 3:
[2, 0, 0, -0, 2, 0, 0, 0, 1] x [1, 0, 0, 0, 1, 0, tx2, ty2, 1] = [2, 0, 0, -0, 2, 0, 0, 1136, 1]
then
[1, 0, 0, 0, 1, 0, tx2, ty2, 1] = [2, 0, 0, 0, 2, 0, 0, 1136, 1]
this result also the same as theory value.
On line 4:
[2, 0, 0, 0, 2, 0, 0, 1136, 1] x [sx2, 0, 0, 0, sy2, 0, 0, 0, 1] = [2*sx2, 0, 0, 0, 2*sy2, 0, 0, 1136*sy2, 1]
then
[2*sx2, 0, 0, 0, 2*sy2, 0, 0, 1136*sy2, 1] = [2, 0, 0, 0, -2, 0, 0, 1136, 1]
2*sx2 = 2 => sx2 = 1; but
2*sy2 = -2 (1)
1136*sy2 = 1136 (2)
In equation (1) sy2 = -1, but in equation (2) sy2 = 1, So Question 2: Why this happened? How to explain this case?

Kalman filter 3D implementation

I want to implement the kalman filter for a moving object in r3 (X,Y,Z-coordinate) in OpenCV.
I tried to understand the OpenCV documentation but this is really not helpful and very rare.
The syntax for the initialization is:
KalmanFilter::KalmanFilter ( int dynamParams, int measureParams, int
controlParams = 0, int type = CV_32F )
In my case, is dynamParams = 9 and measureParams=3?
And what is the transitionMatrix in my case?
In that case the Transition Matrix A looks like:
A = [1, 0, 0, v, 0, 0, a, 0, 0;
0, 1, 0, 0, v, 0, 0, a, 0;
0, 0, 1, 0, 0, v, 0, 0, a;
0, 0, 0, 1, 0, 0, v, 0, 0;
0, 0, 0, 0, 1, 0, 0, v, 0;
0, 0, 0, 0, 0, 1, 0, 0, v;
0, 0, 0, 0, 0, 0, 1, 0, 0;
0, 0, 0, 0, 0, 0, 0, 1, 0;
0, 0, 0, 0, 0, 0, 0, 0, 1]
With
v = dt
a = 0.5*dt^2
See http://campar.in.tum.de/Chair/KalmanFilter
I found out, that for the 3D-Case often the position, velocity and acceleration is used. That means, that for the OpenCV implementation dynamParams=9 and measureParams=3 is right.

OpenCV arithmetic operations on matrices

Can someone explain the following, totally unintuitive, results:
Mat_<Vec3f> mat(Size(3,3),0);
Mat_<Vec3f> mat_add = (mat + 9);
Mat_<Vec3f> mat_add_div = (mat + 9) / 3;
magically, I don't have any other explanation for it:
mat_add = [9,0,0,9,0,0,9,0,0];
mat_add_div = [3,3,3,3,3,3,3,3,3];
EDIT:
My take: this is a legacy bug that can't be fixed anymore because it is retroactive and will impact lot of projects. Also it would be pretty nasty to debug (except project has already pretty thorough unit testing)
Mat_<Vec3f> mat_add = (mat + 9);
is equivalent to
Mat_<Vec3f> temp(Size(3,3),Vec3f(9,0,0));
Mat_<Vec3f> mat_add = mat+temp;
So, you will get
mat_add =
[9, 0, 0, 9, 0, 0, 9, 0, 0;
9, 0, 0, 9, 0, 0, 9, 0, 0;
9, 0, 0, 9, 0, 0, 9, 0, 0]
However, I have no clue for why you will get values like that for mat_add_div. In fact, if you replace it by:
Mat_<Vec3f> mat_add_div = mat_add / 3;
You will end up with
mat_add_div =
[3, 0, 0, 3, 0, 0, 3, 0, 0;
3, 0, 0, 3, 0, 0, 3, 0, 0;
3, 0, 0, 3, 0, 0, 3, 0, 0]
This result is however reasonable based on the same theory as said in above.

OpenCV Help on cvPerspectiveTransform

I have a problem with the follow code, i´m trying to change a perspective of an image using cvPerspectiveTransform, but I get the follow error:
OpenCV Error: Assertion failed (scn + 1 == m.cols && (depth == CV_32F || depth == CV_64F))
CvMat* p = cvCreateMat(2, 4, CV_64FC1);
CvMat* h = cvCreateMat(2, 4, CV_64FC1);
CvMat* p2h = cvCreateMat(2, 4, CV_64FC1);
cvZero(p);
cvZero(h);
cvZero(p2h);
//set src points
for (int i = 0; i < 4; i++) {
CvPoint point = verifiedPoints[i];
cvmSet( p, 0, i, point.x );
cvmSet( p, 1, i, point.y );
printf("point %d (%d , %d)\n",i,point.x,point.y);
}
//set dst points
cvmSet( h, 0, 0, 0 );
cvmSet( h, 1, 0, real_height );
cvmSet( h, 0, 1, real_width );
cvmSet( h, 1, 1, real_height );
cvmSet( h, 0, 2, real_width );
cvmSet( h, 1, 2, 0 );
cvmSet( h, 0, 3, 0 );
cvmSet( h, 1, 3, 0);
//cvPerspectiveTransform or cvFindHomography?
cvPerspectiveTransform(p,h,p2h);
cvReleaseMat(&p);
cvReleaseMat(&h);
I try to change p2h to other values, for example:
CvMat* p2h = cvCreateMat(3, 3, CV_32F)
but I get other error:
OpenCV Error: Assertion failed (dst.type() == src.type() && dst.channels() == m.rows-1) in cvPerspectiveTransform
Any help?
According to the OpenCV documentation for cvPerspectiveTransform:
src – Source two-channel or three-channel floating-point array. Each
element is a 2D/3D vector to be transformed.
dst – Destination array
of the same size and type as src.
mtx – 3x3 or 4x4 floating-point
transformation matrix.
So you need to declare your matrices this way:
CvMat* p = cvCreateMat(1, 4, CV_64FC2);
CvMat* h = cvCreateMat(1, 4, CV_64FC2);
CvMat* p2h = cvCreateMat(3, 3, CV_64FC1);

Resources