#include <stdio.h> // For printf()
#include <cv.h> // Main OpenCV library.
#include <highgui.h> // OpenCV functions for files and graphical windows.
#include<ml.h>
#include<fstream>
using namespace std;
using namespace cv;
class imagepro {
int MOMpq(int p, int q, float xt, float yt, float* x, float* y, int size) {
float u[size];
float v[size];
for (int i = 0; i < size; i++) {
u[i] = x[i];
v[i] = y[i];
}
for (int i = 0; i < size; i++) {
u[i] = u[i] - xt;
v[i] = v[i] - yt;
}
for (int i = 0; i < size; i++) {
u[i] = pow(u[i], p);
v[i] = pow(v[i], q);
}
float mpq = 0;
for (int j = 0; j <= size; j++) {
mpq = mpq + (u[j] * v[j]);
}
return mpq;
}
public:
void getFeatures(Mat img, long double* feat) {
float x[img.rows * img.cols];
float y[img.rows * img.cols];
int k = 0;
for (int i = 0; i < img.rows; i++) {
for (int j = 0; j < img.cols; j++) {
int n = (int) img.at<uchar>(i, j);
if (n == 255) {
x[k] = i;
y[k] = j;
k++;
}
}
}
//find COG
float a1 = 0;
float b1 = 0;
for (int i = 0; i < k; i++) {
a1 = a1 + x[i];
b1 = b1 + y[i];
}
float arr[2];
arr[0] = a1 / k;
arr[1] = b1 / k;
//find moments
float m00 = MOMpq(0, 0, arr[0], arr[1], x, y, k);
float m20 = MOMpq(2, 0, arr[0], arr[1], x, y, k);
float m02 = MOMpq(0, 2, arr[0], arr[1], x, y, k);
float m11 = MOMpq(1, 1, arr[0], arr[1], x, y, k);
float m30 = MOMpq(3, 0, arr[0], arr[1], x, y, k);
float m03 = MOMpq(0, 3, arr[0], arr[1], x, y, k);
float m21 = MOMpq(2, 1, arr[0], arr[1], x, y, k);
float m12 = MOMpq(1, 2, arr[0], arr[1], x, y, k);
float m22 = MOMpq(2, 2, arr[0], arr[1], x, y, k);
float m13 = MOMpq(1, 3, arr[0], arr[1], x, y, k);
float m31 = MOMpq(3, 1, arr[0], arr[1], x, y, k);
float m04 = MOMpq(0, 4, arr[0], arr[1], x, y, k);
float m40 = MOMpq(4, 0, arr[0], arr[1], x, y, k);
//Find Affine moments invariants
//cout<<m00<<" "<<m20<<" "<<m02<<" "<<m11<<"\n";
long double I1 = ((m02 * m20) - (m11 * m11)) / (pow(m00, 4));
long double I2 = ((m30 * m30 * m03 * m03) - (6 * m03 * m30 * m21 * m12)
+ (4 * m30 * (pow(m12, 3))) + (4 * m03 * (pow(m21, 3)))
- (3 * m21 * m21 * m12 * m12)) / ((long double) pow(m00, 10));
long double I3 = ((m20 * m21 * m03) - pow(m12, 2)
- (m11 * m30 * m03 - m21 * m12)
+ (m02 * m12 * m30 - (pow(m21, 2))))
/ ((long double) pow(m00, 7));
long double I4 = ((long double) pow(m20, 3) * pow(m03, 2)
- ((long double) 6 * pow(m20, 2) * m11 * m12 * m03)
- ((long double) 6 * pow(m20, 2) * m02 * m21 * m03)
+ ((long double) 9 * pow(m20, 2) * m02 * pow(m12, 2))
+ ((long double) 12 * m20 * m21 * m03 * pow(m11, 2))
+ ((long double) 6 * m02 * m20 * m30 * m03 * m11)
- ((long double) 18 * m20 * m02 * m11 * m21 * m12)
- ((long double) 8 * pow(m11, 3) * m03 * m30)
- ((long double) 6 * pow(m02, 2) * m20 * m30 * m12)
+ ((long double) 9 * pow(m02, 2) * pow(m21, 2) * m20)
+ ((long double) 12 * m02 * m30 * m12 * pow(m11, 2))
- ((long double) 6 * m11 * m30 * m21 * pow(m02, 2))
+ ((long double) pow(m02, 3) * pow(m30, 2)))
/ ((long double) pow(m00, 11));
long double I5 = ((m40 * m04 * m22) + (2 * m22 * m13 * m31)
- (m40 * pow(m13, 2)) - (m04 * pow(m31, 2)) - pow(m22, 3))
/ pow(m00, 9);
long double I6 = ((m40 * m04) - (4 * m13 * m31) + (3 * m22 * m22))
/ ((long double) pow(m00, 6));
//cout<<I1<<" "<<I2<<" "<<I3<<","<<I4<<","<<I5<<","<<I6<<" \n";
//cout<<"";
feat[0] = I1;
feat[1] = I2;
feat[2] = I3;
feat[3] = I4;
feat[4] = I5;
feat[5] = I6;
}
};
int main() {
char* filename = "caps.txt";
ifstream readFile(filename);
string line;
string str = "OCR/EnglishHnd/English/Hnd/";
ofstream outputFile("features.txt",
std::ios_base::app);
if (readFile.is_open()) {
while (readFile >> line) {
string location = line;
long double feat[6];
Mat im_gray = imread(str + line, CV_LOAD_IMAGE_GRAYSCALE);
Mat img_bw = im_gray > 128;
threshold(img_bw, img_bw, 0, 255, CV_THRESH_BINARY_INV);
resize(img_bw, img_bw, Size(256, 256));
imagepro obj;
obj.getFeatures(img_bw, feat);
//obj=NULL;
cout << feat[0] << " " << feat[1] << " " << feat[2] << " "
<< feat[3] << " " << feat[4] << " " << feat[5] << "\n";
cout.flush();
outputFile << feat[0] << " " << feat[1] << " " << feat[2] << " "
<< feat[3] << " " << feat[4] << " " << feat[5] << "\n";
outputFile.flush();
}
outputFile.close();
}
readFile.close();
//waitKey(0);
return 0;
}
The values returning same features array say [x,y,z,u,v,w] for a number of images, and this feature array does not correspond to any image. but when I put "cout<<m00<<" "<<m20<<" "<<m02<<" "<<m11<<"\n";
in the function getfeatures() it is giving the correct values.What is happening here?? I am completely lost.. please help..
Try to allocate x[]
and y[]
dynamically instead of allocating it on the stack. AFAIK you have a about 500k allocated if your image is 256x256*2*sizeof(float)
Don't forget to free the memory after you are done.
Since the function doesn't use the array after it is done, you could also allocate it globally or statically only once, so you don't need to allocate and free it several times.
updated
A quick and dirty way to solve your problem would be this:
void getFeatures(Mat img, long double* feat, float *x, float *y)
{
int k = 0;
...
a = x[n];
}
main()
{
float *x = new float[256*256];
float *y = new float[256*256];
while()
{
obj.getFeatures(img_bw, feat, x, y);
}
delete [] x;
delete [] y;
}
However if this class is reused, you should consider adding a constractur where you can pass in the size or the image and which allocates the memory and deallocate it in the destructor. The above way is not really safe, because you don't check the size of the memory and so on, so this hould be handled in the class itself IMO.
From your example above this code assumes that the size of the memory stays always the same for all images, and it doesn't get used. if this assumption changes, this code will break of course.