2015-04-01 2 views
2

Я пытаюсь отобразить изображение, которое содержит эти точки, нарисованные как прямоугольники, используя верхнюю левую точку и нижние правые точки, хотя у меня есть точки как четырехугольникиUnwarping набор прямоугольников для создания квадратной сетки в OpenCV

enter image description here

Я пытаюсь отобразить изображение с вышеперечисленными квадратов ниже квадратов:

enter image description here

Я считаю, что я должен получить в перспективе пла nsform от каждого квадрата. Вот код, который я написал, чтобы попытаться облегчить это:

cv::Mat output = cv::Mat::zeros(outputSize,CV_32F); 


    // Uses the size of the quadOutput to 
    std::vector<std::vector<cv::Point2f>> quadOutputImage = quadralateralsFromImageOutput(imageToWarp.size().height); 

    cv::Mat perspectiveMatrix = cv::Mat(3,3,CV_32F); 

    cv::Mat warp = cv::Mat::zeros(outputSize,CV_32F); 

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

      // get the mapping from the quadtriangles 
      perspectiveMatrix = cv::getPerspectiveTransform(quadCentroids[i],quadOutputImage[i]); 

      // perform the warp with the current quadtriangles 
      cv::warpPerspective(imageToWarp,warp,perspectiveMatrix,output.size()); 

      // copy roi to output 

    } 

    return warp; 

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

Редактировать

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

cv::Mat warpedImageGeneration(const cv::Mat& imageToWarp,cv::Size outputSize, std::vector<std::vector<cv::Point2f>> quadCentroids) {   

    // Uses the size of the quadOutput 50 by 50 squares 
    std::vector<std::vector<cv::Point2f>> quadOutputImage = quadralateralsFromImageOutput(450); 

    // flatten the matrices 
    std::vector<cv::Point2f> flattenedQuads = flattenMatrix(quadOutputImage); 
    std::vector<cv::Point2f> flattenedCentroids = flattenMatrix(quadCentroids); 

    cv::Mat perspectiveMatrix = cv::Mat(3,3,CV_32F); 

    cv::Mat warp = cv::Mat::zeros(450,450,CV_32F); 

    perspectiveMatrix = cv::findHomography(flattenedCentroids, flattenedQuads); 

    cv::warpPerspective(imageToWarp, warp, perspectiveMatrix, warp.size()); 

    return warp; 
} 

На примере изображения, это unwarped результат я получаю:

enter image description here

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

+0

Если вы знаете точные координаты, где каждый из четырехъядерных исходное изображение отображается в искаженном, попробуйте определить ** одну ** перспективную матрицу преобразования, которая объединяет все эти соответствия вместе. В частности, взгляните на все угловые точки для каждого квадрата в исходном изображении, определите, где они должны отображаться в искаженном изображении, и определите одну матрицу перспективного преобразования, описывающую все эти точки. Таким образом, когда вы указываете точки исходного изображения, они должны точно отображать искаженные точки в извращенном состоянии, а все остальное должно интерполировать чисто. – rayryeng

+0

Как получить одну матрицу преобразования перспективы из всех квадратов в одном изображении? –

+0

Легко. У вас уже есть код, который содержит вектор вектора точек для каждого соответствующего квадрата для входного и искаженного изображения. Вы получаете доступ к каждому вектору и указали это в 'getPerspectiveTransform', чтобы получить матрицу перспективного преобразования для каждого квадрата. Просто укажите ** один ** вектор для ввода и ** один ** вектор для искаженного изображения, который содержит ** все ** четырех точек, а затем сделать ** одиночный ** вызов 'getPerspectiveTransform'. Очевидно, что порядок важен, поэтому убедитесь, что каждое местоположение квада во входном изображении соответствует расположению вывода искаженного изображения. – rayryeng

ответ

1

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

С точкой зрения реализации, имеет два vector контейнеров, где один контейнер содержит все источник точек изображения и другой vector контейнера, который содержит все искривленных точек изображения. Порядок имеет значение, поэтому убедитесь, что каждое место в контейнере источника vector соответствует тому же месту на извращенном контейнере vector.

Однако, вам нужно будет переключать передачи и использовать вместо этого findHomography. findHomography - это более общий случай getPerspectiveTransform тем, что вы определяете матрицу преобразования, которая наилучшим образом разбивает один набор точек на другой набор точек с наименьшим количеством ошибок. getPerspectiveTransform позволяет указывать только 4 балла. findHomography позволяет указать столько очков, сколько вы хотите.

Если вы хотите изменить это на свою текущую структуру, у вас уже есть код, который содержит вектор вектора точек для каждого соответствующего квадрата для входного и искаженного изображения.Вы получаете доступ к каждому вектору и указываете это на getPerspectiveTransform, чтобы получить матрицу перспективного преобразования для каждого квадрата. Просто укажите один вектор для ввода и один вектор для искаженного изображения, который содержит все четыре точки, а затем сделайте один вызов findHomography. Очевидно, что порядок важен, поэтому убедитесь, что каждое местоположение квада во входном изображении соответствует расположению вывода искаженного изображения.

Также убедитесь, что ваша система координат верна. Конструкции OpenCV Point предполагают, что x - это горизонтальный координата, а y - вертикальный координаты. Как вы разместили изменения, которые я указывал в своей первоначальной должности, я буду размещать их здесь для полноты и сделать ответ самодостаточный:

cv::Mat warpedImageGeneration(const cv::Mat& imageToWarp,cv::Size outputSize, std::vector<std::vector<cv::Point2f>> quadCentroids) { 

    // Uses the size of the quadOutput 50 by 50 squares 
    std::vector<std::vector<cv::Point2f>> quadOutputImage = quadralateralsFromImageOutput(450); 

    // flatten the matrices 
    std::vector<cv::Point2f> flattenedQuads = flattenMatrix(quadOutputImage); 
    std::vector<cv::Point2f> flattenedCentroids = flattenMatrix(quadCentroids); 

    cv::Mat perspectiveMatrix = cv::Mat(3,3,CV_32F); 

    cv::Mat warp = cv::Mat::zeros(450,450,CV_32F); 

    perspectiveMatrix = cv::findHomography(flattenedCentroids, flattenedQuads); 

    cv::warpPerspective(imageToWarp, warp, perspectiveMatrix, warp.size()); 

    return warp; 
} 
Смежные вопросы