Guest User

Untitled

a guest
Jun 24th, 2018
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.06 KB | None | 0 0
  1. #include "Histogramm.hpp"
  2.  
  3. namespace OpenCV {
  4.  
  5. Dimension::Dimension ()
  6. : _gueltig(false) {};
  7.  
  8. Dimension::Dimension (float untererWert, float obererWert, int unterteilungen)
  9. : _gueltig(true)
  10. , _untererWert(untererWert)
  11. , _obererWert(obererWert)
  12. , _unterteilungen(unterteilungen) {};
  13.  
  14. bool Dimension::gueltig () {
  15. return _gueltig;
  16. };
  17.  
  18. float Dimension::untererWert () {
  19. return _untererWert;
  20. };
  21.  
  22. float Dimension::obererWert () {
  23. return _obererWert;
  24. };
  25.  
  26. int Dimension::unterteilungen () {
  27. return _unterteilungen;
  28. };
  29.  
  30. Histogramm::Histogramm (Dimension d1, Dimension d2, Dimension d3, Dimension d4) {
  31. // für einfacheren Zugriff in Schleifen Parameter in Feld anordnen
  32. Dimension* d[] = {&d1, &d2, &d3, &d4};
  33.  
  34. // übergebene Dimensionen abzählen
  35. int n = 0;
  36. for (int i = 0; i < 4; i++)
  37. if (d[i]->gueltig())
  38. n++;
  39. else
  40. break;
  41. if (n == 0)
  42. throw HistogrammFehler();
  43.  
  44. // Feld mit Unterteilungen erzeugen
  45. int* unterteilungen = new int[n];
  46. for (int i = 0; i < n; i++)
  47. unterteilungen[i] = d[i]->unterteilungen();
  48.  
  49. // Feld mit Bereichen erzeugen; jeder Bereich
  50. // ist wieder ein Feld mit zwei Einträgen
  51. float** bereiche = new float*[n];
  52. for (int i = 0; i < n; i++) {
  53. bereiche[i] = new float[2];
  54. bereiche[i][0] = d[i]->untererWert();
  55. bereiche[i][1] = d[i]->obererWert();
  56. };
  57.  
  58. // Histogramm-Datenstruktur erzeugen
  59. _histogramm = cvCreateHist(n, unterteilungen, CV_HIST_ARRAY, bereiche);
  60.  
  61. // Speicher für dynamische Felder wieder freigeben
  62. delete [] unterteilungen; unterteilungen = 0;
  63. for (int i = 0; i < n; i++) {
  64. delete [] bereiche[i];
  65. bereiche[i] = 0;
  66. };
  67. delete [] bereiche; bereiche = 0;
  68. };
  69.  
  70. Histogramm::~Histogramm () {
  71. // Histogramm freigeben, wenn nicht leer
  72. if (_histogramm)
  73. cvReleaseHist(&_histogramm);
  74. };
  75.  
  76. void Histogramm::analysiereBild (IplImage* bild) {
  77. // Ausnahme werfen, wenn Histogramm leer
  78. if (!_histogramm)
  79. throw HistogrammFehler();
  80.  
  81. // Anzahl der Kanäle im Bild und Dimensionen
  82. // des Histogramms vergleichen
  83. if (bild->nChannels != _histogramm->mat.dims)
  84. throw HistogrammFehler();
  85.  
  86. // übergebenes Bild in Kanäle zerlegen; dazu Hilfsbilder
  87. // erstellen und bei Bedarf 'cvSplit' einsetzen
  88. IplImage* kanaele[4];
  89. if (bild->nChannels == 1) {
  90. kanaele[0] = cvCloneImage(bild); // Kopie ist notwendig, damit unten einheitlich
  91. for (int i = 1; i < 4; i++) // Speicher freigegeben werden kann
  92. kanaele[i] = 0;
  93. } else {
  94. for (int i = 0; i < 4; i++)
  95. if (i < bild->nChannels)
  96. kanaele[i] = cvCreateImage(cvGetSize(bild), bild->depth, 1);
  97. else
  98. kanaele[i] = 0;
  99. cvSplit(bild, kanaele[0], kanaele[1], kanaele[2], kanaele[3]);
  100. };
  101.  
  102. // in einzelne Kanäle zerlegtes Bild analysieren
  103. cvClearHist(_histogramm);
  104. cvCalcHist(kanaele, _histogramm);
  105.  
  106. // Hilfsbilder freigeben
  107. for (int i = 0; i < 4; i++)
  108. cvReleaseImage(&kanaele[i]);
  109. };
  110.  
  111. IplImage* Histogramm::diagramm (CvSize groesse) {
  112. // Ausnahme werfen, wenn Histogramm leer
  113. if (!_histogramm)
  114. throw HistogrammFehler();
  115.  
  116. // Maximum im Histogramm ermitteln
  117. float hoechsterWert;
  118. cvGetMinMaxHistValue(_histogramm, 0, &hoechsterWert, 0, 0);
  119.  
  120. IplImage* bild = 0;
  121. // zwischen Dimensionen unterscheiden
  122. int schrittX, schrittY;
  123. switch (_histogramm->mat.dims) {
  124. case 1:
  125. bild = cvCreateImage(groesse, IPL_DEPTH_8U, 1);
  126. cvZero(bild);
  127. for (int x=0 ; x<bild->width; x++) {
  128. int b = int(x * _histogramm->mat.dim[0].size / bild->width);
  129. float f = cvQueryHistValue_1D(_histogramm, b);
  130. int y = int(f * bild->height / hoechsterWert);
  131. cvLine(
  132. bild,
  133. cvPoint(x, bild->height-1),
  134. cvPoint(x, bild->height-1 - y),
  135. cvScalar(255)
  136. );
  137. };
  138. break;
  139. case 2:
  140. bild = cvCreateImage(groesse, IPL_DEPTH_8U, 1);
  141. schrittX = bild->width / _histogramm->mat.dim[0].size;
  142. schrittX = (schrittX == 0) ? 1 : schrittX;
  143. schrittY = bild->height / _histogramm->mat.dim[1].size;
  144. schrittY = (schrittY == 0) ? 1 : schrittY;
  145. for (int x=0 ; x<bild->width; x+=schrittX)
  146. for (int y=0 ; y<bild->height; y+=schrittY) {
  147. int x2 = int(x * _histogramm->mat.dim[0].size / bild->width);
  148. int y2 = int(y * _histogramm->mat.dim[1].size / bild->height);
  149. float f = cvQueryHistValue_2D(_histogramm, x2, y2);
  150. int i = int(pow(f/hoechsterWert, float(0.2))*255);
  151. cvRectangle(bild, cvPoint(x, y), cvPoint(x+schrittX-1, y+schrittY-1), cvScalar(i), CV_FILLED);
  152. };
  153. break;
  154. default:
  155. // für drei- und vierdimensionale Diagramme gibt es keine Darstellung
  156. throw HistogrammFehler();
  157. };
  158. return bild;
  159. };
  160.  
  161. int Histogramm::haeufigkeit (int idx1, int idx2, int idx3, int idx4) {
  162. // Ausnahme werfen, wenn Histogramm leer
  163. if (!_histogramm)
  164. throw HistogrammFehler();
  165.  
  166. // abhängig von der Anzahl der Dimensionen Wert zurckgeben
  167. if (idx4 != -1) {
  168. int idx[] = {idx1, idx2, idx3, idx4};
  169. return int(cvQueryHistValue_nD(_histogramm, idx));
  170. } else if (idx3 != -1)
  171. return int(cvQueryHistValue_3D(_histogramm, idx1, idx2, idx3));
  172. else if (idx2 != -1)
  173. return int(cvQueryHistValue_2D(_histogramm, idx1, idx2));
  174. else
  175. return int(cvQueryHistValue_1D(_histogramm, idx1));
  176. };
  177.  
  178. Histogramm::operator CvHistogram* () {
  179. // Ausnahme werfen, wenn Histogramm leer
  180. if (!_histogramm)
  181. throw HistogrammFehler();
  182. // Histogramm zurckgeben
  183. return _histogramm;
  184. };
  185.  
  186. CvHistogram* Histogramm::operator-> () {
  187. // Ausnahme werfen, wenn Histogramm leer
  188. if (!_histogramm)
  189. throw HistogrammFehler();
  190. // Histogramm zurckgeben
  191. return _histogramm;
  192. };
  193.  
  194. };
Add Comment
Please, Sign In to add comment