Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "Histogramm.hpp"
- namespace OpenCV {
- Dimension::Dimension ()
- : _gueltig(false) {};
- Dimension::Dimension (float untererWert, float obererWert, int unterteilungen)
- : _gueltig(true)
- , _untererWert(untererWert)
- , _obererWert(obererWert)
- , _unterteilungen(unterteilungen) {};
- bool Dimension::gueltig () {
- return _gueltig;
- };
- float Dimension::untererWert () {
- return _untererWert;
- };
- float Dimension::obererWert () {
- return _obererWert;
- };
- int Dimension::unterteilungen () {
- return _unterteilungen;
- };
- Histogramm::Histogramm (Dimension d1, Dimension d2, Dimension d3, Dimension d4) {
- // für einfacheren Zugriff in Schleifen Parameter in Feld anordnen
- Dimension* d[] = {&d1, &d2, &d3, &d4};
- // übergebene Dimensionen abzählen
- int n = 0;
- for (int i = 0; i < 4; i++)
- if (d[i]->gueltig())
- n++;
- else
- break;
- if (n == 0)
- throw HistogrammFehler();
- // Feld mit Unterteilungen erzeugen
- int* unterteilungen = new int[n];
- for (int i = 0; i < n; i++)
- unterteilungen[i] = d[i]->unterteilungen();
- // Feld mit Bereichen erzeugen; jeder Bereich
- // ist wieder ein Feld mit zwei Einträgen
- float** bereiche = new float*[n];
- for (int i = 0; i < n; i++) {
- bereiche[i] = new float[2];
- bereiche[i][0] = d[i]->untererWert();
- bereiche[i][1] = d[i]->obererWert();
- };
- // Histogramm-Datenstruktur erzeugen
- _histogramm = cvCreateHist(n, unterteilungen, CV_HIST_ARRAY, bereiche);
- // Speicher für dynamische Felder wieder freigeben
- delete [] unterteilungen; unterteilungen = 0;
- for (int i = 0; i < n; i++) {
- delete [] bereiche[i];
- bereiche[i] = 0;
- };
- delete [] bereiche; bereiche = 0;
- };
- Histogramm::~Histogramm () {
- // Histogramm freigeben, wenn nicht leer
- if (_histogramm)
- cvReleaseHist(&_histogramm);
- };
- void Histogramm::analysiereBild (IplImage* bild) {
- // Ausnahme werfen, wenn Histogramm leer
- if (!_histogramm)
- throw HistogrammFehler();
- // Anzahl der Kanäle im Bild und Dimensionen
- // des Histogramms vergleichen
- if (bild->nChannels != _histogramm->mat.dims)
- throw HistogrammFehler();
- // übergebenes Bild in Kanäle zerlegen; dazu Hilfsbilder
- // erstellen und bei Bedarf 'cvSplit' einsetzen
- IplImage* kanaele[4];
- if (bild->nChannels == 1) {
- kanaele[0] = cvCloneImage(bild); // Kopie ist notwendig, damit unten einheitlich
- for (int i = 1; i < 4; i++) // Speicher freigegeben werden kann
- kanaele[i] = 0;
- } else {
- for (int i = 0; i < 4; i++)
- if (i < bild->nChannels)
- kanaele[i] = cvCreateImage(cvGetSize(bild), bild->depth, 1);
- else
- kanaele[i] = 0;
- cvSplit(bild, kanaele[0], kanaele[1], kanaele[2], kanaele[3]);
- };
- // in einzelne Kanäle zerlegtes Bild analysieren
- cvClearHist(_histogramm);
- cvCalcHist(kanaele, _histogramm);
- // Hilfsbilder freigeben
- for (int i = 0; i < 4; i++)
- cvReleaseImage(&kanaele[i]);
- };
- IplImage* Histogramm::diagramm (CvSize groesse) {
- // Ausnahme werfen, wenn Histogramm leer
- if (!_histogramm)
- throw HistogrammFehler();
- // Maximum im Histogramm ermitteln
- float hoechsterWert;
- cvGetMinMaxHistValue(_histogramm, 0, &hoechsterWert, 0, 0);
- IplImage* bild = 0;
- // zwischen Dimensionen unterscheiden
- int schrittX, schrittY;
- switch (_histogramm->mat.dims) {
- case 1:
- bild = cvCreateImage(groesse, IPL_DEPTH_8U, 1);
- cvZero(bild);
- for (int x=0 ; x<bild->width; x++) {
- int b = int(x * _histogramm->mat.dim[0].size / bild->width);
- float f = cvQueryHistValue_1D(_histogramm, b);
- int y = int(f * bild->height / hoechsterWert);
- cvLine(
- bild,
- cvPoint(x, bild->height-1),
- cvPoint(x, bild->height-1 - y),
- cvScalar(255)
- );
- };
- break;
- case 2:
- bild = cvCreateImage(groesse, IPL_DEPTH_8U, 1);
- schrittX = bild->width / _histogramm->mat.dim[0].size;
- schrittX = (schrittX == 0) ? 1 : schrittX;
- schrittY = bild->height / _histogramm->mat.dim[1].size;
- schrittY = (schrittY == 0) ? 1 : schrittY;
- for (int x=0 ; x<bild->width; x+=schrittX)
- for (int y=0 ; y<bild->height; y+=schrittY) {
- int x2 = int(x * _histogramm->mat.dim[0].size / bild->width);
- int y2 = int(y * _histogramm->mat.dim[1].size / bild->height);
- float f = cvQueryHistValue_2D(_histogramm, x2, y2);
- int i = int(pow(f/hoechsterWert, float(0.2))*255);
- cvRectangle(bild, cvPoint(x, y), cvPoint(x+schrittX-1, y+schrittY-1), cvScalar(i), CV_FILLED);
- };
- break;
- default:
- // für drei- und vierdimensionale Diagramme gibt es keine Darstellung
- throw HistogrammFehler();
- };
- return bild;
- };
- int Histogramm::haeufigkeit (int idx1, int idx2, int idx3, int idx4) {
- // Ausnahme werfen, wenn Histogramm leer
- if (!_histogramm)
- throw HistogrammFehler();
- // abhängig von der Anzahl der Dimensionen Wert zurckgeben
- if (idx4 != -1) {
- int idx[] = {idx1, idx2, idx3, idx4};
- return int(cvQueryHistValue_nD(_histogramm, idx));
- } else if (idx3 != -1)
- return int(cvQueryHistValue_3D(_histogramm, idx1, idx2, idx3));
- else if (idx2 != -1)
- return int(cvQueryHistValue_2D(_histogramm, idx1, idx2));
- else
- return int(cvQueryHistValue_1D(_histogramm, idx1));
- };
- Histogramm::operator CvHistogram* () {
- // Ausnahme werfen, wenn Histogramm leer
- if (!_histogramm)
- throw HistogrammFehler();
- // Histogramm zurckgeben
- return _histogramm;
- };
- CvHistogram* Histogramm::operator-> () {
- // Ausnahme werfen, wenn Histogramm leer
- if (!_histogramm)
- throw HistogrammFehler();
- // Histogramm zurckgeben
- return _histogramm;
- };
- };
Add Comment
Please, Sign In to add comment