Sunday, 12 November 2017

Moving Average Filter Matlab Code Beispiel


KAPITEL 22 Bildverarbeitung mit MATLAB und GPU Bildverarbeitung mit MATLAB und GPU 1 Institut für Onkologie, Universität Cambridge, Cambridge, UK 1. Einleitung MATLAB (The MathWorks, Natick, MA, USA) ist ein Softwarepaket für numerische Datenverarbeitung Verwendet in verschiedenen wissenschaftlichen Disziplinen wie Mathematik, Physik, Elektronik, Ingenieurwesen und Biologie. Mehr als 40 Toolboxes gibt es im aktuellen Release (R2013b ab September 2013), zu dem zahlreiche integrierte Funktionen gehören, die durch den Zugriff auf eine Programmiersprache auf hohem Niveau erweitert werden. Da die Bilder durch 2D - oder 3D-Matrizen dargestellt werden können und die MATLAB-Verarbeitungsmaschine auf der Matrixdarstellung aller Elemente beruht, eignet sich MATLAB besonders für die Implementierung und das Testen von Bildverarbeitungs-Workflows. Die Bildverarbeitungs-Toolbox (IPT) beinhaltet alle notwendigen Werkzeuge für die universelle Bildverarbeitung mit mehr als 300 Funktionen, die optimiert wurden, um eine hohe Genauigkeit und hohe Verarbeitungsgeschwindigkeit zu bieten. Darüber hinaus wurde die integrierte Parallel Computing Toolbox (PCT) kürzlich erweitert und unterstützt nun die Grafikverarbeitungseinheit (GPU) für einige Funktionen des IPT. Für viele Bildverarbeitungsanwendungen müssen wir jedoch unseren eigenen Code entweder in MATLAB oder, im Falle von GPU-beschleunigten Anwendungen, die eine spezifische Kontrolle über GPU-Ressourcen erfordern, in CUDA (Nvidia Corporation, Santa Clara, CA, USA) schreiben. In diesem Kapitel widmet sich der erste Teil einigen wesentlichen Werkzeugen der IPT, die in der Bildanalyse und - bewertung sowie bei der Extraktion von nützlichen Informationen für die weitere Verarbeitung und Bewertung genutzt werden können. Dazu gehören das Abrufen von Informationen über digitale Bilder, Bildanpassung und Verarbeitung sowie Feature-Extraktion und Video-Handling. Der zweite Teil ist der GPU-Beschleunigung der Bildverarbeitungstechniken entweder durch die Verwendung der eingebauten PCT-Funktionen oder durch das Schreiben eigener Funktionen gewidmet. Jeder Abschnitt wird von MATLAB-Beispielcode begleitet. Die Funktionen und der Code in diesem Kapitel werden aus der MATLAB-Dokumentation 1, 2 übernommen, sofern nicht anders angegeben. 2. Bildverarbeitung auf CPU 2.1. Grundlegende Bildkonzepte 2.1.1. Pixeldarstellung Ein digitales Bild ist eine visuelle Darstellung einer Szene, die unter Verwendung einer digitalen optischen Vorrichtung erhalten werden kann. Es besteht aus einer Anzahl von Bildelementen, Pixeln und kann entweder zweidimensional (2D) oder dreidimensional (3D) sein. In der wissenschaftlichen Bildverarbeitung sind jedoch die 1-Bit-Binärbilder (Pixelwerte 0 oder 1), die 8-Bit-Graustufenbilder (Pixelbereich 0-255) und die 16 - Bit-Farbbildern (Pixelbereich 0-65535) 3. Fig. 1 zeigt die Graustufenvariation von Schwarz zu Weiß für ein 8-Bit-Bild. Variation der Graustufenintensitäten für ein 8-Bit-Bild. 2.1.2. MATLAB-Pixelkonvention MATLAB verwendet eine einstufige Indexierung, wobei das erste Pixel entlang einer beliebigen Dimension index1 hat, während viele andere Plattformen nullbasiert sind und den ersten Index als 0 betrachten. Nach der Konvention beginnt das Zählen von Pixelindizes von oben links Ecke eines Bildes, wobei die ersten und zweiten Indizes jeweils nach unten bzw. nach rechts abfallen. Abbildung 2 zeigt, wie MATLAB ein 512512 Pixel-Bild indiziert. Diese Information ist besonders wichtig, wenn der Benutzer beabsichtigt, eine Transformation auf ein bestimmtes Pixel oder eine Nachbarschaft von Pixeln anzuwenden. MATLABs-Pixelindexierungskonvention. 2.1.3. Bildformate Verschiedene Bildformate werden von MATLAB unterstützt, einschließlich der am häufigsten verwendeten, wie JPEG, TIFF, BMP, GIF und PNG. Bilder können gelesen, verarbeitet und in einem anderen Format als ihrem ursprünglichen gespeichert werden. Verschiedene Parameter wie Auflösung, Bittiefe, Kompressionsebene oder Farbraum können entsprechend den Benutzereinstellungen angepasst werden. 2.1.4. Digitale Bildverarbeitung Die digitale Bildverarbeitung bezieht sich auf die Modifikation eines digitalen Bildes mit Hilfe eines Computers, um relevante Informationen hervorzuheben. Dies kann erreicht werden, indem sowohl latente Details aufgedeckt werden als auch unerwünschte Störungen unterdrückt werden. Das Verfahren wird gewöhnlich entsprechend dem gewünschten Endresultat entworfen, das eine einfache Bildverstärkungsobjektdetektion, Segmentierung oder Verfolgungsparameterschätzung oder Zustandsklassifikation umfassen kann. Darüber hinaus kann die Struktur und Funktion des menschlichen Sehsystems bei der Behandlung von Bildern, die für die Inspektion durch Menschen bestimmt sind, ein kritischer Faktor bei der Gestaltung einer solchen Technik sein, die bestimmt, was als ein leicht unterscheidbares Merkmal wahrgenommen werden kann. 2.2. Bildvorverarbeitung Bildvorverarbeitung ist ein Verfahren, das erste Informationen über den digitalen Zustand eines Kandidatenbildes liefert. Um solche Informationen zu erhalten, müssen wir das Bild auf die Softwareplattform laden und deren Typ - und Pixelwerte untersuchen. 2.2.1. Bildeingabe und Ausgabe Wie alle anderen Daten in MATLAB werden auch Bilder durch eine Variable dargestellt. Wenn wir eine Bilddatei mit Namensbild und Format tiff betrachten, verwenden wir die Funktion imread. Kann das Bild je nach Bildtyp als 2D - oder 3D-Matrix geladen werden. Die Bildvisualisierung wird mit der Funktion imshow erreicht, um eine neue Figur zu erzeugen. Dem Aufruf eines Imshow muss ein Aufruf zur Figur vorangestellt werden. Wird stattdessen imshow eigenständig verwendet, ersetzt das neue Bild das letzte im letzten geöffneten Fenster. Das Speichern eines Bildes kann mit der Funktion imwrite erreicht werden, bei der das gewünschte Bild (d. h. Variable), das Format und der endgültige Name angegeben werden müssen. Obwohl der Name des gespeicherten Bildes frei gewählt werden kann, wird beim Aufbau einer großen Pipeline vorgeschlagen, dass der Name jedes resultierenden Bildes repräsentativ für den Verarbeitungsschritt ist, um die Prozesskohärenz aufrechtzuerhalten. Das folgende Beispiel zeigt, wie diese Reihenfolge erreicht werden kann. Die Funktion imshow kann auch von einem Zwei-Element-Vektor Low High begleitet werden, mit dem der Anwender den Anzeigebereich des Graustufenbildes spezifiziert. Wenn dieser Vektor leer bleibt. Werden die minimalen und maximalen Grauskalenwerte des Bildes als Schwarz-Weiß-Pixel mit den Zwischenwerten als verschiedene Grauschattierungen angezeigt. 2.2.2. Bildtypkonvertierungen Die Bildtypkonvertierung ist ein nützliches Werkzeug, da der Anwender das eingegebene Bild in einen beliebigen Typ umwandeln kann. Eine besondere und oft nützliche Umsetzung ist die Transformation einer ganzen Zahl ohne Vorzeichen in eine doppelte Genauigkeitsdarstellung. Jeder Bildverarbeitungsalgorithmus kann somit zu genaueren Ergebnissen führen, da diese Umwandlung den dynamischen Bereich der Intensitäten erhöht. Der Bereich des resultierenden Bildes beträgt 0,0 bis 1,0, wobei MATLAB bis zu 15 Dezimalstellen beibehält. Die folgenden Befehle sind Beispiele für Bildkonvertierungen. 2.2.3. Pixelinformation Ein Histogramm ist eine nützliche Intensitätsdarstellung, da es die Pixelintensitätsverteilung aufdeckt. Es kann mit der Funktion imhist erhalten werden. Diese Informationen können beispielsweise zur Auswahl eines geeigneten Schwellenwerts verwendet werden. Abgesehen davon kann ein Intensitätsprofil auch Informationen über lokale Intensitätsschwankungen aufzeigen, mit denen kleine Details modelliert werden können. Die Funktion improfile kann entweder auf vorgewählte Pixel oder als Eingabeaufforderung für den Benutzer angewendet werden, um den gewünschten Bereich manuell auszuwählen. Beispiel eines Codes für solche Prozesse folgt 1, 3. 2.2.4. Kontrasteinstellung Eine der Hauptvorverarbeitungstechniken ist die Kontrasteinstellung, da dieser Vorgang die gewünschten Merkmale verbessern kann, während andere, unerwünschte Unterdrückungen unterdrückt werden. MATLAB verfügt über verschiedene Werkzeuge zur Veränderung des Bildkontrasts. Die Funktion imcontrast liefert ein manuelles Justierwerkzeug, mit dem der Anwender experimentieren und den optimalen Kontrast finden kann. Die resultierenden Parameter können dann übernommen, gespeichert und auf einen unter den gleichen Bedingungen aufgenommenen Stapel von Bildern angewendet werden. Die Funktion imadjust kann verwendet werden, um einen Intensitätsbereich festzulegen, wenn der Benutzer die optimalen Werte kennt oder mit dem Imcontrast-Tool gefunden hat. Die gleiche Funktion liefert auch die Eingabe für den Gamma-Faktor der nichtlinearen Leistungsregelung. Darüber hinaus kann eine maßgeschneiderte logarithmische Transformation angewendet werden 3. Fig. 3 zeigt ein ursprüngliches Graustufenbild und sein kontrastjustiertes Gegenstück unter Verwendung der Parameter, die in dem vorhergehenden Beispiel spezifiziert wurden. Originalbild (links, 12961936 Pixel) und Kontrasteinstellung (rechts). Parameter a. B und c können durch den Benutzer definiert und angepasst werden, dh jede derartige maßgeschneiderte logarithmische Transformation kann entsprechend den spezifischen Bedürfnissen eingeführt werden. Andere Techniken, die den Kontrast beeinflussen können, sind histogrammbasiert. Ein Histogramm repräsentiert eine Graustufenintensitätsverteilung oder eine Wahrscheinlichkeitsdichtefunktion. Solches Wissen kann bei der Weiterverarbeitung helfen, indem es dem Benutzer hilft, die richtigen Werkzeuge auszuwählen 4. Die Histogrammstreckung kann durch die Imadjust-Funktion durchgeführt werden, während die Histogrammausgleichung durch die Funktion histeq durchgeführt werden kann. Die adaptive Histogramm-Entzerrung kann auch mit der Funktion adaptthisteq angewendet werden, die kleine Bildnachbarschaften anstelle des gesamten Bildes als Eingabe betrachtet. Der Parameter NumTilesValue hat die Form eines Vektors, der die Anzahl der Kacheln in jeder Richtung angibt. Andere Parameter können auch in der adapthisteq-Funktion angegeben werden, wie zB der Dynamikbereich der Ausgangsdaten oder die Histogrammform. Fig. 4 zeigt Beispiele für die Histogramm-Entzerrung bzw. die adaptive Histogramm-Entzerrung. Histogramm-Entzerrungstransformation (links) und adaptive Histogramm-Entzerrungstransformation (rechts) des Originalbildes in Abbildung 3. Beachten Sie die erweiterten Details im rechten Bild. 2.2.5. Arithmetische Operationen Arithmetische Operationen beziehen sich auf Addition, Subtraktion, Multiplikation und Division von zwei Bildern oder ein Bild und eine Konstante. Bilder, die arithmetischen Operationen unterliegen, müssen dieselben Dimensionen und Graustufenrepräsentationen aufweisen. Das resultierende Bild hat die gleichen Abmessungen wie die Eingabe. Wenn ein konstanter Wert addiert oder subtrahiert wird (anstelle eines zweiten Bildes), wird diese Konstante zu jeder Pixelintensität addiert oder subtrahiert, wodurch die Bildhelligkeit erhöht oder verringert wird. Meistens werden solche Operationen zur Detailverbesserung oder Unterdrückung unnötiger Informationen verwendet. In dem obigen Code kann der zweite Eingangsparameter (im2) durch eine skalare Konstante ersetzt werden. 2.2.6. Verschiedene Transformationen Andere nützliche Bildtransformationen umfassen das Zuschneiden, die Größenänderung und die Rotation. Zuschneiden kann verwendet werden, wenn der Benutzer nur an einem bestimmten Teil des Eingabebildes interessiert ist. Der Benutzer kann einen bestimmten Bereich von Interesse definieren und jede Transformation nur auf diesen Teil anwenden. Größenänderung kann angewendet werden, um die Bildgröße zu erweitern oder zu verkleinern. Die Bildgrößenverringerung kann insbesondere bei der Beschleunigung eines Prozesses bei größeren Bildern oder großen Datensätzen nützlich sein. Die Rotation kann besonders nützlich sein, wenn ein Bild Merkmale einer bestimmten Direktionalität aufweist. Der Benutzer kann die angewendete Interpolationsmethode aus nächster Nachbarschaft, bilinear und bikubisch spezifizieren. Inversion von Graustufen-Intensitäten kann nützlich sein, wenn die interessanten Objekte haben Intensitäten niedriger als der Hintergrund. Folgende Funktionen führen diese Prozesse aus. 2.3. Bildverarbeitung 2.3.1. Thresholding Thresholding ist eines der wichtigsten Konzepte der Bildverarbeitung, da es in fast allen Projekten Anwendung findet. Thresholding kann manuell oder automatisch, global oder lokal sein. Im manuellen Modus definiert der Benutzer einen Schwellenwert, der in der Regel von der Konzeption des Bildes abhängt (es können mehrere Versuche erforderlich sein). Im automatischen Modus ist ein genaues Verständnis des Bildes erforderlich, um die richtige Methode auszuwählen. Das IPT stellt die Funktion graythresh zur Verfügung, die auf der Otsus-Methode und dem bimodalen Zeichen eines Bildes 5 basiert. Diese globale Schwelle erzeugt ein Schwarz-Weiß-Bild, bei dem Pixel mit Intensitäten oberhalb dieses Schwellenwerts weiß werden (Wert 1), und Pixel mit Intensitäten unterhalb dieses Schwellenwerts werden schwarz (Wert 0). Diese Methode kann problemlos auf Multi-Thresholding erweitert werden, indem die IPT-Funktion Multithresh verwendet wird. Mit dieser Funktion legt der Benutzer eine geeignete Anzahl von Schwellenwerten (k) für das Bild fest. Wird dieser Parameter nicht mitgeliefert, hat er die gleiche Funktionalität wie die ursprüngliche graythresh-Funktion. Das IPT kann das Ergebnis der Multithresh-Funktion mit der Imquantisierungsfunktion visualisieren. Dieser markiert die verschiedenen Bereiche des Bildes entsprechend der Anzahl der zuvor festgelegten Schwellenwerte. Das markierte Bild kann dann in ein RGB-Bild transformiert werden, wobei der Typ (z. B. uint8) der ursprünglichen Eingabe erhalten bleibt. Der folgende Code kann in diesen Prozessen verwendet werden. 5 stellt ein Beispiel einer Ein-und Mehrfachschwellenanwendung für das Originalbild von 3 bereit. Einschwelliges Bild (links) und mehrschwelliges Bild mit 5 Schwellenwerten (rechts). 2.3.2. Kantenerkennung Die Kantenerkennung ist ein wesentlicher Bestandteil der Bildverarbeitung, da sie in der Regel Objekte oder eine interne Struktur hervorhebt. Eine Kante ist eine Darstellung der Diskontinuität in einem Bild und kann eine Oberfläche charakterisieren, die zwei Objekte oder ein Objekt von dem Bildhintergrund 4 trennt. Boundaries können durch einzelne Pixel oder verbundene Sequenzen von Pixeln charakterisiert werden. Ein solches Merkmal kann bei einer weiteren Objekterkennung helfen und somit wird die Kantenerfassung in vielen Bildverarbeitungssequenzen angewendet. Das Ergebnis der Kantenerfassung ist ein binäres Bild mit Kanten, die von weißen Pixeln dargestellt werden. 2.3.3. Kantenerfassungsoperatoren erster Ordnung Die IPT umfasst die standardmäßigen Kantendetektoren erster Ordnung wie die Roberts, Sobel und Prewitt. Roberts Randdetektor stützt sich auf 22 Masken, während die anderen zwei auf 33 Masken verlassen. Ein optionaler Schwellenwert kann festgelegt werden, um die minimale Gradientengröße zu definieren. Nützlicher Code für solche Detektoren folgt. Andere Kantendetektoren erster Ordnung können auch entworfen werden. Beispiele sind die Kirsch - und die Robinson-Masken, die nicht im IPT enthalten sind, sondern einfach zu entwerfen sind. Sie sind Beispiele von Richtungsranddetektoren, die das Bild aus verschiedenen Richtungen abtasten, um Kanten mit verschiedenen Orientierungen zu detektieren. Es wird ein einziger Kern verwendet, der durch Rotationen von 0 bis 315 in Schritten von 45 acht verschiedene Masken erzeugt. Das Bild wird mit jeder Maske gefaltet und den Pixeln in dem endgültigen Bild wird die höchste Kantenerfassungsgröße zugewiesen, die von irgendeiner der Masken 4 erhalten wird. Der folgende Code stellt diese zwei Kantendetektoren 6 bzw. 4 dar. Der Punktdetektor, ein weiteres Beispiel eines Kantendetektors, erfasst helle Punkte basierend auf der Intensitätsdifferenz zwischen einem zentralen Pixel und seinen Nachbarn. Ein Punktdetektor kann durch den folgenden Code 7 spezifiziert werden. 2.3.4. Kantendetektionsoperatoren zweiter Ordnung Neben Kantendetektoren erster Ordnung können Kantendetektoren zweiter Ordnung breite Anwendung finden. Solche Detektoren sind beispielsweise Canny, Nulldurchgang und Laplace-of-Gaussian (LoG, auch Marr-Hildreth genannt). Das Canny-Verfahren verwendet die Ableitung eines Gaußschen Filters, um den Gradienten des Originalbildes zu finden, wonach es auf lokalen Maxima des resultierenden Bildes beruht. 3 Die Nulldurchgangsmethode sucht nach einem beliebigen Filter nach Nulldurchgängen. Schließlich sucht das LoG-Verfahren nach der Anwendung der LoG-Transformation nach Nulldurchgängen. Nützlicher Code für solche Detektoren folgt. In diesem Fall bezieht sich die Schwelle auf die Stärke eines Kanten-Sigmas, das sich auf die Standardabweichung des Gaußschen Filters bezieht, während das Filter auf alle Filter zutrifft, die der Benutzer vor der Kantenerfassung anwendet. Bei LoG - und Canny-Methoden können Schwelle und Sigma nicht spezifiziert werden, aber im Falle der Nulldurchgangsmethode muss der Benutzer einen Filter definieren. Fig. 6 zeigt die resultierenden Bilder nach dem Aufbringen von Roberts - und Canny-Randdetektoren. Anwendung von Roberts Randdetektor (links) und Canny Randdetektor mit einem Schwellenwert von 0,05 (rechts). 2.3.5. Bildfilterung Die räumliche Filterung ist einer der wichtigsten Prozesse in der Bildverarbeitung, da sie bestimmte Frequenzen aus einem Bild extrahieren und verarbeiten kann, während andere Frequenzen entfernt oder transformiert werden können. Normalerweise wird die Filterung zur Bildverbesserung oder zur Rauschentfernung verwendet. IPT enthält die Standard-Werkzeuge, die für die Bildfilterung benötigt werden. Die Funktion fspecial kann für das Filterdesign verwendet werden. Mittlere, mittlere, Gaußsche, Laplace-, Laplace-von-Gaussian-, Bewegungs-, Prewitt-edge - und Sobel-edge-Filter können eingeführt werden. Das erzeugte Filter wird mit der Funktion imfilter auf das Bild angewendet. Typische Beispiele für Code folgen. Der Parameter hsize ist ein Vektor, der die Anzahl der Zeilen und Spalten der Nachbarschaft repräsentiert, die beim Anwenden des Filters verwendet wird. Der Parameter Sigma ist die Standardabweichung des angewandten Gaußschen Filters. Kantendetektoren können auch angewendet werden, indem das Bild mit dem Kantenoperator gefiltert wird. Ein Beispiel folgt mit der Anwendung des zuvor erwähnten Punktkantendetektors. Neben benutzerdefinierten Filtern enthält IPT Filter, die direkt auf das Bild angewendet werden können. Solche Beispiele sind der Medianfilter (medfilt2), der Wiener-Filter (wiener2) oder der 2D-Ordnungsstatistikfilter (ordfilt2). Die Nachbarschaft in der Funktion medfilt2 gibt die Abmessungen des Bereichs an, in dem der Medianwert des Pixels gefunden wird. Die Funktion ordfilt2 ist eine verallgemeinerte Version des Medianfilters. Eine Nachbarschaft wird durch die Nicht-Null-Pixel der Domäne definiert. Und jedes Pixel in dem Bild wird durch die Ordnung - dkleinster seiner Nachbarn innerhalb dieses Bereichs 1 ersetzt. Ein Beispiel könnte der folgende Befehl sein, wobei jedes Pixel durch den sechsten kleinsten Wert ersetzt wird, der in seiner 33 Nachbarschaft gefunden wird. 7 zeigt Beispiele für Gaußsche und Ordnungsstatistik-gefilterte Bilder. Die Bilder wurden mit einem Gaußschen Filter (links hsize 9 9 und sigma 1) und einem statistischen Filter der 6. Ordnung (rechts) gefiltert. 2.3.6. Morphologische Bildverarbeitung Morphologische Bildverarbeitung bezieht sich auf die Extraktion von Deskriptoren, die interessierende Objekte beschreiben und damit deren Morphologie die verwendeten Werkzeuge bestimmen 8. Strukturelemente werden verwendet, um das Bild 3 zu untersuchen. Die Funktion bwmorph führt alle morphologischen Operationen mit geeigneten Parametern durch. Da die Verarbeitungszeit dieser Funktion mit der Bildkomplexität signifikant zunehmen kann, wird sie durch die PCT für eine erhöhte Verarbeitungsgeschwindigkeit unterstützt. Morphologische Prozesse umfassen Dilatation, Erosion, Öffnen, Schließen, Top-Hat und Bottom-Hat-Transformation, Hit-or-Miss-Transformation sowie andere Prozesse, die pixel-spezifische Änderungen durchführen. Die Parameteroperation berücksichtigt die Art des morphologischen Operators, während n die Anzahl der Wiederholungen dieses Vorgangs ist. Wenn n nicht definiert ist, wird der Prozess nur einmal angewendet. Prozesse wie Dilatation und Erosion können auch mit individuellen Funktionen angewendet werden, wenn ein maßgeschneidertes Strukturierungselement eingesetzt werden soll. Beispiele für einzelne Prozesse folgen. Fig. 8 zeigt Beispiele der Dilatation und Top-Hat-Transformation mit einem Scheibenstrukturierungselement des Radius 10. Diliertes Bild (links) und ein tophut-transformiertes Bild unter Verwendung eines Scheibenstrukturierungselements mit Radius 10 (rechts). Die Abstandstransformation wird üblicherweise auf binäre Bilder angewendet und stellt den Abstand zwischen einem weißen Pixel und seinem nächsten Nullpixel dar. Pixel im neuen Bild erhalten höhere Werte mit größerem Abstand von einem Nullpixel. Diese Transformation kann als Segmentierungsfunktion wirken und wird häufig bei der Segmentierung von überlappenden Scheiben 1, 8 verwendet. 2.3.7. Farbverarbeitung Farbbilder unterliegen der Verarbeitung in vielen wissenschaftlichen Bereichen, da unterschiedliche Farben unterschiedliche Funktionen darstellen können. Die am häufigsten verwendete Farbdarstellung ist RGB (Rot-Grün-Blau). Die Transformation von RGB-Bildern in Graustufenintensität oder Extraktion einer bestimmten Farbe kann mit dem folgenden Code erfolgen: 2.4. Feature-Extraktion Feature-Extraktion ist der Prozess, durch den erkannte Objekte nach bestimmten geometrischen Kriterien bewertet werden. Der erste Schritt dieses Prozesses besteht darin, die Objekte eines binären Bild-Imbins mit der Funktion bwlabel zu kennzeichnen. Das resultierende Bild wird als markiertes Bild (imlab) bezeichnet. Die Funktion scannt das Bild von oben nach unten und von links nach rechts, wobei jedem Pixel eine Zahl zugewiesen wird, die angibt, zu welchem ​​Objekt es gehört. Zusätzlich verfügt das IPT über die Funktion regionprops, die Merkmale markierter Objekte wie Fläche, äquivalenter Durchmesser, Exzentrizität, Umfang und Haupt - und Nebenachsenlängen mißt. Diese Funktion arbeitet mit beschrifteten Bildern, die n beschriftete Objekte enthalten. Eine vollständige Liste der Funktionen, die mit regionprops berechnet werden können, finden Sie in der MATLAB IPT-Dokumentation 1. Neben den Standardfunktionen, die im IPT enthalten sind, können kundenspezifische Merkmale entweder mit bereits berechneten Merkmalen oder mit völlig neuen Messungen gemessen werden. Ein Beispiel könnte die Messung von geometrischen Eigenschaften eines Objekts, des Dünnheitsverhältnisses und der Kompaktheit (oder Unregelmäßigkeit) unter Verwendung einer for-Schleife zur Bewertung aller n Objekte sein. Da der Benutzer viele Messungen für viele Objekte durchführen muss, ist es gewöhnlich zweckmäßig, Speicher vorzuverteilen, um die Verarbeitungszeit zu verkürzen. Mit dem folgenden Code können Sie Bildobjekte beschriften, die Merkmale messen und als Tabelle der Variablen 1, 3 speichern. Gemessene Merkmale werden in Strukturarrays gespeichert. Normalerweise erfordert die weitere Verarbeitung von Merkmalen die Transformation von Strukturanordnungen in Matrizen. MATLAB kann solche Transformationen nicht ohne die Anwendung eines Zwischenschrittes durchführen: Die Struktur-Arrays müssen zunächst in Zell-Arrays umgewandelt werden, die wiederum in Matrizen umgewandelt werden können. Beachten Sie, dass die Transponierung der Zellarray-Zellenfunktionen verwendet wurde, um Funktionen an Matrixspalten anstelle von Zeilen zuzuordnen. Aus Performancegründen ist es in der Regel am besten, die Daten so zu orientieren, dass sie spaltenweise und nicht zeilenweise bearbeitet werden. In diesem Fall erwarten wir, dass wir das Datenmerkmal nicht mehr nach Bild sondern nach Merkmal durchlaufen. 2.5. Verarbeitung von Bildern In vielen Fällen kann die Handhabung von mehreren Bildern eine aufwändige Aufgabe sein, es sei denn, ein automatisierter Prozess kann hergestellt werden. Angenommen, wir haben eine Charge von 100 Bildern, die wir verarbeiten möchten, mit einer for-Schleife und der Definition des Pfads zum Image-Verzeichnis, können wir laden, verarbeiten und speichern Sie die Bilder ein zu einer Zeit. Nach dem Speichern des ersten Bildes wird automatisch das nächste Verzeichnis geladen, verarbeitet und gespeichert. Der Vorgang wird fortgesetzt, bis das letzte Bild gespeichert ist. Der folgende Code führt diesen Vorgang aus. 2.6. Videoverarbeitung 2.6.1. Video to frames Eine interessante Anwendung für die Bildverarbeitung ist die Handhabung von Videodaten. In diesem Fall muss die Videodatei in einzelne Frames unterteilt werden. Die Funktion VideoReader kann verwendet werden, um die Datei als Variable einzugeben. Für n Rahmen wird jeder Rahmen dann als separates Bild in jedem Format gespeichert. Der folgende Code liest ein Video (genannt Film) zu einer MATLAB-Struktur und speichert die Frames eins nach dem anderen in das TIFF-Format. 9 2.6.2. Frames to video Da jedes Frame als einzelnes Bild gespeichert wird, kann es entweder einzeln oder im Batch-Modus entsprechend verarbeitet werden. Ein möglicher nächster Schritt in diesem Prozess kann sein, die verarbeiteten Bilder zu einem einzigen Video wieder zu kombinieren. Wenn aus Frames (Frame) ein neuer Film (genannt movienew) erzeugt werden soll, liefert der folgende Code das Backbone für einen solchen Prozess 9. 3. Bildverarbeitung auf GPU in MATLAB Große Mengen an Bilddaten werden in vielen technischen und experimentellen Situationen produziert, insbesondere dort, wo Bilder im Laufe der Zeit immer wieder aufgenommen werden oder bei Bildern mit höherer Dimensionalität als zwei. Zeitraffer-Bilderzeugung und Videoaufzeichnung können als Beispiele der ersteren erwähnt werden, während die letzteren durch irgendeine der vielen vorhandenen tomographischen Bildgebungsmodalitäten repräsentiert werden können. 4D-Computertomographie (CT), in der 3D-CT-Bilder in regelmäßigen Intervallen zur Überwachung der internen Patientenbewegung erfasst werden, ist ein Beispiel für eine Anwendung, die beide Kategorien betrifft. Es ist oft wünschenswert oder sogar kritisch, die Analyse und Verarbeitung solcher großen Bilddatensätze zu beschleunigen, insbesondere für Anwendungen, die in oder nahezu in Echtzeit laufen. Aufgrund der inhärent parallelen Natur vieler Bildverarbeitungsalgorithmen sind sie für die Implementierung auf einer Grafikverarbeitungseinheit (GPU) gut geeignet, und folglich können wir eine wesentliche Beschleunigung von einer solchen Implementierung über einen auf einer CPU laufenden Code erwarten. Trotz der Tatsache, dass GPUs heute in Desktop-Computern ubiquitär sind, sind in der aktuellen MATLAB-Version (2013b) nur 34 der mehreren hundert Funktionen des IPT durch den PCT GPU-fähig. In diesem Unterkapitel werden wir die Möglichkeiten für jemanden erforschen, der entweder die Rechenleistung der GPU direkt aus MATLAB nutzen oder einen externen GPU-Code in MATLAB-Programme einbinden möchte. Der Schwerpunkt liegt auf Bildverarbeitungsanwendungen, aber die dargestellten Techniken können mit geringem oder ohne Aufwand an andere Anwendungen angepasst werden. Im ersten Teil dieses Teils wird untersucht, wie die integrierten, GPU-fähigen Bildverarbeitungsfunktionen des PCT verwendet werden können. Im Folgenden erklären wir, wie pixelweise Manipulationen mit der GPU-fähigen Version von arrayfun durchgeführt werden können und wie wir unsere eigenen Bildverarbeitungsfunktionen schreiben können, die von über hundert elementaren MATLAB-Funktionen, die implementiert wurden, um auf GPUs laufen, implementiert zu werden. Im zweiten Teil dieses Abschnitts zeigen wir, wie mit dem PCT Kernel-Funktionen aufgerufen werden können, die in der CUDA-Programmiersprache direkt von MATLAB geschrieben werden. Damit können wir in unseren MATLAB-Anwendungen die vorhandenen Kernelfunktionen nutzen. Darüber hinaus ist es für diejenigen mit Wissen über CUDA, macht es mehr von der GPU-Potenzial verfügbar von MATLAB und bietet auch eine einfache Möglichkeit, Kernel-Funktionen in der Entwicklung zu testen. Der dritte und letzte Teil ist für fortgeschrittene Benutzer gedacht, die eine der von NVIDIA zur Verfügung gestellten CUDA-Bibliotheken nutzen möchten, die es vorziehen, ihren Code in einer anderen Sprache als CUDA zu schreiben, die keinen Zugriff auf die Parallel Computing Toolbox hat Die Zugriff auf eine vorhandene GPU-Codebibliothek haben, die sie von MATLAB anrufen möchten. Wir untersuchen, wie CUDA-Code direkt in MEX-Funktionen mit dem PCT kompiliert werden kann, gefolgt von einer Beschreibung, wie GPU-Code in entweder CUDA oder OpenCL kann von MATLAB zugänglich gemacht werden, indem Sie es in einer Bibliothek und die Schaffung einer MEX-Wrapper-Funktion um ihn herum . Schließlich zeigen wir, wie der Code für eine MEX-Wrapper-Funktion direkt in unserem externen Compiler erstellt werden kann und z. B. in einer vorhandenen Lösung von Visual Studio (Microsoft Corporation, Redmond, WA, USA) enthalten ist, so dass dies automatisch beim Bauen erfolgt die Lösung. 3.1. GpuArray und integrierte GPU-fähige Funktionen Für die Beispiele in diesem Teil benötigen wir einen Computer, der mit einer NVIDIA GPU der CUDA-Berechnungsfähigkeit 1.3 oder höher ausgestattet ist, die vom PCT 10 korrekt eingerichtet und erkannt wird. Mit den Funktionen gpuDeviceCount und gpuDevice können Sie eine GPU identifizieren und auswählen, wie in der PCT-Dokumentation 11 beschrieben. Um ein Bild auf der GPU verarbeiten zu können, müssen zunächst die entsprechenden Daten aus dem Haupt-CPU-Speicher über den PCI-Bus in den GPU-Speicher kopiert werden. In MATLAB werden Daten auf der GPU über Objekte vom Typ gpuArray aufgerufen. Der Befehl erzeugt ein neues gpuArray-Objekt namens imGpu und weist ihm eine Kopie der Bilddaten im im zu. ImGpu vom selben Typ wie im (z. B. double, single int32 etc.) sein, was die Leistung der GPU-Berechnung beeinträchtigen könnte, wie unten diskutiert wird. Lassen Sie uns jetzt davon ausgehen, dass im ist ein 30723072 Array von einzelnen Genauigkeit Gleitkommazahlen (single). Entsprechend, wenn wir alle unsere GPU-Berechnungen ausgeführt haben, rufen wir die Funktion sammeln, um das Ergebnis abzurufen. Zum Beispiel kopiert die Daten in das gpuArray-Objekt resultGpu zurück, um zu einem CPU-Speicher zu führen. Im Allgemeinen ist das Kopieren von Daten über den PCI-Bus relativ langsam, was bedeutet, dass bei der Arbeit mit großen Datensätzen sollten wir versuchen, unnötige Kopien zwischen CPU und GPU-Speicher zu vermeiden. Wenn möglich, kann es daher schneller sein, Filter, Masken oder Zwischenprodukte direkt auf der GPU zu erzeugen. Zu diesem Zweck verfügt gpuArray über mehrere statische Konstruktoren, die den Standard-MATLAB-Funktionen entsprechen. Falsch Inf. Nan Einsen . wahr . Nullen. Linspace. Logspace. Rand Randi und randn. Um den GPU-Speicher vorher zuzuweisen und zu initialisieren. Diese können durch Aufrufen von gpuArray aufgerufen werden. Konstruktor, wo Konstruktor durch den Funktionsaufruf ersetzt wird. Zum Beispiel erstellt eine 3072 3072 Array von normal verteilten Pseudozufallszahlen mit Null-Mittelwert und Standardabweichung ein. Wie bei den entsprechenden Standard-MATLAB-Funktionen gibt das letzte Funktionsargument den Array-Element-Typ (in diesem Fall single) an, und wenn er weggelassen wird, ist er standardmäßig doppelt. Obwohl dies bei der Arbeit an modernen CPUs normalerweise nicht problematisch ist, lohnt es sich zu beachten, dass NVIDIAs Consumer-GPUs bei der Verarbeitung einzelner Fließkommazahlen (single) im Vergleich zu doppelter Genauigkeit (double) oder ganzen Zahlen (int32 ). Dies bedeutet, dass dort, wo doppelte Genauigkeit nicht entscheidend ist, es eine gute Angewohnheit ist, Arrays auf der GPU als einzelne Genauigkeit zu deklarieren. Alternativ können die ersten sieben statischen Konstruktoren, die oben aufgelistet sind, durch ihre entsprechende MATLAB-Funktion aufgerufen werden, indem die Argumentliste mit gpuArr ay angehängt wird. Z. B. Erstellt ein gpuArray-Objekt, das 30723072 32-Bit-Integer (int32) enthält, die auf Null initialisiert werden. Beim Aufruf dieser Funktionen ist eine Alternative zum expliziten Angeben des Typs das gleiche Argument. Dies erzeugt ein Array des gleichen Typs wie das Argument, das dem gleichen Argument folgt, d. h. ein gpuArray-Objekt von int32-Werten erzeugt, die auf 1 initialisiert sind, während ein Standard-MATLAB-Array von Einzelwerten erstellt wird, die zu einem initialisiert werden. Dies kann nützlich sein, wenn Sie neue Variablen in Funktionen erstellen, die sowohl auf der CPU als auch in der GPU laufen sollen, wo wir keine Vorkenntnisse über den Eingabetyp haben. Damit ein gpuArray-Objekt komplexe Zahlen enthalten kann, muss es explizit bei der Konstruktion angegeben werden, indem es entweder das komplexe Argument verwendet, wenn es direkt in der GPU erzeugt wird, oder durch explizites Gießen beim Kopieren nicht komplexer Daten, z. B. GpuArray (komplex (im)). Um die Eigenschaften eines GPU-Arrays zu überprüfen, können wir die Standard-MATLAB-Funktionen wie Größe verwenden. Länge. Isreal usw. Darüber hinaus gibt die Funktion classUnderlying die Klasse zurück, die dem GPU-Array zu Grunde liegt (da class einfach gpuArray zurückgibt), während existsOnGPU den Wert true zurückgibt, wenn das Argument ein GPU-Array ist, das auf der GPU vorhanden ist und auf das zugegriffen werden kann. Sobald sich unsere Bilddaten im GPU-Speicher befinden, haben wir zwei Möglichkeiten, sie zu manipulieren: Entweder können wir die Sub-Menge der eingebauten MATLAB-Funktionen (einschließlich einiger Funktionen in Toolboxes) verwenden, die auf der GPU laufen, oder wir können schreiben Unsere eigenen Funktionen verwenden nur elementweise Operationen und starten sie durch arrayfun oder bsxfun. In the first case, we use normal MATLAB syntax with the knowledge that any of these functions are automatically executed on the GPU as long as at least one argument is of type gpuArray . Using imGpu and randNoiseGpu defined above we can create a new, noisy image on the GPU by typing: A list of the GPU-enabled MATLAB functions available on the current system, together with all static constructors of gpuArray . can be displayed by typing methods(gpuArray) . For MATLAB 2013b, the list comprises around 200 standard functions plus any additional functions in installed toolboxes 2 . For example, using the GPU-enabled function imnoise from the IPT, the same result as above can be obtained through: (where a variance of 0.09 equals a standard deviation of 0.3). Another, potentially more useful, GPU-enabled function from the IPT is imfilter . Using imGpu from earlier filters the image using a horizontal Sobel filter. Note that sobelFilter is an ordinary 2D MATLAB array, 1 2 1 0 0 0 -1 -2 -1 . but since imGpu is a GPU array, the GPU-enabled version of imfilter is automatically called and the output, filteredImGpu . will be a GPU array. The second option for manipulating GPU arrays directly from MATLAB is by calling our own functions through the built-in bsxfun or arrayfun functions. As before, if any of the input arguments to the function is a GPU array, the calculation will automatically be carried out on the selected GPU. Thus, a third way of producing a noisy version of imGpu would be to first create the function addAndOffset that performs an element-wise addition of two images and adds a constant offset: and then calling The benefit of writing functions and launching them through bsxfun or arrayfun compared to calling MATLAB functions directly on GPU arrays is a potential speedup for large functions. This is because in the former case, the whole function can automatically be compiled to a GPU function, called CUDA kernel, resulting in a single launch of GPU code (although the overhead for compiling the function will be added to the first call). In contrast, in the latter case, each operation has to be launched in sequence using the precompiled kernel functions available in MATLAB. However, when running on a GPU, arrayfun and bsxfun are limited to element-wise operations. In a typical image processing application, this means that each pixel is unaware of its neighbours, which limits the use to functions where pixels are processed independently of one another. As a result, many image filters cannot be implemented in this way, in which case we are left either to use built-in functions as described earlier, or to write our own kernel functions as described in the next part. Further, since we are constrained to element-wise manipulations, the number of built-in functions at our disposal inside our function is somewhat limited. For a complete list of the available built-in functions, as well as some further limitations when using bsxfun and arrayfun with GPU arrays, see the PCT documentation 12 . Before moving on to the next part we should stress that since GPUs are built to process large amounts of data in parallel, there is no guarantee that running code on a GPU instead of a CPU will always result in a speedup. Although image processing algorithms provide good candidates for substantial speedups, this characteristic of the GPU means that vectorisation of code and simultaneous processing of large amounts of data (i. e. avoiding loops wherever possible) becomes even more crucial than in ordinary MATLAB programs. Further, GPU memory latency and bandwidth often limit the performance of GPU code. This can be alleviated by ensuring that, as far as possible, data that are operated on at the same time are stored nearby in memory. Since arrays are stored in a sequential column-major order in MATLAB, this means avoiding random memory-access patterns where possible and organising our data so that we mostly operate on columns rather than on rows. Finally, when evaluating the performance of our GPU code we should use the function gputimeit . It is called in the same manner as the regular MATLAB function timeit . i. e. it takes as argument a function, which itself does not take any arguments, and times it, but is guaranteed to return the accurate execution time for GPU code (which timeit is not). If this is not feasible, the code section we want to time can be sandwiched between a tic and a toc . as long as we add a call to wait(gpuDevice) just before the toc . This ensures that the time is measured only after execution on the currently selected GPU has finished. (Otherwise MATLAB continues to execute ensuing lines of GPU-independent code, like toc . asynchronously without waiting for the GPU calculation to finish). Since the MATLAB profiler only measures CPU time, we need to employ a similar trick to get accurate GPU timings when profiling: if we sandwich the lines or blocks of GPU code we want to time between two calls to wait(gpuDevice) . the execution time reported for the desired line or block plus the time taken by the second call to wait gives the correct timing. 3.2. Calling CUDA kernel functions from MATLAB By using the techniques described in the previous part we can use MATLAB to perform many of our standard image processing routines on the GPU. However, it does not allow us to test our own CUDA-implemented algorithms or use existing ones in our MATLAB programs, nor does it provide a means to explicitly control GPU resources, such as global and shared memory. In this part we demonstrate how this can be remedied by creating a CUDAKernel object from a kernel function written in CUDA. Instructions on how to write CUDA code is well beyond the scope of this chapter, and therefore this part assumes some previous basic knowledge of this language. A CUDAKernel object required to launch a CUDA kernel function from MATLAB is constructed by calling the static constructor parallel. gpu. CUDAKernel . The constructor takes three MATLAB string arguments: the path to a . ptx file containing the kernel code, the interface of the kernel function, and the name of the desired entry point. For the first argument, a . ptx file with the same name as the source file, containing the corresponding code compiled into pseudo-assembly language, is automatically generated when using the NVIDIA CUDA Compiler (NVCC) with the flag - ptx to compile a . cu file (if it contains one or more kernel functions). (Note that if using an integrated development environment, you might have to instruct it not to delete . ptx files when finishing the build for example Visual Studio 2010 requires that the flag - - keep is used.) The second argument can be either the . cu file corresponding to the . ptx file specified in the first argument, from which the argument list of the desired kernel function can be derived, or the explicit argument list itself. The latter is useful when the . cu file is not available, or when the argument list contains standard data types that have been renamed through the use of the typedef keyword. The third argument specifies which kernel function in the . ptx file to use, and although NVCC mangles function names similar to a C compiler, the names in the . ptx file are guaranteed to contain the original function name. MATLAB uses substring matching when searching for the entry point and it is therefore often enough to provide the name of the original kernel function (see exceptions below). Let us assume that we have access to myFilters. cu containing several kernel functions named myFilter1 . myFilter2 . etc. and its corresponding myFilters. ptx . Then creates a CUDAKernel object called gpuFilter1 that can be used to launch the CUDA kernel function myFilter1 from MATLAB. If we further assume that myFilter1 is declared as the second argument above, myFilters. cu . could equally be replaced by the string const float , float , float . In some cases, care has to be taken when specifying the entry point. For example, if myFilter2 is a templated function instantiated for more than one template argument, each instance of the resulting function will have a name containing the string myFilter2 . Likewise, if another kernel function called myFilter1v2 is declared in the same . cu file, specifying myFilter1 as the third argument of parallel. gpu. CUDAKernel becomes ambiguous. In these cases, we should provide the mangled function names, which are given during compilation with NVCC in verbose mode, i. e. with - - ptxas-options-v specified. The full mangled name of the kernel used by a CUDAKernel object is stored in the object property EntryPoint . and can be obtained by e. g. gpuFilter1.EntryPoint. Once a CUDAKernel object has been created, we need to specify its launch parameters which is done through the ThreadBlockSize . GridSize and SharedMemorySize object properties. Thus, sets the block size to 328 threads, the grid size to 96384 blocks and the shared memory size per block to 43281024 bytes, enough to hold 256 single or int32 values, or 128 double values. In total this will launch 30723072 threads, one per pixel of our sample image. A fourth, read-only property called MaxThreadsPerBlock holds the upper limit for the total number of threads per block that we can use for the kernel function. If the kernel function is dependent on constant GPU memory, this can be set by calling setConstantMemeory . taking as the first parameter the CUDAKerner object, as the second parameter the name of the constant memory symbol and as the third parameter a MATLAB array containing the desired data. For example, we can set the constant memory declared as constant float myConstData 128 in myFilters. cu and needed in myFilter1 To execute our kernel function we call feval with our GPUKernel object as the first parameter, followed by the input parameters for our kernel. For input parameters corresponding to arguments passed by value in the CUDA kernel (here: scalars), MATLAB scalars are normally used (although single element GPU arrays also work), whereas for pointer type arguments, either GPU arrays or MATLAB arrays can be used. In the latter case, these are automatically copied to the GPU. A list of supported data types for the kernel arguments can be found in the PCT documentation 13 . In general these are the CC standard types (along with their corresponding pointers) that have MATLAB counterparts, with the addition of float2 and double2 that map to MATLABs complex single and double types, respectively. CUDAKernel objects have three additional, read-only properties related to input and output. NumRHSArguments and MaxNumLHSArguments respectively hold the expected number of input arguments and the maximum number of output arguments that the objects accepts, and ArgumentTypes holds a cell of strings naming the expected MATLAB input types. Each type is prefixed with either in or inout to signal whether it is input only (corresponding to an argument passed by value or a constant pointer in CUDA) or combined inputoutput (corresponding to a non-constant pointer in CUDA). To function in a MATLAB context, a call to a CUDA kernel through a GPUKernel object must support output variables. Therefore, pointer arguments that are not declared const in the kernel declaration are seen as output variables and, if there is more than one, they are numbered according to their order of appearance in the declaration. This means that calling gpuFilter1 above produces one output, whereas gpuFilter2 created from produces two outputs. With this information we can now call the myFilter1 kernel function through Similarly, we can call myFilter2 through The output from a CUDAKernel object is always a GPU array, which means that if the corresponding input is a MATLAB array it will be created automatically. Consider the kernel with its corresponding CUDAKernel object gpuFilter3 . Since im from our previous examples a MATLAB array, calling automatically copies im to the GPU and creates a new gpuArray object called gpuRes3 to hold the result. 3.3. MEX functions and GPU programming In the previous part we saw how, by running our own CUDA kernels directly from MATLAB, we can overcome some of the limitations present when working only with built-in MATLAB functionality. However, we are still (in release 2013b) limited to using kernel functions that take only standard type arguments, and we can access neither external libraries, such as the NVIDIA Performance Primitives, the NVIDIA CUDA Fast Fourier Transform or the NVIDIA CUDA Random Number Generation libraries, nor the GPUs texture memory with its spatial optimised layout and hardware interpolation features. Further, we need to have an NVIDIA GPU, be writing our code in CUDA and have access to the PCT to use the GPU in our MATLAB code. In this section we look at how we can use MEX functions to partly or fully circumnavigate these limitations. This again assumes previous experience of GPU programming and some knowledge of how to write and use MEX functions. A good overview of the latter can be found in the MATLAB documentation 14 . The first option, which removes the technical restrictions but still requires access to the PCT (running on a 64-bit platform) and a GPU from NVIDIA, is to write MEX functions directly containing CUDA code. The CUDA code itself is written exactly as it would be in any other application, and can either be included in the file containing the MEX function entry point or in a separate file. Although this process is well documented in the PCT documentation 15 and through the PCT examples 16 , we briefly describe it here for consistency. The main advantage of this approach over the one described later is that it enables us to write MEX functions that use GPU arrays as input and output through the underlying CC object mxGPUArray . As all MEX input and output, GPU arrays are passed to MEX functions as pointers to mxArray objects. The first step is therefore to call either mxGPUCreateFromMxArray or mxGPUCopyFromMxArray on the pointer to the mxArray containing the GPU data, in order to obtain a pointer to an mxGPUArray . In the former case, the mxGPUArray becomes read-only, whereas in the latter case the data is copied so that the returned mxGPUArray can be modified. ( mxGPUCreateFromMxArray and mxGPUCopyFromMxArray also accept pointers to mxArray objects containing CPU data, in which case the data is copied to the GPU regardless of the function used.) We can now obtain a raw pointer to device memory that can be passed to CUDA kernels by calling mxGPUGetDataReadOnly (in the case of read-only data) or mxGPUGetData (otherwise) and explicitly casting the returned pointer to the correct type. Information about the number of dimensions, dimension sizes, total number of elements, type and complexity of the underlying data of an mxGPUArray object can be further obtained through the functions mxGPUGetNumberOfDimensions . mxGPUGetDimensions . mxGPUGetNumberOfElements . mxGPUGetClassID . and mxGPUGetComplexity . We can also create a new mxGPUArray object through mxGPUCreateGPUArray . which allocates and, if we want, initialises memory on the GPU for our return data. With this we are in a position where we can treat input from MATLAB just as any other data on the GPU and perform our desired calculations. Once we are ready to return our results to MATLAB we call either mxGPUCreateMxArrayOnCPU or mxGPUCreateMxArrayOnGPU to obtain a pointer to an mxArray object that can be returned to MATLAB through plhs . The former copies the data back to the CPU making the MEX function return a standard MATLAB array whereas in the latter case the data stays on the GPU and a GPU array is returned. Finally, we should call mxGPUDestroyGPUArray on any mxGPUArray objects that we have created. This deletes them from the CPU and, unless they are referenced by another mxArray object (as will be the case if they are returned through plhs ), frees the corresponding GPU memory. Note that there are several other functions in the mxGPU family to examine, duplicate, create and copy mxGPUArray objects, and in particular for working with complex arrays, that work in a similar way and which are described in the PCT documentation 17 . For the above to work, we need to include mxGPUArray. h . in addition to mex. h . in our source file. The source file has to have the extension . cu and it should contain a call to the function mxInitGPU before launching any GPU code in order to initialise the MATLAB GPU library. Provided that the environment variable MWNVCCPATH is set to the NVCC folder path and that a copy of the PCT version of mexopts. bat or mexopts. sh ( matlabroot toolboxdistcompgpuexternsrcmex xxx 64 ) is located in the same folder as the source code, we can compile our CUDA containing MEX functions from MATLAB in the usual way using the mex command. If using external libraries, these also have to be provided, which can normally be done by passing the full library path, including file name, to the mex command after the. c ..cpp or. cu file path. A bare-bone MEX function calling the kernel function myFilter1 from earlier, which takes into account the considerations above but is stripped of any boundary or argument checking, follows: After compilation, assuming the above code is found in mexFilter1.cu . we can call the MEX function like this: Note the explicit type conversion necessary to convert the second argument to single to match the input type. Note also that, depending on the compiler and system settings, in order to have mwSize correctly identified as a 64-bit type, we might need to use the largeArraysDims flag when compiling using the mex command. The rest of this part will be dedicated to describing how we can call GPU code from MATLAB even if we do not have access to the PCT or write our code in CUDA. Since without the PCT, the mex command is not set up to compile anything except standard CC code, we have two alternatives to achieve what we want. The only drawback with these, compared to when using mxGPUArray from the PCT is that it is harder to have data in GPU memory persist when returning to MATLAB between calls to MEX functions. (This can still be achieved by explicitly casting a GPU memory pointer to an integer type of correct length which is returned to MATLAB. The integer is then passed to the next MEX function which casts it back to the correct pointer type. However, the problem with this approach lies in eliminating the risk of memory leaks although solutions for this exist, they are beyond the scope of this chapter.) This means that unless we go through any extra effort, we are left either to perform all our GPU calculations from the same MEX function before returning control to MATLAB or suffer the penalty associated with copying our data back and forth between each call. In many cases, however, this may provide less of a limitation than one might initially think, especially when using MATLAB to test GPU code under development or using MATLAB as a front-end to existing code libraries. The first alternative is to compile our GPU code, regardless of in which language it is written, into a static library using our external compiler, and then to call this library from a MEX function that we compile using the mex command. Since our MEX function cannot call GPU functions directly, a small CC wrapper function has to be written around our GPU code. A wrapper for the myFilter1 CUDA kernel, which we can place either in the same file as the CUDA code or in a separate . cu file, could look like this (again, error checking has been omitted for brevity): Once the static library, normally a . lib file under Windows or a . a file under Linux and Mac OS, has been created, we can write a MEX function calling the wrapper: Note that it is normally better, especially if using a pre-existing library, to use include to include the corresponding header files rather than, as in the example above, to manually enter the function prototype. We should now be able to compile this wrapper using the mex command, remembering to pass the path to our own library as well as to the necessary GPU runtime library. For CUDA, this is cudart. lib on Windows, libcuda. so on Linux, or libcuda. dylib on Mac OS. Thus, assuming that the code above is found in myFilter1Mex. cpp and that the library is called myLibrary. lib . on Windows the call would look like: The second alternative is to build the MEX function directly in our external compiler, without going through the mex command. By doing this, the whole process can be carried out in one step and, if we wish, we are free to keep all our code in a single file. The main advantage of this approach occurs if we are developing or using an existing GPU library which we would like to call from MATLAB, for example for testing purposes. In such a case we can add the MEX file to our normal build routine so that every time we rebuild our library we automatically get the MEX function to call it from MATLAB. A MEX function is a dynamically linked shared library which exports a single entry point called mexFunction . Hence, by mimicking the steps carried out by the mex command (found in mexopts. bat or mexopts. sh ) when calling the external compiler, we can replicate this from outside MATLAB. We can view the exact steps carried out on a particular system by calling the mex command in verbose mode, i. e. using the v flag. Detailed information on how to build MEX functions for Windows and UNIX-like systems (Linux and Mac OS) can be also found in the MATLAB documentation 18 . Here we look at a minimal example from a Windows-centric point of view, although the procedure should be similar on other systems. First, we need to specify that we want to build a dynamically linked shared library, called a dynamic-link library on Windows, and give it the correct file extension, e. g. mexw64 second, we have to provide the compiler with the path to our MEX header files, normally mex. h third, we have to pass the libraries needed to build our MEX function, called libmx. lib . libmex. lib and libmat. lib on Windows, to the linker together with their path and finally, as mentioned above, we need to export the function named mexFunction . In Visual Studio 2010, all of the above steps are done in the Project Properties page of the project in question. Under Configuration properties-gt General . we set the Target Extension to . mexw64 and the Configutation Type to Dynamic Library (.dll) . For the header files we add (MATLABROOT)externinclude to Include Directories under Configuration Properties-gt VCDirectories . For the libraries, we add libmx. liblibmex. liblibmat. lib to Additional Dependencies under Configuration Properties-gt Linker-gt Input and (MATLABROOT)externlibwin64microsoft to Additional Library Directories under Configuration properties-gt Linker-gt General . Finally, we add export:mexFunction to Additional Options under Configuration Properties-gt Linker-gt Command Line . In the above steps it is assumed that the variable MATLABROOT is set to the path of the MATLAB root, otherwise we have to change (MATLABROOT) to, for example, C :Program FilesMATLAB2013b . The code for the MEX example, finally, would look something like this: In the case of an existing code library, we can add a new component (such as a new project to an existing solution in Visual Studio) containing a MEX function calling our desired GPU functions so that it is built directly with the original library without any additional steps. 4. Conclusion In conclusion, MATLAB is a useful tool for prototyping, developing and testing image processing algorithms and pipelines. It provides the user with the option of either using the functions of the IPT or leveraging the capabilities of a high-level programming language combined with many built-in standard functions to create their own algorithms. When high performance or processing of large amounts of data is required, the computational power of a GPU can be exploited. At this point, there are three main options for image processing on GPU in MATLAB: i) we can stick entirely to MATALB code, making use of the built-in, GPU-enabled functions in the IPT and the PCT as well as our own GPU functions built from element-wise operations only ii) we can use the framework provided by the PCT to call our own CUDA kernel functions directly from MATLAB iii) we can write a MEX function in CC that can be called from MATLAB and which in turn calls the GPU code of our choice. 5. Acknowledgements The authors would like to acknowledge the European Commission FP7 ENTERVISION programme, grant agreement no. 264552Calculate Moving Average Posted on April 28th, 2009 in Learn Excel - 191 comments Moving average is frequently used to understand underlying trends and helps in forecasting. MACD oder gleitende durchschnittliche Konvergenzdivergenz ist wahrscheinlich die am meisten verwendete technische Analyse-Tools im Aktienhandel. Es ist ziemlich häufig in mehreren Unternehmen zu bewegen gleitenden Durchschnitt von 3 Monaten Umsatz zu verstehen, wie der Trend ist. Today we will learn how you can calculate moving average and how average of latest 3 months can be calculated using excel formulas. Berechnen Sie den gleitenden Durchschnitt Um den gleitenden Durchschnitt zu berechnen, benötigen Sie nur die gute alte AVERAGE-Excel-Funktion. Assuming your data is in the range B1:B12, Just enter this formula in the cell D3 AVERAGE(B1:B3) And now copy the formula from D3 to the range D4 to D12 (remember, since you are calculating moving average of 3 months, you will only get 10 values 12-31) That is all you need to calculate moving average. Berechnen Sie Moving Average der letzten 3 Monate allein Lets sagen, dass Sie den Durchschnitt der letzten 3 Monate zu jedem Zeitpunkt berechnen müssen. Das heißt, wenn Sie den Wert für den nächsten Monat eingeben, sollte der Durchschnitt automatisch angepasst werden. Zuerst wollen wir einen Blick auf die Formel und dann werden wir verstehen, wie es funktioniert. Also, was das Heck der oben genannten Formel ist es sowieso Es zählt, wie viele Monate sind bereits eingegeben 8211 COUNT (B4: B33) Dann ist es offsetting count minus 3 Zellen von B4 und Abrufen von 3 Zellen von dort 8211 OFFSET (B4, COUNT (B4 : B33) -3,0,3,1). Dies sind nur die letzten 3 Monate. Schließlich übergibt dieser Bereich an die AVERAGE-Funktion, um den gleitenden Durchschnitt der letzten 3 Monate zu berechnen. Ihre Hausarbeit Nun, da Sie gelernt haben, wie zu berechnen gleitenden Durchschnitt mit Excel, hier ist Ihre Heimarbeit. Nehmen wir an, Sie wollen die Anzahl der Monate, die verwendet werden, um den gleitenden Durchschnitt zu berechnen, um in der Zelle E1 konfigurierbar zu sein. Dh wenn E1 von 3 auf 6 geändert wird, sollte die gleitende Durchschnittstabelle den gleitenden Durchschnitt für 6 Monate zu einem Zeitpunkt berechnen. Wie schreibst du die Formeln dann Don8217t Blick auf die Kommentare, gehen Sie und Abbildung dieses für sich selbst. Wenn Sie die Antwort nicht finden können, kommen Sie zurück und lesen Sie die Kommentare. Go Dieser Beitrag ist Teil unserer Spreadcheat-Serie. Ein 30 Tage Online-Excel-Trainingsprogramm für Bürogänger und Spreadsheet-Nutzer. Tritt heute bei . Teilen Sie diesen Tipp mit Ihren Freunden Hallo, vor kurzem fanden Sie Ihre Website und Im lieben alle Tipps. Vielen Dank für all Ihre Tutorials. Seine genau brauchte ich jedoch, lief ich in ein bisschen ein Problem, wie ich auch mit Vlookup mit Offset. Zum Beispiel, in Ihrem Beispiel würde ich Vlookup in meiner Vorlage, so dass, wie ich in neue Daten jeden Monat, würde es automatisch aktualisieren die Verkaufsdaten jeden Monat. Mein Problem ist in meinem OFFSET Formel, ich habe COUNTA, die offensichtlich zählt alle Zellen mit Formeln, sogar. Irgendwelche Ideen, wie diese beiden Funktionen besser zu integrieren, vor allem, wenn ich versuche zu grafieren und durchschnittlich, dass letzten 12 Monate würde ich schätzen alle Ideen, die Sie oder Ihre Leser meine haben. Vielen Dank für die tolle Website Twee. Willkommen bei PHD und vielen Dank für die Frage. Ich bin nicht sicher, ob ich es richtig verstanden. Haben Sie versucht mit count anstelle von counta Sie havent gezeigt uns die Offset-Formel, ohne zu sehen, dass die Festsetzung wäre es schwierig sein. I need to calculate a 12-month rolling average that will encompass a 24 month period when completed. Kannst du mir auch in die richtige Richtung zeigen, wie ich anfangen soll? Meine Daten sind Fahrzeugmeilen und startet auf B2 und endet auf B25. Hilfe Chandoo, das ist eine großartige Formel für das, was ich verwende, außer ich versuche erfolglos, um die Formel bedingte. Ich habe eine Tabelle, siehe Links unten, die alle Runden von Disc-Golf gespielt von Freunden und mir. Ive erhielt es bereits, um jeden unserer Gesamtdurchschnitte und jeden unserer Durchschnitte auf spezifischen Kursen zu berechnen. Was ich jetzt versuche, ist aber auch ein gleitender Durchschnitt basierend auf unseren 5 letzten Runden. Once more data has been entered I will change it to 10, but for now 5 will be just fine. Ich kann den gleitenden Durchschnitt zu arbeiten, aber ich kann nicht herausfinden, wie man bedingte Einschränkungen hinzufügen. IE Ich möchte zum Beispiel nur die letzten 5 Runden, die von Kevin gespielt wurden. Danach will ich nur die letzten 5 Runden von Kevin beim Oshtemo Kurs spielen. Der Code Im mit ist unten. Code für Cell C9 ist unten aufgelistet. IF(B90,,IF(B9lt6,AVERAGEIF(DiscRoundsA2:A20000,A9,DiscRoundsM2:M20000),AVERAGE(OF FSET(DiscRoundsM2,IF(DiscRoundsA2:A20000A9,COUNT(DiscRoundsM2:M20000),quotquot)-5,0,5,1)))) Essentially if there are 0 rounds it leaves the cell blank. Wenn es 5 oder weniger Runden gibt es nur den Durchschnitt aller Runden. Schließlich, wenn es 6 oder mehr Runden der Code verwendet dann Ihre Funktion AVERAGE aus diesem Beitrag. Nach dem Versuch viele Dinge, aber ich bin unsicher, wie man bedingt ziehen die letzten 5 Runden, so dass es nur zieht die letzten 5 Runden der einzelnen in Zelle A9 benannt. Die Formel, die ich verweise, ist NICHT jetzt in Zelle C9 auf meiner Kalkulationstabelle, die verlinkt ist. Ich habe es nur dort getestet. DND: Verwenden Sie die folgende Formel in Zelle C13 über AVERAGE (B2: B13) und ziehen Sie nach unten. Hallo, Ich bin sicher, es gibt etwas oben aufgeführt, die vermutlich helfen, aber Im immer noch neu zu übertreffen und fühle mich überwältigt. Ich habe gerade einen neuen Job und Im tryin, um einen guten Eindruck zu machen, so jede Hilfe woud groß sein Ich habe Daten für jeden Monat in 2009, 2010 und 2011 gehen über und mehrere Zeilen dieser. Jeden Monat zu Beginn des Monats muss ich die Umsätze des Vorjahres berechnen. Derzeit ist meine Formel SUM (AG4: AR4) SUM (U4: AF4). Beispiel: Der aktuelle Monat ist März. Info Ich brauche ist Umsatz von März 2010-Februar 2011 geteilt durch März 2009-Februar 2010 und es funktioniert super, aber sein zu zeitaufwändig, um es jeden Monat ändern müssen. Gibt es eine Weise, die ich die Formel erhalten kann, um automatisch am Anfang des Monats zu ändern, das ich nicht weiß, wenn ich einen sehr guten Job erklärte dieses oder nicht tat. Glückwunsch zu deinem neuen Job. Sie können Ihre Formel seitwärts ziehen (nach rechts für zB) und es zeigt die s für den nächsten Monat automatisch. Nein, was ich brauche, ist für die Formel ändern jeden Monat. Ich habe Januar 2009 bis Dezember 2011 Boxen gehen mit Daten in ihnen. IFNERROR (SUM (AG4: AR4) SUM (U4: AF4), 0) Nächsten Monat benötige ich für sie gehen von der Berechnung der Summe von 0310 Daten zu 0211 Daten geteilt durch 0309 Daten zu 0210 Daten und Änderung zu 0410 bis 0311 Daten geteilt durch 0409 Daten zu 0311 Daten. IFERROR (SUM (A4: AS4) SUM (V4: AG4), 0) Was ich brauche, ist eine Formel, die sich auf das aktuelle Datum beziehen kann und weiß, dass am 1. eines jeden Monats, es die Formeln für den nächsten wechseln muss Vorherige 1-12 Monate geteilt durch die letzten 13-24 Monate. Ich bin nicht sicher, ob das Sinn macht. Grundsätzlich verwende ich diese Formel etwa 8 mal auf einem Blatt und ich habe ca. 200 Blatt. Sorry für die doppelte Buchung und vielen Dank an die congrats Was ich brauche: Wenn das aktuelle Datum größer ist als das 1. des Monats dann die gesamte Zelle referenziert, um die Verkäufe des vorigen Jahres zu berechnen, um nach rechts um eine Spalte zu bewegen Dies ist Was Ive kommen mit. IF (P1gtN1, SUM (A4: AS4) SUM (V4: AG4))) p1 ist aktuelles Datum n1 ist 1. Tag des Monats AH4: AS4 ist Daten von 0310-0211 V4: AG4 sind Daten von 0309-0210 Teil Im mit Probleme mit: Wie mache ich es so, dass die Formel genau weiß, was 12 Abschnitte zu greifen und wie man automatisch am ersten des Monats zu ändern. Julie Sie können die OFFSET-Formel verwenden, um dies zu beheben. Angenommen, jede Spalte hat einen Monat und der erste Monat ist in C4 und das aktuelle Datum ist in P1. Die obige Formel geht davon aus, dass jede Spalte Monate im Excel-Datumsformat hat. Sie können es zwicken, bis es das richtige Ergebnis erzeugt. Dies ist wahrscheinlich extrem einfach und ich mache es komplizierter, als ich brauche, aber Sie schrieb, Die obige Formel geht davon aus, dass jede Spalte Monate im Excel-Datumsformat hat. Ich habe gekämpft, dies zu tun, ohne dass es meine Daten in Daten. Julie Was ich damit meinte, ist die Zeilennummer 4, wo man Monatsnamen hat, sollte diese Daten enthalten - 1-jan-2009 1-feb-2009 1-mar-2009 Auch ich bemerke nur wenige Fehler in meiner Formel. Die richtige Formel lautet: SUM (Offset (C5, datedif (C4, P1, m) 1-12,1,12)) SUM (Offset (C5, datedif (C4, P1, m) 1-24,1 , 12)) Die obige Formel geht davon aus, dass Daten in Zeile 4 und Werte in Zeile 5 sind. Ich denke, das ist genau das, was ich brauchte. Vielen Dank, dass ich danke Ihnen so sehr Mein Problem ist sehr ähnlich Jasmine (61) und Azrold (74). Ich habe abscheuliche Datenmengen, von D: 2 bis D: 61400 (und entsprechend in E und F, Ill muss das gleiche auch für diese Spalten tun). Ich versuche, den Durchschnitt für Chargen zu finden, so dass D2: 19, D20: 37, D38: 55 und so weiter - verklumpen 18 Zeilen zusammen und dann den nächsten Durchschnitt ohne Wiederverwendung einer vorherigen Zeile. Id haben auch wahrscheinlich dies für alle 19 und 20 Klumpen als gut, aber ein Beispiel mit 18 ist in Ordnung. Könnten Sie annotieren die Formel, die Sie post Im ein wenig verwirrt, was die letzten 4 Zahlen im COUNTA Teil bedeuten. Vielen Dank, das wird mein Leben so viel einfacher Laura Dies ist leicht mit Average und Offset getan. Angenommen, Sie tun dies in Col J und sind durchschnittlich Col D J2: DURCHSCHNITT (OFFSET (D1, (ROW () - 2) J11,, J1)) Wo J1 wird die Zahl 18 für eine bewegte Summe von 18 Zahlen Copy down Zeile 2 wird durchschnittlich Zeilen 2-19 Zeile 3 wird durchschnittlich Zeilen 20-37 usw. Sie können auch Etiketten hinzufügen, zB Col H H2: Zeilenverstärker (ROW () - 2) J12amp - amp (ROW () - 1) J11 Nach unten kopieren. Ich habe verspottet dies auf: rapidsharefiles1923874899Averages. xlsx Ich bin Anfänger versucht,: 1. Struktur einer Kalkulationstabelle, die dann verwendet werden, um 2. den optimalen Zeitraum für meine gleitenden Durchschnitt innerhalb der Reichweite von einem 5 Tage gleitenden Durchschnitt auf 60 zu bestimmen Tag gleitenden Durchschnitt. Jede Zelle repräsentiert die Anzahl der Verkäufe für diesen Tag, von 0 bis 100. Ich würde es vorziehen, dass jeder Monat des täglichen Verkaufs in einer neuen Spalte sein. Im Moment habe ich 3 Monate Daten, aber offensichtlich wird das wachsen. Also können Sie mir bitte sagen, wie die Kalkulationstabelle und dann die entsprechenden Formeln (und ihre Standorte) Vielen Dank, Hallo wieder Hui, kämpfe ich noch einmal mit der gleichen Tabelle, die Sie mir mit früher geholfen. Wie beore, habe ich die folgenden Zeilen der monatlich manuell eingegebenen Daten: Lautstärke der Anrufe Anrufe Beantwortet Alter der Anrufe aufgegeben Durchschnittliche Bearbeitungszeit Mein Line-Manager würde nun 2 Zeilen unter diesen zeigen (nach Formel): Durchschnittliche Geschwindigkeit der Antwort Durchschnittliche Abwesenheit Zeit Und als ob das nicht genug war, möchte sie, für beide Zeilen, eine Zusammenfassung Zelle am Ende der 12 Monate zeigt die jährliche Zahl: (Vielen Dank nochmals für jede Hilfe, die Sie geben können, bin ich mit der vertikalen Version für Berechnen eines gleitenden Durchschnitts Ich bin stumped, wenn ich einen 6-Perioden-gleitenden Durchschnitt berechnen müssen Meine Daten beginnen in Spalte c und die 6-Periode und 3-Periodendurchschnitte sind zwei Spalten rechts von der letzten Datenperiode (EC8: EH8) Mein letzter Versuch (der fehlgeschlagen) ist: AVERAGE (C6, COUNT (C6: EH6), - 6,6,1 ) Bitte geben Sie eine Erklärung, warum dies nicht funktioniert, wenn reagiert, so kann ich verstehen, wie Sie künftige Formeln zu erstellen. Vielen Dank, Kimber Kimber. Willkommen bei Chandoo. org und vielen Dank für die Kommentare. Ich denke, es ist keine gute Idee, Durchschnittswerte in der rechten Spalte zu platzieren, da es sich bewegt. Stattdessen können Sie Ihre Tabelle so ändern, dass gleitender Durchschnitt an der linken Spalte (und das bleibt auch wenn Sie zusätzliche Spalten rechts). Egal wo die durchschnittliche Zelle ist, können Sie diese Formel verwenden, um den gleitenden Durchschnitt zu berechnen. Afyter, der den ganzen Thread gelesen hat, den ich sehen kann Im, das ein Kombination Offset, Match, Zählimpuls und averageif aber Im nicht sure wo benötigt wird. Mein Problem ist, wie folgt: Jeden Monat gibt es über 100 Leute, die Tätigkeit melden - Spalte A ist ihr Name, Spalte B ist der Monat, Spalte C ist das Jahr und Spalten D durch M ist ihre Tätigkeit in mehreren Kategorien. Ich brauche, um ihre 3 Monate und 6 Monate Durchschnittswerte zu finden und zeigen, dass in einem anderen Arbeitsblatt obwohl ich sie in Spalten N und O angezeigt, wenn nötig. Ich verwende eine Pivot-Tabelle, um Summen und Gesamtdurchschnitte zu produzieren, aber es behandelt nicht gleitende Durchschnitte. Irgendwelche Hinweise würden sehr geschätzt. Thanks, Ben This will average the last MovAvg number of rows including itself (take out the -1 if you want it to not include itself). D75 ist die Zelle, auf die sich diese Formel bezieht (meine Daten waren sehr lang) MovAvg ist, wie groß du den gleitenden Durchschnitt sein willst (Ich habe diesen als benannte Zelle zugewiesen (markiere die Zelle, Formeln --gt Defined Names --gt Define Name) Sie können Variablennamen in einer Tabelle erstellen, um zu vermeiden, dass immer die Zeilenspalte verwendet werden muss.) Dies startet von der aktuellen Zelle (D75 in diesem Fall), verschiebt MovAvg-1 Zeilen über 0 Spalten, wählt MovAvg nuber von Zeilen aus 1 Säule. Übergibt dies an die durchschnittliche Funktion. Hallo Ich las durch jeden Pfosten, aber havent in der Lage gewesen, diese Funktion richtig zu erhalten. Wie berechnen wir den gleitenden Durchschnitt eines Prozentsatzes Dieser wird wöchentlich berechnet. Spalte A - Spalte A Spalte B - Spalte A Spalte A Spalte A Spalte A Spalte A Spalte A Spalte A Spalte A Spalte A Spalte A Spalte A Spalte A Spalte A Spalte A Spalte A Spalte A Spalte A Spalte A Spalte A Spalte A Spalte A Spalte A Spalte A Spalte A Spalte A Spalte A Spalte A Spalte A Und Zeile 8 ist 1 Spalte K, Zeile 7 Formel ist 125 (4) und Zeile 8 ist 11 (100) Spalte D - Die Formel in einem früheren Beitrag gibt mir eine Antwort von 52 2 Wochen Durchschnitt, aber das ist nicht richtig. (K7, COUNT (K7: K26) -2), und zwar mit dem Wert 226 (7) IF (ISERROR (AVERAGE (OFFSET (K7, COUNT (K7: K26) -2,0,2,1)) , 0,2,1))) Was muss ich in dieser Formel ändern, um die Spalten verwenden A Ampere B anstelle der Spalte K Sie versuchen, durchschnittliche Mittelwerte, die nicht funktioniert. Versuchen Sie diese einfache Formel beginnend in D8: IF (ISBLANK (B8) ,, (B7B8) (A7A8)) Kopieren und fügen Sie die Formel auf D26. Dies sollte Ihnen eine bewegte 2 Wochen Durchschnitt. Remember to format column D as a percentage with how ever many decimal points you want. Im so ziemlich ein excel neophyte. Ich stolperte über Ihre Website amp freue mich darauf, es in den kommenden Monaten ausführlich zu lesen. Ich versuche, einen 3-monatigen gleitenden Durchschnitt der Aufwendungen zu berechnen amp kann nicht herausfinden, was ich falsch mache. Auch nach der Lektüre dieses Artikels und die Post auf Offset Im nicht sicher, ich verstehe die Formel. In meinem Sandkasten habe ich: Spalte A - Monate A2: A17Sept 2012 - Dez 2013 Spalte B - Monatliche Gesamtausgaben B2: B8 (B8, weil März der letzte abgeschlossene Monat ist) - Diese Summen sind 362599,372800,427317,346660,359864 , 451183,469681 Kolum C - 3 Monate Gleitender Durchschnitt. Ich habe die folgende Formel in C4 (zu Beginn Berechnung im November des letzten Jahres, nur für Grins). Da es zu diesem Zeitpunkt nur drei Monate im Datensatz gibt, würde ich davon ausgehen, dass er den gleitenden Durchschnitt der ersten drei Monate berechnet. Die Formel kommt mit 469.681. Wenn ich die ersten drei Monate Durchschnitt bin, komme ich mit 387.572. Was mache ich falsch oder Missverständnis Vielen Dank für die Hilfe und für die Umsetzung dieser Website zusammen. Hallo Chandoo Sie haben ein wirklich nützliches Projekt hier, tonnenweise Danke Am Anfang dieses Thread Shamsuddin etwas gefragt, was ich brauche, umgekehrte Berechnung der Werte aus dem gleitenden Durchschnitt. Vielleicht ist seine dumm, aber ich kann nicht kommen mit Ideen, außer für Abbildung für Abbildung nachschlagen. Wenn möglich - wenden Sie sich bitte mit diesem Artikel Daten, um das Konzept zu erhalten. Eigentlich bin ich glücklich, alles zu bekommen, da google war nutzlos) Noch einmal - ich danke Ihnen so sehr für diese Website Im nicht wirklich sicher, was Sie mit der Reverse-Berechnung einen gleitenden Durchschnitt Können Sie erklären, was Sie versuchen, doachieve Posting ein Beispiel Hallo Hui, ich meine, ich habe eine Spalte von Zahlen (zB monatliche Sendungen), die als gleitender Durchschnitt auf Basis eines anderen Datensatzes berechnet werden (zB monatliche Produktion) . Smith wie folgt: (A1) Jan Feb Mär Apr Mai Jun Mfg Schiff 100 500 450 600 600 700 Wo Schiff Durchschnitt (B2: C2) Ich kenne nur Sendungen Volumes, und müssen Sie entsprechende mfg Volumes. Generally speaking, the question is how we can find initial data with only MA on hand Suppose, this thread may not be the one for asking this (if you agree - maybe you know where to ask). Seine nur, dass Shamsuddins Frage war das relevanteste Ergebnis von 10 Google-Seiten Mey Um die ursprünglichen Daten aus einem Moving Average (MA) zu berechnen, benötigen Sie zwei MAs zB eine 9 und eine 10 Tage MA oder 1 MA und 1 Stück von diesen Daten (B2: C2) MA (B2C2) 2 Wenn Sie eine Formel Durchschnitt (B2: C2) haben, sollten Sie Zugriff auf die Daten haben B2 C2 (2MA) - B2 Wenn Sie eine Reihe von Daten, die Sie teilen können, kann ich eine bessere Lösung geben Verweis: chandoo. orgforumstopicposting-a-sample-workbook Große Website. Verzeihen Sie diese Frage. Ich war ein Experte in Lotus vor 123 Jahrzehnten, aber ich finde Excel etwas rückwärts in seinen Progressionen zu Lotus 123, so fange ich über Excel 2010. Ich bin eine logische Person und ich versuche zu verstehen, was die Formeln tun, wenn ich benutze sie. Ich stelle fest, dass es in Spalte B nicht mehr als 14 Verkaufszahlen gibt, aber irgendwie zählen wir von B4 bis B33. Ich habe die Formel unter Verwendung von: AVERAGE (OFFSET (B4, COUNT (B4: B14) -3,0,3,1)) getestet und ich bekomme das gleiche Ergebnis, wenn ich AVERAGE (OFFSET (B4, COUNT (B4: B33 ) -3,0,3,1)). Meine erste Regel der alten Schülersprecherzeugung ist, niemals eine Datentabelle zu erstellen, die größer ist als die bereitgestellten Daten, wenn sie statisch ist (dh nicht in Daten expandiert). Als Ergebnis habe ich keine wirkliche Ahnung, wie OFFSET funktioniert. Gibt es eine klare Erklärung von OFFSET mit einem einzigartigen Beispiel dafür, dass es außerhalb des Durchschnitts und ganz von selbst verwendet wird Der Grund, warum ich hierher kam, ist ein Kalkulationstabellenmodell, das iterative Berechnungen verwenden würde, um die am besten passen für Profit-Daten zu finden (das heißt Gewinnmaximierung), wenn ein kurzer gleitender Durchschnitt der kumulierten Gewinnkurve (oder Eigenkapitalkurve) über den längerfristigen bewegten Durchschnitt der Eigenkapitalkurve hinausgeht. Ich finde nichts, was die Erweiterung der gleitenden Durchschnitte aus 3 Perioden zu sagen, 100 Perioden (für beide Mittelwerte). Durch die Verwendung des MA-Crossover, um festzustellen, welche Trades zu nehmen, kann man ein optimales Gewinnniveau finden, um das Modell auszuführen (was beim Optimieren des Modells angepasst werden kann). Ich kann nichts finden, in den meisten Excel-Bücher, die diese zu decken, und diese Art von Berechnungen sollte relativ einfach zu ziehen. Wo finde ich solche Informationen Danke nochmals für die wunderbare Website. Nur für den Fall, dass Sie havent es noch nicht gefunden, heres einen Link für die OFFSET-Funktion: Ich habe eine Frage. Ich habe bereits einen 3 Tage gleitenden Durchschnitt, dass ich in meinem Problem gegeben wurde. Ist es im Zusammenhang mit dem Durchschnitt der Bestände. Die Fragen sagen, dass Sie 1 Aktie, die Sie PLAN auf den Verkauf am Tag 10. Mein 3 Tage gleitenden Durchschnitt ist eine Integration von a, b, wo at und bt3 zu jeder Zeit. Wenn Sie den Preis finden möchten, den Sie erwarten, den Anteil für zu verkaufen, integrieren Sie von 6,9 9,11 7,10. Wollen Sie das fernen Ende des Tages 10, die Mitte des Tages 10, oder verlassen Tag 10 aus Ich bin nicht sicher, welche Zeitrahmen, um diese 3 Tage Durchschnitt zwischen setzen. Wieder stellt meine Funktion bis zu Tag 14, aber ich brauche den Preis am Tag 10. ivan Santos sagt: Im schauen, um den gleitenden Durchschnitt für ein Call-Center zu sehen. Ich versuche, den Index für jeden Monat für ein ganzes Jahr zu finden. Ich habe nur 2 Jahre im Wert von Daten und im wollen Vorhersage für 2014 in Quartalen. Kann ich diese Methode für diese verwenden Ich habe ein Problem im Durchschnitt, ich möchte den Durchschnitt der hervorgehobenen Zeilen nur in coloumn F auf colomn G, die auch leere Zellen hervorgehoben hat zu berechnen Hallo, Ich arbeite an einer Tabelle, die die letzten vier Jahre hat Der wöchentlichen Daten, aber die aktuellen Jahre Daten unvollständig ist, da es nur jede Woche eingegeben wird. Gibt es eine Möglichkeit der Einrichtung einer Formel, die einen Durchschnitt auf der Grundlage der Anzahl der Wochen, die Daten in ihnen zu berechnen. In der Mitte des Jahres wird es einen Durchschnitt basierend auf Zellen 2-27 26, aber die nächste Woche würde es Zellen 2-28 27. Sein tut mein Kopf in und ich möchte nicht, dass manuell den Durchschnitt jede Woche. Tolle Seite übrigens Sehr hilfreich. ) Rosie Ja das kann getan werden Kannst du bitte die Frage an die Foren stellen und eine Beispieldatei anhängen chandoo. orgforum Ok hier ist meine Frage, die mich für die letzten 2 12 Monate geplagt hat und ich habe keine Lösung irgendwo im Web gefunden : Ich habe ein Vertriebsteam und ich brauche ein bewegliches avg, aber mit einem fixen Format und einem veränderlichen Datum Rage, die auch fixiert ist. Dh Verkäufe Person 1115 2115 3115 12114 11114 10114 ME 1 2 0 4 5 6 Was ich versuche, zu tun ist, das ist: Sagen wir heute Datum ist 3115 Ich brauche einen Weg zurück 3 (6 und 12 als auch) Monate aus der aktuellen gehen Datum und Anzahl der Verkaufszahlen. Der schwierige Teil ist, ich möchte nur das Jahr der Daten ändern, damit ich nicht mit dem Format messing haben oder wenn ich (Feuer) jemand einstellen. Also im obigen Beispiel würde ich die Formel nehmen die 6 1 2 (9) 3 3 aber dann im Laufe der Zeit würde dies gehen würde aber sobald das neue Jahr begann im Januar 2016 würde es die Zahlen aus der Vergangenheit verwenden müssen 2015 Daten (3,6 und 12 Monate rollenden avgs). Ich hoffe, dass dies klar und ich würde gerne einige Hilfe mit diesem bekommen. Vielen Dank im Voraus. Können Sie bitte fragen Sie die Frage in der Chandoo. org Foren unter: forum. chandoo. org Fügen Sie eine Beispieldatei, um den Prozess zu vereinfachen OK Ich habe in den Foren gepostet und eine Beispieldatei hochgeladen. 8230 Berechnen Gleitender Durchschnitt Chandoo. org 8211 Learn Gleitender Durchschnitt wird häufig verwendet, um zugrunde liegende Trends zu verstehen und hilft bei der Prognose. MACD oder gleitende durchschnittliche Konvergenzdivergenz ist vermutlich der 8230 Amelia McCabe sagt: Suchen nach einer kleinen Hilfe. Ich habe versucht, was ich denke, ist eine modifizierte Version dieser Formel, die nicht wirklich funktioniert. Ich habe eine Reihe von Daten (eine Anzahl pro Monat), dass ich einen kontinuierlichen Durchschnitt für basierend auf der Anzahl der Monate der eingegebenen Daten nicht auf 12 Monate benötigen. Die Daten sind in den Zellen b53 bis m53. Also habe ich versucht, diese Formel wie folgt zu ändern (es hat nicht funktioniert) und ich frage mich, ob ich diese Formel auf diese Weise überhaupt verwenden kann, da meine Daten in einer Reihe nicht eine Spalte sind. DURCHSCHNITT (OFFSET (B53COUNT (B53: M53) -12,0,1,12)). Haben auch die Argumente als 0,0,1,12 und -1,0,1,12 versucht. Bitte helfen Sie mir zu verstehen, wenn ich den völlig falschen Baum oder nur auf dem falschen Zweig. Amelia Ohne die Daten-ID zu sehen, sollte AVERAGE (OFFSET (B53, COUNT (B53: M53) -12,0,1,12)) sein: AVERAGE (OFFSET (B53.1, COUNT (B53: M53))) Eins Problem mit der ursprünglichen Formel ist, dass es 12 Zellen zwischen B53: M53, wenn nur 5 haben Daten in ihnen, dann nehmen Sie 12 weg, versucht der Offset B53, eine negative 7 Spalten versetzen, die einen Fehler erzwingen werden Sie können (B53: M53, B53: M53,0) Sind Sie in der Lage, eine Beispieldatei im Chandoo. org Foren forum. andoo. org zu posten

No comments:

Post a Comment