Распознавание знаков с использованием DFT и PCA - PullRequest
0 голосов
/ 25 декабря 2018

Я создаю систему распознавания дорожных знаков в C ++ с библиотекой OpenCV.Моя текущая задача - распознать правильно найденный знак.Мне сказали, что я должен использовать дискретное преобразование Фурье (ДПФ), чтобы различать знаки.Когда я выполняю DFT на разных знаках, я получаю результаты, такие как: DFT Чтобы уменьшить вектор признаков, я использую PCA и получаю следующий результат: PCA

На этом этапе IЯ не знаю, как использовать эти данные, чтобы сопоставить знак, найденный на картинке, со знаком модели, собранным в базе.

Я нашел такие методы, как среднеквадратическая ошибка или расстояние Махаланобиса, но я не знаю, какое значение сравнить сдруг друга.

Может быть, кто-то знает лучше, но тот же самый простой инструмент для распознавания знаков или знает, как использовать тот, который я пробовал.Было бы идеально, если бы кто-то показал пример кода, выполняющего эти методы.

Здесь вы можете найти мой код:

    int main()
    { 
Mat fimage = imread( "baza/zbiór testowy znaków/test11/znak966.tif", CV_LOAD_IMAGE_COLOR ); 
        Mat dimage, dftimage;
        cout << "r " << fimage.cols << " c " << fimage.rows << endl;
        resize(fimage,fimage,Size(128,128));
        cvtColor(fimage,fimage,CV_RGB2GRAY);
        imshow("resul",fimage);

        cvMoveWindow("resul", 372, 500);
        fimage.copyTo(dftimage);
        //---------------==========================dct-----------------================================

        fimage.convertTo(fimage, CV_32F);
        fimage.copyTo(dimage);

        cout << "r " << fimage.cols << " c " << fimage.rows << endl;

        dct( fimage, fimage, DCT_INVERSE ); 
        dct( dimage, dimage); 

        imshow("dct",dimage);
        cvMoveWindow("dct", 500, 500);
        imshow("dct_inverse",fimage);
        cvMoveWindow("dct_inverse", 628, 500);


        //=================================================DFT==========================================
         Mat padded;                            //expand input image to optimal size
        int m = getOptimalDFTSize( dftimage.rows );
        int n = getOptimalDFTSize( dftimage.cols ); // on the border add zero values
        copyMakeBorder(dftimage, padded, 0, m - dftimage.rows, 0, n - dftimage.cols, BORDER_CONSTANT, Scalar::all(0));
        Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)};
        Mat complexI;
        merge(planes, 2, complexI);         // Add to the expanded another plane with zeros
        dft(complexI, complexI);            // this way the result may fit in the source matrix
        // compute the magnitude and switch to logarithmic scale
        // => log(1 + sqrt(Re(DFT(I))^2 + Im(DFT(I))^2))
        split(complexI, planes);                   // planes[0] = Re(DFT(I), planes[1] = Im(DFT(I))
        magnitude(planes[0], planes[1], planes[0]);// planes[0] = magnitude
        Mat magI = planes[0];
        magI += Scalar::all(1);                    // switch to logarithmic scale
        log(magI, magI);
        // crop the spectrum, if it has an odd number of rows or columns
        magI = magI(Rect(0, 0, magI.cols & -2, magI.rows & -2));
        // rearrange the quadrants of Fourier image  so that the origin is at the image center
        int cx = magI.cols/2;
        int cy = magI.rows/2;
        Mat q0(magI, Rect(0, 0, cx, cy));   // Top-Left - Create a ROI per quadrant
        Mat q1(magI, Rect(cx, 0, cx, cy));  // Top-Right
        Mat q2(magI, Rect(0, cy, cx, cy));  // Bottom-Left
        Mat q3(magI, Rect(cx, cy, cx, cy)); // Bottom-Right
        Mat tmp;                           // swap quadrants (Top-Left with Bottom-Right)
        q0.copyTo(tmp);
        q3.copyTo(q0);
        tmp.copyTo(q3);
        q1.copyTo(tmp);                    // swap quadrant (Top-Right with Bottom-Left)
        q2.copyTo(q1);
        tmp.copyTo(q2);
        normalize(magI, magI, 0, 1, NORM_MINMAX); // Transform the matrix with float values into a
                                                // viewable image form (float between values 0 and 1).
        imshow("Input Image"       , dftimage   );    // Show the result
        imshow("spectrum magnitude", magI);


    //===============================================PCA===============================================
        cv::PCA pca(magI,                 //Input Array Data
                Mat(),                //Mean of input array, if you don't want to pass it   simply put Mat()
                CV_PCA_DATA_AS_ROW,   //int flag
                1);                   // liczba wierszy 

        Mat mean=pca.mean;                // get mean of Data in Mat form
        Mat eigenvalue=pca.eigenvalues;
        Mat eigenvectors=pca.eigenvectors;
        cout << "rows: " << eigenvectors.rows << " cols: " << eigenvectors.cols << endl; 

        cout << " eigenvalue " << pca.eigenvalues << endl << "eigenvector "<< pca.eigenvectors << endl << "average "<< pca.mean << endl; 
            Mat point = pca.project(eigenvectors.row(0)); // project into the eigenspace, thus the image becomes a "point"
        Mat reconstruction = pca.backProject(point); // re-create the image from the "point"
        imshow("reconstruction", reconstruction);


                waitKey(0);
        return 0;
    }
...