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