OpenCV Unity — получить 3D-позицию из 2D-позиции изображения

Я программирую приложение Hololens и пытаюсь создать систему отслеживания в реальном времени. Я буду использовать OpenCV для алгоритма компьютерного зрения. Я видел там, что это возможно, чтобы получить контур цветного объекта -> https://www.youtube.com/watch?v=hQ-bpfdWQh8&т = 26s

Итак, с помощью этого решения я могу получить контур цветовой зоны, а затем получить среднюю позицию в пикселях этой зоны, верно, но как теперь преобразовать эту 2D-позицию в 3D-позицию в системе координат гололинсов?

Я видел там какое-то решение для оценки позы -> http://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_calib3d/py_pose/py_pose.html

Это использует этот метод: https://docs.opencv.org/3.0-beta/modules/cuda/doc/calib3d.html

У меня есть все параметры, которые нужны функции, кроме «объекта», который является положением объекта в 3D, если я правильно прочитал, но у меня нет этого объекта в 3D позе, я пытаюсь его вычислить.

Так вот что у меня так далеко

#include <sstream>
#include <string>
#include <iostream>
#include <vector>

#include "Object.h"
// default capture width and height
const int FRAME_WIDTH = 640;
const int FRAME_HEIGHT = 480;

// max number of objects to be detected in frame
const int MAX_NUM_OBJECTS = 50;

// minimum and maximum object area
const int MIN_OBJECT_AREA = 20 * 20;
const int MAX_OBJECT_AREA = FRAME_HEIGHT * FRAME_WIDTH / 1.5;

// names that will appear at the top of each window
const string windowName = "Original Image";
const string threesholdName = "Threeshold Image";

// List of objects to track
std::vector<Object> objects;string intToString(int number) {

std::stringstream ss;
ss << number;
return ss.str();
}

Object* getObjectByCoord(int x, int y) {
for (Object &o : objects) {
if (o.getXPos() == x && o.getYPos() == y)
return &o;
}

return NULL;
}

void drawObject(Object o, int index, Mat &frame, vector< vector<Point> > contours, vector<Vec4i> hierarchy) {
cv::drawContours(frame, contours, index, o.getColor(), 3, 8, hierarchy);
cv::circle(frame, cv::Point(o.getXPos(), o.getYPos()), 5, o.getColor());
cv::putText(frame, intToString(o.getXPos()) + " , " + intToString(o.getYPos()), cv::Point(o.getXPos(), o.getYPos() + 20), 1, 1, o.getColor());
cv::putText(frame, o.getType(), cv::Point(o.getXPos(), o.getYPos() - 20), 1, 2, o.getColor());
}

void morphOps(Mat &thresh) {

//create structuring element that will be used to "dilate" and "erode" image.
//the element chosen here is a 3px by 3px rectangle
Mat erodeElement = getStructuringElement(MORPH_RECT, Size(3, 3));
//dilate with larger element so make sure object is nicely visible
Mat dilateElement = getStructuringElement(MORPH_RECT, Size(8, 8));

erode(thresh, thresh, erodeElement);
erode(thresh, thresh, erodeElement);

dilate(thresh, thresh, dilateElement);
dilate(thresh, thresh, dilateElement);
}

void trackFilteredObject(Object theObject, Mat threshold, Mat &cameraFeed) {
Mat temp;
threshold.copyTo(temp);

//these two vectors needed for output of findContours
vector< vector<Point> > contours;
vector<Vec4i> hierarchy;

//find contours of filtered image using openCV findContours function
findContours(temp, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);

//use moments method to find our filtered object
double refArea = 0;

if (hierarchy.size() > 0) {
int numObjects = hierarchy.size();

for (int index = 0; index >= 0; index = hierarchy[index][0]) {

Moments moment = moments((cv::Mat)contours[index]);
double area = moment.m00;

if (area>MIN_OBJECT_AREA) {
int x = moment.m10 / area;
int y = moment.m01 / area;

if (getObjectByCoord(x, y) != NULL)
continue;

theObject.setXPos(x);
theObject.setYPos(y);

drawObject(theObject, index, cameraFeed, contours, hierarchy);

break;
}
}
}
}

int main(int argc, char* argv[])
{
//Matrix to store each frame of the webcam feed
Mat cameraFeed;
Mat threshold;
Mat HSV;

namedWindow(windowName, 0);

// Preparing all the objects to track
// Color in BGR and HSV -> SV are to 255
objects.push_back(Object("blue", Scalar(160, 70, 50), Scalar(190, 255, 255), Scalar(255, 252, 123)));

//video capture object to acquire webcam feed
VideoCapture capture;

//open capture object at location zero (default location for webcam)
capture.open(0);

//set height and width of capture frame
capture.set(CV_CAP_PROP_FRAME_WIDTH, FRAME_WIDTH);
capture.set(CV_CAP_PROP_FRAME_HEIGHT, FRAME_HEIGHT);

//start an infinite loop where webcam feed is copied to cameraFeed matrix
//all of our operations will be performed within this loop
waitKey(1000);

while (1) {
capture.read(cameraFeed);

if (!cameraFeed.data)
{
return -1;
}

// Track objects
for (Object &o : objects) {
cvtColor(cameraFeed, HSV, COLOR_BGR2HSV);
inRange(HSV, o.getHSVmin(), o.getHSVmax(), threshold);
morphOps(threshold);
imshow(threesholdName, threshold);
trackFilteredObject(o, threshold, cameraFeed);
}

imshow(windowName, cameraFeed);

//delay 30ms so that screen can refresh.
waitKey(30);
}
return 0;
}

Я могу получить контур объекта в пределах цветового диапазона, но мне нужно перевести 2D-точку в 3D-точку, соответствующую системе координат гололинза. (У меня может быть projectionMatrix и т. Д.)

Кто-нибудь из вас может мне помочь?

1

Решение

Задача ещё не решена.

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

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

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