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:
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.
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
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.
calculer le centre du cercle
juste la moyenne de tous les points de frontière …
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
.
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))
où 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
[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