C ++中的仿射变换

时间:2016-12-13 17:01:47

标签: c++ visual-studio-2013 affinetransform opencv3.1

我目前正在使用Open CV 3.1为Visual Studio 2013中的图像处理创建一个项目。我的目标(目前)是使用仿射变换转换图像,以便将梯形板转换为矩形。

为此,我减去了某些通道并对图像进行了阈值处理,以便现在我在板的角落有一个带有白色块的二进制图像。 现在我需要选择最接近每个角落的4个白点(并使用仿射变换)将它们设置为变换图像的角落。

由于这是我第一次使用Open CV,我被困住了。

这是我的代码:

#include <iostream>
#include <opencv2\core.hpp>
#include <opencv2\highgui.hpp>
#include<opencv2/imgproc.hpp>
#include <stdlib.h>
#include <stdio.h>
#include <vector>


int main(){

    double dist;
    cv::Mat image;
    image = cv::imread("C:\\Users\\...\\ideal.png");

    cv::Mat imagebin;
    imagebin = cv::imread("C:\\Users\\...\\ideal.png");

    cv::Mat imageerode;

    //cv::imshow("Test", image);

    cv::Mat src = cv::imread("C:\\Users\\...\\ideal.png");
    std::vector<cv::Mat>img_rgb;
    cv::split(src, img_rgb);

    //cv::imshow("ideal.png", img_rgb[2] - img_rgb[1]);

    cv::threshold(img_rgb[2] - 0.5*img_rgb[1], imagebin , 20, 255, CV_THRESH_BINARY);
    cv::erode(imagebin, imageerode, cv::Mat(), cv::Point(1, 1), 2, 1, 1);
    cv::erode(imageerode, imageerode, cv::Mat(), cv::Point(1, 1), 2, 1, 1);

    //  cv::Point2f array[4];
    //  std::vector<cv::Point2f> array;

    for (int i = 0; i < imageerode.cols; i++)
    {
        for (int j = 0; j < imageerode.rows; j++)
        {
            if (imageerode.at<uchar>(i,j) > 0)
            {
                dist = std::min(dist, i + j);
            }
        }
    }

    //cv::imshow("Test binary", imagebin);
    cv::namedWindow("Test", CV_WINDOW_NORMAL);
    cv::imshow("Test", imageerode);
    cv::waitKey(0);

    std::cout << "Hello world!";
    return 0;
}

正如您所看到的,我不知道如何使用image.at循环每个白色像素并保存到每个角落的距离。

我将不胜感激。

另外:我不想这样做。我真的想学习如何做到这一点。但我现在有一些心思。

谢谢

编辑:

我想我已经找到了4分的坐标。但我无法真正理解warpAffine语法。

代码:

for (int i = 0; i < imageerode.cols; i++)
{
    for (int j = 0; j < imageerode.rows; j++)
    {
        if (imageerode.at<uchar>(i, j) > 0)
        {

            if (i + j < distances[0])
            {
                distances[0] = i + j;
                coordinates[0] = i;
                coordinates[1] = j;
            }

            if (i + imageerode.cols-j < distances[1])
            {
                distances[1] = i + imageerode.cols-j;
                coordinates[2] = i;
                coordinates[3] = j;
            }

            if (imageerode.rows-i + j < distances[2])
            {
                distances[2] = imageerode.rows - i + j;
                coordinates[4] = i;
                coordinates[5] = j;
            }

            if (imageerode.rows-i + imageerode.cols-j < distances[3])
            {
                distances[3] = imageerode.rows - i + imageerode.cols - j;
                coordinates[6] = i;
                coordinates[7] = j;
            }

        }
    }

我将所有距离值设置为imageerode.cols + imageerode.rows,因为它是可以获得的最大值。 另外:请注意我使用出租车几何。我被告知速度更快,结果几乎相同。

如果有人能用warpAffine帮我,那就太好了。我不明白我在哪里找到我找到的坐标。

谢谢

1 个答案:

答案 0 :(得分:0)

我不确定你的“梯形板”是什么样的,但如果它有一个透视变换,就像你用相机捕捉一个矩形,那么仿射变换是不够的。使用透视变换。我认为Features2D + Homography to find a known object非常接近你想要做的事情。