2017-02-10 11 views
0

Im, использующий OpenCV и C++. Я уже сделал код, где можно найти центр объекта. У меня также есть предварительная информация о расстоянии между камерой и объектом (объектами) на изображении. Мне нужно вычислить расстояние (реальное физическое в m или см, а также одно в пикселях) между двумя объектами изображения или между двумя центрами этих объектов).Как найти расстояние (физическое в м и пикселях) между двумя объектами (точками) на изображении в OpenCV и C+++?

Это код, который поможет вам найти момент центра прямоугольного объекта. Аналогичным подходом было бы найти центр другой формы (объекта).

int main(int argc,char** argv) 
{ 

      Mat image = imread("000167.png"); 
      Mat gray,bw,dil,erd, dst_final; 
     Mat new_src=image.clone(); 

    for(int y = 0; y < image.rows; y++) 
    { 
     for(int x = 0; x < image.cols; x++) 
     { 
       for(int c = 0; c < 3; c++) 
       { 
        new_src.at<Vec3b>(y,x)[c]= saturate_cast<uchar>(1.5*(image.at<Vec3b>(y,x)[c])); 

       } 
     } 
    } 


     cv::GaussianBlur(new_src, src_gray, cv::Size(3,3),1,1,BORDER_DEFAULT); //original 
     medianBlur(new_src, src_gray, 11); 
     blur(new_src, src_gray, Size(3,3)); 
     cvtColor(src_gray,gray,CV_BGR2GRAY); 
     Canny(gray,bw,600,1200,5,true); 
        Mat grad,bw1; 
        Mat morphKernel = getStructuringElement(MORPH_ELLIPSE, Size(20,10)); 
        morphologyEx(bw, grad, MORPH_GRADIENT, morphKernel);   
        threshold(grad, bw1, 255.0, 255.0, THRESH_BINARY | THRESH_OTSU);     

      vector<vector<Point> > contours; 
     vector<vector<Point> > rough; 
     vector<vector<Point> >rough_color; 
     vector<vector<Point> >precise; 
      vector<Vec4i> hierarchy; 
     Mat dst = image.clone(); 
      findContours(bw1.clone(), contours, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE); 

     vector<Point> approx; 

     for(int i = 0; i< contours.size(); i++) 
     { 

      approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true) * 0.01, true); 
      if (fabs(contourArea(approx)) <2000 || fabs(contourArea(approx))>50000)          
       continue; 

        Rect r = boundingRect(contours[i]); 
        if((float) (r.height/r.width) > 1.5 && (float) (r.height/r.width) <3) 
        { 
        rough.push_back(approx); 
        } 
     } 

     for(int i = 0; i < rough.size(); i++) 
     { 
      Rect bound=boundingRect(rough[i]); 
      Rect x, y, w, h = boundingRect(rough[i]); 
      rectangle(dst,Point(bound.br().x,bound.br().y), Point(bound.tl().x,bound.tl().y),Scalar(255, 0, 0),2); 
      RotatedRect rectPoint = minAreaRect(rough[i]); 

       Point2f fourPoint2f_rough[4]; 
       rectPoint.points(fourPoint2f_rough); 
      vector<Point> fourPoint_rough; 
      for(int i = 0; i <4; i++) 
     { 
      fourPoint_rough.push_back(fourPoint2f_rough[i]); 
     } 


     { 
      line(dst, fourPoint2f_rough[i], fourPoint2f_rough[i + 1], Scalar(255,0,0), 3); 
     } 
     line(dst, fourPoint2f_rough[0], fourPoint2f_rough[3], Scalar(255,0,0), 3); */ 
     } 

     if(rough.size() !=0) 
     { 
     for(int i = 0; i< rough.size(); i++) 
     { 
      vector<Moments> mu(1); 
      vector<Point2f> mc(1); 
      int gray_level; 
      // compute the central momment 
      mu[0] = moments(rough[i], false); 
      mc[0] = Point2f(mu[0].m10/mu[0].m00 , mu[0].m01/mu[0].m00); 
      circle(dst, mc[0], 4, Scalar(0,0,255), -1, 8, 0); 
      gray_level=gray.at<uchar>(mc[0]); 
      if(gray_level<200 && gray_level>20) 
      {rough_color.push_back(rough[i]);} 
     } 


     for(int i = 0; i < rough_color.size(); i++) 
     { 
      Rect bound=boundingRect(rough_color[i]); 
      Rect x, y, w, h = boundingRect(rough_color[i]); 
      RotatedRect rectPoint = minAreaRect(rough_color[i]); 
       Point2f fourPoint2f_color[4]; 
       rectPoint.points(fourPoint2f_color); 
     vector<Point> fourPoint_color; 
     for(int i = 0; i <4; i++) 
     { 
      fourPoint_color.push_back(fourPoint2f_color[i]); 
     } 


     for (int i = 0; i < 3; i++) 
     { 
      line(dst, fourPoint2f_color[i], fourPoint2f_color[i + 1], Scalar(0,255,0), 3); 
     } 
     line(dst, fourPoint2f_color[0], fourPoint2f_color[3], Scalar(0,255,0), 3); 
     } 

     } 
... 

Так просто нужен код, чтобы получить расстояние (реальное в см или м и один в пикселях) между этими двумя моментами центра (два центра объектов в изображении). Я включаю исходное изображение центра в окне прямоугольника (красная точка в окне). Поэтому в этом случае я хотел бы вычислить расстояние между окном и знаком «ОТКРЫТЬ».

Center of rectangular window

+0

Непонятный. Какова взаимосвязь между кодом, который вы опубликовали, и задачей, которую вы намереваетесь сделать? Вы запрашиваете как метрическое, так и пиксельное расстояние. Для последнего, разве это не очевидно, если у вас есть координаты центров? Для метрического расстояния это невозможно с помощью одной камеры, если вы не знаете расстояние между камерой и объектами. Не могли бы вы изменить вопрос и уточнить? – kebs

+0

ОК. Код - это найти центр объекта. В этом случае это окно двери самолета. Очистить? Хорошо да, если координаты пикселей этих двух центров легче, чем просто. В моем вопросе я указал, что уже знаю расстояние между камерой и объектом.Я сказал, что у меня есть расстояние между камерой и объектом, я знаю, что информация, полученная ранее, может измерить это расстояние с помощью лазера. – user3035413

+0

Теперь ясно? Так что просто нужно найти метрическое расстояние, зная расстояние между камерой и объектами. ОК? – user3035413

ответ

1

Этот ответ о получении метрики расстояния между двумя точками.

Если:

  • две точки находятся на (геометрической) плоскости, перпендикулярной к оптической оси камеры
  • у вас есть расстояние между центром камеры и плоскости

то метрика расстояние между этими двумя точками может быть вычислено с помощью основы проекции:

  • d_m: метрическое расстояние между двумя точками (м.)
  • d_p: расстояние пикселя между двумя точками
  • F: (м.) Фокусное
  • к: NBE пикселей на метр датчика камеры (= 1/пс, пс: размер пикселя, Ususally от 5 до 10 мкм)
  • z_M:. расстояние между двумя точками (м)

Мы имеем: d_p = k . f . d_M/Z_M

так: d_M = d_p . z_M/(k.f)

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

+0

Да, я понимаю – user3035413