Quelle est la meilleure façon d'estimer la mesure des choses photographiées?

Mon application est censée estimer la longueur (en millimètres) d'un object en utilisant des pièces en euros comme reference. Ceci est un exemple de capture d'écran:

entrez la description de l'image ici

Pour get le diamètre de la pièce photographiée, je calcule d'abord l'équation d'un cercle passant par ces 3 points de la forme

x^2 + y^2 + ax + by + c = 0

et puis j'ai le diamètre de

2 * square_root((a/2)^2 + (b/2)^2 -c) .

Enfin, je peux effectuer la proportion suivante pour get la longueur du stylo rouge:

 /* length_estimated_pen (mm) : distance_green_pins (points) = real_diameter_coin (mm) : diameter_on_screen (points) */ let distanceGreen:Double = Double(sqrt(pow(self.greenLocationA.center.x - self.greenLocationB.center.x, 2.0) + pow(self.greenLocationA.center.y - self.greenLocationB.center.y, 2.0))) let estimatedMeasure:Double = (distanceGreen * Double(ChosenMeter.moneyDiameter)) / diameter 

où dans ChosenMeter.moneyDiameter est stocké le diamètre réel de la pièce choisie (en cliquant sur l'un des 3 buttons ci-dessous).

J'ai besoin de travailler avec Double au lieu de CGFloat parce que ce tutoriel pour résoudre un système d'équations linéaires (pour get une équation de coefficient de cercle a, b, c) fonctionne avec Double.

Le problème est que la longueur estimée du stylo rouge est toujours surestimée de plus de 10 mm. Je suppose que je devrais appliquer un facteur de correction ou compliquer le calcul en tenant count d'autres facteurs, mais lequel? Pouvez-vous me donner quelques indices? Toute aide serait utile pour moi.

    1. find la pièce (rectangle de délimitation green )

      soit manuellement, soit par une search de couleur spécifique, de motif, de transformation de hough, de segmentation … Cela limitera la zone à searchr pour les prochaines étapes

    2. find la limite (bord red distinct de l'intensité de la couleur)

      alors créez une list de points qui sont la limite de la pièce (attention aux ombres), scannez juste pour des bosses d'intensité assez élevée.

    3. calculer le centre du cercle

      juste la moyenne de tous les points de frontière …

    4. tester tous les points limites pour la distance min/max au centre

      Si l'inclinaison est faible, vous aurez de nombreux points avec un rayon min et max donc prenez le milieu d'eux. Si le |max-min| est très petit alors vous n'avez pas d'inclinaison. La ligne entre le sharepoint distance min / max et le centre vous donne black vectors de base black .

    5. utiliser black vectors de base black pour mesurer

      Sélectionnez donc 2 points (ligne red d) pour mesurer et lancer green rayons green parallèlement aux vectors de base. Leur intersection va créer 2 lignes a,b . de cela c'est facile:

      • d = sqrt((a*a)+(b*b))

      a,b est la taille des lignes en unités. vous pouvez l'get comme:

      • a_size_unit = a_size_pixel * coin_r_unit / rmax_pixel
      • b_size_unit = b_size_pixel * coin_r_unit / rmin_pixel

    pièce de monnaie

    [Remarque]

    Cette image a été sélectionnée pour souligner l'inclinaison mais vous devez utiliser des images de plans presque parallèles à la surface de la puce pour éviter la distorsion de la perspective. Cette image n'est pas un bon exemple, le cube est plus éloigné de la camera que de la pièce …

    Pour en tenir count, voir les critères de sélection pour différentes projections