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

Python + minGW

Beitragvon drankaner » Mittwoch 13. Dezember 2017, 21:43

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: 7065
Registriert: Sonntag 21. Oktober 2012, 17:20

Re: Python + minGW

Beitragvon Sirius3 » Mittwoch 13. Dezember 2017, 21:56

@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.
Benutzeravatar
__deets__
User
Beiträge: 2175
Registriert: Mittwoch 14. Oktober 2015, 14:29

Re: Python + minGW

Beitragvon __deets__ » Donnerstag 14. Dezember 2017, 00:33

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: 2243
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: Görgeshausen
Kontaktdaten:

Re: Python + minGW

Beitragvon noisefloor » Donnerstag 14. Dezember 2017, 08:26

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

Re: Python + minGW

Beitragvon drankaner » Donnerstag 14. Dezember 2017, 13:29

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.
Benutzeravatar
__deets__
User
Beiträge: 2175
Registriert: Mittwoch 14. Oktober 2015, 14:29

Re: Python + minGW

Beitragvon __deets__ » Donnerstag 14. Dezember 2017, 14:18

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

Re: Python + minGW

Beitragvon drankaner » Donnerstag 14. Dezember 2017, 14:46

__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

Re: Python + minGW

Beitragvon drankaner » Freitag 22. Dezember 2017, 11:06

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: 7065
Registriert: Sonntag 21. Oktober 2012, 17:20

Re: Python + minGW

Beitragvon Sirius3 » Freitag 22. Dezember 2017, 13:08

@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:
  1.     s = x_pPoint3d - o
  2.     s2 = (s**2).sum(axis=1)
  3.     local = (r*s).sum(axis=1)
  4.     local = s2 - local**2 * r2r
  5.     maxsquaredist = local.max()
  6.     meansquaredist = local.mean()
  7.     return x_pPoint3d, maxsquaredist, meansquaredist
drankaner
User
Beiträge: 13
Registriert: Freitag 27. Oktober 2017, 13:22

Re: Python + minGW

Beitragvon drankaner » Mittwoch 27. Dezember 2017, 09:43

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

Re: Python + minGW

Beitragvon Sirius3 » Mittwoch 27. Dezember 2017, 10:28

@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: 779
Registriert: Mittwoch 15. Oktober 2008, 09:27
Wohnort: Düsseldorf

Re: Python + minGW

Beitragvon kbr » Mittwoch 27. Dezember 2017, 11:00

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

Re: Python + minGW

Beitragvon drankaner » Mittwoch 27. Dezember 2017, 11:05

@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

Re: Python + minGW

Beitragvon drankaner » Mittwoch 27. Dezember 2017, 11:08

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

Re: Python + minGW

Beitragvon drankaner » Mittwoch 27. Dezember 2017, 11:32

@kbr: Wenn du den cProfiler meinst, dann führt dass nur zu einer deutlichen verlangsamung. Oder liege ich auf dem Holzweg?

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder