2015-04-06 1 views
5

J'ai un ensemble de points discrets représentés dans une image, comme ce qui suit discrete maskOpenCV trouver la coque concave

Je veux reconstruire ou d'échantillonnage (je ne suis pas sûr quelle est la bonne façon de le décrire) la image, de sorte que l'image du résultat serait comme le suivant after-processed mask. Il n'a pas besoin d'être exactement le même que l'image d'exemple, mais l'idée principale est de remplir l'original.

J'ai une idée initiale sur la façon de le faire. Mais je ne sais pas comment le faire après la première étape. Mon idée est de séparer d'abord l'image en utilisant kmeans et de trouver les différents objets. Et j'ai réussi à le faire. Les images résultantes après kmeans sont: object 1 maskobject 2object 3 mask. Après les kmeans, je veux utiliser un contour de recherche ou quelque chose comme concave pour obtenir le contour de ces formes et remplir la forme en utilisant des fonctions comme des trous de remplissage. Cependant, j'ai trouvé "trouver le contour" ne fonctionne pas, il considérera chaque pixel comme un contour.

L'autre façon que je pense est d'utiliser l'interpolation. Mais je ne suis pas sûr que ce soit possible avec des points aussi épars. Est-ce que quelqu'un a des idées sur la façon de faire cela? Je ne sais pas si je suis sur la bonne voie et je suis ouvert à toutes les solutions.

Merci beaucoup!

+1

Je ne pense pas "suréchantillonnage" est le terme que vous recherchez. –

+0

@MarkRansom Oui, je ne sais pas quel est le bon terme à utiliser. Aucune suggestion? – user1964417

Répondre

1

Regardez les transformations morphologiques. Je commencerais par une opération de dilatation en utilisant un gros noyau, disons le MORPH_ELLIPSE avec une taille (15,15). Ensuite, amincissez les blobs en utilisant l'opération d'érosion avec le même grain de taille. Jetez un oeil à la docs here. Notez qu'OpenCV propose également des opérations morphologiques chaînées ou séquencées. Voir here. Vous verrez alors que ma suggestion est une opération de «fermeture».

Mise à jour: J'ai expérimenté avec une simple dilatation et contour pour obtenir les résultats montrés dans l'image. Les résultats semblent satisfaire aux exigences générales du problème.

De même, ce que signifie "en temps réel" pour l'application n'est pas spécifié, mais cet ensemble d'opérations peut être rapidement exécuté et pourrait facilement être appliqué à une application 30fps. Contoured image

Extrait de code ci-dessous:

// Convert image to grayscale 
cvtColor(src, gray, CV_BGR2GRAY); 
threshold(gray, gray, 128.0, 128.0, THRESH_BINARY); 

// Dilate to fill holes 
dilate(gray, dest, getStructuringElement(MORPH_ELLIPSE, Size(13,13))); 

// Find contours 
vector<vector<Point> > contours; 
vector<Vec4i> hierarchy; 
findContours(dest, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0,0)); 

    // Prune contours 
    float maxArea = 0.0f; 
    for (size_t i = 0; i< contours.size(); i++) 
    { 
     if (contourArea(contours[i]) >= maxArea) 
     { 
      maxArea = contourArea(contours[i]); 
     } 
    } 

    float minArea = 0.20f * maxArea; 
    vector<vector<Point> > prunedContours; 
    for (size_t i = 0; i< contours.size(); i++) 
    { 
     if (contourArea(contours[i]) >= minArea) 
     { 
      prunedContours.push_back(contours[i]); 
     } 
    } 

// Smooth the contours 
vector<vector<Point> > smoothedContours; 
    smoothedContours.resize(prunedContours.size()); 
    for (size_t i=0;i<prunedContours.size();i++) 
    { 
    vector<float> x; 
    vector<float> y; 

    const size_t n = prunedContours[i].size(); 

    for (size_t j=0;j<n;j++) 
     { 
     x.push_back(prunedContours[i][j].x); 
     y.push_back(prunedContours[i][j].y); 
     } 

    Mat G; 
    transpose(getGaussianKernel(11,4.0,CV_32FC1),G); 

    vector<float> xSmooth; 
    vector<float> ySmooth; 

    filter2D(x,xSmooth, CV_32FC1, G); 
    filter2D(y,ySmooth, CV_32FC1, G); 

    for (size_t j=0;j<n;j++) 
     { 
     smoothedContours[i].push_back(Point2f(xSmooth[j],ySmooth[j])); 
     } 
    } 
+0

J'ai cependant sur la morphologie. Mais cette méthode n'est pas stable si nous avons différents objets et nous ne pouvons pas le faire en temps réel. – user1964417

+0

Deux commentaires: les opérations de morphes ci-dessus sont raisonnablement rapides et peuvent probablement être accélérées en GPU (selon la plateforme). Pouvez-vous clarifier "pas stable"? Cela semble une autre contrainte sur votre problème puisque les opérations de morphing sont généralement considérées comme stables (dans le sens où elles fonctionnent sans grande surprise) – Throwback1986

+0

Ce que je veux dire par pas stable est la morphologie dépend de quel objet vous utilisez et comment les différents objets apparaissent comme. Mon système a besoin de travailler en temps réel, quel que soit l'objet, il doit être fait sans accorder les paramètres pour la morphologie. – user1964417