1

I am currently making a project for school on image processing in visual Studio 2013, using Open CV 3.1. My goal (for now) is to transform an image, using affine transform, so that the trapezoidal board will be transformed into a rectangle.

To do that I have substracted certain channels and thresholded the image so that now I have a binary image with white blocks in the corners of the board. Now I need to pick 4 white points that are closest to each corner and (using affine transform) set them as corners of the transformed image.

And since this is my first time using Open CV, I am stuck.

Here's my code:

#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;
}

As you can see I don't know how to loop over each white pixel using image.at and save the distance to each corner.

I would appreciate some help.

Also: I don't want to just do this. I really want to learn how to do that. But I'm currently having some mindstuck.

Thank you

EDIT:

I think I'm done with finding the coordinates of the 4 points. But I can't really get the idea of the warpAffine syntax.

Code:

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;
            }

        }
    }

Where I set all of the distances values to imageerode.cols+imageerode.rows since it's the maximum value it can get. Also: note that I'm using taxicab geometry. I was told it's faster and the results are pretty much the same.

If anyone could help me with warpAffine it would be great. I don't understand where do I put the coordinates I have found.

Thank you

  • try [`findContours`](http://docs.opencv.org/2.4/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=findcontours#findcontours) – slawekwin Dec 14 '16 at 08:11
  • How about finding the corners instead? Iterate over all pixels that are border pixels (black with an adjacent white pixel) and look if the neighbour border pixels make a turn (that is, a sharp turn, you will probably find no clean way to detect a turn that is close to 180°). Then you have to corners and can easily find the closest white pixels. Or work with the corners directly. – Aziuth Dec 14 '16 at 10:20
  • visual c in school .... it's cool(maybe) – Алексей Неудачин Dec 15 '16 at 11:36
  • I was told exactly that I have to find these 4 points. And I'm not sure how to loop. I understand the logic: I loop over every pixel and take the distance to every corner, then compare with the distance values I've got and choose the smaller one. But I don't know the syntax - how to code it. Any help? – Jakub Oficjalski Dec 15 '16 at 13:46

1 Answers1

0

I am not sure how your "trapezoidal board" looks like but if it has a perspective transform like when you capture a rectangle with a camera, then an affine transform is not enough. Use perspective transform. I think Features2D + Homography to find a known object is very close to what you want to do.

hiroki
  • 381
  • 1
  • 7
  • That's exactly what I meant by trapezoidal board. And I suppose that affine transform might be not enough, but I have to use this very transform for this exercise. – Jakub Oficjalski Dec 15 '16 at 11:57