Holy_Goat | woensdag 25 april 2012 @ 15:51 | |||
Het moet allemaal niet zo moeilijk zijn, denk ik zo, maar ik kom er niet goed uit. Ik heb een 3D sensor (xtion pro live) , en deze levert mij een point cloud op (X,Y,Z). Het camera-assenstelsel is dus bekend. (X,Y,Z) De camera is willekeurig gemonteerd en gericht op een tafel. Het vlak kan ik eenvoudig detecteren, evenals de normaal loodrecht op dit vlak. Op de tafel definieer ik een nieuw assenstelsel (X,Y,Z) op een hoekpunt van de tafel. Samenvattend; de positie en orientatie van beide assenstelsels zijn bekend. Ik wil nu alleen van een xyz punt in assenstelsel 1 naar een xyz punt in assenstelsel 2 ![]() Hoe kan ik dit het beste aanpakken? | ||||
Azreal | woensdag 25 april 2012 @ 16:47 | |||
Je zult de XYZ waarden die je uit de camera krijgt moeten schalen naar de XYZ van het assenstelsel dat je op je tafel gedefinieerd hebt (m.a.w. is een afstand van 1 op de x-as, y-as of z-as gelijk aan een afstand van 1 op de x-,y-of z-as van de tafel, zo nee, waarmee moet je elke as vermenigvuldigen). Denk eraan dat niet elke as met dezelfde waarde geschaald hoeft te zijn! Verder kun je ervoor zorgen dat er geen (of een verwaarloosbare) rotatie is tussen je assenstelsels, dan volstaat een simpele translatie voor elke as, dus iets als Xkamer = Xcamera + A, etc A is hierin een constante. Indien er wel een rotatie is kun je met een lineaire transformatie ook nog wel in de buurt komen, dan krijg je iets als Xkamer = a*(Xcamera) + b*(Ycamera) + c*(Zcamera) + een of andere constante. a,b en c zijn wederom constanten. Wil je het helemaal leuk maken dan zul je ook rekening moeten gaan houden met dingen als lensvervorming. Maar daar wil ik niet eens aan denken ![]() Wat ga je ermee doen? | ||||
Holy_Goat | woensdag 25 april 2012 @ 20:22 | |||
Azreal, bedankt voor je reactie. Ik denk persoonlijk niet dat ik te maken ga krijgen met distortions, of met schaling anderzijds. Het zit als volgt. Ik heb natuurlijk ontzettend veel puntjes, maar stel we doen het even voor 1 puntje, en dat de situatie er als volgt uitziet. ![]() Vanuit de camera (bv kinect), krijg ik "exact" in mm van de betreffende punten P en Q door wat hun X,Y,Z coordinaat is in camera space. Let wel op, ik heb de afstanden aangegeven, maar eigenlijk weet ik die dus niet. Het enige wat ik zeker weet zijn de camera coordinaten, in mm nauwkeurig in camera space. Camera space is qua afstanden gelijk aan world/table space al is er een offset in angle en ook een positie offset. Op punt P creeer ik de table space origin. Dit doe ik door het vlak te detecteren, eerst een normaal en offset van de tafel te berekenen. Nu dacht ik: ik weet exact (in camera space) hoeveel x,y,z offset de origin van deze nieuwe table coordinatenset heeft ten opzichte van mijn camera center. Ook weet ik, door de X en Z as langs de tafel te leggen, de orientatie van dit assenstelsel ten opzichte van de camera. Dan zou je denken dat je dus een punt dat, zeg, in camera space wel " eenvoudig " kunt uitdrukken in tablespace. Ik kom alleen niet echt verder. Ik zit bijvoorbeeld vast met: hoe bepaal ik het verschil in hoeken tussen beide coordinatenstemen bijvoorbeeld? Ohja, ik wil het gebruiken in eerste instantie voor mijzelf, wat spelen, maar wil ook kijken of het leuk te gebruiken is in een force feedback systeempje voor een project op de TUDelft dat ik eventueel kan gaan doen. | ||||
Asphias | donderdag 26 april 2012 @ 01:35 | |||
je zal de hoeken moeten opmeten. dit kan je bijvoorbeeld doen door een aantal objecten te leggen op een bekende coördinaat van de table space(even met een meetlat kijken welke coördinaat precies waar zit op de tafel) en dan met de camera de cameraspace coördinaten te bereken. als we de coördinaten van de table space X Y en Z noemen, en die van de camera space X', Y' en Z', dan geld de volgende relatie: X=Cos(Hoek tussen X en X') * X' + Cos(Hoek tussen X en Y') * Y' + Cos(Hoek tussen X en Z') * Z' + OFFSET Y=Cos(Hoek tussen Y en X') * X' + Cos(Hoek tussen Y en Y') * Y' + Cos(Hoek tussen Y en Z') * Z' + OFFSET Z=Cos(Hoek tussen Z en X') * X' + Cos(Hoek tussen Z en Y') * Y' + Cos(Hoek tussen Z en Z') * Z' + OFFSET het eerste deel met de cosinusen is om de rotatie van je camera te veranderen. de OFFSET is in hoeverre het nulpunt verschoven is. in je voorbeeldplaatje is dat dus -700 voor X, -600 voor Y, en 1000 voor Z. | ||||
Asphias | donderdag 26 april 2012 @ 01:40 | |||
oh sorry, ik las even overheen dat je de hoek zelf niet kon bepalen. ik zou dit doen door, zoals ik zei, testobjecten. de relatie hierboven gegeven geldt in principe altijd (kijk btw als je geintereseerd bent eens waarom deze relatie klopt ![]() | ||||
Holy_Goat | donderdag 26 april 2012 @ 10:01 | |||
mijn 'testobject' is eigenlijk de tafel al ![]() Ik heb nu eea uitgestippeld, zoals ik denk dat het wel eens zou gaan kunnen werken, maar ben er nog niet zeker van. Dit is een voorbeeldopname, met (nu even handmatig) een assenstelsel erin gedefinieerd op de hoek van de tafel. (tablespace) Ik weet in camera coordinaten ook wat de exacte XYZ coordinaten zijn van de hoeken links voor (LV) en rechtsvoor (RV). LV = [-324,-110,636] RV = [214, -151, 598] Mijn tafel is 54.5cm groot, en de euclidische afstand tussen LV en RV (op het ook geklikt) is 541mm, dus zit aardig in de buurt. (geen scaling nodig) Na translatie / rotatie moet het dus worden: LV = [0,0,0] RV = [~545, 0, 0] ![]() ![]() mijn plan beschrijf ik hieronder even | ||||
Holy_Goat | donderdag 26 april 2012 @ 10:16 | |||
Ik vraag mij dus af of het volgende zou gaan werken. Stel ik neem als normaalvector vanuit mijn camera vlak de Z-as. Ik heb ook de normaal van LV loodrecht op het tafelblad. Als voorbeeld neem ik even twee willekeurige vectoren in R3
Uitkomst klopt met verwachting want inderdaad, er is maar rotatie om 1 as (cross product 2 normalen geven de axis, en dat is hetzelfde resultaat)
Wat ik me dan nu bedenk, is dat dit kennelijk inderdaad de rotation matrix is waar ik naar op zoek ben. Immers, m*camnormal = tablenormal. Alleen denk ik dat ik er dan nog niet helemaal ben. Waarom niet? - Z as cam space is denk ik nu wel ' gedraaid ' om parallel to lopen met Z as tablespace, maar hij is in ieder geval nog niet echt OP dezelfde as denk ik zo, alleen parallel aan. (daar heb ik ws offset voor nodig). - Verder; hoewel de Z as dan 'klopt', dan kloppen de X en Y assen toch nog niet per definitie? Moet ik hierna dan nog eens gaan roteren om de Z as? | ||||
Asphias | donderdag 26 april 2012 @ 10:29 | |||
oh, hip. je kent matrixen. ik dacht daar hou ik mn mond even over omdat het dan gelijk weer ingewikkeld wordt. ik zal zometeen ff kijken naar t probleem zoals je het nu schetst. | ||||
Holy_Goat | donderdag 26 april 2012 @ 11:14 | |||
oh , trouwens, hier nog een afbeelding van de 'tafel' plus automagische plaatsing en bepaling van de normaal op een hoekpunt. (let wel, heb zeer strakke ransac threshold gepakt +-3mm, vandaar rode vlekjes) de gegeven normaalvector is (eigenlijk) wel de Y as overigens in table space. De X en Z kan ik wel bepalen door in ieder geval 1 ander hoekpunt te gaan pakken van de tafel, vector ernaar toe (X!) en dan orthogonaal de andere er bij te pakken door cross product (Z!) ![]() | ||||
Azreal | donderdag 26 april 2012 @ 21:21 | |||
Punt 1: Klopt, je moet nog transleren met [324 0 0, 0 110 0, 0 0 -636] uitgaande van coordinaten voor LV in een eerdere post. Stel we noemen deze matrix t, dan krijg je tablenormal = m*camnormal + t Punt 2: Als je alleen de vector alignt (zoals je nu doet) heb je daar inderdaad een punt mee. Je zou om de Z as kunnen gaan draaien, maar ik denk dat het ook wel mogelijk is om na de eerste align de X assen te alignen. Ben je ook nog van plan automatisch de hoek van de tafel te detecteren of wordt dat point & click? [ Bericht 2% gewijzigd door Azreal op 26-04-2012 21:35:32 ] | ||||
Azreal | donderdag 26 april 2012 @ 21:35 | |||
Correctie op punt 1, de matrix moet [1 0 0 324, 0 1 0 110, 0 0 1 -636, 0 0 0 1] zijn en die vermenigvuldig je met een vector [x y z 1]. Zoals ik gisteren al zei, ik ben er alweer even uit... | ||||
Holy_Goat | donderdag 26 april 2012 @ 22:18 | |||
Wat heb jij gedaan dan qua opleiding en werk Azreal? En jij Asphias? Bedankt voor de antwoorden so far trouwens ![]() ![]() Het komt mij enigszins bekend voor nu trouwens, die 3x3 (added) matrix die je in de laatste post maakte. Echter, hier komt toch een 4x1 uit? Alleen de eerste drie gebruiken toch? De hoeken van de tafel worden automagisch gedetecteerd trouwens. Geen rocket science. Even samenvattend.... ik zal later voor de volledigheid van deze post ook even een document welke ik aan het maken ben printscreenen / kopieren, zodra het goed werkt. Over je punt 2 comment: De X assen alignen zou moeten kunnen ja, bv alignen met de vector LV -> RV? Alleen heb ik lichte twijfels of de Z as dan wel fixed blijft qua richting. Wellicht zal ik dan RV in ieder geval op dezelfde Z moeten zetten (forced) als LV. (onnauwkeurigheid in XY qua uitlijnen is minder belangrijk dan de richting van Z) Er begint ook iets te dagen over een homogeneous matrix trouwens, waar Rot. en Trans al in zitten. note: best wel wat translaties nodig eigenlijk! Pc = punt in cam space Pt = punt in table space R1 en R2=Rot mat. T=Trans mat Pc > rotatie > translatie > rotatie > Pt ![]() | ||||
Asphias | donderdag 26 april 2012 @ 23:41 | |||
pfft.. ik ben het even kwijt hoor. qua achtergrond ben ik eersteajaars wiskunde student. het eerste half jaar Lineaire algebra A gehad, en ik begin morgen met lineaire algebra B. anyway, het komt er op neer dat je eerst met een rotatiematrix (3d rotatie matrix kwam bij mij maar heel kort aan bod, dus weet niet meer hoe je die moet opstellen...) de assen goed zet, en dan een translatiematrix erbij optelt. hoop dat je er uit komt, succes ![]() [ Bericht 0% gewijzigd door Asphias op 27-04-2012 00:06:19 ] | ||||
yarnamc | vrijdag 27 april 2012 @ 13:25 | |||
Ik heb het allemaal eens heel vluchtig overlezen, maar volgens mij is dit helemaal niet zo moeilijk eigenlijk. Je gaat voor zover ik lees, vergeef het me als ik over dingen gelezen heb, verkeerd te werk: je bent affien aan het transformeren, en dat wil je juist niet doen, aangezien je van basis verandert. Ik baseer me hiervoor op de formule die ik in een van de posts zag: "tablenormal = m*camnormal + t". Deze formule zou kloppen als het een affiene transformatie was. Maar het klopt wel dat affiene en coordinatenmatrices in elkaar overget kunnen worden, maar zo maak je het misschien onnodig moeilijker. Eerst en vooral zou ik voor het gemak de assen herbenoemen (y en z omwisselen), als dit geen verschil maakt, zodat je een rechtshandige basis hebt (momenteel heb je de minder gebruikte linkshandige basis gekozen). Bovendien ga ik ervan uit dat je assenstelsel genormeerd is. Dan druk je de nieuwe basisvectoren (op de tafel) lineair uit in functie van die van de oude basis. Daarbij komt enkel wat trigonometrie voor. Je basisvectoren zijn genormeerd, je mag dus doen alsof je in de goniometrische cirkel werkt, er komt, als ik juist zie: e'(x) = e(x) e'(y) = cos(a)*e(y) - sin(a)*e(z) e'(z) = cos(a)*e(z) + sin(a)*e(y) (hierbij heb ik de z en y as al omgewisseld, in jouw figuur; a = hoek die de y-as maakt met het tafelvlak. Deze moet je natuurlijk meten, anders is er geen beginnen aan). Nu definieer je de overgangsmatrix M: M = [1 0 0 0 cos(a) sin(a) 0 -sin(a) cos(a) ] Waarbij de kolommen de lineaire combinaties zijn van de oorspronkelijke vectoren naar de nieuwe. Definieer nu verder de translatievector tussen de twee oorsprongen van de assenstelsels (die dus ook overeenstemt met de coördinaten van de tweede oorsprong op de tafel, in functie van het eerste assenstelsel) als T(t1,t1,t3). Dan gaan we nu over op homogene coördinaten, waarbij je dus onderaan bij punten een 1 toevoegt. We definieren: P = [1 0 0 t1 0 cos(a) sin(a) t2 0 -sin(a) cos(a) t3 0 0 0 1 ] Nu is de gezochte transformatie gegeven door: (x y z 1)^(T) = P*(x' y' z' 1)^T. Ofwel: (x y z 1)^T*P^(-1) = (x' y' z' 1)^T. Dus je berekent de inverse van P, vermenigvuldigt die met (x y z 1)^T, en je kunt de gevraagde transformatieformules afleiden, om elke coördinaat te herschrijven naar het andere assenstelsel. Ik hoop dat het is wat je vroeg ![]() [ Bericht 2% gewijzigd door yarnamc op 27-04-2012 13:30:36 ] | ||||
Holy_Goat | vrijdag 27 april 2012 @ 20:47 | |||
Beste yarnamc, bedankt voor je bijdrage! Echter, opmeten van hoeken wil en ga ik niet aan beginnen. Bovendien wil ik de camera straks ook los kunnen koppelen, waardoor de camera ook gewoon bewogen kan worden tijdens gebruik, maar de locale coordinaten ongewijzigd blijven, liefst realtime. Wel ben ik inderdaad met je eens dat het in principe niet zo ingewikkeld hoeft te zijn. Over affine heb ik nog niets gelezen; bedankt, ga ik ook nog even wat over opzoeken! Maar... momenteel kan ik melden dat het .... tadadammm... gelukt is! Nog wel even handmatig 3 punten op het tafelblad gekozen, dat dan weer wel, maar de transformatie is gelukt ![]() Bovenste rij : X, Y, Z camera space Onderste rij : X, Y, Z table space ![]() En dit door een verdwaalde functie die ik in Matlab vond:
- Tableorigin de positie van het tafel assenstelsel relatief aan het cam assenstelsel - tafbleaxis een [3x3] matrix met per kolom een normaal vector voor respectievelijk de locale X,Y en Z in de richting zoals geobserveerd vanuit cam space | ||||
Holy_Goat | vrijdag 27 april 2012 @ 20:48 | |||
Alleen wel een beetje 'jammer' dat dit nu dus niet door rotatiematrices bereikt is. Ik ging er vanuit dat dat eigenlijk de methode was. Bovenstaande snap ik namelijk niet geheel, en dat vind ik erg jammer. | ||||
Azreal | zaterdag 28 april 2012 @ 15:44 | |||
Ik heb Biomedische Technologie gestudeerd en ben na jarenlang cellen kweken en focus op de biologische kant van dingen de image analysis ingedoken. Daar word je ook met dit soort vraagstukken geconfronteerd, hoewel ik zelf er nooit echt mee gewerkt heb. Zelf was ik bezig met machine learning. Zoals Asphias aangeeft is het eigenlijk gewoon lineare algebra (nouja, als je het volledig correct wilt doen niet linear, maar daar wil ik niet eens aan denken ![]() @yamamc: wat is precies het verschil tussen een affine transformatie en transformatie naar een andere basis? Het klinkt namelijk alsof je precies hetzelfde aan het doen bent en P de transformatiematrix voor de affine transformatie is. Maar zoals gezegd, ben niet echt de expert en mijn laatste confrontatie met affine transformatie was het patchen van slechte code van een vriendin van me ![]() @Holy_Goat: wedje maken dat er onder water wel rotatiematrices of iig een transformatiematrix berekend wordt? Je hoeft trouwens voor yamamc's oplossing geen hoek te berekenen/meten aangezien je je assen gedefinieerd hebt aan het tafelvlak. Om van linkshandige naar rechtshandige basis over te gaan kun je als ik me niet vergis een van de assen die het tafelvlak definieren negatief definieren (in dit geval dus de X of de Z as). Om het dat zeker te weten moet ik alleen even uitzoeken hoe het ook alweer zat met linkshandige en rechtshandige basis en daar heb ik nu geen tijd voor. Als je ermee wilt gaan rondlopen, ga je dan niet een automatisch systeem voor de positie van een ankerobject (in dit geval de tafel) nodig hebben? Kijk, dat zijn de echte leuke uitdagingen ![]() | ||||
yarnamc | zaterdag 28 april 2012 @ 17:21 | |||
Een affiene transformatie is een afbeelding, waarbij elke barycentrische combinatie van punten afgebeeld wordt op een nieuwe barycentrische combinatie van punten. Men kan dan aantonen dat transformaties als spiegelingen, rotaties, ... affiene transformaties zijn. Zo kan men aan de hand van rotatiematrices, homothetiematrices, ... de nieuwe coördinaten van de getransformeerde figuren berekenen. Belangrijk is hierbij dat de basis niet verandert, je blijft dus hetzelfde assenstelsel gebruiken. Dat is dus zoals je ziet, helemaal niet wat we in dit geval aan het doen zijn. In dit geval laten we namelijk alle punten op hun plaats staan, maar veranderen we het assenstelsel (eigenlijk exact het omgekeerde van de affiene transformatie). Dit noemen we dan ook een coördinatentransformatie. Het zijn eigenlijk twee volstrekt verschillende dingen, maar men kan bewijzen, dat de matrices van de affiene transformatie omgezet kunnen worden in deze van een equivalente coördinatentransformatie en andersom. Maar het is om verwarring te vermijden beter de twee te scheiden, als je de twee niet 100% uit elkaar kunt houden. Er zijn namelijk subtiele en belangrijke verschillen in de formules, zo is bijvoorbeeld bij een coördinatentransformatie s = As' (met s' de nieuwe coördinaten, formule geldt indien er geen translatievector is) en bij de affiene transformatie s' = As (met dezelfde betekenis van de symbolen). Men maakt dus nogal snel fouten, als men dit niet opmerkt. | ||||
Azreal | zondag 29 april 2012 @ 00:08 | |||
Duidelijk, tnx! Snap nu ook waarom ik het verschil niet zag. |