#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;
}
对于许多图像,返回相同特征数组的值表示[x,y,z,u,v,w],并且此特征数组与任何图像都不对应。但当我把“cout<<m00<<" "<<m20<<" "<<m02<<" "<<m11<<"\n";
在函数getfeatures()中它给出了正确的值。这里发生了什么?我完全失去了..请帮助..
答案 0 :(得分:0)
Vikas,只需将getfeatures方法的返回类型从“int”更改为“float”即可。 返回时返回'return mpq',将float转换为int,然后再转换为float,因此在它们之间进行舍入。
答案 1 :(得分:-1)
尝试动态分配x[]
和y[]
,而不是在堆栈上分配它。如果您的图片是256x256*2*sizeof(float)
完成后不要忘记释放内存。
由于该函数在完成后不使用该数组,因此您也可以全局或静态地分配它,因此您不需要多次分配和释放它。
<强>更新强>
解决问题的快速而肮脏的方法是:
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;
}
但是,如果重用此类,则应考虑添加一个constractur,您可以在其中传入大小或图像,并分配内存并在析构函数中释放它。上面的方法并不是很安全,因为你没有检查内存的大小等等,所以这应该在类本身IMO中处理。
从上面的示例开始,此代码假定所有图像的内存大小始终保持不变,并且不会被使用。如果这个假设发生变化,这个代码当然会破裂。