-1
#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() に " を入れると、正しい値が返されます。ここで何が起こっているのですか?? 私は完全に迷っています..助けてください..

4

2 に答える 2

0

Vikas さん、getfeatures メソッドの戻り値の型を「int」から「float」に変更してください。「return mpq」のように戻りながら、float を int に変換し、さらに float に変換するため、その間に丸めが発生します。

于 2013-06-12T09:56:51.070 に答える
-1

x[]スタックに割り当てるのではなく、y[]動的に割り当てるようにしてください。私の知る限り、画像が256x256*2*sizeof(float)

完了したら、メモリを解放することを忘れないでください。

関数は実行後に配列を使用しないため、配列をグローバルまたは静的に 1 回だけ割り当てることもできるため、何度も割り当てて解放する必要はありません。

更新しました

問題を解決する手っ取り早い方法は次のとおりです。

 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;
 }

ただし、このクラスを再利用する場合は、サイズまたはイメージを渡すことができ、デストラクタでメモリを割り当てて解放するコンストラクタを追加することを検討する必要があります。上記の方法は、メモリのサイズなどをチェックしないため、実際には安全ではありません。したがって、これはクラス自体の IMO で処理する必要があります。

上記の例から、このコードは、メモリのサイズがすべての画像で常に同じであり、使用されないと想定しています。この仮定が変わると、このコードはもちろん壊れます。

于 2013-06-12T09:33:24.713 に答える