int main(int argc, char *argv[]) { int option, ok = 1, usage = 0, smShellSz = -1; FILE *fP = NULL; char *inObjFileStr, *outObjFileStr; WlzObject *obj; WlzDomain ctrDom; WlzErrorNum errNum = WLZ_ERR_NONE; const char *errMsgStr; static char optList[] = "ho:s:"; const char outObjFileStrDef[] = "-", inObjFileStrDef[] = "-"; obj = NULL; ctrDom.core = NULL; inObjFileStr = (char *)inObjFileStrDef; outObjFileStr = (char *)outObjFileStrDef; while(ok && ((option = getopt(argc, argv, optList)) != -1)) { switch(option) { case 'o': outObjFileStr = optarg; break; case 's': if(sscanf(optarg, "%d", &smShellSz) != 1) { usage = 1; ok = 0; } break; case 'h': usage = 1; ok = 0; break; default: usage = 1; ok = 0; break; } } if(smShellSz <= 1) { ok = 0; usage = 1; } if(ok) { if((inObjFileStr == NULL) || (*inObjFileStr == '\0')) { ok = 0; usage = 1; } if(ok && (optind < argc)) { if((optind + 1) != argc) { usage = 1; ok = 0; } else { inObjFileStr = *(argv + optind); } } } if(ok) { if((inObjFileStr == NULL) || (*inObjFileStr == '\0') || ((fP = (strcmp(inObjFileStr, "-")? fopen(inObjFileStr, "r"): stdin)) == NULL) || ((obj = WlzAssignObject(WlzReadObj(fP, &errNum), NULL)) == NULL) || (errNum != WLZ_ERR_NONE)) { ok = 0; (void )fprintf(stderr, "%s: failed to read object from file %s\n", *argv, inObjFileStr); } if(fP && strcmp(inObjFileStr, "-")) { (void )fclose(fP); fP = NULL; } } if(ok) { if(obj->type != WLZ_CONTOUR) { ok = 0; (void )fprintf(stderr, "%s Input object isn't a contour.\n", argv[0]); } } if(ok) { errNum = WlzGMFilterRmSmShells(obj->domain.ctr->model, smShellSz); if(errNum != WLZ_ERR_NONE) { ok = 0; (void )WlzStringFromErrorNum(errNum, &errMsgStr); (void )fprintf(stderr, "%s: failed to filter small shells from contour (%s).\n", *argv, errMsgStr); } } if(ok) { if((fP = (strcmp(outObjFileStr, "-")? fopen(outObjFileStr, "w"): stdout)) == NULL) { ok = 0; (void )fprintf(stderr, "%s: Failed to open output file %s.\n", argv[0], outObjFileStr); } } if(ok) { errNum = WlzWriteObj(fP, obj); if(errNum != WLZ_ERR_NONE) { ok = 0; (void )WlzStringFromErrorNum(errNum, &errMsgStr); (void )fprintf(stderr, "%s: Failed to write output object (%s).\n", argv[0], errMsgStr); } } if(fP) { (void )fclose(fP); fP = NULL; } if(obj) { (void )WlzFreeObj(obj); } if(usage) { (void )fprintf(stderr, "Usage: %s %s", *argv, " [-h] -s<threshold> [<input object>]\n" "Options:\n" " -s Threshold shell size (edges in 2D, loops in 3D).\n" " -h Prints this usage information.\n" "Removes all shells in the contour which have less than the threshold\n" "number of elements.\n"); } return(!ok); }
/*! * \return New contour object. * \brief Create a contour object from a 2D domain object with values, * together with a set of parameters. * \param gObj Given 2D domain object. * \param binFlg Generate contours from binary * (thresholded) image. * \param thrType Threshold type. * \param thrVal Threshold value. * \param medianSz Median filter size if > 0. * \param smooth Gaussian smoothing value. * \param cThr Contour threshold value. * \param minSpx Minimum number of simplicies per shell. * \param objDbgFileName If non-null used as the name of a * file for the image object just prior * to computing the geometric model. * \param dstErr Destination ptr for error, may be NULL. */ static WlzObject *WlzMatchICPPlaneCreateContourObj(WlzObject *gObj, int binFlg, WlzThresholdType thrType, double thrVal, int medianSz, double smooth, double cThr, int minSpx, int debug, char *objDbgFileName, WlzErrorNum *dstErr) { WlzObject *tObj0 = NULL, *cObj = NULL; WlzDomain tDom; WlzValues tVal; FILE *dFP = NULL; WlzPixelV thrV; WlzErrorNum errNum = WLZ_ERR_NONE; const int nrmFlg = 1; tVal.core = NULL; if(binFlg) { thrV.type = WLZ_GREY_DOUBLE; thrV.v.dbv = thrVal; tObj0 = WlzThreshold(gObj, thrV, thrType, &errNum); if(errNum == WLZ_ERR_NONE) { thrV.v.dbv = 0.0; errNum = WlzGreySetValue(gObj, thrV); } if(errNum == WLZ_ERR_NONE) { thrV.v.dbv = 255.0; errNum = WlzGreySetValue(tObj0, thrV); } (void )WlzFreeObj(tObj0); tObj0 = NULL; } if(medianSz > 0) { errNum = WlzRankFilter(gObj, medianSz, 0.5); } if(errNum == WLZ_ERR_NONE) { if(smooth > DBL_EPSILON) { tObj0 = WlzAssignObject( WlzGauss2(gObj, smooth, smooth, 0, 0, &errNum), NULL); } else { tObj0 = WlzAssignObject(gObj, NULL); } } if(errNum == WLZ_ERR_NONE) { if(objDbgFileName) { if((dFP = fopen(objDbgFileName, "w")) != NULL) { (void )WlzWriteObj(dFP, tObj0); (void )fclose(dFP); } } tDom.ctr = WlzContourObj(tObj0, WLZ_CONTOUR_MTD_GRD, cThr, 1.0, nrmFlg, &errNum); } WlzFreeObj(tObj0); if(errNum == WLZ_ERR_NONE) { cObj = WlzMakeMain(WLZ_CONTOUR, tDom, tVal, NULL, NULL, &errNum); } /* There's a bug somewhere in the deletion of small shells. Delete small * shells and then copy the contours. */ if(debug && (errNum == WLZ_ERR_NONE)) { errNum = WlzGMVerifyModel(cObj->domain.ctr->model, NULL); } if(errNum == WLZ_ERR_NONE) { errNum = WlzGMFilterRmSmShells(cObj->domain.ctr->model, minSpx * 3); } if(debug && (errNum == WLZ_ERR_NONE)) { errNum = WlzGMVerifyModel(cObj->domain.ctr->model, NULL); } if(errNum == WLZ_ERR_NONE) { tObj0 = WlzAssignObject(WlzCopyObject(cObj, &errNum), NULL); WlzFreeObj(cObj); if(errNum == WLZ_ERR_NONE) { cObj = tObj0; } tObj0 = NULL; } if(debug && (errNum == WLZ_ERR_NONE)) { errNum = WlzGMVerifyModel(cObj->domain.ctr->model, NULL); } return(cObj); }