плохие результаты на расстоянии при использовании стереокамеры - PullRequest
0 голосов
/ 29 мая 2018

Я пытаюсь измерить расстояние в режиме реального времени от стереопары до человека, обнаруженного на сцене.Сначала я калибровал обе камеры по отдельности с помощью шахматной доски 9x6 (размер квадрата 59 мм) и получил среднеквадратичную ошибку между 0,15 и 0,19 для обеих камер.Используя полученные параметры, я откалибровал стереопару, и среднеквадратическая ошибка составила 0,36.Позже я выполнил исправление, не исказил и переназначил стереопару, дав мне такой результат: выпрямленное и неискаженное стерео

Сделав это, я вычислил стерео соответствие, используя стереоSGBM.Вот как я это сделал:

Mat imgDisp= Mat(frame1.cols, frame1.rows,CV_16S);

cvtColor(frame1, frame1, CV_BGR2GRAY);
cvtColor(frame2, frame2, CV_BGR2GRAY);

//parameters for stereoSGBM
  stereo.SADWindowSize = 3;
  stereo.numberOfDisparities = 144;
  stereo.preFilterCap = 63;
  stereo.minDisparity = -39;
  stereo.uniquenessRatio = 10;
  stereo.speckleWindowSize = 100;
  stereo.speckleRange = 32;
  stereo.disp12MaxDiff = 1;
  stereo.fullDP = false;
  stereo.P1 = 216;
  stereo.P2 = 864;

double minVal; double maxVal;
minMaxLoc(imgDisp, &minVal, &maxVal);

return imgDisp; 

Я прикрепил результат от StereoSGBM здесь: Карта диспаратности .

Для обнаружения человека в сцене я использовал hog + svm (dectector people по умолчанию) и отслеживал этого человека с помощью оптического потока (cvCalcOpticalFlowPyrLK ()).Используя карту диспаратности, полученную в процессе стерео соответствия, я получил диспаратность для каждого угла, отслеживаемого одним человеком, следующим образом:

int x= cornersA[k].x;
int y= cornersA[k].y;

short pixVal= mapaDisp.at<short>(y,x); 
float dispFeatures= pixVal/ 16.0f;

с диспаратностью для каждого угла, отслеженного для одного человека в сцене, я вычислил максимуи вычислил глубину в этом пикселе по формуле ((focal * baseline) / disp):

float Disp =maxDisp_v[p];

cout<< "max disp"<< Disp<<endl;
float d = ((double)(879.85* 64.32)/(double)(Disp))/10; //distance in cms.

** для фокусного расстояния я вычислил среднее значение между fx и fy, полученное в матрице камер [3x3] параметры:

CM1: [9.0472706037497187e + 02 0. 3.7829164759284492e + 02
0. 8.4576999835299739e + 02 1.8649783393160138e + 02 0. 0.1.]

CM2: [9.1390904648169953e + 02 0. 3.5700689147467887e + 02 0. 8.5514555697053311e + 02 2.1723345133656409e + 02 0. 0. 1.]

so fx camera1: 904.7;камера 1: 845,7;fx camera2: 913,9;fy camera2: 855.1

** Результат матрицы T [0,0] соответствует базовой линии, которую я измеряю вручную, поэтому я предположил, что это правильная базовая линия.

** из-за размера квадраташахматной доски в мм, я предположил, что базовая линия должна быть в той же единице, поэтому я положил 64,32 мм в базовой линии.

Результат расстояния - приблизительно.55 см, но реальное расстояние составляет 300 см.Я проверял много раз, но измеренное расстояние все еще неверно: distanceResult

Помогите мне, пожалуйста! Я понятия не имею, что я делаю неправильно.

*** Я использую OpenCV 2.4.9 в ОС OSX.

Ответы [ 2 ]

0 голосов
/ 30 мая 2018

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

Использовать cv2.reprojectImageTo3D

0 голосов
/ 29 мая 2018

Я думаю, что вы делаете ошибку с единицами измерения: фокусное расстояние указывается в пикселях, базовая линия указывается в см. Несоответствие указывается в пикселях.Правильно?По формуле у вас есть пикс * см / пикс = см.Но вы делите это на 10 и получаете дм.Таким образом, у вас есть расстояние около 55 дм, которое в два раза больше, чем 300. Это неплохой случай для вашего подхода.

...