2016-04-28 1 views
2

j'essaie d'effectuer une analyse de forme pour distinguer les objets rectangulaires à partir des objets non rectangulaires (tels que les demi-cercles) en utilisant des images binairesde forme pour distinguer les rectangles d'autres formes

Quelques exemples possibles

Rectangles

enter image description hereenter image description here

non Rectangles

enter image description hereenter image description here

Mon algorithme fonctionne comme suit:

  1. Extrait du masque d'objet en utilisant les contours - OpenCV (comme vous pouvez le voir dans les exemples ci-dessus)
  2. Effectuer la forme analyser ou calculer des statistiques pour détecter si l'objet est rectangulaire ou non

Jusqu'ici, j'ai essayé des mesures d'excentricité et de rectangularité.

Par exemple: Idéalement, la rectangularité doit être élevée pour les rectangles uniquement. Dans mes expériences, j'obtiens parfois la même rectangularité pour un rectangle ou un objet circulaire. Par conséquent, je ne peux pas utiliser cette mesure pour l'analyse car elle n'est pas fiable

Le même problème se produit avec l'excentricité. Idéalement, un cercle a une excentricité de zéro et pour un objet rectangulaire, il devrait être très élevé. Mais il s'avère être très similaire pour les rectangles ou les cercles

Existe-t-il un moyen de déterminer si l'objet est grossièrement un rectangle ou s'il n'utilise aucune information géométrique?

Toute aide sera vraiment apprécié

+0

S'il vous plaît définir le terme "travail bien", "robuste" et "précis". À quoi ressemble le code d'analyse? Quels sont les résultats attendus? Quels sont les résultats réels que vous obtenez maintenant? –

+0

salut, j'ai édité la question et fourni des détails – user1388142

Répondre

2

Je pense que vous pouvez utiliser approxPolyDP. Je vous donne un programme en C++ et je pense qu'il est facile de traduire en python. L'idée cherche la forme avec quatre coins qui se rapprochent du contour réel et calculent ensuite quatre angles (angle de coin). tandis que le nombre de points de contour est supérieur à 4, l'erreur entre le nouveau contour et le contour réel est augmentée. Vous devez choisir un angle de seuil (90 +/- x °) lorsque vous pensez que ce n'est pas un rectangle. (Désolé pour le mauvais anglais)

#include "opencv2/opencv.hpp" 
#include <iostream> 

using namespace cv; 
using namespace std; 


int main(int argc, char **argv) 
{ 
vector<String> fileName; 
fileName.push_back("2nrTo.jpg"); 
fileName.push_back("G3I4t.jpg"); 
fileName.push_back("Q4ZtM.jpg"); 
fileName.push_back("vWgKx.jpg"); 
for (int i = 0; i < static_cast<int>(fileName.size()); i++) 
{ 
    Mat mThresh; 
    Mat m=imread(fileName[i],CV_LOAD_IMAGE_GRAYSCALE); 
    Mat mc; 
    vector<vector<Point> > contours; 
    vector<Vec4i> hierarchy; 
    threshold(m,mThresh,80,255,THRESH_BINARY); 
    findContours(mThresh,contours,hierarchy, cv::RETR_CCOMP, cv::CHAIN_APPROX_NONE, cv::Point(0,0)); 
    cout << "Image " << fileName[i] << "\n"; 
    imshow(fileName[i],m); 
    mc = Mat::zeros(m.size(),CV_8UC3); 
    drawContours(mc,contours,0,Scalar(255,0,0),1); 
    vector<Point> approx; 
    double d=0; 
    do 
    { 
     d=d+1; 
     approxPolyDP(contours[0],approx,d,true); 
    } 
    while (approx.size()>4); 
    cout << "#vertices =" <<approx.size() << "\t error max= " <<d<<endl; 
    if (approx.size() == 4) 
    { 
     cout << "Angles\n"; 
     Point2d u(approx[1]-approx[0]),v(approx[2]-approx[1]),w(approx[3]-approx[2]),x(approx[3]-approx[0]); 
     cout<<acos(u.dot(v)/norm(u)/norm(v))<<"\n"; 
     cout<<acos(v.dot(w)/norm(v)/norm(w))<<"\n"; 
     cout<<acos(w.dot(x)/norm(w)/norm(x))<<"\n"; 
     cout<<acos(x.dot(u)/norm(x)/norm(u))<<"\n"; 

    } 
    else 
     cout << "looks like a triangle\n"; 
    contours.push_back(approx); 
    drawContours(mc,contours,contours.size()-1,Scalar(0,0,255),1); 
    imshow("Ctr",mc); 
    waitKey(); 
} 

return 0; 
} 

Avec programme images précédentes donne thoses résultats:

Image 2nrTo.jpg 
#vertices =4  error max= 17 
Angles 
93.3283 
90.2247 
90 
93.553 
Image G3I4t.jpg 
#vertices =4  error max= 15 
Angles 
112.503 
46.3837 
110.346 
48.5412 
Image Q4ZtM.jpg 
#vertices =4  error max= 6 
Angles 
88.9191 
90.0297 
88.9488 
90 
Image vWgKx.jpg 
#vertices =4  error max= 49 
Angles 
87.0753 
117.999 
90.3148 
114.76 
+0

Juste pour clarifier. Les angles sont calculés entre les deux points, non? Pouvez-vous expliquer la logique un peu !! Merci – user1388142