34#include <fmi_image_filter.h>
35#include <fmi_image_filter_line.h>
36#include <fmi_image_histogram.h>
37#include <fmi_image_filter_speck.h>
38#include <fmi_image_filter_morpho.h>
39#include <fmi_image_restore.h>
40#include <fmi_meteosat.h>
41#include <fmi_radar_image.h>
44#include "rave_debug.h"
45#include "rave_alloc.h"
46#include "raveobject_list.h"
60static const char RopoGenerator_CLEAR_STR[] =
"CLEAR:";
61static const char RopoGenerator_CUTOFF_STR[] =
"CUTOFF:";
62static const char RopoGenerator_BIOMET_STR[] =
"BIOMET:";
63static const char RopoGenerator_SHIP_STR[] =
"SHIP:";
64static const char RopoGenerator_SUN_STR[] =
"SUN:";
65static const char RopoGenerator_EMITTER_STR[] =
"EMITTER:";
66static const char RopoGenerator_EMITTER2_STR[] =
"EMITTER2:";
67static const char RopoGenerator_CLUTTER_STR[] =
"CLUTTER:";
68static const char RopoGenerator_CLUTTER2_STR[] =
"CLUTTER2:";
69static const char RopoGenerator_SPECK_STR[] =
"SPECK:";
70static const char RopoGenerator_SPECKNORMOLD_STR[] =
"SPECKNORMOLD:";
71static const char RopoGenerator_DOPPLER_STR[] =
"DOPPLER:";
73static const char RopoGenerator_METEOSAT_STR[] =
"METEOSAT:";
74static const char RopoGenerator_THRESH1_STR[] =
"THRESH1:";
75static const char RopoGenerator_EMITTER3_STR[] =
"EMITTER3:";
76static const char RopoGenerator_DATA_MIN_STR[] =
"DATA_MIN:";
77static const char RopoGenerator_DATA_MAX_STR[] =
"DATA_MAX:";
78static const char RopoGenerator_NO_DATA_STR[] =
"NO_DATA:";
90 {CLEAR, RopoGenerator_CLEAR_STR},
91 {CUTOFF, RopoGenerator_CUTOFF_STR},
92 {BIOMET, RopoGenerator_BIOMET_STR},
93 {SHIP, RopoGenerator_SHIP_STR},
94 {SUN, RopoGenerator_SUN_STR},
95 {EMITTER, RopoGenerator_EMITTER_STR},
96 {EMITTER2, RopoGenerator_EMITTER2_STR},
97 {CLUTTER, RopoGenerator_CLUTTER_STR},
98 {CLUTTER2, RopoGenerator_CLUTTER2_STR},
99 {SPECK, RopoGenerator_SPECK_STR},
100 {SPECK, RopoGenerator_SPECKNORMOLD_STR},
101 {DOPPLER, RopoGenerator_DOPPLER_STR},
102 {METEOSAT, RopoGenerator_METEOSAT_STR},
103 {THRESH1, RopoGenerator_THRESH1_STR},
104 {EMITTER3, RopoGenerator_EMITTER3_STR},
105 {DATA_MIN, RopoGenerator_DATA_MIN_STR},
106 {DATA_MAX, RopoGenerator_DATA_MAX_STR},
107 {NO_DATA, RopoGenerator_NO_DATA_STR},
114static int RaveRopoGenerator_constructor(RaveCoreObject* obj)
118 this->classification = NULL;
119 this->markers = NULL;
120 this->probabilities = RAVE_OBJECT_NEW(&RaveObjectList_TYPE);
122 if (this->probabilities == NULL) {
127 RAVE_OBJECT_RELEASE(this->probabilities);
134static void RaveRopoGenerator_destructor(RaveCoreObject* obj)
137 RAVE_OBJECT_RELEASE(src->
image);
140 RAVE_OBJECT_RELEASE(src->
markers);
149static int RaveRopoGeneratorInternal_addTask(
RaveFmiImage_t* image,
const char* taskname)
151 RaveAttribute_t* attribute = NULL;
153 RAVE_ASSERT((image != NULL),
"image == NULL");
154 RAVE_ASSERT((taskname != NULL),
"taskname == NULL");
156 attribute = RaveAttributeHelp_createString(
"how/task", taskname);
158 RAVE_CRITICAL0(
"Failed to add attribute to image");
164 RAVE_OBJECT_RELEASE(attribute);
175static int RaveRopoGeneratorInternal_addTaskArgs(
RaveFmiImage_t* image,
const char* fmt, ...)
177 RaveAttribute_t* attribute = NULL;
179 char fmtstring[1024];
183 RAVE_ASSERT((image != NULL),
"image == NULL");
184 RAVE_ASSERT((fmt != NULL),
"fmt == NULL");
187 n = vsnprintf(fmtstring, 1024, fmt, ap);
189 if (n < 0 || n >= 1024) {
190 RAVE_ERROR0(
"Failed to generate name");
194 attribute = RaveAttributeHelp_createString(
"how/task_args", fmtstring);
196 RAVE_CRITICAL0(
"Failed to add attribute to image");
202 RAVE_OBJECT_RELEASE(attribute);
206static int RaveRopoGeneratorInternal_addProbabilityTaskArgs(
RaveFmiImage_t* image, RaveObjectList_t* probs,
const char* fmt, ...)
209 RaveAttribute_t* attr = NULL;
214 char fmtstring[1024];
218 RAVE_ASSERT((image != NULL),
"image == NULL");
219 RAVE_ASSERT((probs != NULL),
"probs == NULL");
220 RAVE_ASSERT((fmt != NULL),
"fmt == NULL");
223 n = vsnprintf(fmtstring, 1024, fmt, ap);
225 if (n < 0 || n >= 1024) {
226 RAVE_ERROR0(
"Failed to generate name");
230 memset(pstr,
'\0', 1024);
232 sz = RaveObjectList_size(probs);
233 for (i = 0; i < sz; i++) {
237 char* attrstr = NULL;
238 if (!RaveAttribute_getString(attr, &attrstr) || attrstr == NULL) {
241 if (strlen(pstr) > 0) {
243 strcat(pstr, attrstr);
245 strcpy(pstr, attrstr);
248 RAVE_OBJECT_RELEASE(attr);
249 RAVE_OBJECT_RELEASE(field);
252 if (strlen(fmtstring) > 0) {
253 if (strlen(pstr) > 0) {
255 strcat(pstr, fmtstring);
257 strcpy(pstr, fmtstring);
261 attr = RaveAttributeHelp_createString(
"how/task_args", pstr);
263 RAVE_CRITICAL0(
"Failed to add attribute to image");
269 RAVE_OBJECT_RELEASE(field);
270 RAVE_OBJECT_RELEASE(attr);
280static FmiRadarPGMCode RaveRopoGeneratorInternal_getPgmCode(
RaveFmiImage_t* image)
282 RaveAttribute_t* taskargs = NULL;
283 FmiRadarPGMCode result = CLEAR;
284 RAVE_ASSERT((image != NULL),
"image == NULL");
287 if (taskargs != NULL) {
288 char* argument = NULL;
290 if (!RaveAttribute_getString(taskargs, &argument)) {
293 if (argument == NULL) {
296 while (PGM_CODE_MAPPING[index].
str != NULL) {
297 if (strncmp(PGM_CODE_MAPPING[index].
str, argument, strlen(PGM_CODE_MAPPING[index].
str))==0) {
298 result = PGM_CODE_MAPPING[index].
type;
305 RAVE_OBJECT_RELEASE(taskargs);
322static int RaveRopoGeneratorInternal_valueToByteRange(
int value,
RaveFmiImage_t* image)
328 RAVE_ASSERT((image != NULL),
"image == NULL");
333 result = (int)((value - offset)/gain);
337 }
else if (result >= 255) {
351static int RaveRopoGeneratorInternal_relValueToByteRange(
int value,
RaveFmiImage_t* image)
356 RAVE_ASSERT((image != NULL),
"image == NULL");
361 result = (int)(value/gain);
365 }
else if (result >= 255) {
380 RAVE_OBJECT_RELEASE(self->
markers);
392static int RaveRopoGeneratorInternal_createProbabilityField(
396 const char* fmt, ...)
400 char fmtstring[1024];
404 RAVE_ASSERT((self != NULL),
"self == NULL");
405 RAVE_ASSERT((probability != NULL),
"probability == NULL");
406 RAVE_ASSERT((fmt != NULL),
"fmt == NULL");
409 n = vsnprintf(fmtstring, 1024, fmt, ap);
411 if (n < 0 || n >= 1024) {
412 RAVE_ERROR0(
"Failed to generate name");
416 if (self->
image == NULL) {
417 RAVE_ERROR0(
"Creating probability field when there is no image");
421 outprob = RAVE_OBJECT_CLONE(self->
image);
422 if (outprob == NULL) {
423 RAVE_CRITICAL0(
"Failed to clone image");
429 if (!RaveRopoGeneratorInternal_addTask(outprob, task) ||
430 !RaveRopoGeneratorInternal_addTaskArgs(outprob, fmtstring)) {
431 RAVE_CRITICAL0(
"Failed to add task arguments");
435 RAVE_OBJECT_RELEASE(*probability);
436 *probability = RAVE_OBJECT_COPY(outprob);
440 RAVE_OBJECT_RELEASE(outprob);
450 RAVE_ASSERT((self != NULL),
"self == NULL");
451 RAVE_ASSERT((image != NULL),
"image == NULL");
454 RAVE_OBJECT_RELEASE(self->
image);
455 self->
image = RAVE_OBJECT_COPY(image);
460 RAVE_ASSERT((self != NULL),
"self == NULL");
461 return RAVE_OBJECT_COPY(self->
image);
466 RAVE_ASSERT((self != NULL),
"self == NULL");
468 if (self->
image == NULL) {
469 RAVE_ERROR0(
"Calling threshold when there is no image to operate on?");
482 RAVE_ASSERT((self != NULL),
"self == NULL");
484 if (!RaveRopoGeneratorInternal_createProbabilityField(self,
486 "fi.fmi.ropo.detector",
487 "SPECK: %d,%d",minDbz, maxA)) {
493 RaveRopoGeneratorInternal_valueToByteRange(minDbz, self->
image),
499 if (!RaveObjectList_add(self->
probabilities, (RaveCoreObject*)probability)) {
500 RAVE_ERROR0(
"Failed to add probability field to probabilities");
504 RaveRopoGeneratorInternal_removeClassifications(self);
508 RAVE_OBJECT_RELEASE(probability);
516 RAVE_ASSERT((self != NULL),
"self == NULL");
518 if (!RaveRopoGeneratorInternal_createProbabilityField(self,
520 "fi.fmi.ropo.detector",
521 "SPECKNORMOLD: %d,%d,%d",minDbz, maxA, maxN)) {
527 RaveRopoGeneratorInternal_valueToByteRange(minDbz, self->
image),
534 if (!RaveObjectList_add(self->
probabilities, (RaveCoreObject*)probability)) {
535 RAVE_ERROR0(
"Failed to add probability field to probabilities");
539 RaveRopoGeneratorInternal_removeClassifications(self);
543 RAVE_OBJECT_RELEASE(probability);
551 RAVE_ASSERT((self != NULL),
"self == NULL");
553 if (!RaveRopoGeneratorInternal_createProbabilityField(self,
555 "fi.fmi.ropo.detector",
556 "EMITTER: %d,%d",minDbz, length)) {
562 RaveRopoGeneratorInternal_valueToByteRange(minDbz, self->
image), length);
564 if (!RaveObjectList_add(self->
probabilities, (RaveCoreObject*)probability)) {
565 RAVE_ERROR0(
"Failed to add probability field to probabilities");
569 RaveRopoGeneratorInternal_removeClassifications(self);
573 RAVE_OBJECT_RELEASE(probability);
581 RAVE_ASSERT((self != NULL),
"self == NULL");
583 if (!RaveRopoGeneratorInternal_createProbabilityField(self,
585 "fi.fmi.ropo.detector",
586 "EMITTER2: %d,%d,%d",minDbz, length, width)) {
592 RaveRopoGeneratorInternal_valueToByteRange(minDbz, self->
image),
596 if (!RaveObjectList_add(self->
probabilities, (RaveCoreObject*)probability)) {
597 RAVE_ERROR0(
"Failed to add probability field to probabilities");
601 RaveRopoGeneratorInternal_removeClassifications(self);
605 RAVE_OBJECT_RELEASE(probability);
613 RAVE_ASSERT((self != NULL),
"self == NULL");
615 if (!RaveRopoGeneratorInternal_createProbabilityField(self,
617 "fi.fmi.ropo.detector",
618 "CLUTTER: %d,%d",minDbz, maxCompactness)) {
624 RaveRopoGeneratorInternal_valueToByteRange(minDbz, self->
image),
625 histogram_compactness);
630 if (!RaveObjectList_add(self->
probabilities, (RaveCoreObject*)probability)) {
631 RAVE_ERROR0(
"Failed to add probability field to probabilities");
635 RaveRopoGeneratorInternal_removeClassifications(self);
639 RAVE_OBJECT_RELEASE(probability);
647 RAVE_ASSERT((self != NULL),
"self == NULL");
649 if (!RaveRopoGeneratorInternal_createProbabilityField(self,
651 "fi.fmi.ropo.detector",
652 "CLUTTER2: %d,%d",minDbz, maxSmoothness)) {
658 RaveRopoGeneratorInternal_valueToByteRange(minDbz, self->
image),
659 histogram_smoothness);
664 if (!RaveObjectList_add(self->
probabilities, (RaveCoreObject*)probability)) {
665 RAVE_ERROR0(
"Failed to add probability field to probabilities");
669 RaveRopoGeneratorInternal_removeClassifications(self);
673 RAVE_OBJECT_RELEASE(probability);
681 RAVE_ASSERT((self != NULL),
"self == NULL");
683 if (!RaveRopoGeneratorInternal_createProbabilityField(self,
685 "fi.fmi.ropo.detector",
686 "SOFTCUT: %d,%d,%d",maxDbz, r, r2)) {
692 RaveRopoGeneratorInternal_valueToByteRange(maxDbz, self->
image),
695 if (!RaveObjectList_add(self->
probabilities, (RaveCoreObject*)probability)) {
696 RAVE_ERROR0(
"Failed to add probability field to probabilities");
700 RaveRopoGeneratorInternal_removeClassifications(self);
704 RAVE_OBJECT_RELEASE(probability);
712 RAVE_ASSERT((self != NULL),
"self == NULL");
714 if (!RaveRopoGeneratorInternal_createProbabilityField(self,
716 "fi.fmi.ropo.detector",
717 "BIOMET: %d,%d,%d,%d",maxDbz, dbzDelta, maxAlt, altDelta)) {
723 RaveRopoGeneratorInternal_valueToByteRange(maxDbz, self->
image),
724 RaveRopoGeneratorInternal_relValueToByteRange(dbzDelta, self->
image),
728 if (!RaveObjectList_add(self->
probabilities, (RaveCoreObject*)probability)) {
729 RAVE_ERROR0(
"Failed to add probability field to probabilities");
733 RaveRopoGeneratorInternal_removeClassifications(self);
737 RAVE_OBJECT_RELEASE(probability);
745 RAVE_ASSERT((self != NULL),
"self == NULL");
747 if (!RaveRopoGeneratorInternal_createProbabilityField(self,
749 "fi.fmi.ropo.detector",
750 "SHIP: %d,%d",minRelDbz, minA)) {
756 RaveRopoGeneratorInternal_relValueToByteRange(minRelDbz, self->
image),
759 if (!RaveObjectList_add(self->
probabilities, (RaveCoreObject*)probability)) {
760 RAVE_ERROR0(
"Failed to add probability field to probabilities");
764 RaveRopoGeneratorInternal_removeClassifications(self);
768 RAVE_OBJECT_RELEASE(probability);
776 RAVE_ASSERT((self != NULL),
"self == NULL");
778 if (!RaveRopoGeneratorInternal_createProbabilityField(self,
780 "fi.fmi.ropo.detector",
781 "SUN: %d,%d,%d", minDbz, minLength, maxThickness)) {
787 RaveRopoGeneratorInternal_valueToByteRange(minDbz, self->
image),
791 if (!RaveObjectList_add(self->
probabilities, (RaveCoreObject*)probability)) {
792 RAVE_ERROR0(
"Failed to add probability field to probabilities");
796 RaveRopoGeneratorInternal_removeClassifications(self);
800 RAVE_OBJECT_RELEASE(probability);
808 RAVE_ASSERT((self != NULL),
"self == NULL");
810 if (!RaveRopoGeneratorInternal_createProbabilityField(self,
812 "fi.fmi.ropo.detector",
813 "SUN2: %d,%d,%d,%d,%d", minDbz, minLength, maxThickness,azimuth,elevation)) {
819 RaveRopoGeneratorInternal_valueToByteRange(minDbz, self->
image),
825 if (!RaveObjectList_add(self->
probabilities, (RaveCoreObject*)probability)) {
826 RAVE_ERROR0(
"Failed to add probability field to probabilities");
830 RaveRopoGeneratorInternal_removeClassifications(self);
834 RAVE_OBJECT_RELEASE(probability);
844 RaveAttribute_t* attribute = NULL;
849 RAVE_ASSERT((self != NULL),
"self == NULL");
851 if (self->
image == NULL) {
852 RAVE_ERROR0(
"Calling speck when there is no image to operate on?");
856 probability = RAVE_OBJECT_CLONE(self->
image);
857 markers = RAVE_OBJECT_CLONE(self->
image);
858 if (probability == NULL || markers == NULL) {
859 RAVE_CRITICAL0(
"Failed to clone image");
875 for (i = 0; i < probCount; i++) {
879 FmiRadarPGMCode pgmCode = RaveRopoGeneratorInternal_getPgmCode(image);
881 for (j = 0; j < fmiProbImage->volume; j++) {
882 if (probImage->array[j] >= fmiProbImage->array[j]) {
884 fmiMarkersImage->array[j]=pgmCode;
885 fmiProbImage->array[j]=probImage->array[j];
888 RAVE_OBJECT_RELEASE(image);
891 if (!RaveRopoGeneratorInternal_addTask(probability,
"fi.fmi.ropo.detector.classification") ||
892 !RaveRopoGeneratorInternal_addProbabilityTaskArgs(probability, self->
probabilities,
"")) {
893 RAVE_CRITICAL0(
"Failed to add task arguments");
897 if (!RaveRopoGeneratorInternal_addTask(markers,
"fi.fmi.ropo.detector.classification_marker") ||
898 !RaveRopoGeneratorInternal_addProbabilityTaskArgs(markers, self->
probabilities,
"")) {
899 RAVE_CRITICAL0(
"Failed to add task arguments");
904 RAVE_OBJECT_RELEASE(self->
markers);
909 attribute = RaveAttributeHelp_createDouble(
"what/gain", -1/255.0);
911 RAVE_CRITICAL0(
"Failed to add gain to image");
914 RAVE_OBJECT_RELEASE(attribute);
915 attribute = RaveAttributeHelp_createDouble(
"what/offset", 1.0);
917 RAVE_CRITICAL0(
"Failed to add offset to image");
921 self->
markers = RAVE_OBJECT_COPY(markers);
925 RAVE_OBJECT_RELEASE(attribute);
926 RAVE_OBJECT_RELEASE(probability);
927 RAVE_OBJECT_RELEASE(markers);
933 RAVE_ASSERT((self != NULL),
"self == NULL");
935 RAVE_OBJECT_RELEASE(self->
markers);
944 RAVE_ASSERT((self != NULL),
"self == NULL");
950 restored = RAVE_OBJECT_CLONE(self->
image);
951 if (restored == NULL) {
952 RAVE_CRITICAL0(
"Failed to clone image");
959 if (!RaveRopoGeneratorInternal_addTask(restored,
"fi.fmi.ropo.restore") ||
960 !RaveRopoGeneratorInternal_addProbabilityTaskArgs(restored, self->
probabilities,
"RESTORE_THRESH: %d",threshold)) {
961 RAVE_CRITICAL0(
"Failed to add task arguments");
971 result = RAVE_OBJECT_COPY(restored);
973 RAVE_OBJECT_RELEASE(restored);
982 RAVE_ASSERT((self != NULL),
"self == NULL");
987 restored = RAVE_OBJECT_CLONE(self->
image);
988 if (restored == NULL) {
989 RAVE_CRITICAL0(
"Failed to clone image");
996 if (!RaveRopoGeneratorInternal_addTask(restored,
"fi.fmi.ropo.restore2") ||
997 !RaveRopoGeneratorInternal_addProbabilityTaskArgs(restored, self->
probabilities,
"RESTORE2_THRESH: %d",threshold)) {
998 RAVE_CRITICAL0(
"Failed to add task arguments");
1008 result = RAVE_OBJECT_COPY(restored);
1010 RAVE_OBJECT_RELEASE(restored);
1019 RAVE_ASSERT((self != NULL),
"self == NULL");
1023 if (restored == NULL) {
1024 RAVE_ERROR0(
"Failed to restore self");
1028 RAVE_OBJECT_RELEASE(self->
image);
1029 self->
image = RAVE_OBJECT_COPY(restored);
1033 RAVE_OBJECT_RELEASE(restored);
1039 RAVE_ASSERT((self != NULL),
"self == NULL");
1045 RaveCoreObject*
object = NULL;
1047 RAVE_ASSERT((self != NULL),
"self == NULL");
1056 RAVE_ASSERT((self != NULL),
"self == NULL");
1065 RAVE_ASSERT((self != NULL),
"self == NULL");
1069 return RAVE_OBJECT_COPY(self->
markers);
1075 RAVE_ASSERT((image != NULL),
"image == NULL");
1079 if (result == NULL) {
1080 RAVE_CRITICAL0(
"Failed to allocate memory for generator");
1083 result->
image = RAVE_OBJECT_COPY(image);
1090 "RaveRopoGenerator",
1092 RaveRopoGenerator_constructor,
1093 RaveRopoGenerator_destructor,
FmiImage * RaveFmiImage_getImage(RaveFmiImage_t *self)
void RaveFmiImage_fill(RaveFmiImage_t *self, unsigned char v)
double RaveFmiImage_getOffset(RaveFmiImage_t *self)
int RaveFmiImage_addAttribute(RaveFmiImage_t *self, RaveAttribute_t *attribute)
RaveAttribute_t * RaveFmiImage_getAttribute(RaveFmiImage_t *self, const char *name)
void RaveFmiImage_fillOriginal(RaveFmiImage_t *self, double v)
double RaveFmiImage_getGain(RaveFmiImage_t *self)
RaveCoreObjectType RaveRopoGenerator_TYPE
RaveRopoGenerator_t * RaveRopoGenerator_new(RaveFmiImage_t *image)
int RaveRopoGenerator_getProbabilityFieldCount(RaveRopoGenerator_t *self)
RaveFmiImage_t * RaveRopoGenerator_restore(RaveRopoGenerator_t *self, int threshold)
int RaveRopoGenerator_speckNormOld(RaveRopoGenerator_t *self, int minDbz, int maxA, int maxN)
int RaveRopoGenerator_clutter2(RaveRopoGenerator_t *self, int minDbz, int maxSmoothness)
void RaveRopoGenerator_threshold(RaveRopoGenerator_t *self, int threshold)
RaveFmiImage_t * RaveRopoGenerator_restore2(RaveRopoGenerator_t *self, int threshold)
RaveFmiImage_t * RaveRopoGenerator_getMarkers(RaveRopoGenerator_t *self)
int RaveRopoGenerator_sun2(RaveRopoGenerator_t *self, int minDbz, int minLength, int maxThickness, int azimuth, int elevation)
void RaveRopoGenerator_setImage(RaveRopoGenerator_t *self, RaveFmiImage_t *image)
void RaveRopoGenerator_declassify(RaveRopoGenerator_t *self)
int RaveRopoGenerator_sun(RaveRopoGenerator_t *self, int minDbz, int minLength, int maxThickness)
int RaveRopoGenerator_restoreSelf(RaveRopoGenerator_t *self, int threshold)
RaveFmiImage_t * RaveRopoGenerator_getClassification(RaveRopoGenerator_t *self)
int RaveRopoGenerator_clutter(RaveRopoGenerator_t *self, int minDbz, int maxCompactness)
int RaveRopoGenerator_speck(RaveRopoGenerator_t *self, int minDbz, int maxA)
int RaveRopoGenerator_classify(RaveRopoGenerator_t *self)
RaveFmiImage_t * RaveRopoGenerator_getImage(RaveRopoGenerator_t *self)
int RaveRopoGenerator_ship(RaveRopoGenerator_t *self, int minRelDbz, int minA)
int RaveRopoGenerator_biomet(RaveRopoGenerator_t *self, int maxDbz, int dbzDelta, int maxAlt, int altDelta)
int RaveRopoGenerator_emitter(RaveRopoGenerator_t *self, int minDbz, int length)
int RaveRopoGenerator_emitter2(RaveRopoGenerator_t *self, int minDbz, int length, int width)
int RaveRopoGenerator_softcut(RaveRopoGenerator_t *self, int maxDbz, int r, int r2)
RaveFmiImage_t * RaveRopoGenerator_getProbabilityField(RaveRopoGenerator_t *self, int index)
struct _RaveRopoGenerator_t RaveRopoGenerator_t
RaveObjectList_t * probabilities
RAVE_OBJECT_HEAD RaveFmiImage_t * image
RaveFmiImage_t * classification