int8 array umformatieren

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
felue
User
Beiträge: 6
Registriert: Donnerstag 21. August 2008, 13:26

int8 array umformatieren

Beitragvon felue » Donnerstag 21. August 2008, 14:28

Hallo

Ich habe eine binäre Bilddatei (1=weisses Pixel, 0=schwarzes pixel) in einem int8 array gespeichert (jeweils 8 pixel in einem byte). Jetzt möchte ich gerne ein array erzeugen, das weiterhin das bild repräsentiert, jedoch mit 8 bit pro pixel. Dazu müsste ich aus jeweils einem byte im array 8 byte machen, in denen dann jeweils 0 oder 1 steht.

dazu habe ich eine Schleife programmiert. Die ist schweine langsam:

Code: Alles auswählen

def update(self, image, width, height):
      for i in range(height):
         for j in range(width/8):
            k = image[i,j]
            if (k/128):
               k=k%128
               self.mean[i,(j*8)] = 1
            if (k/64):
               k=k%64
               self.mean[i,(j*8)+1] = 1
            if (k/32):
               k=k%32
               self.mean[i,(j*8)+2] = 1
            if (k/16):
               k=k%16
               self.mean[i,(j*8)+3] = 1
            if (k/8):
               k=k%8
               self.mean[i,(j*8)+4] = 1
            if (k/4):
               k=k%4
               self.mean[i,(j*8)+5] = 1
            if (k/2):
               k=k%2
               self.mean[i,(j*8)+6] = 1
            if (k/1):
               self.mean[i,(j*8)+7] = 1   


Gibt's da ne elegantere und schnellere Lösung?

Vielen Dank für eure Antworten
Felix

Edit (Leonidas): Code in Tags gesetzt.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7471
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Beitragvon Hyperion » Donnerstag 21. August 2008, 14:30

1.) Nutze bitte Code-Tags
2.) Doppelpost ;-) (Kannst Du als Autor nen Thema löschen?)
3.) Du kannst eine dritte Schleife einbauen und die ifs damit auf eines zusammenstauchen! (Ob das insgesamt eine saubere Lösung ist, habe ich mir jetzt nicht überlegt!)
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Beitragvon numerix » Donnerstag 21. August 2008, 15:14

Eleganter ganz sicher, schneller weiß ich nicht (habe ich nicht getestet).

Probier doch mal (ungetestet):

Code: Alles auswählen

def update(self, image, width, height):
    for i in xrange(height):
        for j in xrange(width/8):
            a = image[i,j]
            p = 8*j           
            n = 7
            while a:               
                self.mean[i,p+n] = a & 1
                n -= 1
                a >>= 1
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Donnerstag 21. August 2008, 16:01

Hyperion hat geschrieben:2.) Doppelpost ;-) (Kannst Du als Autor nen Thema löschen?)

Ja, das geht. man kann seine Postings immer löschen, sofern kein anderer darauf schon geantwortet hat. Aber ich habe den Doppelpost jetzt selbt gelöscht, bevor da jemand auf die Idee kommt, darauf zu Antworten, so dass wir zwei Threads haben, die man in PHPbb nicht mergen kann.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
felue
User
Beiträge: 6
Registriert: Donnerstag 21. August 2008, 13:26

Beitragvon felue » Donnerstag 21. August 2008, 16:53

OK Danke

Leider ist das nicht schneller und genausowenig praktikabel wie vorher. Dann muss ich mir die Bilddatei schon von vornherein als Grauwertdatei einlesen. Habe dann halt 8 mal so viel Datenaufkommen im WLAN...

VG
[/quote]
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Beitragvon numerix » Donnerstag 21. August 2008, 17:09

Evtl. gibt es in der PIL etwas passendes:

http://www.pythonware.com/products/pil/index.htm
BlackJack

Beitragvon BlackJack » Donnerstag 21. August 2008, 20:21

Ansonsten könnte man noch 256 Listen mit je 8 Werten vorberechnen und/oder mal Psyco ausprobieren.
Benutzeravatar
HerrHagen
User
Beiträge: 430
Registriert: Freitag 6. Juni 2008, 19:07

Beitragvon HerrHagen » Samstag 23. August 2008, 09:38

Die Variante mit Vorberechnen ist sicher die beste, zumal die 8bit eine Zahl darstellen die du gleich als Listenindex für dein Lock-Up-Table verwenden kannst. Hier mal schnell ne Variante:

Code: Alles auswählen

import numpy

def makeLUT(x):
   return numpy.array((128&x,64&x,32&x,16&x,8&x,4&x,2&x,1&x), dtype='b')!=0
LUT = [makeLUT(i) for i in range(256)]

x = numpy.array((0,1,2,3)) #dein Ausgangsarray
y = numpy.zeros((x.size*8))

for i, val in enumerate(x):
   y[i*8:(i*8)+8]=LUT[val]

>>> y # das Ergebnis
[ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  1.  0.  0.  0.  0

Aber mal ne andere Frage,... Ich hatte kürzlich das Problem andersrum, d.h. ich will aus z.b. [0,0,0,0,0,0,1,1] ne 3 machen. Da wirds mit dem LUT schwieriger, da ich ein ganzes Array vergleichen muss.
Fällt jemand da ne elegantere Lösung ein?

MFG HerrHagen
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Samstag 23. August 2008, 11:25

Also Binär in Dezimal umwandeln?

Code: Alles auswählen

int(''.join(map(str, [0, 0, 0, 0, 0, 0, 1, 1])), 2)
My god, it's full of CARs! | Leonidasvoice vs Modvoice
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Beitragvon rayo » Samstag 23. August 2008, 11:29

Hi

oder so:

Code: Alles auswählen

reduce(lambda x, y: (x << 1) | y, [0, 0, 0, 0, 0, 0, 1, 1])


Gruss
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Beitragvon numerix » Samstag 23. August 2008, 12:10

Nein, es geht nicht einfach darum, Binärzahlen in Dezimalzahlen umzuwandeln, sondern ein Byte als Bitmuster gelesen in 8 Byte umzuwandeln:

Also z.B. 14710 = 100100112 => [1,0,0,1,0,0,1,1]
Benutzeravatar
HerrHagen
User
Beiträge: 430
Registriert: Freitag 6. Juni 2008, 19:07

Beitragvon HerrHagen » Samstag 23. August 2008, 12:55

Bei meiner Anschlussfrage schon...

Mir gings um eine performante Variante von Binär in Dezimal.

@Leonidas: Das war auch meine erste Idee. Is aber für ein großes Array sehr langsam.
Wenn ich mirs jetzt recht überleg, brauch man ein Numpy-Array ja auch nich stückweiße in Strings umwandeln sondern kann gleich x.tostring() machen (wobei man da nur binäre Nullen und Einsen und nicht das Zeichen 0 bzw 1 hat). Deshalb könnte es doch noch recht recht fix von statten gehen.

Die Variante von rayo hat aber auf jeden Fall höchste B-Noten verdient.

Mir is auch noch was eingefallen. Dürfte sogar recht fix gehen:

Code: Alles auswählen

>>> a=numpy.array((128,64,32,16,8,4,2,1), dtype='b')
>>> x=numpy.array((0,0,0,0,0,0,1,1), dtype='?')
>>> a[x].sum()
3
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Beitragvon numerix » Samstag 23. August 2008, 13:22

HerrHagen hat geschrieben:Bei meiner Anschlussfrage schon...


Oh sorry, das habe ich übersehen, dass es inzwischen gar nicht mehr um das ursprüngliche Problem ging ... :oops:

Wer ist online?

Mitglieder in diesem Forum: Sirius3