How to use calcCovarMatrix on IplImage? - visual-c++

There's a single-channel grayscale IplImage whose covariance matrix is to be calculated. There does happen to be a similar question on SO but no one has answered it and the code is significantly different.
Here's the code that's throwing an "unhandled exception":
int calcCovar( IplImage *src, float* dst, int w )
{
// Input matrix size
int rows = w;
int cols = w;
int i,j;
CvScalar se;
float *a;
a = (float*)malloc( w * w * sizeof(float) );
long int k=0;
//image pixels into 1D array
for(i = 0; i < w; ++i)
{
for(j = 0; j < w; ++j)
{
se = cvGet2D(src, i, j);
a[k++] = (float)se.val[0];
}
}
CvMat input = cvMat(w,w,CV_32FC1, a); //Is this the right way to format input pixels??
// Covariance matrix is N x N,
// where N is input matrix column size
const int n = w;
// Output variables passed by reference
CvMat* output = cvCreateMat(n, n, CV_32FC1);
CvMat* meanvec = cvCreateMat(1, rows, CV_32FC1);
// Calculate covariance matrix - error is here!!
cvCalcCovarMatrix((const void **) &input, rows, output, meanvec, CV_COVAR_NORMAL);
k = 0;
//Show result
cout << "Covariance matrix:" << endl;
for(i=0; i<n; i++) {
for(j=0; j<n; j++) {
cout << "(" << i << "," << j << "): ";
printf ("%f ", cvGetReal2D(output,i,j) / (rows - 1));
dst[k++] = cvGetReal2D(output,i,j) / (rows - 1);
//cout << "\t";
}
cout << endl;
}
return(0);
}

read in the manual about this function. if you store your values in the single matrix 'input', the second function parameter must not be 'rows'. The second parameter is used to say how many matrices you passes in the first parameter. You have passed just one matrix, 'input'. Segfault is no surprise.

Related

How to correctly calculate ACF in C++?

I would like to manually reproduce the method that authors of an article used in their research (DOI: 10.1038/s41598-017-02750-9 (Page 8. top)). It is mentioned as "ACF", so I wrote different functions:
1, a version based on a youtube video (https://youtu.be/ZjaBn93YPWo?t=417) using Alglibs Pearson correlation coefficient function
2, then another version based on the formula that is described in the article mentioned above
3, then another version based on the simplified formula described at an online ACF calculator page (https://planetcalc.com/7908/)
4, then a version based on the longer formula described there (https://planetcalc.com/7908/)
=> Yet, all of these give different output. However, method 3. is consistent with the output coming from the online calculator ran in my browser: https://planetcalc.com/7884/?d=.bTkjs.ymyQ8blXMoYiMgIOOmzhhI4fnckel.J5yEDWtV89Gz32Ch0kse2s
My code is here:
#include <iostream>
#define _WIN32_WINNT 0x0500
#include<windows.h>
//#include <cmath>
#include "alglib/alglibinternal.h"
#include "alglib/alglibmisc.h"
#include "alglib/ap.h"
#include "alglib/dataanalysis.h"
#include "alglib/diffequations.h"
#include "alglib/fasttransforms.h"
#include "alglib/integration.h"
#include "alglib/interpolation.h"
#include "alglib/linalg.h"
#include "alglib/optimization.h"
#include "alglib/solvers.h"
#include "alglib/specialfunctions.h"
#include "alglib/statistics.h"
#include "alglib/stdafx.h"
using namespace std;
double* normalize(double* _arr, int _s) {
double* output = new double[_s];
double mod = 0.0;
for (size_t i = 0; i < _s; ++i)
mod += _arr[i] * _arr[i];
double mag = sqrt(mod); //TODO: if 0, throw exc
double mag_inv = 1.0 / mag;
for (size_t i = 0; i < _s; ++i)
output[i] = _arr[i] * mag_inv;
return output;
}
void doACFyoutube(double* _ina, int _s)
// https://youtu.be/ZjaBn93YPWo?t=417 => the most unefficient, but understandable method
{
double* temp_x;
double* temp_y;
double* ACFoutput = new double[_s];
for(int shift = 0; shift < _s; shift++)
{
temp_x = new double[_s-shift];
temp_y = new double[_s-shift];
for(int cpy = 0; cpy < _s-shift; cpy++)
{
temp_x[cpy] = _ina[cpy];
temp_y[cpy] = _ina[cpy+shift];
}
temp_y = normalize(temp_y, _s-shift); //not sure if needed //TODO: leak
alglib::real_1d_array temp_x_alglib;
alglib::real_1d_array temp_y_alglib;
temp_x_alglib.setcontent(_s-shift, temp_x);
temp_y_alglib.setcontent(_s-shift, temp_y);
ACFoutput[shift] = alglib::pearsoncorr2(temp_x_alglib, temp_y_alglib); //Pearson product-moment correlation coefficient
delete temp_x;
delete temp_y;
}
for(int i=0; i<_s; i++)
cout << " lag = " << i << "\tACF(lag) = " << ACFoutput[i] << endl;
}
void doACFgoal(double* _ina, int _s)
// DOI: 10.1038/s41598-017-02750-9 => page 8, first equation (my goal is to reproduce this)
{
double mean = 0; //mean
for(int a = 0; a < _s; a++ )
mean += _ina[a];
mean /= _s;
double var = 0; //variance
for(int b = 0; b < _s; b++ )
var += (_ina[b]-mean)*(_ina[b]-mean);
var /= _s-1; //needed? (-1) a.k.a. Bessell's correction ?
double* ACFoutput = new double[_s];
for(int i = 0; i < _s; i++)
{
double temp_sum = 0;
for(int j = 1; j <= _s-i; j++)
temp_sum += (_ina[j]-mean)*(_ina[j+i]-mean);
ACFoutput[i] = (double)1/(((double)_s-(double)i)*var*var) * temp_sum;
}
for(int i=0; i<_s; i++)
cout << " lag = " << i << "\tACF(lag) = " << ACFoutput[i] << endl;
}
void doACFplanetcalcCoarse(double* _ina, int _s)
// https://planetcalc.com/7908/
{
double mean = 0; //mean
for(int a = 0; a < _s; a++ )
mean += _ina[a];
mean /= _s;
double* ACFoutput = new double[_s];
for(int i = 0; i < _s; i++)
{
double temp_sum1 = 0;
double temp_sum2 = 0;
for(int j = 0; j < _s-i; j++)
temp_sum1 += (_ina[j]-mean)*(_ina[j+i]-mean);
for(int k = 0; k < _s; k++)
temp_sum2 += (_ina[k]-mean)*(_ina[k]-mean);
ACFoutput[i] = temp_sum1 / temp_sum2;
}
for(int i=0; i<_s; i++)
cout << " lag = " << i << "\tACF(lag) = " << ACFoutput[i] << endl;
}
void doACFplanetcalcFine(double* _ina, int _s)
// https://planetcalc.com/7908/ => gives different output than the online calculator script, even though uses the longer formula described there
{
double* ACFoutput = new double[_s];
for(int k = 0; k < _s; k++)
{
double mean1 = 0; //mean of first N-k values
for(int a = 0; a < _s-k; a++ )
mean1 += _ina[a];
mean1 /= _s-k;
// cout << "\t mean of first N-" << k << " values = " << mean1 << endl;
double mean2 = 0; //mean of last N-k values
for(int a = k; a < _s; a++ )
mean2 += _ina[a];
mean2 /= _s-k;
// cout << "\t mean of last N-" << k << " values = " << mean2 << endl;
double temp_sum1 = 0;
double temp_sum2 = 0;
double temp_sum3 = 0;
for(int i = 0; i < _s-k; i++)
{
temp_sum1 += (_ina[i]-mean1)*(_ina[i+k]-mean2);
// cout << "\t\t temp_sum1 (" << i << ") = " << temp_sum1 << endl;
}
// cout << "\t temp_sum1 = " << temp_sum1 << endl;
for(int i = 0; i < _s-k; i++)
{
temp_sum2 += (_ina[i]-mean2)*(_ina[i]-mean2); //pow2
// cout << "\t\t temp_sum2 (" << i << ") = " << temp_sum2 << endl;
}
// cout << "\t temp_sum2 = " << temp_sum2 << endl;
for(int i = 0; i < _s-k; i++)
{
temp_sum3 += (_ina[i+k]-mean2)*(_ina[i+k]-mean2); //pow2
// cout << "\t\t temp_sum3 (" << i << ") = " << temp_sum3 << endl;
}
// cout << "\t temp_sum3 = " << temp_sum3 << endl;
ACFoutput[k] = temp_sum1 / (sqrt(temp_sum2)*sqrt(temp_sum3));
}
for(int i=0; i<_s; i++)
cout << " lag = " << i << "\tACF(lag) = " << ACFoutput[i] << endl;
}
int main()
{
//fullscreenhez
HWND hWnd = GetConsoleWindow();
ShowWindow(hWnd,SW_SHOWMAXIMIZED);
double ina[15] = {2,3,4,5,4,3,4,5,6,7,6,5,4,3,4}; //15 elem
for(int x=0; x<15; x++)
cout << ina[x] << ",";
cout << endl;
cout << endl;
// https://youtu.be/ZjaBn93YPWo?t=417 => the most unefficient, but understandable method
doACFyoutube(ina, 15); // ??? result doesn't match any other
cout << endl;
// DOI: 10.1038/s41598-017-02750-9 => page 8, first equation (my goal is to reproduce this)
doACFgoal(ina, 15); // ??? result doesn't match any other
cout << endl;
// https://planetcalc.com/7908/ (simplified formula)
doACFplanetcalcCoarse(ina, 15); //result equals to the online calculator result: https://planetcalc.com/7884/?_d=.bTkjs.ymyQ8blXMoYiMgIOOmzhhI4fnckel.J5yEDWtV89Gz32Ch0kse2s_
cout << endl;
// https://planetcalc.com/7908/ (longer formula)
doACFplanetcalcFine(ina, 15); // ??? result doesn't match any other
return 0;
}
The output looks like this:
As I do not have the original data they used in the publication, I can only rely on how consistent the output of my program is related to other codes output. But these outputs are different, and I do not know why. Could you please have a look at the code and help me end up in four equal outputs?
(Codeblocks project zipped here:
https://drive.google.com/file/d/1s3SeJSiDgk-hiMazp94HfFerL582VG2K/view?usp=sharing)

Having trouble with pointers in C++

I am trying to access an array from inside of a function, but I get the
"Error C2065 'i': undeclared identifier." I know that I am making a mistake with the pointer. I was able to pull information from the array in the function below the one I'm having issues with, so I'm not sure why I am unable to do the same thing here. Thank you for your time.
#include <iostream>
#include <cmath>
using namespace std;
double mean(int size, int* numbers);
double sDeviation(int numOfScores, int average, int* scores);
int histogram(int numOfScores, int* scores); //<<<This is what I'm having trouble with
int main()
{
int count = 0;
int scores[100];
while (true)
{
int scoreToBeEntered;
cout << "Please enter a score: ";
cin >> scoreToBeEntered;
if(scoreToBeEntered == NULL)
cout << "No value entered" << endl;
else if(scoreToBeEntered != -1)
scores[count++] = scoreToBeEntered;
else
break;
}
for(int i = 9; i >= 0; i--)
cout << i << "|" << endl;
cout << "SD: " << sDeviation(count, mean(count, scores), scores) << endl;
system("pause");
return 0;
}
int histogram(int numOfScores, int* scores)//this is where the issue starts
{
int* bins = new int[10];
for(int i = 0; i < numOfScores; i++);
if(scores[i] >= 90) //<<<<This is the undeclared "i"
{
bins[9]++;
}
}
double sDeviation(int numOfScores, int average, int* scores)
{
double deviation = 0;
for (int i = 0; i < numOfScores; i++)
deviation += pow(scores[i] - average, 2);
return sqrt(deviation / numOfScores);
}
double mean(int size, int* numbers)
{
double sum = 0;
for (int i = 0; i < size; i++)
sum += numbers[i];
return sum / size;
}

Attempting to print a tree in C++ (Not using x's)

I am trying to print a tree using C++. I can print the tree using only the "/"'s, but I need to use both "/" and "\"'s on each side of the tree, with empty space in between, if that makes sense. I need to make the "cone part of the tree" with only 3 "for" loops.
I'm good with the base and the trunk, but I need help with the cone.
I know that I need to account for the empty spaces on each side of the cone and inside each side of the cones but everything I try messes it all up, and being as new as I am I'm having a hard time keeping it at 3 "for" loops. Also, my teacher looks down at using the internet as a learning resource, so anything outside of "for" loops for this program with throw red flags. Any help is appreciated.
#include <iostream>
using namespace std;
int main()
{
cout << "Please enter a height for the cone of the tree. [3 - 15]: ";
int height;
cin >> height;
if(height < 3 || height > 15)
{
cout << "ERROR: Value entered is out of bounds." << endl;
system("pause");
exit(0);
}
int level = 0;
int space = 0;
int slashes = 0;
int base = 0;
int wood = 0;
int trunk = 0;
for (int level = 0; level < height; level++) //First "Cone" For Loop
{
for (int space = height - level - 1; space > 0; space--) //Second "cone" for loop
cout << ' ';
for (int slashes = 0; slashes < 2 * level + 1; slashes++) //Third "cone" for loop
cout << '/';
cout << endl;
}
for (int base = 0; base < 2 * height; base++)
cout << '-';
cout << endl;
for (int trunk = 0; trunk < (height / 2); trunk++)
{
for( int wood = 0; wood < height - 1; wood++)
cout << ' ';
cout << '|' << '|';
cout << endl;
}
system ("pause");
return 0;
}
Actual:
/
///
/////
///////
/////////
///////////
------------
||
||
||
Expected:
/\
/ \
/ \
/ \
/ \
/ \
------------
||
||
||
For anyone else Googling this, here is how I did it. It's ugly and probably wrong, but it works.
#include <iostream>
using namespace std;
int main()
{
cout << "Please enter a height for the cone of the tree. [3 - 15]: ";
int height;
cin >> height;
if(height < 3 || height > 15)
{
cout << "ERROR: Value entered is out of bounds." << endl;
system("pause");
exit(0);
}
int level = 0;
int space = 0;
int base = 0;
int trunk = 0;
for (int level = 0; level < height; level++)
{
for (int space = height - level - 1; space > 0; space--)
cout << ' ';
cout << '/';
for (int space = 0; space < (2 * level); space++)
cout << ' ';
cout << '\\';
cout << endl;
}
for (int base = 0; base < 2 * height; base++)
cout << '-';
cout << endl;
for (int trunk = 0; trunk < (height / 2); trunk++)
{
for( int trunk = 0; trunk < height - 1; trunk++)
cout << ' ';
cout << '|' << '|';
cout << endl;
}
//system ("pause");
return 0;
}

need to input numbers and output as stars c++

this is my first question, i have to write a simple program that asks the user to input an integer, where according to the input, it outputs stars according to the input.
for example:
#include <iostream>
using namespace std;
int main()
{
int n=0;
char star='*';
cout<<"Enter number Desired "<<endl;
cin>> n;
star=n;
cout<<' \n'<<star<<endl;
cout<<' \n'<<star-1<<endl;
cout<<' \n'<<star-2<<endl;
cout<<' \n'<<star-3<<endl;
cout<<' \n'<<star-4<<endl;
system ("pause");
return 0;
}
You should use a for-loop for printing out stars one by one.
An example is given below:
for (int i = 0; i < n; i++) {
cout << "*" << endl;
}
To make this loop print out less and less stars in each row, use nested for-loops:
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
cout << "*" << endl;
}
cout << "\n" << endl;
}
This loop will print out n star characters in the first row, n-1 characters in the second row, and so on.
Let's say, if n == 5, then the output will be:
*****
****
***
**
*
This will print out a descending number of stars from the entered number:
#include <iostream>
using namespace std;
int main() {
int n=0;
char star='*';
cout<<"Enter number Desired "<<endl;
cin>> n;
for (int i = 0; i < n; i++)
{
for (int j = i; j < n; j++)
{
cout << "*";
}
cout << " " << endl;
}
system ("pause");
return 0;
}

Prime number checker?

I'm trying to create a program that will check if a given number (between 1 and 1000) is prime but ran across a problem or two. The code I have below will run, but output 1000 times because of line 14 (for(int i = 3; i <= ELEMENTS; i++){) I know why it's running 1000 times but I can't find a way around it.
#include<iostream>
using namespace std;
int main(){
cout << "enter number of interest: ";
int num;
cin >> num;
const int ELEMENTS =1000;
bool multiples[ELEMENTS] = {};
for(int i = 3; i <= ELEMENTS; i++){
for(int j = 2; j <= i - 1; j++){
multiples[i]=true;
if(i % j == 0){
multiples[j]=false;
}
}
if((multiples[num] == true)){
cout << num << " is prime" << endl;
}
else
cout <<num<< " is not prime"<<endl;
}
return 0;
}
Move it out of for loop. Since variables it uses are defined out of for loop scope, it will work fine.
Edit: correct fragment:
for(int i = 3; i <= ELEMENTS; i++){
for(int j = 2; j <= i - 1; j++){
multiples[i]=true;
if(i % j == 0){
multiples[j]=false;
}
}
}
if (multiples[num] == true) {
cout << num << " is prime" << endl;
}
else
cout << num << " is not prime" << endl;

Resources