2016-12-13 4 views
0

Je réalise actuellement un projet d'école de traitement d'image dans Visual Studio 2013, en utilisant Open CV 3.1. Mon but (pour le moment) est de transformer une image, en utilisant une transformation affine, de sorte que le tableau trapézoïdal se transforme en un rectangle. Pour ce faire, j'ai soustrait certains canaux et seuillé l'image de sorte que j'ai maintenant une image binaire avec des blocs blancs dans les coins de la carte. Maintenant, je dois choisir 4 points blancs qui sont les plus proches de chaque coin et (en utilisant une transformation affine) les définir comme des coins de l'image transformée.Transformation affine en C++

Et puisque c'est ma première fois en utilisant Open CV, je suis bloqué.

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

Comme vous pouvez le voir, je ne sais pas comment faire une boucle sur chaque pixel blanc en utilisant image.at et enregistrer la distance à chaque coin.

J'apprécierais de l'aide.

Aussi: Je ne veux pas juste faire ça. Je veux vraiment apprendre à faire ça. Mais je suis en train d'avoir un peu d'esprit.

Merci

EDIT:

Je pense que je suis fait de trouver les coordonnées des 4 points. Mais je ne peux pas vraiment avoir l'idée de la syntaxe warpAffine.

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

     } 
    } 

Où je toutes les valeurs des distances à imageerode.cols + imageerode.rows car il est la valeur maximale qu'il peut obtenir. Aussi: notez que j'utilise taxicab géométrie. On m'a dit que c'est plus rapide et que les résultats sont à peu près les mêmes.

Si quelqu'un pouvait m'aider avec warpAffine ce serait génial. Je ne comprends pas où je mets les coordonnées que j'ai trouvées.

Merci

+0

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

+0

Que diriez-vous de trouver les coins à la place? Itérer sur tous les pixels qui sont des pixels de bordure (noir avec un pixel blanc adjacent) et regarder si les pixels de la bordure voisine font un tour (c'est-à-dire un virage serré, vous ne trouverez probablement aucun moyen propre de détecter un virage proche de 180 °). Ensuite, vous avez des coins et pouvez facilement trouver les pixels blancs les plus proches. Ou travaillez directement avec les coins. – Aziuth

+0

visuel c à l'école .... c'est cool (peut-être) –

Répondre

0

Je ne sais pas comment votre « carte trapézoïdale » ressemble mais si elle a une perspective de transformer comme lorsque vous capturez un rectangle avec une caméra, puis une transformation affine ne suffit pas. Utilisez la transformation de perspective. Je pense que Features2D + Homography to find a known object est très proche de ce que vous voulez faire.

+0

C'est exactement ce que je voulais dire par un panneau trapézoïdal.Et je suppose que cette transformation affine pourrait ne pas suffire, mais je dois utiliser cette transformation pour cet exercice. –