Как найти расстояние (физическое в м и пикселях) между двумя объектами (точками) на изображении в OpenCV и C +++?

Я использую 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);
}

}
...

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

Центр прямоугольного окна

0

Решение

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

Если:

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

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

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

У нас есть: d_p = k . f . d_M/Z_M

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

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

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]