Перейти к содержимому
Compvision.ru

ProgRoman

Пользователи
  • Количество публикаций

    190
  • Зарегистрирован

  • Посещение

  • Days Won

    7

Сообщения, опубликованные пользователем ProgRoman


  1. В 20.04.2016 at 12:25, mrgloom сказал:

    Потому что low level features для всех классов одинаковые и на большой разнообразной выборке они получаются хорошие\репрезентативные.

    low level features это признаки на первых слоях?


  2. привожу проверенный код для сохранения и считывания сетки

    #сохранение сетки
    import cPickle as pickle
    
    
    with open('net1.pickle', 'wb') as f:
        pickle.dump(net, f, -1)

    net это обученная сеть

    #загрузка обученной сетки из файла
    import cPickle as pickle
    
    with open('net1.pickle', 'rb') as f:
        net_pretrain = pickle.load(f)

    net_pretrain новая сеть загруженная из файла, теперь её можно дообучать довольно удобно

    дообучение сетки происходит так же как и просто обучение

    net_pretrain.fit(X,y)

    причём можно установить другое количество эпох (к примеру сеть net обучалась 10-ть эпох,  для до обучения можно поставить как меньше так и больше ну или оставить столько же))

    net_pretrain.max_epochs = 30

    • Like 1

  3. Обучил сеть используя библиотеки nolearn и lasagne привожу код

    import os
    import matplotlib.pyplot as plt
    %pylab inline
    import numpy as np
    import lasagne
    from lasagne import layers
    from lasagne.updates import nesterov_momentum
    from lasagne.layers import DenseLayer
    from lasagne.layers import InputLayer
    from lasagne.layers import DropoutLayer
    from lasagne.layers import Conv2DLayer
    from lasagne.layers import MaxPool2DLayer
    from lasagne.nonlinearities import softmax
    from lasagne.updates import adam
    from lasagne.layers import get_all_params
    
    from nolearn.lasagne import NeuralNet
    from nolearn.lasagne import TrainSplit
    from nolearn.lasagne import objective
    from nolearn.lasagne import visualize
    
    from sklearn.metrics import confusion_matrix, classification_report, accuracy_score
    
    net_cnn = NeuralNet(
    layers=[
    ('input', layers.InputLayer),
    ('conv1', layers.Conv2DLayer), #Convolutional layer. Params defined below
    ('pool1', layers.MaxPool2DLayer), # Like downsampling, for execution speed
    ('conv2', layers.Conv2DLayer),
    ('hidden3', layers.DenseLayer),
    ('output', layers.DenseLayer),
    ],
    
    input_shape=(None, 1, 28, 28),
    conv1_num_filters=7,
    conv1_filter_size=(3, 3),
    conv1_nonlinearity=lasagne.nonlinearities.rectify,
    
    pool1_pool_size=(2, 2),
    
    conv2_num_filters=12,
    conv2_filter_size=(2, 2),
    conv2_nonlinearity=lasagne.nonlinearities.rectify,
    
    hidden3_num_units=1000,
    output_num_units=10,
    output_nonlinearity=lasagne.nonlinearities.softmax,
    
    update_learning_rate=0.0001,
    update_momentum=0.9,
    
    max_epochs=10,
    verbose=1,
    )
    
    net_cnn.fit(train,target)

    как можно сохранить net_cnn в какой-нибудь файлик, что бы потом можно было бы загрузить  как-нибудь

    net_new = load_net('имя файла')

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

    • Like 1

  4. проект довольно старый и изначально там привязались к этой версии, заливать более свежие версии на отрез отказываются:)

    opencv-шные либы к своим.. да надо попробовать, идея хорошая)


  5. Почему так происходит не понятно... может версия старая.. не знаю.. для отладки сделал что бы просто считывались и сохранялись отдельные кадры..  так вроде бы работает...


  6. Какая-то странная ситуация у меня происходит..

    Пишу под линуксом в eclipse  в проекте используется opencv 2.2.0

    подключал внутренние (написанные) библиотеки через -rpath вот и начались проблемы перестали работать imshow, waitkey, и видео не читается

    ...
    VideoCapture  cap;
    cap.open(filename);
    Mat frm;
    cap>>frm;
    ...

    тоже не работает как будто ролика нету.. (остальные функции работают..) т.е. даже читать и писать изображение можно..

    если исключить подключаемые дополнительные(внутренние) библиотеки то роботоспособность opencv возвращается) можно ли как-то восстановить что бы работали методы всегда) или это какой-то косяк старых версий?...


  7. Попробовал предложенный метод детекции теней... что-то у меня совсем не только тени детектируются.. приведу код и картинки

    ....
    Mat ims = imread(filename);
    Mat imslb;
    
    cvtColor(ims,imslb,CV_BGR2Lab);
    vector<Mat> vlb;
    split(imslb, vlb);
    Mat imL = vlb[0].clone();
    
    Scalar mean, dev;
    meanStdDev(imL, mean, dev);
    
    float mnL = (float)(mean.val[0]);
    float dvL = ((float)(dev.val[0]))/3.0;
    float thr = mnL - dvL;
    
    Mat bin = Mat::zeros(imL.size(),CV_8UC1);
    threshold(imL,bin,thr,255,CV_THRESH_BINARY);
    ...

    ну и соответственно получил следующий результат вывожу маску после пороговой обработки

    бинарная маска это результат обработки..

    bin.jpg

    img.jpg


  8. Эта матрица зависит от модели движения и может быть, в принципе, произвольной.

    а как её задавать тогда?... для 2-х мерной точки вроде бы ничего сложного не было просто писал

    ...
    KalmanFilter KF(4,2,0);//x,y,dx,dy
    KF.transitionMatrix = *(Mat_<float>(4, 4) << 1,0,1,0,   0,1,0,1,  0,0,1,0,  0,0,0,1);
    ...

    я так задавал, вроде бы было корректно...  а с трёхмерными точками каким образом модель движения получать что бы матрицу задать...


  9. Добрый день! У меня тут появился вопрос.. в примерах фильтра Калмана обычно рассматривают предсказание и или (сглаживание) 2d точек, каким образом изменится матрица перехода если у нас точки 3-хмерные

    ....
    KalmanFilter KF(6,3,0);//x,y,z,dx,dy,dz
    KF.transitionMatrix = *(Mat_<float>(6, 6) << 1,0,1,0,1,0   0,1,0,1,0,1,  0,0,1,0,1,0,  0,0,0,1,0,1, 0,0,0,0,1,0, 0,0,0,0,0,1);
    ....

    матрица KF.transitionMatrix должна иметь такой блочный вид или она должна быть просто единичной?..


  10. Да в opencv уже есть реализация, я пока с алгоритмом не определился буду пробовать и opencv конечно тоже, вообще нужна стабилизация за реальное время, так что буду тестировать несколько вариантов, вроде бы на ютубе есть стабилизация... правда не знаю есть ли реализация в открытом доступе)


  11. камера неподвижная.

    Далее надо как-то оценивать качество алгоритма слияния кадров (называется warping, warp, fuse). Особенно на границах. Тут могут быть варианты, но основной - неподвижность всех элементов сцены и их минимальное искажение. То есть как ни шатается камера, а здание в центре должно оставаться зданием в центре и не искажаться краевыми эффектами.

    Неподвижность я думаю просто вектором смещений(dx,dy)(т.к. камера неподвижна) чем меньше тем лучше) а вот о границах я даже не подумал... как я понимаю их же обрезать придётся...


  12. что-то непонятно... сейчас явно гружу opencv_ffmpeg2410_64.dll но видео не идёт.. 

    есть метод open в файле cap_ffmpeg.cpp

        virtual bool open( const char* filename )
        {
            icvInitFFMPEG::Init();
            close();
    
            if( !icvCreateFileCapture_FFMPEG_p )
                return false;
            ffmpegCapture = icvCreateFileCapture_FFMPEG_p( filename );
            return ffmpegCapture != 0;
        }
    
    
    

    ffmpegCapture = icvCreateFileCapture_FFMPEG_p( filename );

    эта строка похоже как-то некорректно отрабатывает filename корректный, а связать она почему-то не может..

    выводит следующее сообщение

    1.1435602135.jpg


  13. Здравствуйте! Есть IP камера видео передаётся через rtsp вставляю ссылку в vlc и всё работает...  абсолютно такая же строка но при коннекте камеры через opencv ничго не происходит... вернее самого конекта не происходит... формат строки rtsp://x.x.x.x:PORT при связывании через vlc видео показывает...

    .....................
    VideoCapture cap;
    cap.open(filename);//filename - строка конекта
    ............................
    

    он даже его не открывает...


  14. Их столько и должно быть.

    Просто каскадная система отсекает почти все, остаются самые сильные на каждом каскаде.

    Ясно тогда понятно почему так много, у меня ещё вопрос т.е. правильно понимаю, что конечно можно выделить из изображения все признаки Хаара, но для распознавания это совсем не лучший вариант, т.е. имеет смысл не просто извлекать признаки, а делать выборку из них ну как это сделано в алгоритме Виолы Джонса 


  15. Добрый день! Подумал написать функцию выделения признаков Хаара из изображения для обучения классификаторов как это сделано с HOG к примеру, т.е. на вход подаём просто изображение, а на выходе к примеру cv::Mat с признаками что бы потом подать на вход классификатору. В Opencv есть класс CvHaarEvaluator вот его я взял за основу и немного изменил, точнее удалял  многое, приведу код 

    /*
    haarfeatures.h
    */
    #ifndef _OPENCV_HAARFEATURES_H_
    #define _OPENCV_HAARFEATURES_H_
    
    #include "opencv2/core/core.hpp"
    #include "opencv2\core\mat.hpp"
    #include "opencv2\imgproc\imgproc.hpp"
    
    #define CV_HAAR_FEATURE_MAX      3
    
    #define HFP_NAME "haarFeatureParams"
    
    using namespace cv;
    
    #define CV_SUM_OFFSETS( p0, p1, p2, p3, rect, step )                      \
        /* (x, y) */                                                          \
        (p0) = (rect).x + (step) * (rect).y;                                  \
        /* (x + w, y) */                                                      \
        (p1) = (rect).x + (rect).width + (step) * (rect).y;                   \
        /* (x + w, y) */                                                      \
        (p2) = (rect).x + (step) * ((rect).y + (rect).height);                \
        /* (x + w, y + h) */                                                  \
        (p3) = (rect).x + (rect).width + (step) * ((rect).y + (rect).height);
    
    #define CV_TILTED_OFFSETS( p0, p1, p2, p3, rect, step )                   \
        /* (x, y) */                                                          \
        (p0) = (rect).x + (step) * (rect).y;                                  \
        /* (x - h, y + h) */                                                  \
        (p1) = (rect).x - (rect).height + (step) * ((rect).y + (rect).height);\
        /* (x + w, y + w) */                                                  \
        (p2) = (rect).x + (rect).width + (step) * ((rect).y + (rect).width);  \
        /* (x + w - h, y + w + h) */                                          \
        (p3) = (rect).x + (rect).width - (rect).height                        \
               + (step) * ((rect).y + (rect).width + (rect).height);
    
    inline float calcNormFactor( const Mat& sum, const Mat& sqSum )
    {
        CV_Assert( sum.cols > 3 && sqSum.rows > 3 );
        Rect normrect( 1, 1, sum.cols - 3, sum.rows - 3 );
        size_t p0, p1, p2, p3;
        CV_SUM_OFFSETS( p0, p1, p2, p3, normrect, sum.step1() )
        double area = normrect.width * normrect.height;
        const int *sp = (const int*)sum.data;
        int valSum = sp[p0] - sp[p1] - sp[p2] + sp[p3];
        const double *sqp = (const double *)sqSum.data;
        double valSqSum = sqp[p0] - sqp[p1] - sqp[p2] + sqp[p3];
        return (float) sqrt( (double) (area * valSqSum - (double)valSum * valSum) );
    }
    
    class CvHaarEvaluator
    {
    public:	
        void init(const int _maxSampleCount = 1, const cv::Size& _winSize = Size(24,24));
    	void CvHaarEvaluator::setImage(const Mat& img/*, uchar clsLabel*/, int idx = 1);
        float operator()(int featureIdx, int sampleIdx) const;	
    
    protected:    
    
    	void generateFeatures();
    
        class Feature
        {
        public:
            Feature();
            Feature( int offset, bool _tilted,
                int x0, int y0, int w0, int h0, float wt0,
                int x1, int y1, int w1, int h1, float wt1,
                int x2 = 0, int y2 = 0, int w2 = 0, int h2 = 0, float wt2 = 0.0F );
            float calc( const cv::Mat &sum, const cv::Mat &tilted, size_t y) const;
    
            bool  tilted;
            struct
            {
                cv::Rect r;
                float weight;
            } rect[CV_HAAR_FEATURE_MAX];
    
            struct
            {
                int p0, p1, p2, p3;
            } fastRect[CV_HAAR_FEATURE_MAX];
        };
    
        std::vector<Feature> features;
        cv::Mat  sum;         /* sum images (each row represents image) */
        cv::Mat  tilted;      /* tilted sum images (each row represents image) */
        cv::Mat  normfactor;  /* normalization factor */
    	cv::Mat  sumimg;	  /*integral images*/
    	cv::Size winSize;
    	int numFeatures;
    };
    
    inline float CvHaarEvaluator::operator()(int featureIdx, int sampleIdx) const
    {	
        float nf = normfactor.at<float>(0, sampleIdx);
        return !nf ? 0.0f : (features[featureIdx].calc( sum, tilted, sampleIdx)/nf);
    }
    
    inline float CvHaarEvaluator::Feature::calc( const cv::Mat &_sum, const cv::Mat &_tilted, size_t y) const
    {
        const int* img = tilted ? _tilted.ptr<int>((int)y) : _sum.ptr<int>((int)y);
        float ret = rect[0].weight * (img[fastRect[0].p0] - img[fastRect[0].p1] - img[fastRect[0].p2] + img[fastRect[0].p3] ) +
            rect[1].weight * (img[fastRect[1].p0] - img[fastRect[1].p1] - img[fastRect[1].p2] + img[fastRect[1].p3] );
        if( rect[2].weight != 0.0f )
            ret += rect[2].weight * (img[fastRect[2].p0] - img[fastRect[2].p1] - img[fastRect[2].p2] + img[fastRect[2].p3] );
        return ret;
    }
    
    #endif
    
    

    ну и его реализация 

    /*
    haarfeatures.cpp
    */
    
    #include "opencv2\core\core.hpp"
    #include "opencv2\core\internal.hpp"
    #include "opencv2\imgproc\imgproc.hpp"
    
    
    #include "haarfeatures.h"
    
    using namespace std;
    using namespace cv;
    
    //--------------------- HaarFeatureEvaluator ----------------
    
    void CvHaarEvaluator::init(const int _maxSampleCount, const Size& _winSize)
    {
        CV_Assert(_maxSampleCount > 0);
    	winSize = _winSize;
    	numFeatures = 0;
    	int cols = (_winSize.width + 1) * (_winSize.height + 1);
    
    	sum.create((int)_maxSampleCount, cols, CV_32SC1);
        tilted.create((int)_maxSampleCount, cols, CV_32SC1);
        normfactor.create(1, (int)_maxSampleCount, CV_32FC1);    
    	generateFeatures();
    }
    
    void CvHaarEvaluator::setImage(const Mat& img/*, uchar clsLabel*/, int idx)
    {
        CV_Assert( !sum.empty() && !tilted.empty() && !normfactor.empty() );
    
        Mat innSum(winSize.height + 1, winSize.width + 1, sum.type()/*, sum.ptr<int>((int)idx)*/);
        Mat innTilted(winSize.height + 1, winSize.width + 1, tilted.type()/*, tilted.ptr<int>((int)idx)*/);
        Mat innSqSum;
        integral(img, innSum, innSqSum, innTilted);
    	sumimg = innSum.clone();	
        normfactor.ptr<float>(0)[idx] = calcNormFactor( innSum, innSqSum );
    }
    
    
    
    void CvHaarEvaluator::generateFeatures()
    {    
        int offset = winSize.width + 1;
    
        for( int x = 0; x < winSize.width; x++ )
        {
            for( int y = 0; y < winSize.height; y++ )
            {
                for( int dx = 1; dx <= winSize.width; dx++ )
                {
                    for( int dy = 1; dy <= winSize.height; dy++ )
                    {
                        // haar_x2
                        if ( (x+dx*2 <= winSize.width) && (y+dy <= winSize.height) )
                        {
                            features.push_back( Feature( offset, false,
                                x,    y, dx*2, dy, -1,
                                x+dx, y, dx  , dy, +2 ) );
                        }
                        // haar_y2
                        if ( (x+dx <= winSize.width) && (y+dy*2 <= winSize.height) )
                        {
                            features.push_back( Feature( offset, false,
                                x,    y, dx, dy*2, -1,
                                x, y+dy, dx, dy,   +2 ) );
                        }
                        // haar_x3
                        if ( (x+dx*3 <= winSize.width) && (y+dy <= winSize.height) )
                        {
                            features.push_back( Feature( offset, false,
                                x,    y, dx*3, dy, -1,
                                x+dx, y, dx  , dy, +3 ) );
                        }
                        // haar_y3
                        if ( (x+dx <= winSize.width) && (y+dy*3 <= winSize.height) )
                        {
                            features.push_back( Feature( offset, false,
                                x, y,    dx, dy*3, -1,
                                x, y+dy, dx, dy,   +3 ) );
                        }                    
                        {
                            // haar_x4
                            if ( (x+dx*4 <= winSize.width) && (y+dy <= winSize.height) )
                            {
                                features.push_back( Feature( offset, false,
                                    x,    y, dx*4, dy, -1,
                                    x+dx, y, dx*2, dy, +2 ) );
                            }
                            // haar_y4
                            if ( (x+dx <= winSize.width ) && (y+dy*4 <= winSize.height) )
                            {
                                features.push_back( Feature( offset, false,
                                    x, y,    dx, dy*4, -1,
                                    x, y+dy, dx, dy*2, +2 ) );
                            }
                        }
                        // x2_y2
                        if ( (x+dx*2 <= winSize.width) && (y+dy*2 <= winSize.height) )
                        {
                            features.push_back( Feature( offset, false,
                                x,    y,    dx*2, dy*2, -1,
                                x,    y,    dx,   dy,   +2,
                                x+dx, y+dy, dx,   dy,   +2 ) );
                        }                    
                        {
                            if ( (x+dx*3 <= winSize.width) && (y+dy*3 <= winSize.height) )
                            {
                                features.push_back( Feature( offset, false,
                                    x   , y   , dx*3, dy*3, -1,
                                    x+dx, y+dy, dx  , dy  , +9) );
                            }
                        }                    
                        {
                            // tilted haar_x2
                            if ( (x+2*dx <= winSize.width) && (y+2*dx+dy <= winSize.height) && (x-dy>= 0) )
                            {
                                features.push_back( Feature( offset, true,
                                    x, y, dx*2, dy, -1,
                                    x, y, dx,   dy, +2 ) );
                            }
                            // tilted haar_y2
                            if ( (x+dx <= winSize.width) && (y+dx+2*dy <= winSize.height) && (x-2*dy>= 0) )
                            {
                                features.push_back( Feature( offset, true,
                                    x, y, dx, 2*dy, -1,
                                    x, y, dx, dy,   +2 ) );
                            }
                            // tilted haar_x3
                            if ( (x+3*dx <= winSize.width) && (y+3*dx+dy <= winSize.height) && (x-dy>= 0) )
                            {
                                features.push_back( Feature( offset, true,
                                    x,    y,    dx*3, dy, -1,
                                    x+dx, y+dx, dx,   dy, +3 ) );
                            }
                            // tilted haar_y3
                            if ( (x+dx <= winSize.width) && (y+dx+3*dy <= winSize.height) && (x-3*dy>= 0) )
                            {
                                features.push_back( Feature( offset, true,
                                    x,    y,    dx, 3*dy, -1,
                                    x-dy, y+dy, dx, dy,   +3 ) );
                            }
                            // tilted haar_x4
                            if ( (x+4*dx <= winSize.width) && (y+4*dx+dy <= winSize.height) && (x-dy>= 0) )
                            {
                                features.push_back( Feature( offset, true,
                                    x,    y,    dx*4, dy, -1,
                                    x+dx, y+dx, dx*2, dy, +2 ) );
                            }
                            // tilted haar_y4
                            if ( (x+dx <= winSize.width) && (y+dx+4*dy <= winSize.height) && (x-4*dy>= 0) )
                            {
                                features.push_back( Feature( offset, true,
                                    x,    y,    dx, 4*dy, -1,
                                    x-dy, y+dy, dx, 2*dy, +2 ) );
                            }
                        }
                    }
                }
            }
        }    
    
    	numFeatures = (int)features.size();
    }
    
    CvHaarEvaluator::Feature::Feature()
    {
        tilted = false;
        rect[0].r = rect[1].r = rect[2].r = Rect(0,0,0,0);
        rect[0].weight = rect[1].weight = rect[2].weight = 0;
    }
    
    
    
    CvHaarEvaluator::Feature::Feature( int offset, bool _tilted,
                                              int x0, int y0, int w0, int h0, float wt0,
                                              int x1, int y1, int w1, int h1, float wt1,
                                              int x2, int y2, int w2, int h2, float wt2 )
    {
        tilted = _tilted;
    
        rect[0].r.x = x0;
        rect[0].r.y = y0;
        rect[0].r.width  = w0;
        rect[0].r.height = h0;
        rect[0].weight   = wt0;
    
        rect[1].r.x = x1;
        rect[1].r.y = y1;
        rect[1].r.width  = w1;
        rect[1].r.height = h1;
        rect[1].weight   = wt1;
    
        rect[2].r.x = x2;
        rect[2].r.y = y2;
        rect[2].r.width  = w2;
        rect[2].r.height = h2;
        rect[2].weight   = wt2;
    
        if( !tilted )
        {
            for( int j = 0; j < CV_HAAR_FEATURE_MAX; j++ )
            {
                if( rect[j].weight == 0.0F )
                    break;
                CV_SUM_OFFSETS( fastRect[j].p0, fastRect[j].p1, fastRect[j].p2, fastRect[j].p3, rect[j].r, offset )
            }
        }
        else
        {
            for( int j = 0; j < CV_HAAR_FEATURE_MAX; j++ )
            {
                if( rect[j].weight == 0.0F )
                    break;
                CV_TILTED_OFFSETS( fastRect[j].p0, fastRect[j].p1, fastRect[j].p2, fastRect[j].p3, rect[j].r, offset )
            }
        }
    }
    

    окошко я выбрал размера 24*24 и после запуска

    CvHaarEvaluator haar;
    haar.init(); 
    ....
    haar.setImage(frame);
    
    

    получаю массив с признаками std::vector<Feature> features; его размер 216600 признаков.. это как я понимаю не для всего изображения, а только для окошка размером 24*24, а что бы получить признаки из всего изображения надо будет окошком 24*24 иди по картинке  признаки сгенерированы поэтому надо будет только проходиться по массиву признаков и считать результаты по интегральному изображению..

    с количеством признаков у меня что-то большие сомнения что их должно быть так много для небольшого участка изображения..  

     


  16. Есть ли базы данных с автомобилями разных типов(грузовые, легковые ну и т.д.) что бы можно было натренировать и протестировать классификатор на базе.


  17. Подправил код со сферическими координатами теперь он работает гораздо лучше кидаю исправленный код и полученные картинки

    Mat convert(const Mat& src)
    {
    	Point pfish;
    	float theta, phi,r;
    	Point3f psph;
    	Mat dst(2*src.rows,src.cols,src.type());
    
    	float FOV = CV_PI;// FOV of the fisheye, eg: 180 degrees
    	float width = dst.size().width;
    	float heigh = dst.size().height;
    	Vec3b balck(0,0,0);
    	for(int y = 0; y<heigh; y++)
    	{
    		for(int x = 0; x<width; x++)
    		{
    			//polar angles			
    			theta = 2.0 * CV_PI * (x / width - 0.5); // -pi to pi
    			phi = CV_PI * (y / heigh - 0.5);	// -pi/2 to pi/2			
    
    			//vector in 3D space
    			psph.x = cos(phi)*sin(theta);
    			psph.y = cos(phi)*cos(theta);
    			psph.z = sin(phi);
    
    			// Calculate fisheye angle and radius			
    			theta = atan2(psph.z,psph.x);
    			phi = atan2(sqrt(psph.x*psph.x+psph.z*psph.z),psph.y);
    			r = width * phi / FOV; 
    
    			// Pixel in fisheye space
    			pfish.x = 0.5 * width + r * cos(theta);
    			pfish.y = 0.5 * width + r * sin(theta);
    
    			if(((pfish.y>0)&&(pfish.y<int(heigh/2)))&&((pfish.x>0)&&(pfish.x<(int)(width))))
    			{
    				//dst.at<Vec3b>(pfish) = src.at<Vec3b>(Point(x,y));
    				dst.at<Vec3b>(Point(x,y)) = src.at<Vec3b>(pfish);
    			}
    		}
    	}
    
    	return dst;
    }
    

    post-2515-0-91870800-1418370108_thumb.jp

    post-2515-0-75163500-1418370126_thumb.jp

    • Like 1

  18. Ок спасибо большое!

    по первой ссылке есть код SelfCalibration.cpp от Smorodov который должен устранять дисторсии как я понял, скачал попробовал на тестовом изображении с решётками и всё получилось, попробовал на других изображениях.. как-то особо не получилось) привожу картинку  

    post-2515-0-20498200-1418110215_thumb.jp


  19. Что получилось,smile.png  Пробовал устранять дисторсию вручную с помощью gimp, но как то особо не получилось возможно из за большого ракурса съёмки не знаю или может просто я не смог правильно параметры подобрать)  Посмотрел в интернете оказалось что снимки сделанные камерой рыбий глаз переводят в панорамные снимки

    Mat convert(const Mat& src)
    {
    	int midy = src.size().height / 2;
    	int midx = src.size().width / 2;
    	int maxmag = (midy > midx ? midy : midx);
    	int circum = 2 * CV_PI * maxmag;     // c = 2*pi*r
    
    	Mat dst(Size(circum,maxmag),src.type());
    
    	Vec3b black(0,0,0);
    	for (int y = 0; y < maxmag; y++) 
    	{
    		for (int x = 0; x < circum; x++) 
    		{
    			double theta = -1.0 * x / maxmag;       
    			double mag = maxmag - y;                
    			
    			int targety = int(midy + mag * cos(theta) + 0.5);
    			int targetx = int(midx + mag * sin(theta) + 0.5);
    			int ix =-(x * 2.0 * CV_PI / src.size().width);
    			int iy = y * 1.0 * maxmag / src.size().height;
    
    			if (targety < 0 || targety >= src.size().height || targetx < 0 || targetx >= src.size().width) 
    			{
    				dst.at<Vec3b>(Point(x,y)) = black;
    			} 
    			else 
    			{
    				dst.at<Vec3b>(Point(x,y)) = src.at<Vec3b>(targety,targetx );				
    			}
    		}
    	}
    
    	return dst;
    }
    

    Панораму я конечно получаю, но всё равно она сильно искажена, думаю её надо как-то делить на несколько частей и повторно пытаться убрать искажения прилагаю картинки(res1, res2,res3).

    так же нашёл код который переводит изображение из fisheye в прямоугольник прилагаю класс

    class Analyzer
     {
     private:
          vector<double> mFisheyeCorrect;
          int mFELimit;
          double mScaleFESize;
    
     public:
          Analyzer()
          {
                //A lookup table so we don't have to calculate Rdistorted over and over
                //The values will be multiplied by focal length in pixels to 
                //get the Rdistorted
    		  mFELimit = 1500;
    		  mScaleFESize = 0.9;
                //i corresponds to Rundist/focalLengthInPixels * 1000 (to get integers)
              for (int i = 0; i < mFELimit; i++)
              {
                  double result = sqrt(1 - 1 / sqrt(1.0 + (double)i * i / 1000000.0)) * 1.4142136;
    			  mFisheyeCorrect.push_back(result);
              }
          }
    
          Mat RemoveFisheye(Mat& aImage, double aFocalLinPixels)
          {
    		  Mat correctedImage(aImage.rows, aImage.cols,aImage.type());
    		  //The center points of the image
              double xc = aImage.size().width / 2.0;
              double yc = aImage.size().height / 2.0;
    
              bool xpos, ypos;
    		  //Move through the pixels in the corrected image; 
    		  //set to corresponding pixels in distorted image
              for (int i = 0; i < correctedImage.size().width; i++)
              {
    			  for (int j = 0; j < correctedImage.size().height; j++)
                  {
                         //which quadrant are we in?
                      xpos = i > xc;
                      ypos = j > yc;
                         //Find the distance from the center
                      double xdif = i-xc;
                      double ydif = j-yc;
                         //The distance squared
                      double Rusquare = xdif * xdif + ydif * ydif;
                         //the angle from the center
                      double theta = atan2(ydif, xdif);
                         //find index for lookup table
                      int index = (int)(sqrt(Rusquare) / aFocalLinPixels * 1000);
                      if (index >= mFELimit) index = mFELimit - 1;
                         //calculated Rdistorted
                      double Rd = aFocalLinPixels * (double)mFisheyeCorrect[index]
                                            /mScaleFESize;
                         //calculate x and y distances
                      double xdelta = abs(Rd*cos(theta));
                      double ydelta = abs(Rd * sin(theta));
                         //convert to pixel coordinates
                      int xd = (int)(xc + (xpos ? xdelta : -xdelta));
                      int yd = (int)(yc + (ypos ? ydelta : -ydelta));
    				  
                      xd = std::max(0, min(xd, aImage.size().width-1));
                      yd = std::max(0, min(yd, aImage.size().height-1));
                         //set the corrected pixel value from the distorted image
                      correctedImage.at<Vec3b>(Point(i, j)) = aImage.at<Vec3b>(Point(xd, yd));
                  }
              }
              return correctedImage;
          }
    };
    
    /*
    так же функция для вычисления фокусного расстояния
    */
    
    double dist(double x, double y)
    {
    	return sqrt(x*x + y*y);
    }
    
    double calculate_focal_distance(int src_size_x, int src_size_y, double crop_factor)
    {
    	double f = dist(src_size_x, src_size_y)*crop_factor/CV_PI;
    
    	return f;
    }
    

    Результаты работы этого класса  это изображения (rect1, rect2, rect3)

    Сейчас пытаюсь делать преобразования из сферических координат, но что-то явно делаю не так буду разбираться код ниже

    Mat convert6(const Mat& src)
    {
    	Point pfish;
    	float theta, phi,r;
    	Point3f psph;
    	Mat dst(src.rows,src.cols,src.type());
    
    	float FOV = CV_PI;// FOV of the fisheye, eg: 180 degrees
    	float width = src.size().width;
    	float heigh = src.size().height;
    	Vec3b balck(0,0,0);
    	for(int y = 0; y<heigh; y++)
    	{
    		for(int x = 0; x<width; x++)
    		{
    			//polar angles			
    			theta = 2.0 * CV_PI * (x / width - 0.5); // -pi to pi
    			phi = CV_PI * (y / heigh - 0.5);	// -pi/2 to pi/2
    
    			//vector in 3D space
    			psph.x = cos(phi)*sin(theta);
    			psph.y = cos(phi)*cos(theta);
    			psph.z = sin(phi);
    
    			// Calculate fisheye angle and radius			
    			theta = atan2(psph.z,psph.x);
    			phi = atan2(sqrt(psph.x*psph.x+psph.z*psph.z),psph.y);
    			r = width * phi / FOV; 
    
    			// Pixel in fisheye space
    			pfish.x = 0.5 * width + r * cos(theta);
    			pfish.y = 0.5 * width + r * sin(theta);
    
    			if(((pfish.x>0)&&(pfish.x<width))&&((pfish.y>0)&&(pfish.y<heigh)))
    			{
    				dst.at<Vec3b>(pfish) = src.at<Vec3b>(Point(x,y));
    			}			
    		}
    	}
    
    	return dst;
    }
    

    Результаты этого кода это изображения(sphr1,sphr2,sphr3)

    Есть ещё код в матлабе, но не знаю может в силу того что я его плохо знаю как у меня так и не получилось адаптировать его для изображений привожу код

    clear;
    
    M=fspecial('gaussian',256,32); % generate fake image
    
     X0=size(M,1)/2; Y0=size(M,2)/2;
     [Y X z]=find(M);
     X=X-X0; Y=Y-Y0;
     theta = atan2(Y,X);
     rho = sqrt(X.^2+Y.^2);
    
     % Determine the minimum and the maximum x and y values:
     rmin = min(rho); tmin = min(theta);
     rmax = max(rho); tmax = max(theta);
    
     % Define the resolution of the grid:
     rres=128; % # of grid points for R coordinate. (change to needed binning)
     tres=128; % # of grid points for theta coordinate (change to needed binning)      
     
     F = TriScatteredInterp(rho,theta,z,'natural');
    
     %Evaluate the interpolant at the locations (rhoi, thetai).
     %The corresponding value at these locations is Zinterp:
    
     [rhoi,thetai] = meshgrid(linspace(rmin,rmax,rres),linspace(tmin,tmax,tres));
     Zinterp = F(rhoi,thetai);
    
     subplot(1,2,1); imagesc(M) ; axis square
     subplot(1,2,2); imagesc(Zinterp) ; axis square
    
    

    Добавлю ещё как мне кажется полезные ссылки 

    http://paulbourke.net/dome/fish2/

    http://paulbourke.net/dome/fishtilt/

    http://paulbourke.net/dome/2fish/

    http://www.kscottz.com/fish-eye-lens-dewarping-and-panorama-stiching/

    http://stackoverflow.com/questions/12924598/examples-to-convert-image-to-polar-coordinates-do-it-explicitly-want-a-slick-m

    http://stackoverflow.com/questions/2477774/correcting-fisheye-distortion-programmatically

    http://mathworld.wolfram.com/CylindricalEquidistantProjection.html

    http://mathworld.wolfram.com/OrthographicProjection.html

     

    post-2515-0-89436100-1418027981_thumb.jp

    post-2515-0-35481100-1418027999_thumb.jp

    post-2515-0-28481700-1418028017_thumb.jp

    post-2515-0-14639200-1418028031_thumb.jp

    post-2515-0-50882000-1418028045_thumb.jp

    post-2515-0-19522200-1418028059_thumb.jp

    post-2515-0-24721900-1418028090_thumb.jp

    post-2515-0-80573700-1418028109_thumb.jp

    post-2515-0-90494300-1418028147_thumb.jp


  20. Добрый день, стоит такая задача есть камера типа "рыбий глаз" с него идёт видео и необходимо видео преобразовывать так что бы избавляться от этого эффекта рыбьего глаза или(радиальной дисторсии как я понял) тема для меня достаточно новая, как я понял так как видео идёт с одной камеры и она неподвижна, то откалибровать нормально невозможно.. поэтому пользоваться функцией 

    undistort(frame,dst,cameraMatrix,distCoeffs);
    

    так же невозможно, можно ли как-то корректно преобразовать не зная ни cameraMatrix ни distCoeffs...

    ---

    В архиве ролик с камерыsmile.png

    3.rar


  21. Вчера увидел проект визуального программирования http://blendocv.damiles.com/ проект как я понял довольно свежий и мне показалось довольно интересный, на страничке есть примеры его работы, так же обещают что скоро будет выпущена первая релизная версия, на страничке проекта написано, что используется библиотека opencv.

    • Like 1
×