Python + minGW

Python in C/C++ embedden, C-Module, ctypes, Cython, SWIG, SIP etc sind hier richtig.
drankaner
User
Beiträge: 13
Registriert: Freitag 27. Oktober 2017, 13:22

Hallo Freunde,

ich versuche derzeit ein paar Funktionen aus Python in C auszulagern um Zeit zu sparen.

Bevor ich damit Anfange wollte ich zumindestens ein einfaches Beispiel ausprobieren. Ein Bekannter der schon länger nichts in Python gemacht hat, hat mir syipy.Weave empfohlen, aber das wird ja leider nicht mehr unterstützt bei Python 3.x.
Daraufhin empfahl er mir Swice: https://github.com/jochenn/swice

Soweit so gut. Nun habe ich MinGW und Swig installiert und habe versucht das Beispiel Programm zum laufen zu bringen.

Dabei kommt immer folgender Fehler:

Code: Alles auswählen

Python 3.5.4 (v3.5.4:3f56838, Aug  8 2017, 02:17:05) [MSC v.1900 64 bit (AMD64)]
Type "copyright", "credits" or "license" for more information.

IPython 6.1.0 -- An enhanced Interactive Python.

running build
running build_ext
building '_m72ccdd29ff6e6e8dbfb22df83e921ea9' extension
C:\MinGW32\bin\gcc.exe -mdll -O -Wall -IC:\WinPython-64bit-3.5\python-3.5.4.amd64\lib\site-packages\numpy\core\include -I. -IC:\WinPython-64bit-3.5\python-3.5.4.amd64\include -IC:\WinPython-64bit-3.5\python-3.5.4.amd64\include -IC:\WinPython-64bit-3.5\python-3.5.4.amd64\lib\site-packages\numpy\core\include -I. -IC:\WinPython-64bit-3.5\python-3.5.4.amd64\include -IC:\WinPython-64bit-3.5\python-3.5.4.amd64\include -c m72ccdd29ff6e6e8dbfb22df83e921ea9.cpp -o build\temp.win-amd64-3.5\Release\m72ccdd29ff6e6e8dbfb22df83e921ea9.o
C:\MinGW32\bin\gcc.exe -mdll -O -Wall -IC:\WinPython-64bit-3.5\python-3.5.4.amd64\lib\site-packages\numpy\core\include -I. -IC:\WinPython-64bit-3.5\python-3.5.4.amd64\include -IC:\WinPython-64bit-3.5\python-3.5.4.amd64\include -IC:\WinPython-64bit-3.5\python-3.5.4.amd64\lib\site-packages\numpy\core\include -I. -IC:\WinPython-64bit-3.5\python-3.5.4.amd64\include -IC:\WinPython-64bit-3.5\python-3.5.4.amd64\include -c m72ccdd29ff6e6e8dbfb22df83e921ea9_wrap.cxx -o build\temp.win-amd64-3.5\Release\m72ccdd29ff6e6e8dbfb22df83e921ea9_wrap.o
An exception has occurred, use %tb to see the full traceback.

SystemExit: error: command 'C:\\MinGW32\\bin\\gcc.exe' failed with exit status 1
Kann mir hier jemand von euch weiterhelfen? Ich komme trotz Google überhaupt nicht weiter und verzweifle inzwischen daran.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@drankaner: etwas in C zu schreiben, braucht eigentlich immer viel Zeit, sparen kann man da nichts. `swice` sieht ziemlich tot aus. Erster Schritt ist immer, einen effektiven Algorithmus in Python zu schreiben. Weiteres Optimieren ist meist in nicht zu rechtfertigender Luxus. Aus Deinem anderen Thread lese ich, dass da noch viel Potential ist.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Hast du schon probiert mit PyPy zu arbeiten? Je nach Anwendungsfall bringt das dramatische Verbesserungen.

Und wenn es denn C sein soll, dann bau eine DLL und benutz ctypes.
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
ich versuche derzeit ein paar Funktionen aus Python in C auszulagern um Zeit zu sparen.
Welche denn bzw. was hast du vor? Zeig' doch deine Python-Code, der deiner Ansicht nach zu langsam ist.

Gruß, noisefloor
drankaner
User
Beiträge: 13
Registriert: Freitag 27. Oktober 2017, 13:22

Den Code kann ich gerne hochladen:

Hier bekomme ich eine Matrix correspondance 12x5907330 , die Anzahl der Spalten "totalmax", wieviele Kameras (4) "Cams", sequenz wird noch nicht benutzt, aber später benötigt.

triangulation_batch2.py:

Code: Alles auswählen

def triangulation_batch(correspondance, totalmax, Cams, sequenz):
 
    print("Step1")
    local_camparamset_vector = [[],[],[],[],[],[],[],[]];

    camparamsetCollection = getCamparamset()

    for camindex in range(0,Cams):
        #Kameraparameter in Vektor bereitstellen
        local_camparamset_vector[camindex]=[camparamsetCollection[camindex][14]]

    for index in range(0,totalmax):
        
        
        #Aktueller Kamerasatz
        currentline =  correspondance[index][:];
        
        local_cs_in_global_vector = [[],[],[],[],[],[],[],[]];
        
        
        for camindex in range(0,Cams):
            area = currentline[camindex*3+2]
            if(area > 0 ):
                xcoord = currentline[camindex*3]/area*2
                ycoord = currentline[camindex*3+1]/area*2
                if(area >=1):
                    #Punkte in Kamerakoordinatensystem umrechnen
                    local_cs_in_ebene1 = calc.calculatePointInCameraCoordSys(xcoord,ycoord,camparamsetCollection[camindex],camindex)
                    #Globaleskoordinatensystem
                    local_cs_in_global = numpy.matmul(camparamsetCollection[camindex][13],local_cs_in_ebene1); 
                    #Koordinatensystem 
                    local_cs_in_global_vector[camindex]=[local_cs_in_global]
                    #local_cs_in_global_vector.append([local_cs_in_global])    
                    # push in den lokalen punkt in den vektor der akzeptierten punkte
                    
        #Zwischendeklaration & Reset            
        enoughcams=0
        camcorrectNo=0
        camcorrect=[]
        
        #Wieviele Kameras sind gültig? Mindestens zwei nötig
        for x in range(0,Cams):
            if local_cs_in_global_vector[x]:
                enoughcams+=1
                
        if(enoughcams>=2):
            #Welche Kamera ist gültig? Erkennbar an der Area
            for camindex in range(0,Cams):
                if(currentline[camindex*3+2]>=1):
                    camcorrect.append(1)
                    camcorrectNo+=1
                else:
                    camcorrect.append(0)
            #Welche Kamerakombination kann verwendet werden
            x_acceptableCameraConfigs=Cameraset.Cameraset(camcorrect,camcorrectNo,Cams)
            localPoint=[[],[],[]]
            #3D Punkte berechnen
            localPoint[0],localPoint[1],localPoint[2],maxsquaredist, localSquaredMaxDistance = Cameraset.Triangle(local_cs_in_global_vector,local_camparamset_vector,x_acceptableCameraConfigs[0])
                
        
            #Nur wenn der Abstand vom erwarteten Punkt nicht zu groß ist, ist den Werten zu vertrauen!
            if localSquaredMaxDistance < 0.1:
                xP.append(localPoint[0])
                yP.append(localPoint[1])
                zP.append(localPoint[2])
        
    
    return xP,yP,zP, Zaehler, squaredist
Lösen des Linearengleichungssystems zur Errechnung der 3D-Punkte. (Noch nicht kommentiert)

solverTriangulationLGS.py:

Code: Alles auswählen

def solverTriangulationLGS(local_cs_in_global_vector, local_tRefk_vector):
    

    
    x_iCamNo = len(local_cs_in_global_vector);
    for ich in range(0,8):
        if not local_cs_in_global_vector[ich]:
            x_iCamNo-=1
    
    
    b0 = 0.0;
    b1 = 0.0;
    b2 = 0.0;
    a00 = x_iCamNo;
    a11 = x_iCamNo;
    a01 = 0.0;
    a02 = 0.0;
    a12 = 0.0;
    
    for camera in range(0,x_iCamNo):
        ox = local_tRefk_vector[camera][0][0];
        rx = local_cs_in_global_vector[camera][0][0]; 
        
        oy = local_tRefk_vector[camera][0][1];
        ry = local_cs_in_global_vector[camera][0][1];
        
        oz = local_tRefk_vector[camera][0][2];
        rz = local_cs_in_global_vector[camera][0][2];
        r2r = 1.0/(rx*rx+ry*ry+rz*rz);
        
        if (r2r>20000):
            break;
            
        local = rx*ox + ry*oy + rz*oz;
        rx_r2 = rx *r2r;
        ry_r2 = ry *r2r;
        rz_r2 = rz *r2r;
        b0 += ox - local*rx_r2;
        b1 += oy - local*ry_r2; 
        b2 += oz - local*rz_r2;
        
        
        a00 -= rx*rx_r2
        a01 -= rx*ry_r2        
        a02 -= rx*rz_r2        
        a11 -= ry*ry_r2
        a12 -= ry*rz_r2
    a10=a01
    a20=a02
    a21=a12
    

    
    a22 = x_iCamNo * 2 - a00 - a11;
   
    x_pPoint3d = numpy.matmul(numpy.linalg.inv([[a00,a01,a02],[a10,a11,a12],[a20,a21,a22]]),([[b0],[b1],[b2]]))
   
    
    sumsquaredist = 0;
    maxsquaredist = 0;
    
    for camera in range(0,x_iCamNo):
        ox = local_tRefk_vector[camera][0][0];
        rx = local_cs_in_global_vector[camera][0][0]; # rx
        sx = (x_pPoint3d[0] - ox);
        
        oy = local_tRefk_vector[camera][0][1];
        ry = local_cs_in_global_vector[camera][0][1];
        sy = (x_pPoint3d[1] - oy);
        
        oz = local_tRefk_vector[camera][0][2];
        rz = local_cs_in_global_vector[camera][0][2];
        sz = (x_pPoint3d[2] - oz);

        r2r = 1.0/(rx*rx+ry*ry+rz*rz);
        s2 = sx*sx + sy*sy + sz*sz;
        local = rx*sx + ry*sy + rz*sz;
        
        
        local = s2 - local*(local * r2r); 
        
        if (maxsquaredist < local):
            maxsquaredist = local;
        sumsquaredist += local;
        
    return x_pPoint3d[0][0],x_pPoint3d[1][0],x_pPoint3d[2][0],local, sumsquaredist/x_iCamNo
Umrechnung der Werte in das entsprechende Kamera koordinatensystem

calculatePointInCameraCoordSys.py:

Code: Alles auswählen

def calculatePointInCameraCoordSys(x, y, Parameter, Camera):
    destpoint=[[],[],[]]
    
    f=Parameter[0]
    fy=Parameter[1]
    indexoffset = 1;
    sx=Parameter[indexoffset+3]
    alpha_s=Parameter[indexoffset+4]
    beta_s=Parameter[indexoffset+5]
    k_verz1=Parameter[indexoffset+6]
    R_t=Parameter[indexoffset+8]
    T_t=Parameter[indexoffset+9]
    fy=f
    fx=f
    

    Messpunkte_Bild_Kamerakoordinatensystem_hilf=[[],[],[]]
    
    Messpunkte_Bild_Kamerakoordinatensystem_hilf[0] = x - T_t[0];
    Messpunkte_Bild_Kamerakoordinatensystem_hilf[1] = y - T_t[1];
    Messpunkte_Bild_Kamerakoordinatensystem_hilf[2] = 0 - T_t[2];
    
    Messpunkte_Bild_Kamerakoordinatensystem=numpy.matmul(R_t,Messpunkte_Bild_Kamerakoordinatensystem_hilf)   
    
    Rx_s = [[1, 0, 0], [0, mathe.cos(alpha_s) , -mathe.sin(alpha_s)], [0, mathe.sin(alpha_s),  mathe.cos(alpha_s)]];
    Ry_s = [[mathe.cos(beta_s), 0, mathe.sin(beta_s)], [0, 1, 0],[-mathe.sin(beta_s), 0, mathe.cos(beta_s)]];
	
    m_Rt = numpy.matmul(Rx_s,Ry_s);
         
    z_wert = Messpunkte_Bild_Kamerakoordinatensystem[2]
    y_parallel = Messpunkte_Bild_Kamerakoordinatensystem[1] / (fy + z_wert); 
    x_parallel = (Messpunkte_Bild_Kamerakoordinatensystem[0] - y_parallel * sx) / (fx + z_wert)

# ------------------ Correct distortion-----------------

    k_verz_u_x = (k_verz1* fx *fx)
    k_verz_u_y = (k_verz1* fy *fy)
    r2verz = (x_parallel*x_parallel*k_verz_u_x + y_parallel*y_parallel*k_verz_u_y)

# ------------------ Correct distortion-----------------

    destpoint[0] = (x_parallel + x_parallel *r2verz)
    destpoint[1] = (y_parallel + y_parallel *r2verz)
    destpoint[2] = (1.0)

    return destpoint
Ich bin nicht sehr geübt im Programmieren wie man sieht. Allerdings muss ich da jetzt halt einfach ran.
Ich hoffe dass Ihr etwas damit anfangen könnt.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Kannst du mal erzaehlen, was das sein soll? Denn fuer zB Kamera-Kalibration, Pose-Estimation, etc. gibt es schon fertige Pakete in der OpenCV, schoen angebunden an Python, aber in C++ und ggf nach Verfuegbarkeit GPU-optimiert.

Und wenn es selbst gemacht sein soll, dann wenigstens numpy verwenden, mit dem die Berechnungen (wenn richtig gemacht) deutlich schneller weil auch in C gemacht werden.

Last but not least: fuer genau sowas ist PyPy gut geeignet, zB hier ein Beispiel aus dem Video-Processing (etwas aelter, aber schlechter sind die nicht geworden): https://morepypy.blogspot.de/2011/07/re ... ython.html
drankaner
User
Beiträge: 13
Registriert: Freitag 27. Oktober 2017, 13:22

__deets__ hat geschrieben:Kannst du mal erzaehlen, was das sein soll?
Ich bekomme von einem Multkamerasystem, Phasenbilder von insgesamt 4 Kameras. Aus diesen wird ein Correspondance Tabelle berrechnet. Ab hier kann ich eingreifen.
Und berechne an Hand der Phasenwerte und der Kamerakalibrationswerte, den jeweiligen 3D Punkt zurück und Prüfe ob dieser Vertrauenswürdig sind.
__deets__ hat geschrieben:Denn fuer zB Kamera-Kalibration, Pose-Estimation, etc. gibt es schon fertige Pakete in der OpenCV, schoen angebunden an Python, aber in C++ und ggf nach Verfuegbarkeit GPU-optimiert.
Ich werde mir die Pakete mal anschauen.

Danke!
drankaner
User
Beiträge: 13
Registriert: Freitag 27. Oktober 2017, 13:22

So ich habe jetzt soweit es geht mit Numpy gearbeitet und habe auch ein Zeitersparnis von 10 Minuten, jedoch dauert die Geschichte immernoch über 20 Minuten. Habt Ihr vielleich noch Ideen wo ich angreifen kann?

Code: Alles auswählen

def solverTriangulationLGS(local_cs_in_global_vector, local_tRefk_vector,x_iCamNo):


    a=numpy.full((3,3),0,dtype= numpy.float64)
    b=numpy.full((3),0,dtype= numpy.float64)
    r_r2=numpy.full((x_iCamNo,3),0,dtype= numpy.float64)
    o=numpy.full((x_iCamNo,3),0,dtype= numpy.float64)
    r=numpy.full((x_iCamNo,3),0,dtype= numpy.float64)
    r2r=numpy.full((x_iCamNo),0,dtype= numpy.float64)
 
    a[0,0]=x_iCamNo
    a[1,1]=x_iCamNo

    for camera in range(0,x_iCamNo):

        o[camera]=numpy.asarray(local_tRefk_vector[camera][0])
        r[camera]=numpy.asarray(local_cs_in_global_vector[camera][0])

        r2r[camera] = 1.0/(numpy.inner(r[camera], r[camera]));
        if (r2r[camera]>20000):

            break;
        local =  numpy.inner(r[camera], o[camera])
        r_r2[camera] = numpy.asarray(r[camera] * r2r[camera])
        b += o[camera]-local*r_r2[camera]
    a-=numpy.tensordot(r, r_r2, axes=[0,0])
    
    a[2][2] = x_iCamNo * 2 - a[0][0] - a[1][1];
    x_pPoint3d = numpy.matmul(numpy.linalg.inv(a),(b))

   sumsquaredist = 0;
    maxsquaredist = 0;

    for camera in range(0,x_iCamNo):

        s=x_pPoint3d-o[camera]
        s2 = numpy.inner(s,s)
        local = numpy.inner(r[camera],s)
        local = s2 - local*(local * r2r[camera]); 

        if (maxsquaredist < local):

            maxsquaredist = local;
        sumsquaredist += local;

    return x_pPoint3d[0],x_pPoint3d[1],x_pPoint3d[2],maxsquaredist, sumsquaredist/x_iCamNo
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@drankaner: statt numpy.full nimmt man numpy.zeros. Welches Format haben denn local_cs_in_global_vector und local_tRefk_vector?
Ist x_iCamNo nicht einfach die Länge der Vektoren? Das braucht man dann nicht extra angeben.
Die ganzen asarray-Aufrufe sind in Deinem Fall überflüssig. Die Klammern bei den if und alle Strichpunkte sind das auch. Die einbuchstabigen Namen sind allesamt schlecht, weil sie nichts aussagen, für was sie stehen.

Die erste Hälfte ist vor allem mit dem `break` etwas seltsam, kann man aber bestimmt genauso zusammenfassen wie die zweite Hälfte, so dass es keine for-Schleifen mehr gibt:

Code: Alles auswählen

    s = x_pPoint3d - o
    s2 = (s**2).sum(axis=1)
    local = (r*s).sum(axis=1)
    local = s2 - local**2 * r2r
    maxsquaredist = local.max()
    meansquaredist = local.mean()
    return x_pPoint3d, maxsquaredist, meansquaredist
drankaner
User
Beiträge: 13
Registriert: Freitag 27. Oktober 2017, 13:22

@Sirius3 Danke schon mal! Habe soweit das ganze nun ohne for Schleifen, hat mir aber dennoch leider keine Zeitersparnis eingebracht.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@drankaner: ein paar Matrixmultiplikationen mit 70Mio Zahlen brauchen etwas Zeit, aber ich bezweifle, dass es 20 Minuten sind. Wo genau wird wieviel Zeit verbraucht? Ich vermute, Du suchst an der falschen Stelle.
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@drankaner: Hast Du schon versucht den Python Profiler auf Dein Programm anzuwenden?
drankaner
User
Beiträge: 13
Registriert: Freitag 27. Oktober 2017, 13:22

@sirius3: Ich habe etwa drei Zeitfresser:
1. sind die Matrixmultiplikationen von oben ca. 40%,
2. Ist die Umrechnung in Kamerakoordinaten oben: calculatePointInCameraCoordSys.py diese benötigt etwa 35% der Zeit und
3. ist die Berechnung der möglichen Camerasettings (Also welche Kamera können mir zudem Punkt überhaupt einen Anteil liefern) ca 15%.

Die letzte Funktion hatte ich noch nicht gepostet.

Code: Alles auswählen

def combinations(objects, k):
    if objects == [] or len(objects) < k or k == 0:
	yield []
    elif len(objects) == k:
        yield objects
    else:
        for combination in combinations(objects[1:], k-1):
            yield [objects[0]] + combination
        for combination in combinations(objects[1:], k):
            yield combination

def Cameraset(validCams,validCamsNo,Cams):
        invalidCams=[]
    
        combs=list(combinations([0,1,2,3,4,5,6,7],validCamsNo))
        #int(math.factorial(Cams)/(math.factorial(Cams-validCamsNo)*math.factorial(validCamsNo)))
        for x in range(0,len(validCams)):
            if validCams[x]==0:
                invalidCams.append(x)
        for y in range(0,len(invalidCams)):
            i=0
            possible=len(combs)
            for x in range(0,possible):
                if combs[x-i].count(invalidCams[y])>0:
                    combs.pop(x-i)
                    i+=1
        return combs
Wobei diese, auch denk geringsten Zeitaufwand hat.
drankaner
User
Beiträge: 13
Registriert: Freitag 27. Oktober 2017, 13:22

kbr hat geschrieben:@drankaner: Hast Du schon versucht den Python Profiler auf Dein Programm anzuwenden?
Bisher nicht, habe davon auch noch nichts gelesen.
drankaner
User
Beiträge: 13
Registriert: Freitag 27. Oktober 2017, 13:22

@kbr: Wenn du den cProfiler meinst, dann führt dass nur zu einer deutlichen verlangsamung. Oder liege ich auf dem Holzweg?
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Natürlich tut der das. Weil er Informationen sammelt, die man danach auswertet um rauszufinden, wo man bottle necks hat.
drankaner
User
Beiträge: 13
Registriert: Freitag 27. Oktober 2017, 13:22

drankaner hat geschrieben:@sirius3: Ich habe etwa drei Zeitfresser:
1. sind die Matrixmultiplikationen von oben ca. 40%,
2. Ist die Umrechnung in Kamerakoordinaten oben: calculatePointInCameraCoordSys.py diese benötigt etwa 35% der Zeit und
3. ist die Berechnung der möglichen Camerasettings (Also welche Kamera können mir zudem Punkt überhaupt einen Anteil liefern) ca 15%.

Die letzte Funktion hatte ich noch nicht gepostet.

Code: Alles auswählen

def combinations(objects, k):
    if objects == [] or len(objects) < k or k == 0:
	yield []
    elif len(objects) == k:
        yield objects
    else:
        for combination in combinations(objects[1:], k-1):
            yield [objects[0]] + combination
        for combination in combinations(objects[1:], k):
            yield combination

def Cameraset(validCams,validCamsNo,Cams):
        invalidCams=[]
    
        combs=list(combinations([0,1,2,3,4,5,6,7],validCamsNo))
        #int(math.factorial(Cams)/(math.factorial(Cams-validCamsNo)*math.factorial(validCamsNo)))
        for x in range(0,len(validCams)):
            if validCams[x]==0:
                invalidCams.append(x)
        for y in range(0,len(invalidCams)):
            i=0
            possible=len(combs)
            for x in range(0,possible):
                if combs[x-i].count(invalidCams[y])>0:
                    combs.pop(x-i)
                    i+=1
        return combs
Wobei diese, auch denk geringsten Zeitaufwand hat.
Das ganze konnte ich nun doch nochmal effizienter machen, sodass ich hier nun keine Zeit mehr verschwende. Nun ist die Zeitaufteilung wiefolgt:
  • 1. sind die Matrixmultiplikationen von oben ca. 50%,
    2. Ist die Umrechnung in Kamerakoordinaten oben: calculatePointInCameraCoordSys.py diese benötigt etwa 45% der Zeit
Bei nun noch etwa 16 Minuten.

Dann werd eich jetzt mal den Profiler duchlaufen lassen.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@drankaner: wie sieht denn jetzt Dein Code aus, und welche Zeilen brauchen wie lange?

»combinations« gibt es schon fertig in itertools, das braucht man nicht selbst zu schreiben. »Cameraset« und alle Variablennamen halten sich immer noch nicht an die üblichen Konventionen. Funktionen sollten nach einer Tätigkeit benannt sein. `Cams` wird gar nicht verwendet. Man iteriert direkt über Listen und baut sich neue, statt mit pop irgendwie die Liste zu verändern; das versteht nämlich niemand.

Nachdem ich raten konnte, was die unterschiedlichen Parameter bedeuten, kommt das dabei raus:

Code: Alles auswählen

def find_cameraset_with_only_valid_cameras(cameras_validity, set_size):
    combs = list(combinations(range(len(cameras_validity), set_size))
    for num, valid in enumerate(cameras_validity):
        if not valid:
            combs = [c for c in combs if c.count(num) == 0]
    return combs
wobei man sich dann fragen muß, warum Du erst die Kombinationen aller Kameras erzeugst, um dann aus allen Kombinationen die ungültigen wieder zu entfernen und nicht gleich nur aus den Gültigen die Kombinationen erzeugst:

Code: Alles auswählen

def find_cameraset_with_only_valid_cameras(cameras_validity, set_size):
    valid_cameras = [num for num, valid in enumerate(cameras_validity) if valid]
    return list(combinations(valid_cameras, set_size))
drankaner
User
Beiträge: 13
Registriert: Freitag 27. Oktober 2017, 13:22

Sirius3 hat geschrieben:@drankaner: wie sieht denn jetzt Dein Code aus, und welche Zeilen brauchen wie lange?

»combinations« gibt es schon fertig in itertools, das braucht man nicht selbst zu schreiben. »Cameraset« und alle Variablennamen halten sich immer noch nicht an die üblichen Konventionen. Funktionen sollten nach einer Tätigkeit benannt sein. `Cams` wird gar nicht verwendet. Man iteriert direkt über Listen und baut sich neue, statt mit pop irgendwie die Liste zu verändern; das versteht nämlich niemand.
Genau an dem Punkt habe ich angegriffen und den Quatsch mit "pop" wieder rausgeschmissen. Hier muss ich auch gestehen, dass die Funktion erstmal Blind geschrieben habe (Hauptsache es funktioniert).

Code: Alles auswählen

def find_valid_Cameraset(validCams,validCamsNo):
      return list(combinations(validCams,validCamsNo))
Die Zeiten genau Untersuche ich jetzt nochmal genau. Bisher habe ich nur die Zeit für die gesamte Funktion.
8 Minuten für solveTriangulationLGS.py und 6-7 Minuten für calculatePointInCameraCoordSys.py.
drankaner
User
Beiträge: 13
Registriert: Freitag 27. Oktober 2017, 13:22

Das die Variablen nicht der Konvention entsprechen, da stimme ich dir volkommen zu. Allerdings habe ich diese aus unserem tatsächlichen Programm das in C++ besteht (nicht von mir) übernommen und um später einfacher Sachen in dieses zu übernehmen habe diese bestehen lassen.

Nun ja mein
Sirius3 hat geschrieben:@drankaner: statt numpy.full nimmt man numpy.zeros. Welches Format haben denn local_cs_in_global_vector und local_tRefk_vector?
Ist x_iCamNo nicht einfach die Länge der Vektoren? Das braucht man dann nicht extra angeben.
Die ganzen asarray-Aufrufe sind in Deinem Fall überflüssig. Die Klammern bei den if und alle Strichpunkte sind das auch. Die einbuchstabigen Namen sind allesamt schlecht, weil sie nichts aussagen, für was sie stehen.

Die erste Hälfte ist vor allem mit dem `break` etwas seltsam, kann man aber bestimmt genauso zusammenfassen wie die zweite Hälfte, so dass es keine for-Schleifen mehr gibt:

Code: Alles auswählen

    s = x_pPoint3d - o
    s2 = (s**2).sum(axis=1)
    local = (r*s).sum(axis=1)
    local = s2 - local**2 * r2r
    maxsquaredist = local.max()
    meansquaredist = local.mean()
    return x_pPoint3d, maxsquaredist, meansquaredist
Ich habe den Code jetzt so angepasst.

local_cs_in_global_vector übergibt einen Vektor der so aussehen kann:
[array([ 0.06999708, 0.68877751, -0.72814772]), array([ 0.68212451, 0.08660196, -0.7334991 ])] (Je nach Anzahl der Kameras, kommt jeweils noch eine Zeile hinzu)

local_tRefk_vector übergibt einen solchen Vektor:
[[1.45608435, -220.028403, 264.029949], [-219.686839, 0.265470325, 264.474263]] (Je nach Anzahl der Kameras, kommt jeweils noch eine Zeile hinzu)

Und x_iCamNo die Anzahl der gültigen Kameras.

Ich habe auch schon einmal anngepasst das local_cs_in_global_vector und local_tRefk_vector jeweils im richtigen Format ankommen, sodass ich numpy.asarray nicht benötige, daraufhin bin ich aber direkt langsamer geworden und zwar deutlich. (Finde ich unlogisch, war aber tatsächlich so)

Code: Alles auswählen

def solverTriangulationLGS(local_cs_in_global_vector, local_tRefk_vector,x_iCamNo):

    a=numpy.zeros((3,3))
    o=numpy.asarray(local_tRefk_vector)
    r=numpy.asarray(local_cs_in_global_vector)

    a[0,0]=x_iCamNo
    a[1,1]=x_iCamNo

    ###Vorbereitung 3D Punkt
    #r2r = Ein einzelner Wert, je Kamera existiert einer!     
    r2r=1/(r**2).sum(axis=1)
    #local = Ein einzelner Wert, je Kamera existiert einer! 
    local=(r*o).sum(axis=1)
    #r_2r = Ein 3er Vector, je Kamera existiert einer! 
    r_r2=(r.transpose()*r2r).transpose()
    #b= ein 3er Vector
    b = (o-(r_r2.transpose()*local).transpose()).sum(axis=0)
    #a=eine 3x3 Matrix
    a-=numpy.tensordot(r, r_r2, axes=[0,0])

    a[2][2] = x_iCamNo * 2 - a[0][0] - a[1][1];

   ###3D Punkt berechnen

    x_pPoint3d = numpy.matmul(numpy.linalg.inv(a),(b))

    ###Validierung des 3D Punkts
    #s = Ein 3er Vector, je Kamera existiert einer! 
    s=x_pPoint3d-o
    #s2 = Ein einzelner Wert, je Kamera existiert einer! 
    s2 = (s**2).sum(axis=1)
    #local = Ein einzelner Wert, je Kamera existiert einer! 
    local = (r*s).sum(axis=1)
    local = s2 - local*(local * r2r); 

    maxsquaredist=local.max()
    sumsquaredist=local.mean()

    return x_pPoint3d,maxsquaredist, sumsquaredist
@kbr: Folgendes kommt beim cProfiler raus (Ich habe mal nur die größten Punkte rausgenommen, aber anfangen kann ich damit nichts wirklich :/):

Code: Alles auswählen

1	          252,125	252,125	1309,809	1309,809	trangulation_batch.py:17(triangulation_batch)					
35383040	  81,419	0	        81,419	0		{built-in	method	numpy.core.multiarray.array}			
24840580	  79,705	0	        79,705	0		{method	'reduce'	of	'numpy.ufunc'	objects}	
17639767	  64,23	0	        64,23	0		{built-in	method	numpy.core.multiarray.matmul}			
35486513	  26,408	0	        26,408	0		{built-in	method	numpy.core.multiarray.zeros}			
17743255	  14,453	0	        78,978	0		{method	'sum'	of	'numpy.ndarray'	objects}	
58992005	  10,06	0	        10,06	0		{built-in	method	time.time}			
10645953	  9,351	0	        9,351	0		{method	'reshape'	of	'numpy.ndarray'	objects}	
21291906	  9,039	0	        9,039	0		{method	'transpose'	of	'numpy.ndarray'	objects}	
3548656	  8,684	0	        8,684	0		{method	'astype'	of	'numpy.ndarray'	objects}	
3548651	  7,597	0	        7,597	0		{built-in	method	numpy.core.multiarray.dot}			
13086729	  6,978	0	        6,978	0		{built-in	method	numpy.core.multiarray.may_share_memory}			
16637016	  4,4	        0	        4,4	        0		{built-in	method	builtins.hasattr}			
28632953	  3,764	0	        3,764	0		{method	'append'	of	'list'	objects}	
3548651	  2,383	0	        51,048	0		{method	'mean'	of	'numpy.ndarray'	objects}	
7170593	  2,278	0	        2,283	0		{built-in	method	builtins.isinstance}			
3548723	  2,261	0	        2,261	0		{built-in	method	builtins.max}			
3548652	  2,146	0	        14,725	0		{method	'max'	of	'numpy.ndarray'	objects}	
3551510	  1,268	0	        1,268	0		{built-in	method	builtins.iter}			
3551908	  1,169	0	        1,169	0		{built-in	method	builtins.getattr}			
3548733	  1,09	0	        1,09	        0		{built-in	method	builtins.min}			
3549617	  1,039	0	        1,04	        0		{method	'get'	of	'dict'	objects}	
3548651	  0,785	0	        0,785	0		{method	'__array_prepare__'	of	'numpy.ndarray'	objects}	

Antworten