rect Algorithmus

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.
Antworten
kl.feigling89
User
Beiträge: 42
Registriert: Montag 24. Februar 2014, 14:47

Hallo, ich habe folgenden Algorithmus im Internet gefunden, um das größte Rechteck in einem Binärbild zu finden. Leider Programmiere ich noch nicht lange und verstehe den Code nicht ganz. Ich möchte ihn gern Modifizieren um auch die Koordinaten des gefundenen Rechtecks zu erhalten und nicht nur seine Größe. Vielleicht könnt ihr mir ja helfen.

Code: Alles auswählen


from collections import namedtuple
from operator import mul
import cv2
Info = namedtuple('Info', 'start height')
 
def max_size(mat, value=0):

	it = iter(mat)
	hist = [(el==value) for el in next(it, [])]
	max_size = max_rectangle_size(hist)
	for row in it:
		hist = [(1+h) if el == value else 0 for h, el in zip(hist, row)]
		max_size = max(max_size, max_rectangle_size(hist), key=area)
	return max_size
 
def max_rectangle_size(histogram):
	stack = []
	top = lambda: stack[-1]
	max_size = (0, 0) # height, width of the largest rectangle
	pos = 0 # current position in the histogram
	for pos, height in enumerate(histogram):
		start = pos # position where rectangle starts
		while True:
			if not stack or height > top().height:
				stack.append(Info(start, height)) # push
			elif stack and height < top().height:
				max_size = max(max_size, (top().height, (pos - top().start)),key=area)
				start, _ = stack.pop()
				continue
			break # height == top().height goes here
	 
	pos += 1
	for start, height in stack:
		print 'pos',pos
		print 'start',start
		print 'height',height
		max_size = max(max_size, (height, (pos - start)), key=area)

	return max_size
 
def area(size):
	return reduce(mul, size)

#Beispiel Binärbild: 
	
#Y      0  1  2      X
arr = [[0, 0, 0, 0 ], #0
         [0, 1, 0, 0 ], #1
         [0, 0, 0, 0 ], #2
       ]	

ausgabe = max_size(arr)
print ausgabe 
#(3,2)
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@kl.feigling89: wo verstehst Du was nicht?
kl.feigling89
User
Beiträge: 42
Registriert: Montag 24. Februar 2014, 14:47

Ich suche ein Algorithmus der mir das größte Rechteck sucht und mir seine Koordinaten ausgibt.
Bei dem oberen code, weiß ich nicht wie ich an die Koordinaten des Rechteckes komme. Diese gibt nur die größe des Rechtecks aus, was er gefunden hat, leider jedoch nicht die Position.

Könnte mir jemand den Code so umschreiben das die Ausgabe so aussieht?
[höhe,breite,PositionX,PositionY]
PositionX und Y ist das obere linke Pixel des Rechteckes.
Zuletzt geändert von kl.feigling89 am Montag 7. April 2014, 12:21, insgesamt 1-mal geändert.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

kl.feigling89 hat geschrieben:Hallo, ich habe folgenden Algorithmus im Internet gefunden, um das größte Rechteck in einem Binärbild zu finden.
Code einfach von irgendwo zu kopieren ist eine schlechte Idee. Man sollte schon wissen was der Code macht.
kl.feigling89 hat geschrieben:Leider Programmiere ich noch nicht lange und verstehe den Code nicht ganz.
Wenn du Anfänger bist und Code nicht verstehst, dann hilft nur eins: Sich so lange mit dem Code beschäftigen bis du die Lösung verstanden hast. Schaue dir die einzelnen Teilprobleme an, schreibe dir ausgibige Kommentare zu den Zeilen, mache Zwischenausgaben, schlage unbekannte Funktionen nach und gehe Beispiele per Hand durch. Wenn wir dir die Lösung verraten, dann hast du nichts gelernt. Du wirst den Code wieder blind kopieren und irgendwann hier mit der nächsten Frage aufschlagen.
Das Leben ist wie ein Tennisball.
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@kl.feigling89: das Forum ist kein kostenloser Dienstleister für Programmieraufgaben. Ganz allgemein mußt Du schon selbst verstehen, was der Code macht. Wenn Du aber zu konkreten Problemen Fragen hast, kannst Du sie hier gerne stellen.
kl.feigling89
User
Beiträge: 42
Registriert: Montag 24. Februar 2014, 14:47

Okay, ihr habt wirklich recht. Sonst lerne ich die Spreche ja nie.
Dann würde ich mich aber sehr freuen wenn ihr mir diese funktion erklären könnt.
Verstehe nicht was sie macht und eine Ausgabe davon bringt mich leider auch nicht weiter.

Code: Alles auswählen

stack = []
top = lambda: stack[-1]
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

kl.feigling89 hat geschrieben:

Code: Alles auswählen

stack = []
top = lambda: stack[-1]
Im Prinzip ist die lamda-Zeile eine andere Variante von

Code: Alles auswählen

def top():
    return stack[-1]
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@kl.feigling89: "top" ist eine Funktion, die das oberste Element von stack liefert. Der Stack wird später ja noch gefüllt:

Code: Alles auswählen

>>> stack = [1,2,3]
>>> top = lambda: stack[-1]
>>> print top()
3
>>> print stack.pop()
3
>>> print top()
2
kl.feigling89
User
Beiträge: 42
Registriert: Montag 24. Februar 2014, 14:47

Okay, habs verstanden. Aber was macht dann das height hinter der top funktion?

Code: Alles auswählen

if not stack or height > top().height:
   ...
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

top() liefert dir ja ein Element aus der Liste zurück. Dieses Element hat offensichtlich ein Attribut namens height, das hier abgefragt wird.

Mit dem folgenden Code solltest du das nachvollziehen können.

Code: Alles auswählen

class Element(object):
    def __init__(self, height=0):
        self.height = height

stack = [Element(10), Element(20)]
top = lambda: stack[-1]

height = 15
print(height > top().height)
stack.pop()
print(height > top().height)
Man könnte auch so etwas schreiben, aber das wäre nur unnötig verlängert:

Code: Alles auswählen

element_to_compare = top()
print(height > element_to_compare.height)
Antworten