Hires Data

  • June 2020
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Hires Data as PDF for free.

More details

  • Words: 5,934
  • Pages: 39
Diplomarbeit im Fachbereich Nachrichten- und Elektrotechnik an der Fachhochschule Köln

Erstellung einer Visual C++ Anwendung zur Ermittlung der Ortsauflösung einer Nuklearkamera nach NEMA

Index

INDEX........................................................................................................................................................................... 2 ZUSAMMENFASSUNG ............................................................................................................................................. 3 EINLEITUNG .............................................................................................................................................................. 4 I

DIGITALKAMERA IN DER NUKLEARMEDIZIN ..................................................................................................... 4

II

ORTSAUFLÖSUNG DER ENTSTANDENEN AUFNAHME ......................................................................................... 5

III

ERSTELLUNG DES BILDES ................................................................................................................................. 6

IV

QUALITÄTSKONTROLLE DES BILDES ................................................................................................................ 8

PROGRAMMIERUNG DER ANWENDUNG .......................................................................................................... 9 II

DIE DATEIEN UND KLASSEN DES ANWENDUNGSGERÜSTES ............................................................................ 16

III

CDARBEIT29_07APP – DAS ANWENDUNGSOBJEKT ........................................................................................ 17

IV

CDARBEIT29_07DOC – DIE DOKUMENTKLASSE............................................................................................. 18

V

CMAINFRAME – DAS HAUPTFENSTER DER ANWENDUNG ............................................................................... 18

VI

CDARBEIT29_07VIEW – DAS ANSICHTSFENSTER DER ANWENDUNG ............................................................. 19

VII

ZEICHNEN .................................................................................................................................................. 21

LITERATUR .............................................................................................................................................................. 28 ANHANG .................................................................................................................................................................... 29

2

Zusammenfassung Die Digitalisierung analoger Signale ist in dem letzten Jahrzehnt ein großer Aufgabenbereich in der Nachrichten- und Elektrotechnik geworden. Aufgrund vieler

Vorteile

im

Umgang

mit

digitalisierten

Daten

(zum

Beispiel

Speicherung, Versendung) nimmt sie Einzug in sämtliche Bereiche, in denen große Datenmengen erhoben werden. Ein Anwendungsgebiet stellt die Nuklearmedizin dar. Dort werden im Bereich bildgebender Diagnoseverfahren Nuklearkameras eingesetzt, welche die Aufnahme von Bildern innerer Organe ermöglichen. In der folgenden Arbeit wird eine Software vorgestellt, die Bilder einer solchen Nuklearkamera, nach vollzogener Digitalisierung auf ihre Qualität hin überprüft. An einem Beispielbild (die Aufnahme von äquidistant angeordneten Bleistreifen) soll die Ortsauflösung der Nuklearkamera geprüft werden, das bedeutet wie gut die Distanz zwischen den oben genannten Flächen auf dem Bild eingehalten wird.

3

Einleitung Die Digitalisierung analoger Signale ist in dem letzten Jahrzehnt ein großer Aufgabenbereich in der Nachrichten- und Elektrotechnik geworden. Aufgrund einer Vielzahl von Vorteilen im Umgang mit digitalisierten Daten nimmt sie Einzug in sämtliche Bereiche, in denen große Datenmengen erhoben werden. So ist die Speicherung und Versendung digitaler Daten aufgrund von Reduzierung und Komprimierung der Datenmengen deutlich vereinfacht und der notwendige Speicherplatz drastisch reduziert. Ein Anwendungsgebiet für die Digitalisierung stellt die Nuklearmedizin dar. Dort

werden

im

Bereich

bildgebender

Diagnoseverfahren

Kameras

eingesetzt, die nach einer Injektion von radioaktivem Material die Aufnahme von Bildern innerer Organe ermöglichen. Eine Art der Nuklearkameras stellt die Gammakamera dar, benannt nach dem Frequenzbereich, in dem sie Signale aufzunehmen vermag.

I

Digitalkamera in der Nuklearmedizin Die Nuklearmedizin dient vor allem der Untersuchung von Schilddrüsen-,

Herz-

und

Therapiepatienten.

Der

Patient

bekommt

ein

nukleares

Trägermaterial injiziert, zum Beispiel Technetium oder Jod, das vom Stoffwechsel

aufgenommen

wird.

Eine

Gammakamera

wandelt

die

radioaktiven Strahlen der Substanzen in Bilder um. In einer Gammakamera werden die radioaktiven Strahlen des Trägermaterials zunächst in einem Kristall in ein Lichtsignal umgewandelt. Bis zu 100 Photomultiplier wandeln dann das Lichtsignal in einen Stromimpuls um. Die Signale wurden in 4

analoger Verarbeitungsweise über mehrere Widerstandsnetzwerke addiert, um Koordinatensignale zu erzeugen. Dieses kann jedoch aufgrund Bauteiltoleranzen, Offsetspannungen und Rauschen zu Abbildungsfehler führen. Durch eine frühe Digitalisierung der Signale hingegen können beschriebene Abbildungsfehler vermieden werden, so dass mittels der Bildaufbereitung störungsärmere Bilder in höherer Auflösung produziert werden können. Eine Nuklearkamera verarbeitet Signale aus bis zu 100 Kanäle mit je 50 MHz. Die digitale Signalverarbeitungsleistung für eine Gammakamera ist dadurch etwa fünfzigtausendmal höher als bei einem CD-Spieler. Die Digitalisierung

bewirkt

in

diesem

Fall,

dass

die

elektronische

Verarbeitungseinheit der digitalen Gammakamera mit der Größe zweier Aktenordner nur noch ein Zehntel der analogen Kameras beträgt. Somit können zudem sowohl Fertigungs- und als auch Wartungskosten in erheblichem Maße eingespart werden.

II

Ortsauflösung der entstandenen Aufnahme „Die Ortsauflösung ist definiert als der kleinste meßtechnisch erfaßbare

Abstand

zweier

hannover.de].

Die

reflektierender Ortsauflösung

Grenzflächen“ stellt

ein

[www.ubicampus.mhQualitätskriterium

der

Gammakamera dar, da nicht bestimmt werden wie groß beziehungsweise klein dieser Abstand ist sondern wie gut und wirklichkeitsgetreu ein vorgegebener Abstand auf den Bildern abgebildet wird. Die folgende

5

Anwendungssoftware dient ihrer Überprüfung anhand von verschiedenen Distanzparametern sowie deren graphischer Darstellung.

III

Erstellung des Bildes Zur

Bestimmung

der

Ortsauflösung

der

Gammakamera

wird

ein

Beispielbild erstellt. Dafür wird eine reflektierende Oberfläche, die als Hintergrund dient, mit Blei bedeckt und aufgenommen. Diese Bleiobjekte liegen in einem bestimmten Abstand voneinander, so dass schmale Trennlinien zwischen ihnen entstanden sind. Der gleich bleibende Abstand zwischen diesen Streifen wurde im voraus festgelegt und beträgt 30 mm. Auf dem entstandenen Bild werden die Bleiobjekte als dunkle Flächen abgebildet, die nicht bedeckten Flächen als weisse, hell reflektierende Trennlinien. Das entstandene Bild wird in einer Datei HiResData.dat gespeichert. Diese Datei ist 32 MB groß und sie ist eine zwei dimensionale Matrix, die aus 4096 mal 4096 Werten besteht. Jeder Wert in dieser Matrix steht für einen Pixelwert (0 steht für Schwarz und 255 für weiß). Die zu erstellende Anwendung soll die HiResData.dat einlesen, die Werte als Pixelwerte interpretieren und anschließend als Bild auf dem Bildschirm darstellen. Das Bild wird von oben nach unten in 16 gleich breite Streifen unterteilt und die darin enthaltene Pixelwerte von links nach rechts spaltenweise aufsummiert. Die Ergebnisse können dann als Kurve dargestellt werden (siehe Abbildung 1). Der resultierende Verlauf beschreibt eine flache Linie entlang

Abb. 1: Beispiel eines Kurvenverlauf und den Parametern MAX (233,224), FWHM (41, 40) und FWTM (65, 71)

6

der x-Achse mit y-Wert 0 in den Bereichen der schwarzen Streifen. Die Bereiche auf der x-Achse, in denen die weißen Streifen zu finden sind, werden in dieser Darstellungsform durch den Anstieg der Amplituden abgebildet. Jede dieser Amplituden wird durch 3 Parameter charakterisiert: durch das Maximum der Amplitude (MAX), dem FWHM-Wert (full width half maximum) sowie dem FWTM- Wert (full width tenth maximum, siehe Abbildung 2). Innerhalb einer Amplitude werden die

Werte

der

folgendermaßen

Parameter

ermittelt:

Das

Maximum entspricht dem Punkt mit dem

größten

y-Wert.

Dieser

Abb. 2: Skizze einer Amplitude und die Zuordnung ihrer Parameter MAX, FWHM und FWTM

Wert

befindet sich meist in der Mitte einer Trennlinie und bildet die Spitze der Amplitude. Zur Bestimmung des FWHM-Wertes wird der Maximalwert halbiert. Auf dem linken und rechten Schenkel der Amplitude wird nach Punkten gesucht, deren y-Werte mit dem ermittelten Wert übereinstimmen. Die Distanz zwischen den beiden Punkten bezeichnet den FWHM-Wert. Analog wird der FWTM-Wert ermittelt und beschreibt somit die Distanz der Punkte mit dem y-Wert, der dem Zehntel des maximalen y-Wertes entspricht. Im optimalen Fall sollte die Form der Amplitude einer Rechteckfunktion nahekommen. Der kurvenartige Verlauf der Intensitätswerte hingegen spiegelt einen eher fließenden Übergang zwischen den angrenzenden Bereichen wider.

7

IV

Qualitätskontrolle des Bildes Nach dem man die Werte ermittelt hat, verfügt man über ein objektives

Mittel, das einem erlaubt, zu prüfen wie empfindlich beziehungsweise schnell die Kamera reagiert wenn man von einer weißer zu einer schwarzen Stelle übergeht und umgekehrt. Der Optimalfall vor,

wenn

230

250

225

MAX

liegt

235

B

A

FWHM und FWTM

FWHM 215

200

gleich wären und der

Linien

gleich

bliebe. Je größer der Unterschied zwischen

0

Bildes.

6

8

10

12

8

10

12

8

10

12

Streifen

80,0

100

75,0

70,0

65,0

50

60,0 0

2

4

1 2

3 4

5

6

7

8

9 10 11 12

6

Streifen

55,0

50,0

Streifen FWHM

ist die Qualität des

4

150

diesen beiden Werten ist, desto schlechter

2

85,0

FWTM

den

zwischen

210

mittlerer Abstand

Abstand

MAX 220 FWTM

45,0

40,0

35,0

30,0

Unsere

Messung

für das HighResDataBild

hat

folgende

0

2

4

6

Streifen

Abb.3: Darstellung der Mittelwerte (A) sowie Scatterplotts der einzelnen Messwerte (B) der drei Kurvenparameter MAX, FWHM und FWTM.

Werte ergeben, die Abbildung 3 zu entnehmen sind (Wertetabelle siehe Anhang 5). Wir stellen fest, dass die Werte FWHM und FWTM sich von

8

einander unterscheiden. Das liegt daran, dass sich im schwarzen Teil des Bildes ebenfalls Pixelwerte ungleich null befinden und umgekehrt.

Programmierung der Anwendung Die beschriebene Anwendung wurde ein Visual C++ erstellt. Microsofts Visual C++ 6.0 (VC++) ist eine integrierte Umgebung zum Entwickeln von C++ - Programmen für Windows. Die Arbeit in dieser Umgebung erleichtert die Erstellung einer Windows-Anwendung. Wenn man mit VC++ arbeitet, hat man mittels des Dialogfeldes des Anwendungs-Assistenten, welches als Schnittstelle zwischen dem Anwender und der Entwicklungsumgebung dient, die Möglichkeit, schrittweise das Grundgerüst und die Art seiner Anwendung zu bestimmen ohne dabei eine Code-Zeile selbst zu schreiben. Bei der Erstellung dieser MFC Anwendung sind folgende Schritte notwendig:

9

Erstellen einer neuen VC++-Anwendung durch Aufrufen des Programms Microsoft Visual C++ und öffnen einer neuen Datei unter

dem

Menüpunkt

Datei/Neu (Abbildung 4).

In

der

hier

beschriebenen

Anwen-

dung wurde mit dem Anwendungs-Assisten-

Abb. 4: Öffnen einer VC++-Anwendung

ten (MFC-AnwendungsAssistent.exe)

das

Projekt

namens

DArbeit29_07

angelegt

(Abbildung 5).

Abb. 5: Anlegen einer Anwendung

10

Im des

ersten

Dialogfeld

Anwendungs-Assis-

tenten wird die Option Einzelnes Dokument SDI ausgewählt

und

das

Kontrollkästchen für die Unterstützung der Dokument Ansicht Architektur

Abb. 6: Schritt 1 der MFC-Anwendung

bleibt eingeschaltet (Abbildung 6).

Im zweiten Schritt des Assistenten

werden

Standardwerte

die über-

nommen (Abbildung 7).

Im

dritten

Dialogfeld

Abb. 7: Schritt 2 der MFC-Anwendung

des Assistenten wird das Kontrollkästchen für die Unterstützung von ActiveX -Steuerelementen ausgeschaltet (Abbildung 8).

Abb.8: Schritt 3 der MFC-Anwendung

11

Im vierten Schritt des Anwendungs- Assistenten wird auf die Merkmale Drucken

und

Druck-

sowie

vorschau,

3D-

Steuerelemente verzichtet. Die Auswahl der beiden ersten MenüAbb 9: Schritt 4 der MFC-Anwendung

punkte

Andockbare

Symbolleiste und Statusleiste zu Beginn werden beibehalten (Abbildung 9).

Im fünften Schritt des Anwendungs-Assistenten werden

die

Standard-

einstellungen

übernom-

Abb. 10: Schritt 5 der MFC-Anwendung

men (Abbildung 10).

Im letzten Schritt des Anwendungs-Assistenten wird die Ansichtsklasse mit

dem

Namen

CDArbei29_07View Abb. 11: Schritt 6 der MFC-Anwendung

12

markiert um sie Später im Feld Klassenname in CDArbei29_07View1 umzube-nennen (Abbildung 11). Im Feld Basisklasse wird die Klasse CScrollView für diese Ansichts-datei ausgewählt. Vor der endgültigen Fertigstellung kann man in dem Feld Basisklasse eine Klasse aus verschiedenen auswählen, aus der die Ansichtsklasse ihre Eigenschaften beziehunsgweise Methoden erbt. Aufgrund der Größe des zu erstellenden Bildes braucht die Anwendung Scrollbalken, um das gesamte Bild anschauen zu können. Aus diesem Grund wurde die Basisklasse CScrollView ausgewählt. Ad 2: Die Option SDI–Grundgerüste (SDI- single document interface) wurde in diesem Schritt ausgewählt, da sie universeller einsetzbar sind als MDI-Gerüste (MDI- multiple document interface). Beide Grundgerüste, SDI wie MDI, sind vorrangig für Dateibearbeitungsprogramme konzipiert, das heißt für Programme, die den Inhalt von Dateien laden (Grafiken, Texte, Sounddateien), bearbeiten und wieder abspeichern. Da in dieser Anwendung eine gleichzeitige Bearbeitung mehrere Dateien nicht vorgesehen ist, eignen sich SDI-Programme besser, da sie jeweils nur das Laden und Bearbeiten einer einzigen Datei zur gleichen Zeit erlauben. SDI-Programme haben aufgrund des simpleren und übersichtlicheren Programmtextes zudem den Vorteil der leichteren Anpassung an Programme, die nicht der Bearbeitung von Dateien dienen. Außerdem besteht keine Notwendigkeit zu der Unterstützung von Ausführungen zusätzlicher untergeordneter Rahmen in den eigenen Dokument/Ansicht-Klasseninstanzen.

13

Mit

der

Unterstützung

des

Doc/View-Modells

(Dokument/Ansicht-

Architektur) durch SDI-Grundgerüste verhält es sich genau umgekehrt: Das Grundgerüst wird durch das Doc/View-Modell eher komplexer, manchmal zudem ohne eindeutige Vorteile. Seine Verwendung hat daher folgenden Grund: Je komplexer und professioneller die Anwendung mit der Zeit wird, desto stärker zahlt sich die Verwendung von Doc/View aus. Doc/View bezeichnet ein Modell zur Code-Organisation, das die Trennung von Datenverwaltung und Datenanzeige propagiert. Letztere dient sowohl der besseren Übersichtlichkeit als auch der Erleichterung der Programmierung, zum Beispiel wenn man Daten auf zwei unterschiedliche Arten anzeigen möchte, wie in unserem Falle die Darstellung der Daten als Kurve und Bild (siehe auch CDarbeit29_07Doc). Die MFC (Microsoft Foundation Class) stellt zur Unterstützung dieses Modells eine Reihe von speziellen Klassen und Methoden zur Verfügung. Die Techniken zur Anzeige von Grafiken sind von der Verwendung von Doc/View weitgehend unabhängig. Doc/View ist kein substantielles Element einer Windows- Anwendung und auch keine spezielle Programmiertechnik, die uns eine neue Funktionalität erschließt. Ad 7: Die Umbenennung der Ansichtsklasse von CDArbeit29_07View in CDArbeit29_07View1 gründet auf der Tatsache, dass diese Anwendung über zwei Ansichten verfügen soll (Kurve und Bild), zwischen denen der User beliebig umherschalten kann.

14

Die darzustellenden Daten für das Bild und die Kurven werden in dem Dokument des SDI-Programms verwahrt und in seiner OnDraw() - Methode auf den Bildschirm gemalt. In der OnDraw() - Methode des Ansichtsfensters CDArbeit29_07View1 werden die Kurven gezeichnet. Der zugehörige Quellcode befindet sich im Anhang (Anhang 1). Zur Erstellung der zweiten Ansicht

(des

Bildes)

ist

eine

zweite

Ansichtsklasse

zu

definieren,

CDArbeit29_07View2. Man legt die neue Klasse mit dem KlassenAssistenten an. Um dem Programm eine zweite Ansichtsklasse hinzuzufügen muss man (1) ein Objekt der neuen Ansichtsklasse instantiieren (2) die Create() - Methode des Objekts aufrufen (3) die Ansicht mit dem Dokument verbinden. Ad (2): Die zweite Ansicht wird erzeugt in der CMainFrame-Methode OnCreateClient().

Sie

ist

ein

geeigneter

Ort

dafür,

weil

sie

das

CCreateContext-Objekt für die Einrichtung der ersten Ansicht liefert. In diesem Objekt ist unter anderem festgehalten, mit welchem Dokument die Ansicht zu verbinden ist. Zur Identifizierung der beiden Ansichten definiert man zwei IDs (View1, View2) und weist diese den Ansichtsfenster- Objekten zu. Die Zuweisung erfolgt entweder über die Create() - Methode oder mit Hilfe der CWnd-Methode GetDlgItem(). Unter Menü/Darstellung hat man die Möglichkeit zwischen den Ansichten zu wechseln (siehe Anhang 2 für Näheres hinsichtlich des zugrunde liegenden Quellcodes für die Erstellung des Menü-Punktes ’Darstellung’).

15

II

Die Dateien und Klassen des Anwendungsgerüstes Jedem Anwendungsgerüst liegen Klassen und Dateien zugrunde, die

miteinander in Beziehung stehen (wie man in Abbildung 12 erkennen kann).

Abb.12: Dateien und Klassen des Anwendungsgerüstes.

Dies liegt daran, daß der Anwendungs-Assistent zum Aufbau des Anwendungsgerüst fünf Klassen erzeugen muß (für den Fall, dass die Anwendung nur ein Ansichtsfenster hat, werden vier Klassen erstellt). Für jede dieser Klassen werden eine Header-Datei und eine Quelltextdatei erzeugt.

16

In der Header-Datei wird die Klasse deklariert, in der Quelltextdatei werden die Methoden der Klasse definiert. Auf diese Weise wird der erzeugte Code modularisiert. Die Klasse CAboutDlg, die den INFO-Dialog enthält, besitzt keinen Einfluss auf das Funktionieren des Anwendungsgerüstes. Welche Dateien im Einzelfall angelegt werden ist abhängig von den Einstellungen im Dialogfeld des Anwendungs-Assistenten (SDI/MDI-Anwendung, Doc/ViewModell). Im folgenden werden die fünf Klassen hinsichtlich ihres Inhaltes und ihrer Funktion näher betrachtet:

III

CDarbeit29_07App – das Anwendungsobjekt Zuerst benötigt man ein Objekt, das geeignet ist, die Anwendung zu

repräsentieren. Die MFC definiert hierfür die Klasse CWinApp. Da es zur Anpassung der Anwendung an unsere Vorstellungen nötig ist, einige Methoden der Klasse CWinApp zu überschreiben, hat der AnwendungsAssistent eine eigene Klasse namens CDarbeit29_07App von CWinApp abgeleitet. In der Datei Darbeit29_07.cpp sind nicht nur die überschriebenen Methoden

implementiert,

hier

wird

auch

ein

globales

Objekt

der

Anwendungsklasse erzeugt: theApp. Im Quelltext des Projekts wird dieses Objekt nicht weiter verwendet. Visual C++ fügt dem MFC-Programm einen zusätzlichen Startcode hinzu, aus dem auf dieses Objekt zugegriffen wird. Die wichtigsten Aufgaben des Anwendungsobjektes sind die Erzeugung des Hauptfensters der Anwendung und die Kommunikation mit Windows.

17

IV

CDarbeit29_07Doc – die Dokumentklasse Die Klasse CDarbeit29_07Doc ist von der MFC-Klasse CDocument

abgeleitet. Sie unterstützt den Befehl Datei/Neu sowie das Laden und Speichern von Daten aus und in Dateien. In dieser Anwendung wurde auf die Implementierung von diesen Funktionalitäten verzichtet. Im Falle der Anwendung von der Bearbeitung anderer Bilder oder beim Testen ähnlicher Geräte kann dies jedoch notwendig werden. Die

Doc/

View-

Dokumentvorlagen.

Das

Unterstützung Dokumentobjekt

arbeitet wird

mit

sogenannten

zusammen

mit

der

Dokumentvorlage eingerichtet. Im Konstruktor dieser Klasse wird die HiResData.dat eingelesen und die dadurch gewonnenen Daten in einer geeigneten Form in einem Feld neu gespeichert. Damit können die beiden Ansichten unabhängig von einander darauf zugreifen (siehe Anhang 6).

V

CMainFrame – das Hauptfenster der Anwendung Die Klasse CMainFrame ist von der MFC-Klasse CFrameWnd abgeleitet.

Diese Klasse verleiht der Anwendung ein sichtbares Rahmenfenster. Letzteres sind Fenster mit einem speziellen Rahmen, in welchem bestimmte Elemente wie zum Beispiel ein Menü integriert werden können. In dieser Anwendung musste das Menü um eine weitere Funktionalität erweitert werden um zwischen den Ansichten wechseln zu können. Diese Klasse ist der geeigneter Ort um den Code einzubringen, damit die Funktion für beide Ansichten zur Verfügung steht (siehe Anhang 2).

18

Um nun ein Rahmenfenster zu erzeugen sowie es mit der Anwendung zu verbinden und anzuzeigen, sind folgende Schritte notwendig: 1.

Um das Rahmenfenster zu erzeugen, wird ein Objekt einer abgeleiteten Klasse CMainFrame instantiiert: CMainFrame *pMainWnd = new CMainFrame;

2.

Um das Rahmenfenster mit der Anwendung zu verbinden, wird der Zeiger

auf

das

Fensterobjekt

an

die

globale

MFC-Variable

m_pMainWnd übergeben: m_pMainWnd = pMainWnd; 3.

Um das Rahmenfenster anzeigen zu lassen, werden die Methoden Show-Window() und UpdateWindow() aufgerufen: m_pMainWnd->ShowWindow(SW_SHOW); m_pMainWnd->UpdateWindow();

Es ist zu erwähnen, dass bei der Einrichtung der Dokumentvorlagen gleichzeitig das Rahmenfenster eingerichtet wird, was dazu führen kann, dass manche der oben genannten Methoden versteckt im Quelltext abgespeichert werden.

VI

CDarbeit29_07View – das Ansichtsfenster der Anwendung Das Ansichtsfenster ist ein untergeordnetes Fensterobjekt, das in den

Client – Bereich des Rahmenfensters eingefügt und eingebaut wird. In diesem Bereich kann man zum Beispiel einen Text ausgeben oder eine Grafik zeichnen. Das ginge auch über das Rahmenfenster ohne von dem Ansichtsfenster Gebrauch zu machen. Mit vorliegendem Vorgehen erzielt man eine klare Aufgabenteilung: Das Rahmenfenster ist die Hauptschnitt19

stelle der Anwendung, wenn man dieses schließt, wird auch die Anwendung beendet. Ein weiterer Vorteil dieses Vorgehens ist, dass somit das Ansichtsfensterobjekt einer eigenen Basisklasse angehört, die wichtige und weitere Methoden dem Ansichtsfensterobjekt zur Verfügung stellt, und unabhängig ist von derjenigen, der das Rahmenfensterobjekt zugeordnet ist. Im letzten Schritt des Dialogfeldes des Anwendungs-Assistenten hat man die

Möglichkeit

eine

geeignete

Basisklasse

auszuwählen,

die

ihre

Eigenschaften der Ansichtsklasse der Anwendung vererbt. Für die hier beschriebene Anwendung

wurde CScrollView

ausgewählt,

was

dem

Ansichtsfenster einen Scrollbalken hinzufügte. Dieser war notwendig, um das Bild mit der Größe von 4096 Pixel mal 4096 Pixel vollständig anzeigen zu können. Zudem wurden zwei weitere Funktionen der CDArbeit29_07View2 – Klasse hinzugefügt: OnZoomin() und OnZoomout(), die, wie ihre Namen vermuten lassen, in das Bild hinein – und herauszoomen (siehe Anhang 7). Eine Methode, die die Basisklasse zur Verfügung stellt ist die SetScaleToFitSize()-Methode. Diese passt das gesamte Bild an das zur Verfügung stehenden Ansichtsfenster an, und erst nach Verwendung der Zoom-funktion erscheinen die Scrollbalken am Rande der Benutzeroberflächen. Zur

Einpassung

des

Ansichtsfensters

in

den

Client-Bereich

des

Rahmenfensters übergibt man ersterem bei der Erzeugung einen Zeiger auf das übergeordnete Rahmenfenster. Die Einrichtung des Ansichtsfensters und seine Verknüpfung mit dem Rahmenfenster sind ebenfalls in der Erzeugung der CSingleDocTemplate-Dokumentvorlage enthalten. 20

VII

Zeichnen Die wichtigste Stelle in unserem Quellcode stellt die Methode OnDraw()

dar, enthalten in der Klasse CDarbeit29-07View. Die OnDraw() - Methode dient der Rekonstruktion des Fensterinhaltes und wird automatisch ausgeführt, wenn Windows eine WM_Paint-Nachricht an das Fenster schickt, um ihm mitzuteilen, dass es seinen Fensterinhalt neu zeichnen soll. Die OnDraw() - Methode wird auf einem Umweg aufgerufen. Die WM_PaintNachricht wird von den Fensterklassen der MFC in einer OnPaint() - Methode abgefangen. Diese bereitet einen passenden Gerätekontext für die Zeichenausgabe vor und übergibt diesen an die Methode OnDraw(). Für die Konstruktion des Fensterinhaltes, in unserem Fall die Erstellung des Bildes und der Kurve muss man die OnDraw() - Methode der Ansichtsklasse modifizieren. In einem ersten Schritt werden (a) Leinwand (b) Stift und (c) Farbe ausgewählt. (a) Die Leinwand (Gerätekontext): Für Grafikausgaben am Computer braucht man einen Gerätekontext, der zu dem Fenster korrespondiert in das man zeichnen will. Man spricht die Ausgabegeräte wie Drucker oder Bildschirm nicht direkt an sondern über einen Gerätekontext. Das hat den Vorteil, dass der Programmierer sich nicht um die jeweils installierten Hardware zu kümmern braucht. Der Programmierer schreibt direkt in den Gerätekontext und überläßt Windows die Übergabe an die Hardware.

21

In der Tabelle 1 sind die verschiedenen Ausgabegeräte zusammengestellt, die MFC zur Verfügung stellt. Tabelle 1: Ausgabegeräte, die MFC zur Verfügung stellt Klasse

Ausgabeeinheit

CDC

Basisklasse aller Gerätekontextklassen mit reicher Auswahl an Zeichen- und Ausgabeoperationen.

CPaintDC

Spezieller Fenster-DC zur Implementierung von Behandlungsmethoden zur WM_PAINT-Nachricht.

CClientDC

Gerätekontext für die Ausgabe in den Client-Bereich eines Fensters

CWindowDC

Gerätekontext für den gesamten Bereich eines Fensters ( einschließlich Rahmen, Titel und vieles mehr)

(b) STIFTE( CPen) und PINSEL( CBrush): Für die Linien und Konturen der dargestellten Kurven in dem Programm wird ein CPen-Objekt zum Auftragen der Farbe verwendet. CPen ist das hauptsächliche Ressourcenwerkzeug, mit

Abb.13: Ansicht der On-Draw()-Methode der Klasse Cdarbeit29_07View2

dem man Linien aller Art auf dem Bildschirm darstellt. Erzeugt man eine Instanz der Klasse CPen, kann man den Typ, die Farbe und die Breite der Linie spezifizieren. Nachdem der Stift erzeugt ist, läßt er sich als aktuelles 22

Zeichenwerkzeug für den Gerätekontext auswählen und damit für alle Zeichenbefehle in diesen Geräte-kontext verwenden. (c) DIE FARBEN (RGB): Die Farbe ist als RGB-Wert anzugeben, der sich aus drei separaten Werten für die Helligkeit der roten (R), grünen (G) und blauen

(B)

Komponenten

der

Pixel

auf

dem

Computerbildschirm

zusammensetzt. Die einzelnen Komponenten können Werte im Bereich zwischen 0 und 255 annehmen. Die Funktion RGB faßt die Einzelwerte in einem Format zusammen, das Windows für die Ausgabe benötigt. Dem Ansichtsfenster, welches das Bild (siehe Abbildung 13) beinhaltet, liegt folgende modifizierte OnDraw()-Methode zugrunde: void CDarbeit29_07View2::OnDraw(CDC* pDC) { CDarbeit29_07Doc* pDoc = (CDarbeit29_07Doc*) GetDocument(); // ZU ERLEDIGEN: Code zum Zeichnen hier einfügen /* Wir definieren unser Array, indem wir alle Elemente auf 0 setzen, und verbinden es anschließend mit Bild über die Funktion CreateBitmap(...): */ for(int n = 0; n< 4096*4096; n++) { B[4*n] = B[(4*n) +1] = B[(4*n) +2] = pDoc->A[n]; B[(4*n)+3] = 0; } Bild.CreateBitmap(4096, 4096, 1, 32, B); /* Die Struktur vom Typ BITMAP definiert Typ, Höhe, Breite, Farbformat und Bit-Werte eines Bitmaps */ BITMAP bm; /* Hier kommt die Funktion int CGdiObject::GetObject ( int nCount, LPVOID lpObject ) zum Einsatz. Bedeutung der Funktions-Parameter: nCount: Anzahl Bytes, die in den lpObject-Puffer kopiert werden. lpObject: Zeiger auf einen Puffer, der die Daten aufnimmt. */ Bild.GetObject( sizeof (bm), &bm);

23

/* Die MFC-Klasse CDC umhüllt die Funktion eines Windows-Geräte-Kontexts (device context), der die Bildschirm- oder Druckerausgabe gewährleistet. Die MFC-Funktion virtual BOOL CreateCompatibleDC(CDC*pDC ) erzeugt einen Speicher-Geräte-Kontext. Dieser ist "kompatibel" mit dem durch den Zeiger pDC (gleichbedeutend mit der Speicheradresse des Geräte-Kontexts) angegebenen Geräte-Kontext. Ein mit dieser Funktion erstellter Speicher-Geräte-Kontext ist ein Speicherbereich, der die Bildschirmausgabe erzeugen kann. */ CDC SpeicherDC; SpeicherDC.CreateCompatibleDC(pDC); /* Die MFC-Funktion CDC::SelectObject tritt hier in folgender Variante auf: CBitmap* SelectObject( CBitmap* pBitmap ); Hiermit wird das CBitmap-Objekt Bild in den Speicher-Geräte-Kontext SpeicherDC kopiert. Die Funktion erwartet als Parameter die Adresse von Bild also &Bild. */ SpeicherDC.SelectObject(&Bild); /* Die MFC-Funktion CDC::StretchBlt kopiert ein Bitmap aus einem QuellRechteck in ein Ziel-Rechteck. Die Quelle ist hier der Speicher-Geräte-Kontext, das Ziel der für die Ausgabe zuständige Geräte-Kontext CDC* pDC. Hierbei wird das Bitmap den Abmessungen des Ziel-Rechtecks durch Dehnung oder Streckung angepaßt. Die allgemeine Syntax dieser Funktion lautet: BOOL StretchBlt ( int x, int y, int nWidth, int nHeight, CDC* pSrcDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, DWORD dwRop ); */ pDC->StretchBlt(0, 0, pDoc->k*4096, pDoc->k*4096, &SpeicherDC, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY); // ** SpeicherDC.DeleteDC(); Bild.DeleteObject(); }

**

Gerätekontextobjekte

gehören

genau

wie

alle

Arten

von

Zeichenobjekten zu den Ressourcen im Betriebssystem Windows. Das Betriebssystem verfügt über eine begrenzte Zahl dieser Ressourcen. Obwohl die Gesamtzahl der Ressourcen in den neueren Versionen von Windows recht groß ist, kann dennoch ein Mangel entstehen, wenn eine Anwendung die Ressourcen zwar reserviert, nicht aber wieder korrekt freigibt. 24

Diesen Verlust bezeichnet man als Ressourcenlücke, die analog zu einer Speicherlücke das System des Benutzer blockieren kann. Es empfiehlt sich also, die Ressourcen in Funktionen zu erzeugen, wo sie zum Einsatz kommen, und sie sobald wie möglich wieder freizugeben, wenn die Arbeit mit den betreffenden Ressourcen abgeschlossen ist. Dementsprechend

nutzt

man

Gerätekontexte

und

deren

Zeichenressourcen fast ausschließlich als lokale Variablen innerhalb einer einzigen Funktion. Die einzige echte Ausnahme liegt vor, wenn das Gerätekontextobjekt von Windows erzeugt und in eine ereignisverarbeitende Funktion als

Argument

über-

geben wird. Für diese Anwendung

ist

ein

weiteres

Ansichts-

fenster notwendig, zur Darstellung Bild

der

dem

zugehörigen

Intensitätskurven (siehe Abbildung 14).

Abb. 14: Ansicht der On-Draw()-Methode der Klasse Cdarbeit29_07View1

25

Die Eckpfeiler der OnDraw()-Methode des zweiten Ansichtsfensters sind folgende Schritte: 1.

die Leinwand wird vorbereitet (void CDarbeit29_07View::OnDraw(CDC* pDC)) -die MFC übergibt der OnDraw ()-Funktion als Argument einen Zeiger auf dem Gerätekontext CDC, OnDraw(CDC* pDC). CDC ist eine Basisklasse aller Gerätekontextklassen mit reicher Auswahl an Zeichen- und Ausgabeoperationen.

2.

Anschließend werden die Pinsel bestimmt, in diesem Fall zwei: einen Blaue und den anderen Rosa ( CPen PenBlau; PenBlau.CreatePen(PS_SOLID, 1, RGB(200, 0, 200)); CPen PenRosa; PenRosa.CreatePen(PS_SOLID, 1, RGB(0, 12, 200)); )

3.

Berechnung

der

3

Parameter

MAX

(Programmablauf

siehe

Diagramm in Anhang 3), FWHM und FWTM (Programmablauf siehe Diagramm in Anhang 4). Ad 3: Um die Maxima und den Abstand zwischen zwei aufeinander folgenden Maxima zu bestimmen sind einige Laufvariablen notwendig: die Laufvariabe h steht für die Anzahl der Streifen und läuft daher von 0 bis 15. Innerhalb eines Streifens verläuft die Laufvariable k entlang der x-Achse. Sie deckt den Bereich von 0 bis ((h+1)*4096)-1 ab.

26

Die entsprechenden y-Werte werden mit dem Wert 150 verglichen, wobei 150 als unterer Grenzwert für ein Maximum festgelegt ist. Sobald ein Treffer gefunden ist, wird der Wert der Variable k in einer Konstanten Z gespeichert. Im Bereich von Z bis Z + 49 wird von nun an die Suche fortgesetzt, wobei der größte y-Wert als das Maximum angenommen wird. Der zugehörige x-Wert wird anschließend in einer Konstanten namens mo gespeichert, wobei der Wert ebenfalls als mo-h*4096 in einer Konstanten a abgespeichert wird. Sobald das Maximum gefunden wurde nimmt die Laufvariable k ihre Aufgabe wieder auf, die Kurve auf y-Werte > 150 abzutasten. Den Ausgangspunkt bildet dabei x = Z + 49. Sobald das folgende Maximum gefunden ist, wird der Konstanten a der dem zweiten Maximum zugehörige x-Wert zugewiesen. Die Differenz zwischen dem neuen und dem bestehenden Wert von a stellt die Distanz zwischen den aufeinander folgenden Maxima dar und wird als ’MAX zu Max’-Wert ausgegeben. Sobald der Wert mo einmal bestimmt ist, wird in einem Bereich aus 70 Punkten zu beiden Seiten von mo entlang der x-Achse nach Punkten, die auf dem Verlauf der Amplitude liegen und deren y-Wert die Hälfte des MAXWertes (der ymo-Wert) beträgt, gesucht. Der Abstand zwischen den beiden Punkten stellt den gesuchten FWHM-Wert dar. Analog wird mit dem y-Wert in Höhe eines Zehntels des MAX-Wertes zur Bestimmung des FWTM-Wertes verfahren.

27

Literatur 1- Chapman (1999). Visual C++6 in 21 Tagen. Markt&Technik, Buch- und Software-Verlag GmbH 2- Louis

D

(2005)

Visual

C++

2005.

Professionell

einsteigen.

entwickler.press 3- www.henkessoft.de

28

Anhang Anhang 1: Quellcode der OnDraw() - Methode für das Ansichtsfenster CDArbeit29_07View1 ///////////////////////////////////////////////////////////////////////////// // CDarbeit29_07View1 Zeichnen void CDarbeit29_07View1::OnDraw(CDC* pDC) { CDarbeit29_07Doc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // ZU ERLEDIGEN: Hier Code zum Zeichnen der ursprünglichen Daten hinzufügen CPen PenBlack; PenBlack.CreatePen(PS_SOLID, 1, RGB(200, 0, 200)); CPen PenBlue; PenBlue.CreatePen(PS_SOLID, 1, RGB(0, 12, 200)); CPoint Pt; CPoint PtPrev; int i=0, h=0, s=0, j=0, k=0; int kurv[16*4096]; for (h=0; h<16; h++) { for(i=0; i< 4096; i++) { for(j=h*256; j< (h+1)*256; j++) s= s+ pDoc->A[i+j*4096]; kurv[k]=s; kurv[k]=kurv[k]/255; k++; s=0; } } j=0; h=0; int mo=0, mol=0, mor=0, tor=0, tol=0, FWHM=0, FWTM=0; int a=0, b=0, dif=0; char buff[80]; pDC->SelectObject(&PenBlack);

//

for(h=0; h<16; h++) { int z=0, hl=0; i=0; a=0, b=0, dif=0; k=h*4096; do { Maximum suchen int max =150; if (kurv[k]>max)

29

{ z=k; for(j=z+1; jmax) { mo = j; max = kurv[mo]; } } a=mo-h*4096; dif=a-b; i=i+dif; b=a; if(b==0|| dif>300|| dif<200) dif=0; if(dif!=0) { sprintf(buff,"<-%d->", dif) ; pDC->TextOut(10*i-2050, h*1500-5*255-100, buff); } pDC->MoveTo(10*i, h*1500); pDC->LineTo(10*i, h*1500-4*kurv[mo]); //

Der linke Punkt FWHM int ymol=0; for(j=mo-70; j<mo; j++) { if (kurv[j]==max/2) { mol=j; ymol=kurv[mol]; break; } else if (kurv[j]<max/2 && kurv[j+1]>max/2) { mol=j; ymol=max/2; break; } }

//

Der rechte Punkt FWHM int ymor=0; for(j=mo; j<mo+70; j++) { if (kurv[j]==max/2) { mor=j; ymor=kurv[mor]; break; } else if (kurv[j]>max/2 && kurv[j+1]<max/2) { mor=j+1; ymor=max/2; break;

30

} } pDC->MoveTo(10*(mol-h*4096), h*1500-4*ymol); pDC->LineTo(10*(mor-h*4096), h*1500-4*ymor); dif = mor-mol; sprintf(buff," %d", dif) ; pDC->TextOut(10*(mol-h*4096)-800, h*1500-7*ymor, buff); //

Der linke Punkt FWTM int tol=0, ytol=0; for(j=mo-80; j<mo; j++) { if (kurv[j]==max/10) { tol=j; ytol=kurv[tol]; break; } else if(kurv[j]<max/10 && kurv[j+1]>max/10) { tol=j; if (max%10>5) ytol= max/10+1; else ytol=max/10; break; } }

//

Der rechte Punkt FWTM int tor=0, ytor=0; for(j=mo; j<mor+80; j++) { if (kurv[j]==max/10) { tor=j; ytor=kurv[tor]; break; } else if(kurv[j]>max/10 && kurv[j+1]<max/10) { tor=j+1; if (max%10>5) ytor= max/10+1; else ytor=max/10; break; } } pDC->MoveTo(10*(tol-h*4096), h*1500-4*ytol); pDC->LineTo(10*(tor-h*4096), h*1500-4*ytor); dif = tor-tol; sprintf(buff," %d", dif) ; pDC->TextOut(10*(tor-h*4096)+50, h*1500-4*ytor-350, buff); k=k+49; }

// if k

31

k++; }while(k<((h+1)*4096)-1); } // for h DeleteObject(&PenBlack); pDC->SelectObject(&PenBlue); for(h=0; h<16; h++) { i=0; for(k=h*4096; k<((h+1)*4096)-1; k++) { PtPrev.x=10*i; PtPrev.y= h*1500-4*kurv[k]; Pt.x=10*(i+1); Pt.y=h*1500-4*kurv[k+1];

}

pDC->MoveTo(PtPrev); pDC->LineTo(Pt); i++; } //for(k) // for(h)

DeleteObject(&PenBlue); }

32

Anhang 2: Die Methoden innerhalb der Klasse CMainFrame die den Wechsel zwischen den Darstellungsformen ermöglicht. void CMainFrame::OnDarstellungKurve() { // TODO: Code für Befehlsbehandlungsroutine hier einfügen CView *pView, *pAktView; CDocument *pDoc; pAktView = GetActiveView(); pDoc = pAktView->GetDocument(); POSITION pos = pDoc->GetFirstViewPosition(); while(pos != NULL) { pView = pDoc->GetNextView(pos); if (pView->IsKindOf(RUNTIME_CLASS(CDarbeit29_07View1))) { SetActiveView(pView); pView->ShowWindow(SW_SHOWNORMAL); pView->SetDlgCtrlID(AFX_IDW_PANE_FIRST); pAktView->ShowWindow(SW_HIDE); pAktView->SetDlgCtrlID(VIEW2); } } RecalcLayout(); } void CMainFrame::OnDarstellungBild() { // TODO: Code für Befehlsbehandlungsroutine hier einfügen CView *pView, *pAktView; CDocument *pDoc; pAktView = GetActiveView(); pDoc = pAktView->GetDocument(); POSITION pos = pDoc->GetFirstViewPosition(); while(pos != NULL) { pView = pDoc->GetNextView(pos); if (pView->IsKindOf(RUNTIME_CLASS(CDarbeit29_07View2))) { SetActiveView(pView); pView->ShowWindow(SW_SHOWNORMAL); pView->SetDlgCtrlID(AFX_IDW_PANE_FIRST); pAktView->ShowWindow(SW_HIDE); pAktView->SetDlgCtrlID(VIEW1); } } RecalcLayout(); } 33

Anhang 3: PAP zur Bestimmung des maximalen Wertes (MAX) der Amplituden und des Abstandes zwischen zwei aufeinander folgenden MAX in Pixeln (dif)

h:= 0 k:= h*4096 b:= 0

max= 150

n

kurv[k]> max

k++

j

j Z:= k j:= z+1

k< ((h+1)*4096)-1

n kurv[j]> max

n

h++ b:=0

j mo:= j max:= kurv[mo]

j< z+50

k:= h*4096

j

j++

n a:= mo-h*4096 dif:= a-b b:= a

b==0|| dif>300|| dif<200

n

sprintf(buff,"<-%d->", dif) ; pDC->TextOut(10*i-2050, h*1500-5*255-100,

buff);

j dif:= 0

pDC->MoveTo(10*i, h*1500); pDC->LineTo(10*i, h*1500-4*kurv[mo]);

34

Anhang 4: PAP zur Bestimmung des FWHM

j:= mo-70

mol=j; ymol=kurv[mol];

j

kurv[j] = max/2

j:= mo

n kurv[j] = max/2 kurv[j]>max/2 && kurv[j+1]<max/2

j

mol=j; ymol=kurv[mol];

n

j mor=j; ymor=kurv[mor];

n j++

mor=j+1; ymor=max/2;

kurv[j]>max/2 && kurv[j+1]<max/2

j

n j< mo+70 j++

n

j j++

dif = mor-mol;

sprintf(buff,"%d", dif) ; pDC->TextOut(10*(mol-h*4096)-800, h*1500-7*ymor,

buff);

35

Anhang 5: Tabelle aller ermittlelten Werte für die Kurvenparameter MAX, FWHM und FWTM Spalte Max FWHM_l FWHM_r FWTM_l FWTM_r Max FWHM_l FWHM_r FWTM_l FWTM_r Max FWHM_l FWHM_r FWTM_l FWTM_r Max FWHM_l FWHM_r FWTM_l FWTM_r Max FWHM_l FWHM_r FWTM_l FWTM_r Max FWHM_l FWHM_r FWTM_l FWTM_r Max FWHM_l FWHM_r FWTM_l FWTM_r Max FWHM_l FWHM_r FWTM_l FWTM_r

1 2 3 4 5 6 7 8 9 10 11 12 219 233 224 221 219 225 226 227 216 221 229 214 46 39 41 40 54 40 45 39 51 43 40 40 39 41 40 54 40 45 39 51 43 40 40 44 83 65 71 67 81 62 68 63 81 68 65 63 65 71 67 81 62 68 63 81 68 65 63 70 227 228 216 228 218 229 219 228 216 226 223 227 41 45 45 40 49 40 50 40 47 40 47 46 45 45 40 49 40 50 40 47 40 47 46 39 66 66 70 62 74 61 79 62 72 63 72 70 66 70 62 74 61 79 62 72 63 72 70 64 225 224 223 229 214 229 219 231 219 222 226 224 41 43 42 41 49 40 48 41 49 44 46 42 43 42 41 49 40 48 41 49 44 46 42 43 65 67 64 63 75 60 71 61 72 68 64 67 67 64 63 75 60 71 61 72 68 64 67 66 220 227 224 218 221 224 226 229 217 224 231 215 38 44 44 41 47 40 51 39 45 41 50 45 44 44 41 47 40 51 39 45 41 50 45 40 59 67 71 63 72 67 75 62 68 64 71 69 67 71 63 72 67 75 62 68 64 71 69 63 220 225 220 225 220 228 222 225 225 216 228 228 39 41 42 40 50 39 47 39 48 39 46 38 41 42 40 50 39 47 39 48 39 46 38 44 62 66 64 62 74 64 71 57 73 63 73 63 66 64 62 74 64 71 57 73 63 73 63 66 229 223 223 218 221 234 219 222 225 219 231 221 40 43 43 40 48 39 47 39 50 39 46 41 43 43 40 48 39 47 39 50 39 46 41 45 64 63 64 63 69 61 72 58 74 60 71 61 63 64 63 69 61 72 58 74 60 71 61 69 216 231 216 225 226 221 225 227 221 218 228 213 41 42 44 39 46 40 46 39 47 41 46 41 42 44 39 46 40 46 39 47 41 46 41 47 66 67 67 61 70 58 72 58 71 62 68 65 67 67 61 70 58 72 58 71 62 68 65 72 225 223 219 228 217 235 214 226 224 215 229 225 41 40 44 39 49 40 45 40 47 42 45 40 40 44 39 49 40 45 40 47 42 45 40 48 65 63 68 59 73 62 67 61 70 64 71 60 63 68 59 73 62 67 61 70 64 71 60 71

36

Spalte 1 2 3 4 5 6 7 8 9 10 11 12 Max 222 228 221 221 225 233 211 225 226 224 225 218 FWHM_l 40 41 47 39 46 40 49 38 45 40 47 43 FWHM_r 41 47 39 46 40 49 38 45 40 47 43 42 FWTM_l 64 62 74 60 66 60 72 60 69 63 71 63 FWTM_r 62 74 60 66 60 72 60 69 63 71 63 62 Max 220 229 216 232 214 227 225 224 224 222 218 226 FWHM_l 44 39 46 40 50 40 48 40 50 43 42 42 FWHM_r 39 46 40 50 40 48 40 50 43 42 42 24 FWTM_l 65 63 67 64 72 61 72 58 75 66 66 68 FWTM_r 63 67 64 72 61 72 58 75 66 66 68 66 Max 218 231 223 221 220 232 225 216 223 226 226 219 FWHM_l 39 40 47 42 47 39 51 41 49 42 46 46 FWHM_r 40 47 42 47 39 51 41 49 42 46 46 40 FWTM_l 63 62 72 61 70 65 75 63 74 64 67 69 FWTM_r 62 72 61 70 65 75 63 74 64 67 69 62 Max 220 229 224 221 221 229 221 228 219 225 226 216 FWHM_l 44 38 45 41 51 39 46 38 48 42 40 42 FWHM_r 38 45 41 51 39 46 38 48 42 40 42 41 FWTM_l 75 65 67 62 81 63 72 61 77 68 63 68 FWTM_r 65 67 62 81 63 72 61 77 68 63 68 68 Mittelwert [Max] 220 228 222 223 220 229 221,5 226,5 222 222 227 220 Standabw [Max] 3,9 3,3 3,3 4,6 3,7 4,2 4,9 3,9 3,8 3,8 3,6 5,4 Mittelwert [FWHM] 41,3 42,8 42,0 44,5 44,5 43,5 43,3 43,5 44,5 43,5 43,5 42,5 Standabw 1,3 1,2 1,5 1,3 2,3 2,9 [FWHM] 1,0 1,4 1,1 1,3 1,2 1,1 Mittelwert [FWTM] 64,0 66,5 65,0 67,8 67,5 66,5 65,8 66,3 67,8 66,3 66,8 66,3 Standabw [FWTM] 3,5 1,6 1,9 2,9 2,7 2,2 2,0 2,2 2,7 1,0 2,0 1,6 Bemerke: FWHM_r = FWHM rechts, FWHM_l = FWHM links, FWTM_r = FWTM rechts, FWTM_l = FWTM links, Standabw = Standardabweichung

37

Anhang 6: Definition des Kontruktors der Klasse CDarbeit29_07Doc CDarbeit29_07Doc::CDarbeit29_07Doc() { // ZU ERLEDIGEN: Hier Code für One-Time-Konstruktion einfügen k=1; FILE *fp; fp = fopen("HiResData.dat", "rb"); fread(mat, 2*4096, 4096, fp); int k = 0; for(int i = 0; i< 4096; i++) { for(int j = 0; j< 4096; j++) { A[k] = (unsigned char)mat[i][j]; // Für eine schärfere Auflösung werden die Pixelwerte binarisiert if( A[k] != 0) A[k] = 255; k++; } } fclose(fp); }

38

Anhang

7:

Programmcode

zur

Zoomfunktion

in

der

Klasse

CDArbeit29_07View2 void CDarbeit29_07View2::OnZoomZoomin() { // TODO: Code für Befehlsbehandlungsroutine hier einfügen CDarbeit29_07Doc* pDoc = (CDarbeit29_07Doc*) GetDocument(); pDoc->k=pDoc->k+1; CSize sizeTotal; sizeTotal.cx = sizeTotal.cy = pDoc->k*4096; SetScrollSizes(MM_TEXT, sizeTotal); Invalidate(); UpdateWindow(); } void CDarbeit29_07View2::OnZoomZoomout() { // TODO: Code für Befehlsbehandlungsroutine hier einfügen CDarbeit29_07Doc* pDoc = (CDarbeit29_07Doc*) GetDocument(); pDoc->k=1; CSize sizeTotal; sizeTotal.cx = sizeTotal.cy = pDoc->k*4096; SetScrollSizes(MM_TEXT, sizeTotal); SetScaleToFitSize(sizeTotal); Invalidate(); UpdateWindow(); }

39

Related Documents

Hires Data
June 2020 9
Postcards Hires
November 2019 17
Westus Hires
November 2019 8
Invictamanual Hires
July 2019 22
Mboe-hires
August 2019 16
Gormiti Oldmap Hires
June 2020 4