void HGU_XmImageViewResetGreyRange( HGU_XmImageViewDataStruct *data) { WlzPixelV greyMin, greyMax; WlzErrorNum errNum=WLZ_ERR_NONE; if((data == NULL) || (data->obj == NULL)) { return; } /* calculate the grey-range & reset the scale */ errNum = WlzGreyRange(data->obj, &greyMin, &greyMax); switch( greyMin.type ) { case WLZ_GREY_LONG: data->srcMin = greyMin.v.lnv; data->srcMax = greyMax.v.lnv; break; case WLZ_GREY_INT: data->srcMin = greyMin.v.inv; data->srcMax = greyMax.v.inv; break; case WLZ_GREY_SHORT: data->srcMin = greyMin.v.shv; data->srcMax = greyMax.v.shv; break; case WLZ_GREY_UBYTE: data->srcMin = greyMin.v.ubv; data->srcMax = greyMax.v.ubv; break; case WLZ_GREY_FLOAT: data->srcMin = greyMin.v.flv; data->srcMax = greyMax.v.flv; break; case WLZ_GREY_DOUBLE: data->srcMin = greyMin.v.dbv; data->srcMax = greyMax.v.dbv; break; case WLZ_GREY_BIT: case WLZ_GREY_RGBA: default: return; } return; }
/*! * \return Woolz error number * \ingroup WlzValuesFilters * \brief Normalizes the the grey values of the input object to * fill the range 0-255. Colour values are independently * reset which will change colour balance. Use WlzGreySetRange * directly to avoid this. * Note grey-values are reset in place and not copied. * \par Source: * WlzGreyNormalise.c * \param obj Input object. * \param Dither values if destination range is greater than source * range and this flag is non-zero. */ WlzErrorNum WlzGreyNormalise( WlzObject *obj, int dither) { WlzPixelV min, max, Min, Max; WlzErrorNum errNum=WLZ_ERR_NONE; /* get then set the grey-range of the object */ errNum = WlzGreyRange(obj, &min, &max); Min = min; Max = max; if( errNum == WLZ_ERR_NONE ){ switch( min.type ){ case WLZ_GREY_INT: Min.v.inv = 0; Max.v.inv = 255; break; case WLZ_GREY_SHORT: Min.v.shv = 0; Max.v.shv = 255; break; case WLZ_GREY_UBYTE: Min.v.ubv = 0; Max.v.ubv = 255; break; case WLZ_GREY_FLOAT: Min.v.flv = 0.0; Max.v.flv = 255.0; break; case WLZ_GREY_DOUBLE: Min.v.dbv = 0.0; Max.v.dbv = 255.0; break; case WLZ_GREY_RGBA: Min.v.rgbv = 0xff000000; Max.v.rgbv = 0xffffffff; break; default: errNum = WLZ_ERR_GREY_TYPE; break; } if(errNum == WLZ_ERR_NONE) { errNum = WlzGreySetRange(obj, min, max, Min, Max, dither); } } return(errNum); }
void install_paint_reference_object( WlzObject *obj) { Widget toggle; WlzPixelV bckgrnd; WlzPixelV min, max, Min, Max; WlzErrorNum errNum=WLZ_ERR_NONE; if( globals.orig_obj != NULL ){ WlzFreeObj( globals.orig_obj ); } globals.orig_obj = WlzAssignObject(obj, &errNum); obj = NULL; /* check input object for grey-value type convert if necessary */ if( errNum == WLZ_ERR_NONE ){ bckgrnd = WlzGetBackground(globals.orig_obj, &errNum); Min.type = WLZ_GREY_INT; Max.type = WLZ_GREY_INT; Min.v.inv = 0; Max.v.inv = 255; } if( errNum == WLZ_ERR_NONE ){ switch( bckgrnd.type ){ case WLZ_GREY_LONG: WlzGreyRange(globals.orig_obj, &min, &max); if( (min.v.lnv < 0) || (max.v.lnv > 255) ){ if((obj = WlzConvertPix(globals.orig_obj, WLZ_GREY_INT, &errNum))){ WlzGreySetRange(obj, min, max, Min, Max, 0); bckgrnd = WlzGetBackground(obj, &errNum); } } break; case WLZ_GREY_INT: WlzGreyRange(globals.orig_obj, &min, &max); if( (min.v.inv < 0) || (max.v.inv > 255) ){ obj = WlzConvertPix(globals.orig_obj, WLZ_GREY_INT, &errNum); WlzGreySetRange(obj, min, max, Min, Max, 0); bckgrnd = WlzGetBackground(obj, &errNum); } break; case WLZ_GREY_SHORT: WlzGreyRange(globals.orig_obj, &min, &max); if( (min.v.shv < 0) || (max.v.shv > 255) ){ if((obj = WlzConvertPix(globals.orig_obj, WLZ_GREY_SHORT, &errNum))){ WlzGreySetRange(obj, min, max, Min, Max, 0); bckgrnd = WlzGetBackground(obj, &errNum); } } break; case WLZ_GREY_FLOAT: WlzGreyRange(globals.orig_obj, &min, &max); if( (min.v.flv < 0) || (max.v.flv > 255) ){ if((obj = WlzConvertPix(globals.orig_obj, WLZ_GREY_INT, &errNum))){ WlzGreySetRange(obj, min, max, Min, Max, 0); bckgrnd = WlzGetBackground(obj, &errNum); } } break; case WLZ_GREY_DOUBLE: WlzGreyRange(globals.orig_obj, &min, &max); if( (min.v.dbv < 0) || (max.v.dbv > 255) ){ if((obj = WlzConvertPix(globals.orig_obj, WLZ_GREY_INT, &errNum))){ WlzGreySetRange(obj, min, max, Min, Max, 0); bckgrnd = WlzGetBackground(obj, &errNum); } } break; default: case WLZ_GREY_UBYTE: break; } } /* copy for later transform for display purposes, the original is kept for IP purposes note pixconvert loses the background value */ if( errNum == WLZ_ERR_NONE ){ if( globals.obj != NULL ){ WlzFreeObj( globals.obj ); } if( obj ){ globals.obj = WlzAssignObject(WlzConvertPix(obj, WLZ_GREY_UBYTE, &errNum), NULL); WlzFreeObj(globals.orig_obj); globals.orig_obj = WlzAssignObject(obj, NULL); } else { globals.obj = WlzAssignObject(WlzConvertPix(globals.orig_obj, WLZ_GREY_UBYTE, &errNum), NULL); } } if( errNum == WLZ_ERR_NONE ){ min.type = WLZ_GREY_UBYTE; max.type = WLZ_GREY_UBYTE; Min.type = WLZ_GREY_UBYTE; Max.type = WLZ_GREY_UBYTE; min.v.ubv = 0; max.v.ubv = 255; Min.v.ubv = globals.cmapstruct->gmin; Max.v.ubv = globals.cmapstruct->gmax; errNum = WlzGreySetRange(globals.obj, min, max, Min, Max, 0); } /* also convert the background values */ if( errNum == WLZ_ERR_NONE ){ /* min = WlzGetBackground(globals.orig_obj, NULL);*/ WlzValueConvertPixel(&bckgrnd, bckgrnd, WLZ_GREY_INT); max.type = WLZ_GREY_INT; max.v.inv = ((bckgrnd.v.inv * (Max.v.ubv - Min.v.ubv)) / 255) + Min.v.ubv; WlzSetBackground(globals.obj, max); /* fill blank planes here - should be a resource option */ if( (toggle = XtNameToWidget(read_obj_dialog, "*.fill_blanks")) ){ Boolean fill_blanks, min_domain; XtVaGetValues(toggle, XmNset, &fill_blanks, NULL); if( fill_blanks ){ if( (toggle = XtNameToWidget(read_obj_dialog, "*.min_domain")) ){ XtVaGetValues(toggle, XmNset, &min_domain, NULL); if( min_domain ){ WlzFillBlankPlanes(globals.obj, 1); } else { WlzFillBlankPlanes(globals.obj, 0); } } else { WlzFillBlankPlanes(globals.obj, 1); } } } /* setup the display list and properties dialog */ setup_ref_display_list_cb(read_obj_dialog, NULL, NULL); setup_obj_props_cb(read_obj_dialog, NULL, NULL); } /* log the object size */ if( (errNum == WLZ_ERR_NONE) && globals.logfileFp ){ char strBuf[64]; sprintf(strBuf, "(%d, %d, %d, %d, %d, %d)", globals.obj->domain.p->kol1, globals.obj->domain.p->line1, globals.obj->domain.p->plane1, globals.obj->domain.p->lastkl, globals.obj->domain.p->lastln, globals.obj->domain.p->lastpl); MAPaintLogData("BoundingBox", strBuf, 0, NULL); sprintf(strBuf, "%d", (int) WlzVolume(globals.obj, NULL)); MAPaintLogData("Volume", strBuf, 0, NULL); } if( errNum != WLZ_ERR_NONE ){ MAPaintReportWlzError(globals.topl, "install_paint_reference_object", errNum); } return; }
int main(int argc, char **argv) { int idx, option, dither = 0, overwrite = 1, ok = 1, usage = 0; WlzImArNorm norm = WLZ_IMARNORM_NONE; WlzErrorNum errNum = WLZ_ERR_NONE; FILE *fP = NULL; WlzObject *outObj = NULL; WlzObject *inObj[2]; WlzBinaryOperatorType operator = WLZ_BO_ADD; char *outObjFileStr; char *inObjFileStr[2]; WlzPixelV gMin[3], gMax[3]; const char *errMsg; static char optList[] = "O:o:ab:dgilmsnNh", outObjFileStrDef[] = "-", inObjFileStrDef[] = "-"; opterr = 0; inObj[0] = NULL; inObj[1] = NULL; outObjFileStr = outObjFileStrDef; inObjFileStr[0] = inObjFileStrDef; inObjFileStr[1] = inObjFileStrDef; while(ok && ((option = getopt(argc, argv, optList)) != -1)) { switch(option) { case 'O': if((sscanf(optarg, "%d", &overwrite) != 1) || (overwrite < 0) || (overwrite > 2)) { usage = 1; ok = 0; } break; case 'o': outObjFileStr = optarg; break; case 'a': operator = WLZ_BO_ADD; break; case 'b': operator = atoi(optarg); switch( operator ){ case WLZ_BO_ADD: case WLZ_BO_SUBTRACT: case WLZ_BO_MULTIPLY: case WLZ_BO_DIVIDE: case WLZ_BO_MODULUS: case WLZ_BO_EQ: case WLZ_BO_NE: case WLZ_BO_GT: case WLZ_BO_GE: case WLZ_BO_LT: case WLZ_BO_LE: case WLZ_BO_AND: case WLZ_BO_OR: case WLZ_BO_XOR: case WLZ_BO_MAX: case WLZ_BO_MIN: case WLZ_BO_MAGNITUDE: break; default: usage = 1; ok = 0; break; } break; case 'd': operator = WLZ_BO_DIVIDE; break; case 'g': operator = WLZ_BO_MAGNITUDE; break; case 'l': operator = WLZ_BO_MODULUS; break; case 'm': operator = WLZ_BO_MULTIPLY; break; case 's': operator = WLZ_BO_SUBTRACT; break; case 'n': norm = WLZ_IMARNORM_INPUT; break; case 'N': norm = WLZ_IMARNORM_256; break; case 'i': dither = 1; break; case 'h': default: usage = 1; ok = 0; break; } } if((inObjFileStr[0] == NULL) || (*inObjFileStr[0] == '\0') || (inObjFileStr[1] == NULL) || (*inObjFileStr[1] == '\0') || (outObjFileStr == NULL) || (*outObjFileStr == '\0')) { ok = 0; usage = 1; } if(ok && (optind < argc)) { idx = 0; while((idx < 2) && (optind < argc)) { inObjFileStr[idx] = *(argv + optind); ++optind; ++idx; } } if(ok && (optind != argc)) { usage = 1; ok = 0; } if(ok) { idx = 0; while((errNum == WLZ_ERR_NONE) && (idx < 2)) { errNum = WLZ_ERR_READ_EOF; if((inObjFileStr[idx] == NULL) || (*inObjFileStr[idx] == '\0') || ((fP = (strcmp(inObjFileStr[idx], "-")? fopen(inObjFileStr[idx], "r"): stdin)) == NULL) || ((inObj[idx]= WlzAssignObject(WlzReadObj(fP, &errNum), NULL)) == NULL)) { ok = 0; (void )WlzStringFromErrorNum(errNum, &errMsg); (void )fprintf(stderr, "%s: failed to read object %d from file %s (%s)\n", *argv, idx, inObjFileStr[idx], errMsg); } if(fP && strcmp(inObjFileStr[idx], "-")) { fclose(fP); } ++idx; } } if(ok) { idx = 0; while((errNum == WLZ_ERR_NONE) && (idx < 2)) { if((inObj[idx]->type != WLZ_2D_DOMAINOBJ) && (inObj[idx]->type != WLZ_3D_DOMAINOBJ)) { ok = 0; (void )fprintf(stderr, "%s: input object %d is not a domain object\n", *argv, idx); } ++idx; } } if(ok && (norm == WLZ_IMARNORM_INPUT)) { if(((errNum = WlzGreyRange(inObj[0], gMin, gMax)) != WLZ_ERR_NONE) || ((errNum = WlzGreyRange(inObj[1], gMin + 1, gMax + 1)) != WLZ_ERR_NONE)) { ok = 0; (void )WlzStringFromErrorNum(errNum, &errMsg); (void )fprintf(stderr, "%s: failed to find input objects grey range (%s)\n", *argv, errMsg); } } if(ok) { if( WlzGreyTypeFromObj(inObj[0], &errNum) == WLZ_GREY_RGBA ){ if((outObj = WlzRGBAImageArithmetic(inObj[0], inObj[1], operator, 1, &errNum)) == NULL) { ok = 0; (void )WlzStringFromErrorNum(errNum, &errMsg); (void )fprintf(stderr, "%s: failed to compute new object (%s).\n", *argv, errMsg); } } else if((outObj = WlzImageArithmetic(inObj[0], inObj[1], operator, 0, &errNum)) == NULL) { ok = 0; (void )WlzStringFromErrorNum(errNum, &errMsg); (void )fprintf(stderr, "%s: failed to compute new object (%s).\n", *argv, errMsg); } } if(ok && (norm != WLZ_IMARNORM_NONE) && (WlzGreyTypeFromObj(inObj[0], &errNum) != WLZ_GREY_RGBA) ) { if((errNum = WlzGreyRange(outObj, gMin+ 2, gMax + 2)) != WLZ_ERR_NONE) { ok = 0; (void )WlzStringFromErrorNum(errNum, &errMsg); (void )fprintf(stderr, "%s: failed to find output object's grey range (%s)\n", *argv, errMsg); } if(ok) { if(norm == WLZ_IMARNORM_256) { gMin[0].type = WLZ_GREY_UBYTE; gMin[0].v.ubv = 0; gMax[0].type = WLZ_GREY_UBYTE; gMax[0].v.ubv = 255; (void )WlzValueConvertPixel(gMin, gMin[0], gMin[2].type); (void )WlzValueConvertPixel(gMax, gMax[0], gMax[2].type); } else { (void )WlzValueConvertPixel(gMin, gMin[0], gMin[2].type); (void )WlzValueConvertPixel(gMax, gMax[0], gMax[2].type); (void )WlzValueConvertPixel(gMin + 1, gMin[1], gMin[2].type); (void )WlzValueConvertPixel(gMax + 1, gMax[1], gMax[2].type); switch(gMin[2].type) { case WLZ_GREY_INT: if(gMin[1].v.inv < gMin[0].v.inv) { gMin[0].v.inv = gMin[1].v.inv; } if(gMax[1].v.inv > gMax[0].v.inv) { gMax[0].v.inv = gMax[1].v.inv; } break; case WLZ_GREY_SHORT: if(gMin[1].v.shv < gMin[0].v.shv) { gMin[0].v.shv = gMin[1].v.shv; } if(gMax[1].v.shv > gMax[0].v.shv) { gMax[0].v.shv = gMax[1].v.shv; } break; case WLZ_GREY_UBYTE: if(gMin[1].v.ubv < gMin[0].v.ubv) { gMin[0].v.ubv = gMin[1].v.ubv; } if(gMax[1].v.ubv > gMax[0].v.ubv) { gMax[0].v.ubv = gMax[1].v.ubv; } break; case WLZ_GREY_FLOAT: if(gMin[1].v.flv < gMin[0].v.flv) { gMin[0].v.flv = gMin[1].v.flv; } if(gMax[1].v.flv > gMax[0].v.flv) { gMax[0].v.flv = gMax[1].v.flv; } break; case WLZ_GREY_DOUBLE: if(gMin[1].v.dbv < gMin[0].v.dbv) { gMin[0].v.dbv = gMin[1].v.dbv; } if(gMax[1].v.dbv > gMax[0].v.dbv) { gMax[0].v.dbv = gMax[1].v.dbv; } break; default: errNum = WLZ_ERR_GREY_TYPE; break; } } } if((errNum = WlzGreySetRange(outObj, gMin[2], gMax[2], gMin[0], gMax[0], dither)) != WLZ_ERR_NONE) { ok = 0; (void )WlzStringFromErrorNum(errNum, &errMsg); (void )fprintf(stderr, "%s: failed to set output object's grey range (%s)\n", *argv, errMsg); } } if(ok) { errNum = WLZ_ERR_WRITE_EOF; if(((fP = (strcmp(outObjFileStr, "-")? fopen(outObjFileStr, "w"): stdout)) == NULL) || ((errNum = WlzWriteObj(fP, outObj)) != WLZ_ERR_NONE)) { ok = 0; (void )WlzStringFromErrorNum(errNum, &errMsg); (void )fprintf(stderr, "%s: failed to write output object (%s).\n", *argv, errMsg); } if(fP && strcmp(outObjFileStr, "-")) { fclose(fP); } } WlzFreeObj(inObj[0]); WlzFreeObj(inObj[1]); WlzFreeObj(outObj); if(usage) { fprintf(stderr, "Usage: %s" " [-O#] [-o<out file>] [-a] [-b <op>] [-d] [-g] [-i] [-l] [-m] [-s] [-h] " "[<in object 0>] [<in object 1>]\n" "Options:\n" " -O Overwrite option (only useful for debugging)\n" " -o Output file name.\n" " -a Add the object's grey values.\n" " -b <op> Apply binary operation to the grey-values.\n" " op = %d - Add\n" " = %d - SUBTRACT\n" " = %d - MULTIPLY\n" " = %d - DIVIDE\n" " = %d - MODULUS\n" " = %d - EQ\n" " = %d - NE\n" " = %d - GT\n" " = %d - GE\n" " = %d - LT\n" " = %d - LE\n" " = %d - AND\n" " = %d - OR\n" " = %d - XOR\n" " = %d - MAX\n" " = %d - MIN\n" " = %d - MAGNITUDE\n" " -d Divide the grey values of the 1st object by those of the 2nd.\n" " -g Vector magnitude of horizontal and vertical component objects\n" " -i Dither values if setting range\n" " -l Compute the modulus of the grey values of the 1st object wrt\n" " those of the 2nd.\n" " -m Multiply the object's grey values.\n" " -s Subtract the grey values of the 2nd object from those of the 1st.\n" " -n Normalises the output object to the range of the input objects.\n" " -N Normalises the output objects to the range [0-255].\n" " -h Help, prints this usage message.\n" "Computes an arithmetic binary (two objects) operation on two domain\n" "objects. The default operator is add.\n" "The input objects are read from stdin and values are written to stdout\n" "unless the filenames are given.\n" "Example:\n%s%s%s", *argv, WLZ_BO_ADD, WLZ_BO_SUBTRACT, WLZ_BO_MULTIPLY, WLZ_BO_DIVIDE, WLZ_BO_MODULUS, WLZ_BO_EQ, WLZ_BO_NE, WLZ_BO_GT, WLZ_BO_GE, WLZ_BO_LT, WLZ_BO_LE, WLZ_BO_AND, WLZ_BO_OR, WLZ_BO_XOR, WLZ_BO_MAX, WLZ_BO_MIN, WLZ_BO_MAGNITUDE, "cat obj1.wlz | ", *argv, " -o obj3.wlz -a obj2.wlz\n" "A new object 'obj3.wlz is formed by adding the grey values of obj1 and\n" "obj2.wlz.\n"); } return(!ok); }
int main(int argc, char **argv) { WlzObject *obj; FILE *inFile; char optList[] = "l:L:u:U:dhv"; int dither = 0, option; WlzPixelV max, min, Max, Min; WlzPixelV gmin, gmax; int getminFlg=1, getmaxFlg=1, verboseFlg=0; WlzErrorNum errNum = WLZ_ERR_NONE; const char *errMsg; int objCount=0; /* read the argument list and check for an input file */ opterr = 0; Max.type = Min.type = max.type = min.type = WLZ_GREY_DOUBLE; Max.v.dbv = 255.0; Min.v.dbv = 0.0; while( (option = getopt(argc, argv, optList)) != EOF ){ switch( option ){ case 'd': dither = 1; break; case 'l': min.v.dbv = atof(optarg); getminFlg = 0; break; case 'L': Min.v.dbv = atof(optarg); break; case 'u': max.v.dbv = atof(optarg); getmaxFlg = 0; break; case 'U': Max.v.dbv = atof(optarg); break; case 'v': verboseFlg = 1; break; case 'h': default: usage(argv[0]); return 1; } } inFile = stdin; if( optind < argc ){ if( (inFile = fopen(*(argv+optind), "r")) == NULL ){ fprintf(stderr, "%s: can't open file %s\n", argv[0], *(argv+optind)); usage(argv[0]); return 1; } } /* read objects and threshold if possible */ while(((obj = WlzAssignObject(WlzReadObj(inFile, NULL), NULL)) != NULL) && (errNum == WLZ_ERR_NONE)) { objCount++; switch( obj->type ) { case WLZ_2D_DOMAINOBJ: case WLZ_3D_DOMAINOBJ: /* get the existing min and max grey values */ if( (errNum = WlzGreyRange(obj, &gmin, &gmax)) == WLZ_ERR_NONE ){ if( getminFlg ){ WlzValueConvertPixel(&min, gmin, WLZ_GREY_DOUBLE); } if( getmaxFlg ){ WlzValueConvertPixel(&max, gmax, WLZ_GREY_DOUBLE); } if( verboseFlg ){ fprintf(stderr, "%s:\nconverting object %d with parameters:\n" "\tSource (l, u) = (%f, %f)\n" "\tDestination (L, U) = (%f, %f)\n", argv[0], objCount, min.v.dbv, max.v.dbv, Min.v.dbv, Max.v.dbv); } errNum = WlzGreySetRange(obj, min, max, Min, Max, dither); if( errNum == WLZ_ERR_NONE ){ errNum = WlzWriteObj(stdout, obj); } } if( errNum != WLZ_ERR_NONE ){ (void )WlzStringFromErrorNum(errNum, &errMsg); (void )fprintf(stderr, "%s: failed to write object (%s).\n", argv[0], errMsg); return(errNum); } break; default: if((errNum = WlzWriteObj(stdout, obj)) != WLZ_ERR_NONE) { (void )WlzStringFromErrorNum(errNum, &errMsg); (void )fprintf(stderr, "%s: failed to write object (%s).\n", argv[0], errMsg); return(1); } break; } WlzFreeObj(obj); } return 0; }
double WlzMixtureValue( WlzObject *obj1, WlzObject *obj2, int numCatRows, int numCatCols, double **mixing, double **contrib, WlzErrorNum *dstErr) { double val, con; WlzObject *tmpObj, *tmpObj1, *tmpObj2; WlzIntervalWSpace iwsp; WlzGreyWSpace gwsp; WlzGreyP gptr; WlzGreyValueWSpace *gVWSp; WlzPixelV minP, maxP; int i; WlzErrorNum errNum=WLZ_ERR_NONE; /* objects must be same type with grey-values */ if( (obj1 == NULL) || (obj2 == NULL) ){ errNum = WLZ_ERR_OBJECT_NULL; } else { switch( obj1->type ){ case WLZ_2D_DOMAINOBJ: if( obj2->type != obj1->type ){ errNum = WLZ_ERR_OBJECT_TYPE; } else { if((obj1->values.core == NULL) || (obj2->values.core == NULL)){ errNum = WLZ_ERR_VALUES_NULL; } else { /* convert to int and check range */ if((tmpObj1 = WlzConvertPix(obj1, WLZ_GREY_INT, &errNum)) != NULL){ errNum = WlzGreyRange(tmpObj1, &minP, &maxP); if( errNum == WLZ_ERR_NONE ){ if((minP.v.inv < 1) || (minP.v.inv > numCatRows) || (maxP.v.inv < 1) || (maxP.v.inv > numCatRows)){ errNum = WLZ_ERR_OBJECT_DATA; WlzFreeObj(tmpObj1); } } else { WlzFreeObj(tmpObj1); } } if((errNum == WLZ_ERR_NONE) && (tmpObj2 = WlzConvertPix(obj2, WLZ_GREY_INT, &errNum)) ){ errNum = WlzGreyRange(tmpObj2, &minP, &maxP); if( errNum == WLZ_ERR_NONE ){ if((minP.v.inv < 1) || (minP.v.inv > numCatCols) || (maxP.v.inv < 1) || (maxP.v.inv > numCatCols)){ errNum = WLZ_ERR_OBJECT_DATA; WlzFreeObj(tmpObj1); WlzFreeObj(tmpObj2); } } else { WlzFreeObj(tmpObj1); WlzFreeObj(tmpObj2); } } } } break; case WLZ_3D_DOMAINOBJ: default: errNum = WLZ_ERR_OBJECT_TYPE; break; } } /* get the intersection region */ if( errNum == WLZ_ERR_NONE ){ if((tmpObj = WlzIntersect2(tmpObj1, tmpObj2, &errNum)) != NULL){ tmpObj->values = WlzAssignValues(tmpObj1->values, &errNum); } else { WlzFreeObj(tmpObj1); WlzFreeObj(tmpObj2); } } /* now calculate the mixture value */ if( errNum == WLZ_ERR_NONE ){ errNum = WlzInitGreyScan(tmpObj, &iwsp, &gwsp); gVWSp = WlzGreyValueMakeWSp(tmpObj2, &errNum); val = 0.0; con = 0.0; while((errNum == WLZ_ERR_NONE) && (errNum = WlzNextGreyInterval(&iwsp)) == WLZ_ERR_NONE ){ gptr = gwsp.u_grintptr; for (i=0; i<iwsp.colrmn; i++, gptr.inp++){ WlzGreyValueGet(gVWSp, 0, iwsp.linpos, iwsp.colpos+i); val += mixing[(*gptr.inp)-1][gVWSp->gVal[0].inv-1]; con += contrib[(*gptr.inp)-1][gVWSp->gVal[0].inv-1]; } } if( errNum == WLZ_ERR_EOO ){ errNum = WLZ_ERR_NONE; } WlzGreyValueFreeWSp(gVWSp); WlzFreeObj(tmpObj); WlzFreeObj(tmpObj1); WlzFreeObj(tmpObj2); } if( dstErr ){ *dstErr = errNum; } if( con > 0.0 ){ return val/con; } else { return 0.0; } }
int main(int argc, char *argv[]) { int option, nReg = 0, tNReg = 0, ok = 1, usage = 0, verbose = 0, threshSet = 0, centreSet = 0; double minArea = 2; char *inExt, *dbgExt, *inDir, *dbgDir, *inFile, *dbgFile, *inPath = NULL, *dbgPath = NULL, *outFile = NULL; WlzRadDistVal distSort = WLZ_RADDISTVAL_AREA; WlzRadDistRec *distData = NULL; WlzPixelV thrVal; WlzDVertex2 centre; WlzCompThreshType thrMtd = WLZ_COMPTHRESH_OTSU; WlzThresholdType thrMod = WLZ_THRESH_HIGH; WlzEffFormat inFmt = WLZEFF_FORMAT_NONE, dbgFmt = WLZEFF_FORMAT_NONE; WlzObject *inObj = NULL, *disObj = NULL, *segObj = NULL; WlzGreyValueWSpace *disGVWSp = NULL; WlzObject **regObjs = NULL; FILE *fP = NULL; WlzErrorNum errNum = WLZ_ERR_NONE; const int maxObj = 1000000; char pathBuf[FILENAME_MAX]; const double eps = 1.0e-06; const char *errMsg; static char optList[] = "hvAGDHELR:c:d:n:o:t:", defFile[] = "-"; thrVal.type = WLZ_GREY_DOUBLE; thrVal.v.dbv = 0.0; outFile = defFile; while((usage == 0) && ok && ((option = getopt(argc, argv, optList)) != -1)) { switch(option) { case 'A': distSort = WLZ_RADDISTVAL_AREA; break; case 'D': distSort = WLZ_RADDISTVAL_DIST; break; case 'G': distSort = WLZ_RADDISTVAL_ANGLE; break; case 'H': thrMod = WLZ_THRESH_HIGH; break; case 'E': thrMod = WLZ_THRESH_EQUAL; break; case 'L': thrMod = WLZ_THRESH_LOW; break; case 'R': distSort = WLZ_RADDISTVAL_RADIUS; break; case 'h': usage = 1; break; case 'v': verbose = 1; break; case 'c': centreSet = 1; if(sscanf(optarg, "%lg,%lg", &(centre.vtX), &(centre.vtY)) != 2) { usage = 1; } break; case 'd': dbgPath = optarg; break; case 'o': outFile = optarg; break; case 'n': if(sscanf(optarg, "%lg", &minArea) != 1) { usage = 1; } break; case 't': threshSet = 1; if(sscanf(optarg, "%lg", &(thrVal.v.dbv)) != 1) { usage = 1; } break; default: usage = 1; break; } } ok = !usage; if(ok) { if((optind + 1) != argc) { usage = 1; ok = 0; } else { inPath = *(argv + optind); } } if(ok && verbose) { (void )fprintf(stderr, "inPath = %s\n", inPath); } /* Parse input file path into path + name + ext. */ if(ok) { ok = (usage = WlzRadDistParsePath(inPath, &inDir, &inFile, &inExt, &inFmt)) == 0; } if(ok && verbose) { (void )fprintf(stderr, "inDir = %s\n", inDir); (void )fprintf(stderr, "inFile = %s\n", inFile); (void )fprintf(stderr, "inExt = %s\n", (inExt)? inExt: "(null)"); (void )fprintf(stderr, "inFmt = %s\n", WlzEffStringFromFormat(inFmt, NULL)); } /* Read image. */ if(ok) { errNum = WLZ_ERR_READ_EOF; if(inExt) { (void )sprintf(pathBuf, "%s/%s.%s", inDir, inFile, inExt); } else { (void )sprintf(pathBuf, "%s/%s", inDir, inFile); } if(((inObj = WlzAssignObject(WlzEffReadObj(NULL, pathBuf, inFmt, 0, 0, 0, &errNum), NULL)) == NULL) || (inObj->type != WLZ_2D_DOMAINOBJ)) { ok = 0; (void )WlzStringFromErrorNum(errNum, &errMsg); (void )fprintf(stderr, "%s: Failed to read 2D image object from file %s (%s)\n", *argv, pathBuf, errMsg); } } if(ok && verbose) { (void )fprintf(stderr, "read input image ok.\n"); } /* Convert to grey if needed, normalise 0 - 255 if needed and compute * threshold value unless already known. */ if(ok) { if(WlzGreyTypeFromObj(inObj, NULL) == WLZ_GREY_RGBA) { WlzObject *ppObj; ppObj = WlzAssignObject( WlzRGBAToModulus(inObj, &errNum), NULL); if(errNum == WLZ_ERR_NONE) { (void )WlzFreeObj(inObj); inObj = ppObj; } } if(threshSet == 0) { WlzObject *hObj = NULL; errNum = WlzGreyNormalise(inObj, 1); if(errNum == WLZ_ERR_NONE) { hObj = WlzHistogramObj(inObj, 256, 0.0, 1.0, &errNum); } if(errNum == WLZ_ERR_NONE) { threshSet = 1; errNum = WlzCompThreshold(&thrVal.v.dbv, hObj, thrMtd, 0); } (void )WlzFreeObj(hObj); } if(errNum != WLZ_ERR_NONE) { ok = 0; (void )WlzStringFromErrorNum(errNum, &errMsg); (void )fprintf(stderr, "%s: failed to normalise object (%s)\n", *argv, errMsg); } } /* Segment the object. */ if(ok) { if(inObj->values.core == NULL) { segObj = WlzAssignObject(inObj, NULL); } else { segObj = WlzAssignObject( WlzThreshold(inObj, thrVal, thrMod, &errNum), NULL); if(errNum != WLZ_ERR_NONE) { ok = 0; (void )WlzStringFromErrorNum(errNum, &errMsg); (void )fprintf(stderr, "%s: failed to segment image (%s)\n", *argv, errMsg); } } } /* Compute object with the same domain as the input object but in which * the values are the minimum distance from an edge. */ if(ok) { WlzObject *bObj = NULL; bObj = WlzBoundaryDomain(inObj, &errNum); if(errNum == WLZ_ERR_NONE) { disObj = WlzAssignObject( WlzDistanceTransform(inObj, bObj, WLZ_OCTAGONAL_DISTANCE, 0.0, 0.0, &errNum), NULL); } if(errNum == WLZ_ERR_NONE) { disGVWSp = WlzGreyValueMakeWSp(disObj, &errNum); } if(errNum != WLZ_ERR_NONE) { ok = 0; (void )WlzStringFromErrorNum(errNum, &errMsg); (void )fprintf(stderr, "%s: failed to compute distance object (%s)\n", *argv, errMsg); } (void )WlzFreeObj(bObj); } /* Output the debug image if required. */ if(ok && dbgPath) { WlzObject *dbgObj; dbgObj = WlzAssignObject(WlzCopyObject(inObj, &errNum), NULL); if(errNum == WLZ_ERR_NONE) { WlzPixelV iMin, iMax, oMin, oMax; if(dbgObj->values.core == NULL) { WlzValues tmpVal; oMax.type = WLZ_GREY_UBYTE; oMax.v.ubv = 255; tmpVal.v = WlzNewValueTb(dbgObj, WlzGreyTableType(WLZ_GREY_TAB_RAGR, WLZ_GREY_UBYTE, NULL), oMax, &errNum); if(errNum == WLZ_ERR_NONE) { dbgObj->values = WlzAssignValues(tmpVal, NULL); } } else { WlzObject *tmpObj = NULL; oMin.type = WLZ_GREY_UBYTE; oMin.v.ubv = 0; oMax.type = WLZ_GREY_UBYTE; oMax.v.ubv = 200; errNum = WlzGreyRange(dbgObj, &iMin, &iMax); if(errNum == WLZ_ERR_NONE) { errNum = WlzGreySetRange(dbgObj, iMin, iMax, oMin, oMax, 0); } if(errNum == WLZ_ERR_NONE) { tmpObj = WlzMakeMain(inObj->type, segObj->domain, dbgObj->values, NULL, NULL, &errNum); } if(errNum == WLZ_ERR_NONE) { oMax.v.ubv = 255; errNum = WlzGreySetValue(tmpObj, oMax); } (void )WlzFreeObj(tmpObj); if(errNum == WLZ_ERR_NONE) { tmpObj = WlzConvertPix(dbgObj, WLZ_GREY_UBYTE, &errNum); (void )WlzFreeObj(dbgObj); dbgObj = WlzAssignObject(tmpObj, NULL); } } } if(errNum == WLZ_ERR_NONE) { (void )WlzRadDistParsePath(dbgPath, &dbgDir, &dbgFile, &dbgExt, &dbgFmt); if(dbgExt) { (void )sprintf(pathBuf, "%s/%s.%s", dbgDir, dbgFile, dbgExt); } else { (void )sprintf(pathBuf, "%s/%s", dbgDir, dbgFile); } errNum = WlzEffWriteObj(NULL, pathBuf, dbgObj, dbgFmt); } (void )WlzFreeObj(dbgObj); if(errNum != WLZ_ERR_NONE) { ok = 0; (void )WlzStringFromErrorNum(errNum, &errMsg); (void )fprintf(stderr, "%s: failed to output the debug image (%s)\n", *argv, errMsg); } } /* Label the segmented object. */ if(ok) { errNum = WlzLabel(segObj, &nReg, ®Objs, maxObj, 0, WLZ_8_CONNECTED); if(errNum != WLZ_ERR_NONE) { ok = 0; errNum = WLZ_ERR_MEM_ALLOC; (void )WlzStringFromErrorNum(errNum, &errMsg); (void )fprintf(stderr, "%s: failed to split into components (%s)\n", *argv, errMsg); } if(ok && verbose) { (void )fprintf(stderr, "nReg = %d\n", nReg); } } /* Compute centre of mass if not known. */ if(ok) { if(centreSet == 0) { centre = WlzCentreOfMass2D(inObj, 1, NULL, &errNum); if(errNum != WLZ_ERR_NONE) { ok = 0; (void )WlzStringFromErrorNum(errNum, &errMsg); (void )fprintf(stderr, "%s: failed to compute centre of mass (%s)\n", *argv, errMsg); } } if(ok && verbose) { (void )fprintf(stderr, "centre = %lg,%lg\n", centre.vtX, centre.vtY); } } /* Allocate a radial distribution table. */ if(ok) { if((distData = (WlzRadDistRec *) AlcCalloc(nReg, sizeof(WlzRadDistRec))) == NULL) { ok = 0; errNum = WLZ_ERR_MEM_ALLOC; (void )WlzStringFromErrorNum(errNum, &errMsg); (void )fprintf(stderr, "%s: failed to allocate result lable (%s)\n", *argv, errMsg); } } /* Compute the redial distribution data. */ if(ok) { int idR = 0, idS = 0; while((errNum == WLZ_ERR_NONE) && (idR < nReg)) { double mass; WlzDVertex2 com; com = WlzCentreOfMass2D(regObjs[idR], 1, &mass, NULL); if(mass > minArea - eps) { WlzGreyValueGet(disGVWSp, 0.0, com.vtY, com.vtX); distData[idS].pos = com; distData[idS].area = mass; WLZ_VTX_2_SUB(com, centre, com); distData[idS].radius = WLZ_VTX_2_LENGTH(com); distData[idS].angle = ALG_M_PI + atan2(com.vtY, com.vtX); switch(disGVWSp->gType) { case WLZ_GREY_LONG: distData[idS].dist = *(disGVWSp->gPtr[0].lnp); break; case WLZ_GREY_INT: distData[idS].dist = *(disGVWSp->gPtr[0].inp); break; case WLZ_GREY_SHORT: distData[idS].dist = *(disGVWSp->gPtr[0].shp); break; case WLZ_GREY_UBYTE: distData[idS].dist = *(disGVWSp->gPtr[0].ubp); break; case WLZ_GREY_FLOAT: distData[idS].dist = *(disGVWSp->gPtr[0].flp); break; case WLZ_GREY_DOUBLE: distData[idS].dist = *(disGVWSp->gPtr[0].dbp); break; default: distData[idS].dist = 0.0; break; } ++idS; } ++idR; } tNReg = idS; switch(distSort) { case WLZ_RADDISTVAL_AREA: (void )qsort(distData, tNReg, sizeof(WlzRadDistRec), WlzRadDistRecSortArea); break; case WLZ_RADDISTVAL_ANGLE: (void )qsort(distData, tNReg, sizeof(WlzRadDistRec), WlzRadDistRecSortAngle); break; case WLZ_RADDISTVAL_RADIUS: (void )qsort(distData, tNReg, sizeof(WlzRadDistRec), WlzRadDistRecSortRadius); break; case WLZ_RADDISTVAL_DIST: (void )qsort(distData, tNReg, sizeof(WlzRadDistRec), WlzRadDistRecSortDist); break; } } /* Output the sorted radial distribution table. */ if(ok) { if(((fP = strcmp(outFile, "-")? fopen(outFile, "w"): stdout)) == NULL) { ok = 0; (void )fprintf(stderr, "%s: failed to open output file %s\n", *argv, outFile); } } if(ok) { int idR; for(idR = 0; idR < tNReg; ++idR) { double a; a = (distData[idR].angle > 0.0)? 0 + (180 * distData[idR].angle / ALG_M_PI): 360 + (180 * distData[idR].angle / ALG_M_PI); (void )fprintf(fP, "%g %g %g %g,%g %g\n", a, distData[idR].radius, distData[idR].area, distData[idR].pos.vtX, distData[idR].pos.vtY, distData[idR].dist); } } if(strcmp(outFile, "-")) { (void )fclose(fP); } /* Tidy up. */ AlcFree(distData); WlzGreyValueFreeWSp(disGVWSp); (void )WlzFreeObj(inObj); (void )WlzFreeObj(disObj); (void )WlzFreeObj(segObj); if(regObjs) { int idR; for(idR = 0; idR < nReg; ++idR) { (void )WlzFreeObj(regObjs[idR]); } AlcFree(regObjs); } if(usage) { (void )fprintf(stderr, "Usage: %s [-h] [-v] [-A] [-D] [-G] [-H] [-E] [-L] [-R]\n" "\t\t[-c #,#] [-d <debug image>] [-n #] [-o <out file>]\n" "\t\t[-t #] [<input image>]\n" "Segments the given object using a threshold value and outputs the \n" "radial distribution of the thresholded components.\n" "Version: %s\n" "Options:\n" " -h Help - prints this usage masseage.\n" " -v Verbose output.\n" " -A Sort output by area (default).\n" " -D Sort output by distance from boundary.\n" " -G Sort output by angle.\n" " -H Threshold high, use pixels at or above threshold (default).\n" " -E Threshold equal, use pixels at threshold.\n" " -L Threshold low, use pixels below threshold.\n" " -R Sort output by radial distance from centre.\n" " -c Centre (default is image centre).\n" " -d Debug image.\n" " -n Minimum area (default %g).\n" " -t Threshold value (default is to compute using Otsu's method).\n" "By default the input image object is read from the standard input and\n" "the radial distribution is written to the standard output.\n" "The image formats understood include wlz, jpg and tif.\n" "The output format is:\n" " <angle> <dist from centre> <area> <x pos>,<y pos> <dist form boundary>\n" "Example:\n" " %s -o out.txt -d debug.jpg in.tif\n" "The input image is read from in.tif, a debug image showing the\n" "segmented regions is written to debug.jpg and the radial distribution\n" "statistics are written to the file out.txt. With the output in\n" "out.txt, the following R code would plot the data as a set of circles\n" "with radius proportional to the square root of the component area:\n" " data <- read.table(\"out.txt\")\n" " attach(data)\n" " symbols(x=data$V1, y=data$V2, circles=sqrt(data$V3))\n", argv[0], WlzVersion(), minArea, argv[0]); } return(!ok); }
void getViewDomains( ThreeDViewStruct *view_struct) { int i, j, numOverlays; WlzObject *allDomainsObj=NULL, *tmpObj; WlzPixelV thresh; WlzErrorNum errNum=WLZ_ERR_NONE; /* check initialisation */ if( !view_struct->wlzViewStr->initialised ){ if( init_view_struct( view_struct ) ){ errNum = WLZ_ERR_UNSPECIFIED; } } /* check for painted object */ /* clear any current domains */ numOverlays = globals.cmapstruct->num_overlays + globals.cmapstruct->num_solid_overlays; for(i=0; i <= numOverlays; i++){ if( view_struct->curr_domain[i] ){ errNum = WlzFreeObj(view_struct->curr_domain[i]); view_struct->curr_domain[i] = NULL; } if( errNum != WLZ_ERR_NONE ){ break; } } /* get the union of all domains */ if( errNum == WLZ_ERR_NONE ){ thresh.type = WLZ_GREY_INT; thresh.v.inv = globals.cmapstruct->ovly_cols[DOMAIN_1]; tmpObj = WlzThreshold(view_struct->painted_object, thresh, WLZ_THRESH_HIGH, &errNum); if( (errNum == WLZ_ERR_NONE) && tmpObj ){ if( WlzArea(tmpObj, &errNum) > 0 ){ allDomainsObj = WlzAssignObject(tmpObj, &errNum); } else { errNum = WlzFreeObj(tmpObj); } } } /* segment the painted section image to establish each domain object */ if( (errNum == WLZ_ERR_NONE) && allDomainsObj ){ WlzPixelV min, max; int max_i=numOverlays; /* get maximum number of domains */ WlzGreyRange(allDomainsObj, &min, &max); WlzValueConvertPixel(&max, max, WLZ_GREY_INT); while( (max_i > 0) && (globals.cmapstruct->ovly_cols[max_i] > max.v.inv) ){ max_i--; } for(i=1; i <= max_i; i++){ tmpObj = get_domain_from_object(view_struct->painted_object, i); if( tmpObj ){ view_struct->curr_domain[i] = WlzAssignObject(tmpObj, NULL); } } } /* propogate from previous section asking for confirmation if a domain will be changed by propogation. This will either be if the current domain exists or if the propogating domain overlaps the union of all existing domains */ if( (errNum == WLZ_ERR_NONE) && (globals.propogate||globals.propogate_sel) ){ for(i=1; (i <= numOverlays) && (errNum == WLZ_ERR_NONE); i++){ /* test for propogate currently selected domain only */ if((!globals.propogate) && (i != globals.current_domain)){ continue; } if((view_struct->prev_domain[i]) && (view_struct->prev_domain[i]->type != WLZ_EMPTY_OBJ)){ if( allDomainsObj ){ /* first check if there is a curr_domain */ int needConfirm = 0; if((view_struct->curr_domain[i]) && (view_struct->curr_domain[i]->type != WLZ_EMPTY_OBJ)){ needConfirm = 1; } else { tmpObj = WlzIntersect2(view_struct->prev_domain[i], allDomainsObj, &errNum); if( tmpObj && (WlzArea(tmpObj, &errNum) > 0) ){ needConfirm = 1; WlzFreeObj(tmpObj); } } if( (errNum == WLZ_ERR_NONE) && needConfirm ){ if( HGU_XmUserConfirm(view_struct->dialog, "Warning: propogation may modify\n" " one or more existing domains.\n" " Propogate anyway?", "Yes", "No", 0) ){ if( view_struct->curr_domain[i] ){ tmpObj = WlzUnion2(view_struct->curr_domain[i], view_struct->prev_domain[i], &errNum); WlzFreeObj(view_struct->curr_domain[i]); view_struct->curr_domain[i] = WlzAssignObject(tmpObj, NULL); } else { view_struct->curr_domain[i] = WlzAssignObject(view_struct->prev_domain[i], NULL); } globals.domain_changed_since_saved[i] = 1; } } else { view_struct->curr_domain[i] = WlzAssignObject(view_struct->prev_domain[i], NULL); globals.domain_changed_since_saved[i] = 1; } } else { view_struct->curr_domain[i] = WlzAssignObject(view_struct->prev_domain[i], &errNum); globals.domain_changed_since_saved[i] = 1; } } } } /* put all objects onto painted image in reverse dominance order */ for(j=numOverlays; (j > 0) && (errNum == WLZ_ERR_NONE); j--){ i = globals.priority_to_domain_lut[j]; if( view_struct->curr_domain[i] ){ if( i > globals.cmapstruct->num_overlays ) { if( set_grey_values_from_domain(view_struct->curr_domain[i], view_struct->painted_object, globals.cmapstruct->ovly_cols[i], 255) ){ break; } } else { if( set_grey_values_from_domain(view_struct->curr_domain[i], view_struct->painted_object, globals.cmapstruct->ovly_cols[i], globals.cmapstruct->ovly_planes) ){ break; } } } } /* redisplay the view */ if( errNum != WLZ_ERR_NONE ){ MAPaintReportWlzError(globals.topl, "getViewDomains", errNum); } else{ redisplay_view_cb(view_struct->canvas, view_struct, NULL); } return; }