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

ProgRoman

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

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

  • Посещение

  • Days Won

    7

Все публикации пользователя ProgRoman

  1. Обучил сеть используя библиотеки 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('имя файла') ну и продолжить работать уже как с обученной сетью, ещё интересует вопрос дообучения сети может кто-то пробовал работать с этими библиотеками я не нашёл как это можно сделать.. а всё время обучать сеть заново это как-то совсем печально)
  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
  3. Linux Opencv 2.2.0

    Какая-то странная ситуация у меня происходит.. Пишу под линуксом в eclipse в проекте используется opencv 2.2.0 подключал внутренние (написанные) библиотеки через -rpath вот и начались проблемы перестали работать imshow, waitkey, и видео не читается ... VideoCapture cap; cap.open(filename); Mat frm; cap>>frm; ...тоже не работает как будто ролика нету.. (остальные функции работают..) т.е. даже читать и писать изображение можно.. если исключить подключаемые дополнительные(внутренние) библиотеки то роботоспособность opencv возвращается) можно ли как-то восстановить что бы работали методы всегда) или это какой-то косяк старых версий?...
  4. Linux Opencv 2.2.0

    проект довольно старый и изначально там привязались к этой версии, заливать более свежие версии на отрез отказываются:) opencv-шные либы к своим.. да надо попробовать, идея хорошая)
  5. Linux Opencv 2.2.0

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

    Попробовал предложенный метод детекции теней... что-то у меня совсем не только тени детектируются.. приведу код и картинки .... 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); ...ну и соответственно получил следующий результат вывожу маску после пороговой обработки бинарная маска это результат обработки..
  7. Kalman

    Добрый день! У меня тут появился вопрос.. в примерах фильтра Калмана обычно рассматривают предсказание и или (сглаживание) 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 должна иметь такой блочный вид или она должна быть просто единичной?..
  8. Kalman

    А ок понял! спасибо большое!)
  9. Kalman

    а как её задавать тогда?... для 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); ...я так задавал, вроде бы было корректно... а с трёхмерными точками каким образом модель движения получать что бы матрицу задать...
  10. Стабилизация видеопотока

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

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

    У меня вопрос есть ли стандартные наборы для оценки качества алгоритма стабилизации?
  13. Работа с камерами

    что-то непонятно... сейчас явно гружу 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 корректный, а связать она почему-то не может.. выводит следующее сообщение
  14. Работа с камерами

    Здравствуйте! Есть IP камера видео передаётся через rtsp вставляю ссылку в vlc и всё работает... абсолютно такая же строка но при коннекте камеры через opencv ничго не происходит... вернее самого конекта не происходит... формат строки rtsp://x.x.x.x:PORT при связывании через vlc видео показывает... ..................... VideoCapture cap; cap.open(filename);//filename - строка конекта ............................ он даже его не открывает...
  15. Haar-like features

    Добрый день! Подумал написать функцию выделения признаков Хаара из изображения для обучения классификаторов как это сделано с 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. Haar-like features

    Ясно тогда понятно почему так много, у меня ещё вопрос т.е. правильно понимаю, что конечно можно выделить из изображения все признаки Хаара, но для распознавания это совсем не лучший вариант, т.е. имеет смысл не просто извлекать признаки, а делать выборку из них ну как это сделано в алгоритме Виолы Джонса
  17. Есть ли базы данных с автомобилями разных типов(грузовые, легковые ну и т.д.) что бы можно было натренировать и протестировать классификатор на базе.
  18. Добрый день, стоит такая задача есть камера типа "рыбий глаз" с него идёт видео и необходимо видео преобразовывать так что бы избавляться от этого эффекта рыбьего глаза или(радиальной дисторсии как я понял) тема для меня достаточно новая, как я понял так как видео идёт с одной камеры и она неподвижна, то откалибровать нормально невозможно.. поэтому пользоваться функцией undistort(frame,dst,cameraMatrix,distCoeffs); так же невозможно, можно ли как-то корректно преобразовать не зная ни cameraMatrix ни distCoeffs... --- В архиве ролик с камеры 3.rar
  19. Подправил код со сферическими координатами теперь он работает гораздо лучше кидаю исправленный код и полученные картинки 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; }
  20. Ок спасибо большое! по первой ссылке есть код SelfCalibration.cpp от Smorodov который должен устранять дисторсии как я понял, скачал попробовал на тестовом изображении с решётками и всё получилось, попробовал на других изображениях.. как-то особо не получилось) привожу картинку
  21. Что получилось, Пробовал устранять дисторсию вручную с помощью 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
  22. Ок спасибо, сейчас займусь)
  23. Вчера увидел проект визуального программирования http://blendocv.damiles.com/ проект как я понял довольно свежий и мне показалось довольно интересный, на страничке есть примеры его работы, так же обещают что скоро будет выпущена первая релизная версия, на страничке проекта написано, что используется библиотека opencv.
×