2016-12-13 111 views
0

我目前正在使用Open CV 3.1爲Visual Studio 2013中的圖像處理學校開發一個項目。我的目標(現在)是使用仿射變換來轉換圖像,以便將梯形板轉換成矩形。C++中的仿射變換

要做到這一點,我已經減少了某些渠道和閾值的圖像,所以現在我有一個在板的角落有白色塊的二進制圖像。 現在我需要選擇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並保存到每一個角落的距離在每個白色像素循環。

我將不勝感激。

另外:我不想這樣做。我真的想學習如何做到這一點。但我現在有一些mindstuck。

謝謝

編輯:

我覺得我與發現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來幫助我,那就太好了。我不明白我把我找到的座標放在哪裏。

謝謝

+0

嘗試['findContours'](http://docs.opencv.org/2.4/modules/imgproc/doc/structural_analysis_and_shape_descriptors.html?highlight=findcontours#findcontours) – slawekwin

+0

如何找到角落?迭代邊界像素的所有像素(黑色與相鄰的白色像素)並查看相鄰邊界像素是否轉彎(即急轉彎,您可能找不到乾淨的方式來檢測接近180度的轉彎°)。然後你必須轉彎,並可以很容易地找到最接近的白色像素。或直接與角落工作。 – Aziuth

+0

視覺c在學校....它很酷(也許) –

回答

0

我不知道如何你的「梯形板」的模樣,但如果它有一個透視變換,當你捕捉一個矩形用相機一樣,那麼仿射變換是不夠的。使用透視變換。我認爲Features2D + Homography to find a known object非常接近你想要做的事情。

+0

這就是我所說的梯形板。我認爲仿射變換可能還不夠,但我必須在這個練習中使用這種變換。 –