Example #1
0
WlzObject *HGU_XmFileListReadObject(
  Widget			w,
  HGU_XmFileListCallbackStruct	*cbs,
  WlzErrorNum			*dstErr)
{
  WlzObject	*rtnObj=NULL;
  WlzErrorNum	errNum=WLZ_ERR_NONE;

  if((w != NULL) && (cbs != NULL)){
    rtnObj = WlzEffReadObj(NULL, cbs->file, cbs->format, 0, 0, 0, &errNum);
  }
  else {
    errNum = WLZ_ERR_PARAM_NULL;
  }

  if( dstErr ){
    *dstErr = errNum;
  }
  return rtnObj;
}
Example #2
0
/*!
* \return	Error code.
* \ingroup	Reconstruct
* \brief	Given a destination directory and file body and a 3D image
* 		file, the 3D object is and exploded into a series of 2D section
* 		files (in the destination directory) each with a name formed
* 		from the given file body and the source plane index. A section
* 		list is also created in the directory using the given file body
* 		together with the  '.bib' file extension.
* \param	dstDirStr		Destination directory.
* \param	dstBodyStr		Destination file body.
* \param	srcFile			Source 3D image file.
* \param	srcFmt			Source 3D image file format.
* \param	eMsg			Ptr for any error messages.
*/
RecError	RecExplode3DFileToFile(char *dstDirStr, char *dstBodyStr,
				      char *srcFile, WlzEffFormat srcFmt,
				      char **eMsg)
{
  RecError	errFlag = REC_ERR_NONE;
  WlzErrorNum	wlzErr = WLZ_ERR_NONE;
  WlzObject	*srcObj = NULL;

  REC_DBG((REC_DBG_3D|REC_DBG_LVL_FN|REC_DBG_LVL_1),
	  ("RecExplode3DFileToFile FE 0x%lx 0x%lx 0x%lx %d 0x%lx\n",
	   (unsigned long )dstDirStr, (unsigned long )dstBodyStr,
	   (unsigned long )srcFile, (int )srcFmt, (unsigned long )eMsg));
  if((dstDirStr == NULL) || (strlen(dstDirStr) == 0) ||
     (dstBodyStr == NULL) || (strlen(dstBodyStr) == 0) || 
     (srcFile == NULL) || (strlen(srcFile) == 0))
  {
    errFlag = REC_ERR_FUNC;
  }
  if(errFlag == REC_ERR_NONE)
  {
    srcObj = WlzEffReadObj(NULL, srcFile, srcFmt, 0, &wlzErr);
    errFlag = RecErrorFromWlz(wlzErr);
  }
  if(srcObj)
  {
    if(errFlag == REC_ERR_NONE)
    {
      errFlag = RecExplode3DObjToFile(dstDirStr, dstBodyStr, srcObj,
      				      srcFile, srcFmt, eMsg);
    }
    (void )WlzFreeObj(srcObj);
  }
  REC_DBG((REC_DBG_3D|REC_DBG_LVL_FN|REC_DBG_LVL_1),
  	  ("RecExplode3DFileToFile FX %d\n",
	   (int )errFlag));
  return(errFlag);
}
static WlzErrorNum WlzEFFConAddImg(WlzObject **objP, const char *fStr,
				   int sTrans, int gTrans)
{
  FILE		*fP;
  WlzEffFormat	inFmt = WLZEFF_FORMAT_NONE;
  WlzErrorNum	errNum = WLZ_ERR_NONE;

  if(strcmp(fStr, "NULL") == 0)
  {
    *objP = NULL;
  }
  else
  {
    if(strcmp(fStr, "-") == 0)
    {
      fP = stdin;
      fStr = NULL;
      inFmt = WLZEFF_FORMAT_WLZ;
    }
    else
    {
      fP = NULL;
      inFmt = WlzEffStringFormatFromFileName(fStr);
    }
    if(inFmt == WLZEFF_FORMAT_NONE)
    {
      errNum = WLZ_ERR_FILE_OPEN;
    }
    else
    {
      *objP = WlzAssignObject(
              WlzEffReadObj(fP, fStr, inFmt, 0, sTrans, gTrans,
	                    &errNum), NULL);
    }
  }
  return(errNum);
}
Example #4
0
void read_reference_object_cb(
  Widget	w,
  XtPointer	client_data,
  XtPointer	call_data)
{
  XmFileSelectionBoxCallbackStruct *cbs =
    (XmFileSelectionBoxCallbackStruct *) call_data;
  WlzEffFormat		image_type;
  WlzObject		*obj;
  String		icsfile;
  WlzDomain	domain;
  WlzValues	values;
  WlzObject	*newObj;
  WlzErrorNum		errNum=WLZ_ERR_NONE;

  /* set hour glass cursor */
  HGU_XmSetHourGlassCursor(globals.topl);

  /* read the new reference object
     note the switch is to allow direct read
     given the image type to include the model
     input options */
  if( client_data ){
    image_type = (WlzEffFormat) client_data;
    if((icsfile = HGU_XmGetFileStr(globals.topl, cbs->value,
				   cbs->dir))){
      obj = WlzEffReadObj(NULL, icsfile, image_type, 0, 0, 0, &errNum);
      AlcFree(icsfile);
    }
    else {
      obj = NULL;
    }
  }
  else {
    obj = HGU_XmReadExtFFObject(read_obj_dialog, cbs,
			       &image_type, &errNum);
  }
  if( obj == NULL){
    HGU_XmUserError(globals.topl,
		    "Read Reference Object:\n"
		    "    No reference object read - either the\n"
		    "    selected file is empty or it is not the\n"
		    "    correct object type - please check the\n"
		    "    file or make a new selection",
   		    XmDIALOG_FULL_APPLICATION_MODAL);
    /* set hour glass cursor */
    HGU_XmUnsetHourGlassCursor(globals.topl);
    return;
  }

  if( obj->values.core == NULL ){
    HGU_XmUserError(globals.topl,
		    "Read Reference Object:\n"
		    "    The reference object must have a grey-\n"
		    "    value table. Please select an alternate\n"
		    "    object",
		    XmDIALOG_FULL_APPLICATION_MODAL);
    WlzFreeObj( obj );
    /* set hour glass cursor */
    HGU_XmUnsetHourGlassCursor(globals.topl);
    return;
  }

  /* install the new reference object */
  switch( obj->type ){

  case WLZ_2D_DOMAINOBJ:
    if((domain.p = WlzMakePlaneDomain(WLZ_PLANEDOMAIN_DOMAIN, 0, 0,
				      obj->domain.i->line1,
				      obj->domain.i->lastln,
				      obj->domain.i->kol1,
				      obj->domain.i->lastkl,
				      &errNum))){
      domain.p->domains[0] = WlzAssignDomain(obj->domain, NULL);
      if((values.vox = WlzMakeVoxelValueTb(WLZ_VOXELVALUETABLE_GREY,
					   0, 0, WlzGetBackground(obj, NULL),
					   NULL, &errNum))){
	values.vox->values[0] = WlzAssignValues(obj->values, NULL);
	newObj = WlzMakeMain(WLZ_3D_DOMAINOBJ, domain, values,
			     obj->plist, NULL, &errNum);
	WlzFreeObj(obj);
	obj = newObj;
      }
    }
    globals.origObjType = WLZ_2D_DOMAINOBJ;
    break;

  case WLZ_3D_DOMAINOBJ:
    globals.origObjType = WLZ_3D_DOMAINOBJ;
    break;

  default:
    HGU_XmUserError(globals.topl,
		    "Read Reference Object:\n"
		    "    The reference object must be a 2- or 3-D\n"
		    "    grey-level image. Please select an alternate\n"
		    "    object",
		    XmDIALOG_FULL_APPLICATION_MODAL);
    WlzFreeObj( obj );
    /* set hour glass cursor */
    HGU_XmUnsetHourGlassCursor(globals.topl);
    return;
  }
  globals.origObjExtType = image_type;

  /* set title and reference file list */
  if((icsfile = HGU_XmGetFileStr(globals.topl, cbs->value, cbs->dir)))
  {
    Widget	cascade;
    HGU_XmFileListAddFile(globals.fileList, icsfile, image_type);
    HGU_XmFileListWriteResourceFile(globals.fileList,
				    globals.resourceFile);
    if((cascade = XtNameToWidget(globals.topl,
				 "*file_menu*_pulldown*Recent"))){
      HGU_XmFileListResetMenu(globals.fileList, cascade, referenceFileListCb);
    }
    if( XmStringGetLtoR(cbs->value, XmSTRING_DEFAULT_CHARSET, &icsfile) )
    {
      set_topl_title(icsfile);
      globals.file = icsfile;
    }
  }
  MAPaintLogData("ReferenceFile", globals.file, 0, NULL);

  /* clear feedback object and install new reference object */
  if( errNum == WLZ_ERR_NONE ){
    if( globals.fb_obj ){
      WlzFreeObj(globals.fb_obj);
      globals.fb_obj = NULL;
    }
    install_paint_reference_object( obj );
  }

  /* set hour glass cursor */
  HGU_XmUnsetHourGlassCursor(globals.topl);

  if( errNum != WLZ_ERR_NONE ){
    MAPaintReportWlzError(globals.topl, "read_reference_object_cb", errNum);
  }
  return;
}
int main(int	argc,
	 char	**argv)
{
  char 		optList[] = "hv";
  int		option;
  /* int		verboseFlg=0; */
  WlzErrorNum	errNum=WLZ_ERR_NONE;
  char		*tiffFile=NULL;
  WlzObject	*inObj, *outObj, *obj, **objVec;
  int		i, objVecCount;
  WlzGreyType	gType;

  /* read the argument list and check for an input file */
  opterr = 0;
  while( (option = getopt(argc, argv, optList)) != EOF ){
    switch( option ){

    case 'v':
      /* verboseFlg = 1; */
      break;

    case 'h':
    default:
      usage(argv[0]);
      return WLZ_ERR_UNSPECIFIED;
    }
  }

  if( optind < argc ){
    tiffFile = *(argv+optind);
  }
  else {
    usage(argv[0]);
    return WLZ_ERR_UNSPECIFIED;
  }

  /* read the TIFF file */
  if( (inObj = WlzAssignObject(WlzEffReadObj(NULL, tiffFile,
  			                     WLZEFF_FORMAT_TIFF, 0, 0, 0,
					     &errNum), NULL)) == NULL ){
    usage(argv[0]);
    return errNum;
  }

  /* if 2D then that is the shade file, else take max of 3D stack */
  switch( inObj->type ){
  case WLZ_2D_DOMAINOBJ:
    outObj = inObj;
    break;

  case WLZ_3D_DOMAINOBJ:
    if( (errNum = WlzExplode3D(&objVecCount, &objVec, inObj)) != WLZ_ERR_NONE ){
      usage(argv[0]);
      return errNum;
    }
    gType = WlzGreyTypeFromObj(objVec[0], &errNum);
    outObj = WlzAssignObject(objVec[0], NULL);
    for(i=1; i < objVecCount; i++){
      if( gType == WLZ_GREY_RGBA ){
	obj = WlzRGBAImageArithmetic(outObj, objVec[i], WLZ_BO_MAX, 0, &errNum);
      }
      else {
	obj = WlzImageArithmetic(outObj, objVec[i], WLZ_BO_MAX, 0, &errNum);
      }
      if( obj ){
	WlzFreeObj(outObj);
	outObj = WlzAssignObject(obj, &errNum);
      }
      else {
	break;
      }
    }
    
    WlzFreeObj(inObj);
    break;

  default:
    WlzFreeObj(inObj);
    errNum = WLZ_ERR_OBJECT_TYPE;
  }

  /* write shade object */
  if( errNum == WLZ_ERR_NONE ){
    WlzWriteObj(stdout, outObj);
    WlzFreeObj(outObj);
  }
  else {
    usage(argv[0]);
  }
  return errNum;
}
Example #6
0
void HGU_XmImageViewReadImageCb(
    Widget	w,
    XtPointer	client_data,
    XtPointer	call_data)
{
    HGU_XmImageViewDataStruct
    *data=(HGU_XmImageViewDataStruct *) client_data;
    XmFileSelectionBoxCallbackStruct
    *cbs=(XmFileSelectionBoxCallbackStruct *) call_data;
    Widget		option;
    int			intType;
    String		strBuf, tmpBuf;
    FILE			*fp;
    WlzObject		*obj=NULL;

    /* get image type and file */
    XtVaGetValues(data->typeMenu, XmNmenuHistory, &option, NULL);
    if(WlzStringMatchValue(&intType, XtName(option),
                           "woolz", WLZEFF_FORMAT_WLZ,
                           "pgm", WLZEFF_FORMAT_PNM,
                           "bmp", WLZEFF_FORMAT_BMP,
                           "tiff", WLZEFF_FORMAT_TIFF,
                           "raw", WLZEFF_FORMAT_RAW,
                           NULL)) {
        data->type = (WlzEffFormat) intType;
    }
    else {
        data->type = WLZEFF_FORMAT_RAW;
    }
    data->file = HGU_XmGetFileStr(data->imageForm, cbs->value, cbs->dir);

    /* read the image */
    switch( data->type ) {
    default:
        return;

    case WLZEFF_FORMAT_WLZ:
        if( (fp = HGU_XmGetFilePointer(data->imageForm, cbs->value,
                                       cbs->dir, "r")) == NULL )
        {
            return;
        }
        obj = WlzAssignObject(WlzEffReadObj(fp, NULL,
                                            data->type, 0, 0, 0, NULL), NULL);
        fclose(fp);
        break;

    case WLZEFF_FORMAT_PNM:
    case WLZEFF_FORMAT_BMP:
    case WLZEFF_FORMAT_TIFF:
        if( data->file == NULL )
        {
            return;
        }
        obj = WlzAssignObject(WlzEffReadObj(NULL, data->file,
                                            data->type, 0, 0, 0, NULL), NULL);
        break;

    case WLZEFF_FORMAT_RAW:
        if( data->file == NULL )
        {
            return;
        }
        /* get the data size and byte ordering */
        tmpBuf = (String) AlcMalloc(sizeof(char) * 32);
        sprintf(tmpBuf, "%d,%d,%d,%d", data->width, data->height,
                data->depth, data->byteOrder? 1 : 0);
        if( (strBuf = HGU_XmUserGetstr(w,
                                       "Please type in: w, h, d, o where:\n"
                                       "\n"
                                       "\tw = image width in pixels\n"
                                       "\th = image height in pixels\n"
                                       "\td = number of bits per pixel\n"
                                       "\to = byte order:\n"
                                       "      1 - big-endian\n"
                                       "      0 - small-endian",
                                       "Ok", "Cancel", tmpBuf)) ) {
            if( sscanf(strBuf, "%d,%d,%d,%d", &(data->width), &(data->height),
                       &(data->depth), &(data->byteOrder)) < 4 ) {
                AlcFree(strBuf);
                AlcFree(tmpBuf);
                return;
            }
            AlcFree(strBuf);
            AlcFree(tmpBuf);
        }
        else {
            return;
        }
        strBuf = AlcMalloc(sizeof(char) *
                           (strlen(data->file) + 48));
        switch( data->depth ) {
        case 8:
            intType = 3;
            break;
        case 12:
            intType = 2;
            break;
        case 16:
            intType = 7;
            break;
        case 32:
            intType = 1;
            break;
        }
        sprintf(strBuf, "WlzRawToWlz -%s %d %d %d %s", data->byteOrder?"b":"l",
                data->width, data->height, intType, data->file);
        if( (fp = popen(strBuf, "r")) ) {
            obj = WlzAssignObject(WlzEffReadObj(fp, NULL,
                                                WLZEFF_FORMAT_WLZ, 0, 0, 0, NULL), NULL);
            pclose(fp);
        }
        AlcFree(strBuf);
        break;
    }
    if( obj == NULL ) {
        HGU_XmUserError(data->canvas,
                        "Failed to read the image, please\n"
                        "check the file, permissions and the\n"
                        "image format and try again.\n",
                        XmDIALOG_FULL_APPLICATION_MODAL);
        return;
    }
    if( obj->type != WLZ_2D_DOMAINOBJ ) {
        WlzFreeObj(obj);
        return;
    }

    /* install the object */
    HGU_XmImageViewInstallImage(obj, data);
    WlzFreeObj(obj);

    return;
}
Example #7
0
void HGU_XmImageViewReadImageFromParamsCb(
    Widget	w,
    XtPointer	client_data,
    XtPointer	call_data)
{
    HGU_XmImageViewDataStruct
    *data=(HGU_XmImageViewDataStruct *) client_data;
    int			intType;
    String		strBuf;
    FILE			*fp;
    WlzObject		*obj=NULL;

    /* check image file, read image */
    if( data->file == NULL ) {
        /* report error */
        return;
    }

    switch( data->type ) {
    case WLZEFF_FORMAT_WLZ:
    case WLZEFF_FORMAT_PNM:
    case WLZEFF_FORMAT_BMP:
    case WLZEFF_FORMAT_TIFF:
        obj = WlzAssignObject(WlzEffReadObj(NULL, data->file,
                                            data->type, 0, 0, 0, NULL), NULL);
        break;

    case WLZEFF_FORMAT_RAW:
        strBuf = AlcMalloc(sizeof(char) *
                           (strlen(data->file) + 48));
        switch( data->depth ) {
        default:
        case 8:
            intType = 3;
            break;
        case 12:
            intType = 2;
            break;
        case 16:
            intType = 7;
            break;
        case 32:
            intType = 1;
            break;
        }
        sprintf(strBuf, "WlzRawToWlz -%s %d %d %d %s", data->byteOrder?"b":"l",
                data->width, data->height, intType, data->file);
        if( (fp = popen(strBuf, "r")) ) {
            obj = WlzAssignObject(WlzEffReadObj(fp, NULL,
                                                WLZEFF_FORMAT_WLZ, 0, 0, 0, NULL), NULL);
            pclose(fp);
        }
        AlcFree(strBuf);
        break;

    default:
        /* report error */
        return;
    }

    if( obj == NULL ) {
        HGU_XmUserError(data->canvas,
                        "Failed to read the image, please\n"
                        "check the file, permissions and the\n"
                        "image format and try again.\n",
                        XmDIALOG_FULL_APPLICATION_MODAL);
        return;
    }
    if( obj->type != WLZ_2D_DOMAINOBJ ) {
        WlzFreeObj(obj);
        return;
    }

    /* install the object */
    HGU_XmImageViewInstallImage(obj, data);
    WlzFreeObj(obj);

    return;
}
Example #8
0
int             main(int argc, char **argv)
{
  int           option,
                ok = 1,
                usage = 0,
		dim = 0,
		transform = 0;
  WlzIBox3	bBox[2];
  WlzEffFormat  outFmt = WLZEFF_FORMAT_NONE;
  WlzEffFormat  inFmt[2] = {WLZEFF_FORMAT_NONE};
  WlzObject     *outObj = NULL;
  WlzObject	*inObj[2] = {NULL};
  char          *outFileStr;
  char		*inFileStr[2] = {NULL};
  WlzAffineTransform *tr = NULL;
  WlzErrorNum   errNum = WLZ_ERR_NONE;
  const char    *errMsg;
  static char   optList[] = "s:t:o:u:hT",
                fileStrDef[] = "-";

  opterr = 0;
  inFileStr[0] = fileStrDef;
  inFileStr[1] = fileStrDef;
  outFileStr = fileStrDef;
  while((usage == 0) && ((option = getopt(argc, argv, optList)) != -1))
  {
    switch(option)
    {
      case 's':
	if((inFmt[0] = WlzEffStringExtToFormat(optarg)) == 0)
	{
	  usage = 1;
	  ok = 0;
	}
	break;
      case 't':
	if((inFmt[1] = WlzEffStringExtToFormat(optarg)) == 0)
	{
	  usage = 1;
	  ok = 0;
	}
	break;
      case 'u':
	if((outFmt = WlzEffStringExtToFormat(optarg)) == 0)
	{
	  usage = 1;
	  ok = 0;
	}
	break;
      case 'o':
	outFileStr = optarg;
	break;
      case 'T':
	transform = 1;
	break;
      case 'h': /* FALLTHROUGH */
      default:
	usage = 1;
	break;
    }
  }
  if(usage == 0)
  {
    usage = (optind + 2 != argc);
  }
  if(usage == 0)
  {
    inFileStr[0] = *(argv + optind);
    inFileStr[1] = *(argv + optind + 1);
  }
  if(usage == 0)
  {
    if(inFmt[0] == WLZEFF_FORMAT_NONE)
    {
      inFmt[0] = WlzEffStringFormatFromFileName(inFileStr[0]);
    }
    if(inFmt[1] == WLZEFF_FORMAT_NONE)
    {
      inFmt[1] = WlzEffStringFormatFromFileName(inFileStr[1]);
    }
    if(outFmt == WLZEFF_FORMAT_NONE)
    {
      outFmt = WlzEffStringFormatFromFileName(outFileStr);
    }
    if((inFmt[0] == WLZEFF_FORMAT_NONE) || (inFmt[1] == WLZEFF_FORMAT_NONE) ||
       (outFmt == WLZEFF_FORMAT_NONE))
    {
      usage = 1;
    }
  }
  ok = (usage == 0);
  /* Read source and target objects. */
  if(ok)
  {
    int		idx;

    for(idx = 0; ok && (idx < 2); ++idx)
    {
      char *fStr;
      FILE *fP;

      if(strcmp(inFileStr[idx], "-") == 0)
      {
        fP = stdin;
	fStr = NULL;
      }
      else
      {
        fP = NULL;
	fStr = inFileStr[idx];
      }
      if((inObj[idx] = WlzAssignObject(WlzEffReadObj(fP, fStr, inFmt[idx],
                                       0, 0, 0, &errNum), NULL)) == NULL)
      {
	ok = 0;
	(void )WlzStringFromErrorNum(errNum, &errMsg);
	(void )fprintf(stderr,
	    "%s: Failed to read object from file(s) %s (%s)\n",
	    *argv, inFileStr[idx], errMsg);
      }
    }
  }
  /* Check object dimension */
  if(ok)
  {
    int		idx;
    int		d[2];

    d[0] = 0;
    for(idx = 0; ok && (idx < 2); ++idx)
    {
      d[idx] = WlzObjectDimension(inObj[idx], &errNum);
      ok = (errNum == WLZ_ERR_NONE);
    }
    if(errNum == WLZ_ERR_NONE)
    {
      if((d[0] == 0) || (d[0] != d[1]))
      {
	ok = 0;
        errNum = WLZ_ERR_OBJECT_TYPE;
      }
    }
    dim = d[0];
    if(errNum != WLZ_ERR_NONE)
    {
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
          "%s: Failed to establish object dimensions (%s)\n",
	  *argv, errMsg);
    }
  }
  /* Compute the bounding box of the source and target objects. */
  if(ok)
  {
    int		idx;

    for(idx = 0; ok && (idx < 2); ++idx)
    {
      bBox[idx] = WlzBoundingBox3I(inObj[idx], &errNum);
      if(errNum != WLZ_ERR_NONE)
      {
        ok = 0;
	(void )WlzStringFromErrorNum(errNum, &errMsg);
	(void )fprintf(stderr,
	    "%s: Failed to compute bounding box of object read from file\n"
	    "%s (%s).\n",
	    *argv, inFileStr[idx], errMsg);
      }
    }
  }
  /* Compute affine transform which will register the source to target
   * bounding box. */
  if(ok)
  {
    int		idx,
    		nVtx;
    WlzVertexType vType;
    WlzTransformType tType;
    WlzVertexP vP[2];
    WlzDVertex3	wSp[48];

    vP[0].d3 = wSp;
    vP[1].d3 = wSp + 24;
    if(dim == 2)
    {
      nVtx = 4;
      vType = WLZ_VERTEX_D2;
      tType = WLZ_TRANSFORM_2D_AFFINE;
      for(idx = 0; idx < 2; ++idx)
      {
        (vP[idx].d2)[0].vtX = bBox[idx].xMin;
	(vP[idx].d2)[0].vtY = bBox[idx].yMin;
        (vP[idx].d2)[1].vtX = bBox[idx].xMax;
	(vP[idx].d2)[1].vtY = bBox[idx].yMin;
        (vP[idx].d2)[2].vtX = bBox[idx].xMax;
	(vP[idx].d2)[2].vtY = bBox[idx].yMax;
        (vP[idx].d2)[3].vtX = bBox[idx].xMin;
	(vP[idx].d2)[3].vtY = bBox[idx].yMax;
      }
    }
    else /* dim == 3 */
    {
      nVtx = 8;
      vType = WLZ_VERTEX_D3;
      tType = WLZ_TRANSFORM_3D_AFFINE;
      for(idx = 0; idx < 2; ++idx)
      {
        (vP[idx].d3)[0].vtX = bBox[idx].xMin;
	(vP[idx].d3)[0].vtY = bBox[idx].yMin;
	(vP[idx].d3)[0].vtZ = bBox[idx].zMin;
        (vP[idx].d3)[1].vtX = bBox[idx].xMax;
	(vP[idx].d3)[1].vtY = bBox[idx].yMin;
	(vP[idx].d3)[1].vtZ = bBox[idx].zMin;
        (vP[idx].d3)[2].vtX = bBox[idx].xMax;
	(vP[idx].d3)[2].vtY = bBox[idx].yMax;
	(vP[idx].d3)[2].vtZ = bBox[idx].zMin;
        (vP[idx].d3)[3].vtX = bBox[idx].xMin;
	(vP[idx].d3)[3].vtY = bBox[idx].yMax;
	(vP[idx].d3)[3].vtZ = bBox[idx].zMin;
        (vP[idx].d3)[4].vtX = bBox[idx].xMin;
	(vP[idx].d3)[4].vtY = bBox[idx].yMin;
	(vP[idx].d3)[4].vtZ = bBox[idx].zMax;
        (vP[idx].d3)[5].vtX = bBox[idx].xMax;
	(vP[idx].d3)[5].vtY = bBox[idx].yMin;
	(vP[idx].d3)[5].vtZ = bBox[idx].zMax;
        (vP[idx].d3)[6].vtX = bBox[idx].xMax;
	(vP[idx].d3)[6].vtY = bBox[idx].yMax;
	(vP[idx].d3)[6].vtZ = bBox[idx].zMax;
        (vP[idx].d3)[7].vtX = bBox[idx].xMin;
	(vP[idx].d3)[7].vtY = bBox[idx].yMax;
	(vP[idx].d3)[7].vtZ = bBox[idx].zMax;
      }
    }
    tr = WlzAffineTransformLSq(vType, nVtx, vP[1], nVtx, vP[0], 0, NULL,
                               tType, &errNum);
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
	  "%s: Failed to compute affine transform (%s).\n",
	  *argv, errMsg);
    }
  }
  /* Create affine transform object or affine transform the source object
   * as required. */
  if(ok)
  {
    int		idx,
    		idy;
    const double eps = 1.0e-12;

    /* Tidy up the transform, |t_{ij}| < eps => t_{ij} = 0.0. */
    for(idy = 0; idy < 4; ++idy)
    {
      for(idx = 0; idx < 4; ++idx)
      {
        if(fabs(tr->mat[idy][idx]) < eps)
	{
	  tr->mat[idy][idx] = 0.0;
	}
      }
    }
    if(transform)
    {
      outObj = WlzAffineTransformObj(inObj[0], tr, WLZ_INTERPOLATION_NEAREST,
                                     &errNum);
      if(outObj)
      {
        tr = NULL;
      }
    }
    else
    {
      WlzDomain dom;
      WlzValues val;

      dom.t = tr;
      val.core = NULL;
      outObj = WlzMakeMain(WLZ_AFFINE_TRANS, dom, val, NULL, NULL, &errNum);
    }
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
                     "%s: Failed to %saffine transform object (%s).\n",
		     *argv, (transform)? "create ": "", errMsg);
    }
  }
  /* Write the output object. */
  if(ok)
  {
    char *fStr;
    FILE *fP;

    if(strcmp(outFileStr, "-") == 0)
    {
      fP = stdout;
      fStr = NULL;
    }
    else
    {
      fP = NULL;
      fStr = outFileStr;
    }
    errNum = WlzEffWriteObj(fP, fStr, outObj, outFmt);
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
	  "%s: Failed to write object to file %s (%s)\n",
	  *argv, outFileStr, errMsg);
    }
  }
  (void )WlzFreeObj(inObj[0]);
  (void )WlzFreeObj(inObj[1]);
  (void )WlzFreeObj(outObj);
  if(usage)
  {
    char *fmtStr = NULL;

    fmtStr = WlzEffFormatTable(2, 50, 10, NULL);
    (void )fprintf(
        stderr,
	"Usage: %s%s%s%s%s%s%s%s\n",
	*argv,
	" [-h] [-T]\n"
	"\t\t[-o<out file>] [-s<src fmt>] [-t<tgt fmt>] [-u<out fmt>]\n"
	"\t\t<source object> <target object>\n"
        "Computes the Woolz affine transform which makes the bounding box of\n"
	"the source object equal to that of the target object.\n"
	"Version: ",
	WlzVersion(),
	"\n"
	"  -h Help, prints this usage information.\n"
	"  -o Output file.\n"
	"  -s Source file format.\n"
	"  -t Target file format.\n"
	"  -u Output file format.\n"
	"  -T Transform the source object and write it to the output file\n"
	"     rather than the affine transform.\n"
        "The known file formats are:\n"
	"  Description                                       Extension\n"
	"  ***********                                       *********\n",
	fmtStr,
	"Simple example:\n  ",
	*argv,
	"-o out.wlz small.vtk big.stl\n"
	"Reads the source object from the file small.vtk and the target\n"
	"object from big.stl then computes the affine transform which scales\n"
	"the source objects bounding box to fit that of the target object.\n"
	"The output transform is written to the file out.wlz.\n");
  }
  return(!ok);
}
int main(int	argc,
	 char	**argv)
{
  char 		optList[] = "n:O:hv";
  int		option;
  /* int		verboseFlg=0; */
  int		rows=0, cols=0;
  int		overlap=50;
  int		rowShift, colShift;
  WlzErrorNum	errNum=WLZ_ERR_NONE;
  char		*tiffFile=NULL;
  WlzObject	*inObj=NULL, *outObj=NULL, *obj, **objVec;
  WlzCompoundArray	*outCmpnd;
  int		i, j, objVecCount, objIndx;

  /* read the argument list and check for an input file */
  opterr = 0;
  while( (option = getopt(argc, argv, optList)) != EOF ){
    switch( option ){

    case 'n':
      switch( sscanf(optarg, "%d,%d", &cols, &rows) ){
      default:
	usage(argv[0]);
	return 1;

      case 1:
	fprintf(stderr,
		"%s: number of rows not set and will be estimated\n",
		argv[0]);
	break;

      case 2:
	break;
      }
      break;

    case 'O':
      switch( sscanf(optarg, "%d", &overlap) ){
      default:
	fprintf(stderr,
		"%s: overlap not read", argv[0]);
	usage(argv[0]);
	return 1;

      case 1:
	break;
      }
      break;

    case 'v':
      /* verboseFlg = 1; */
      break;

    case 'h':
    default:
      usage(argv[0]);
      return WLZ_ERR_UNSPECIFIED;
    }
  }

  if( optind < argc ){
    tiffFile = *(argv+optind);
  }
  else {
    fprintf(stderr, "%s: input TIFF file required\n", argv[0]);
    usage(argv[0]);
    return WLZ_ERR_UNSPECIFIED;
  }

  /* read the TIFF file */
  if( (inObj = WlzAssignObject(
	 WlzEffReadObj(NULL, tiffFile, WLZEFF_FORMAT_TIFF,
	               0, 0, 0, &errNum), NULL)) == NULL ){
    usage(argv[0]);
    return errNum;
  }

  /* if 2D then there is only one patch, simply output as a compound object */
  switch( inObj->type ){
  case WLZ_2D_DOMAINOBJ:
    outCmpnd = WlzMakeCompoundArray(WLZ_COMPOUND_ARR_1, 3, 1, &inObj,
				    inObj->type, &errNum);
      outObj = (WlzObject *) outCmpnd;
    break;

  case WLZ_3D_DOMAINOBJ:
    if( (errNum = WlzExplode3D(&objVecCount, &objVec, inObj)) != WLZ_ERR_NONE ){
      usage(argv[0]);
      return errNum;
    }
    /* check if rows and columns plausible */
    if( cols && rows ){
      if( cols*rows != objVecCount ){
	fprintf(stderr,
		"%s: input columns and rows (%d,%d) does not match"
		"number of patches - %d\n Continuing anyway\n",
		argv[0], cols, rows, objVecCount);
      }
    }
    else if( cols ){
      rows = objVecCount / cols;
      if( cols*rows != objVecCount ){
	fprintf(stderr,
		"%s: input columns and estimated rows (%d,%d) does not match"
		"number of patches - %d\nContinuing anyway\n",
		argv[0], cols, rows, objVecCount);
      }
    }
    else {
      if( guessColsRows(objVecCount, &cols, &rows) ){
	fprintf(stderr,
		"%s: estimated cols and rows - (%d,%d)\nContinuing\n",
		argv[0], cols, rows);
      }
      else {
	fprintf(stderr, 
		"%s: cols,rows (%d, %d) estimated seems crazy,"
		"put values in explicitely\n",
		argv[0], cols, rows);
	usage(argv[0]);
	return WLZ_ERR_UNSPECIFIED;
      }
    }

    /* shift patch objects, assume patches all the same size */
    rowShift = (objVec[0]->domain.i->lastln - objVec[0]->domain.i->line1
		+ 1 - overlap);
    colShift = (objVec[0]->domain.i->lastkl - objVec[0]->domain.i->kol1
		+ 1 - overlap);
    objIndx = 0;
    for(j=0; j < rows; j++){
      for(i=0; i < cols; i++, objIndx++){
	if( objIndx < objVecCount ){
	  obj = WlzShiftObject(objVec[objIndx], 
			       colShift*i, rowShift*j, 0, &errNum);
	  WlzFreeObj(objVec[objIndx]);
	  objVec[objIndx] = WlzAssignObject(obj, &errNum);
	}
      }
    }

    /* make array */
    outCmpnd = WlzMakeCompoundArray(WLZ_COMPOUND_ARR_1, 2,
				    objVecCount, objVec,
				    objVec[0]->type, &errNum);
    outObj = (WlzObject *) outCmpnd;
    break;

  default:
    errNum = WLZ_ERR_OBJECT_TYPE;
  }
  WlzFreeObj(inObj);

  /* write compound object */
  if( errNum == WLZ_ERR_NONE ){
    WlzWriteObj(stdout, outObj);
    WlzFreeObj(outObj);
  }
  else {
    usage(argv[0]);
  }
  return errNum;
}
Example #10
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, &regObjs, 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);
}
Example #11
0
int             main(int argc, char **argv)
{
  int		option,
  		ok = 1,
		debug = 0,
		usage = 0,
		verbose = 0,
		verboseDat = 0,
		idx0,
		index,
		binFlg = 0,
  		nMatch = 0,
		useCOfM = 0,
		maxItr = 200,
		minSpx = 15,
		minSegSpx = 10,
		matchImpNN = 7,
		noMatching = 0,
		decompLimit = INT_MAX,
		removeRefOrg = 1,
		refMedianSz = 0,
		srcMedianSz = 0,
		multipleFiles = 0;
  double	tD0,
  		tD1,
		delta = 0.01,	
  		maxAng = 30 * (ALG_M_PI / 180.0),
  		maxDeform = 0.5,
  		maxDisp = 20.0,
		refCThr = 20.0,
		srcCThr = 20.0,
		refThr = 254.0,
		srcThr = 254.0,
		matchImpThr = 2.5,
		refSmooth = 3.0,
		srcSmooth = 3.0;
  FILE		*vFP,
  		*lFP = NULL,
  		*fP = NULL;
  char		*inFileStr = NULL,
		*inTrFileStr = NULL,
  		*outFileBaseStr = NULL,
		*ctrFileBaseStr = NULL;
  char		secParFile[256];
  char		*refObjFileStr = NULL,
  		*srcObjFileStr = NULL;
  WlzThresholdType thrType = WLZ_THRESH_LOW;
  WlzEffFormat	refObjFileType = WLZEFF_FORMAT_WLZ,
  		srcObjFileType = WLZEFF_FORMAT_WLZ;
  WlzObject	*tObj0 = NULL,
  		*refObj3D = NULL,
		*refObj2D = NULL,
  		*srcObj2D = NULL,
		*refCObj2D = NULL,
  		*srcCObj2D = NULL;
  WlzDVertex2	tDV0,
  		refCOfM,
  		srcCOfM,
		refObj2DOrg;
  WlzAffineTransform *inTr = NULL,
		*inPTr = NULL;
  WlzThreeDViewStruct *view = NULL;
  WlzVertexP	matchRP,
  		matchSP;
  WlzInterpolationType interp = WLZ_INTERPOLATION_NEAREST;
  WlzMatchICPWeightCbData cbData;
  WlzAffineTransformPrim inTrPrim;
  WlzErrorNum	errNum = WLZ_ERR_NONE;
  char		fileNameBuf[FILENAME_MAX];
  const char	*errMsg;
  static char	optList[] =
                "dhvVo:r:Yt:x:y:a:s:efg:k:u:b:B:i:p:A:E:S:F:P:m:n:c:NL";
  const int	nScatter = 5;
  const char	nullStr[] = "<NULL>",
  		inFileStrDef[] = "-",
  	        outFileStrDef[] = "-";

  matchRP.v = matchSP.v = NULL;
  srcCOfM.vtX = srcCOfM.vtY = 0.0;
  inFileStr = (char *)inFileStrDef;
  outFileBaseStr = (char *)outFileStrDef;
  (void )memset(&inTrPrim, 0, sizeof(WlzAffineTransformPrim));
  inTrPrim.scale = 1.0;
  while((usage == 0) && ok &&
        ((option = getopt(argc, argv, optList)) != -1))
  {
    switch(option)
    {
      case 'd':
        debug = 1;
	break;
      case 'h':
        usage = 1;
	break;
      case 'v':
        verbose = 1;
	break;
      case 'V':
        verboseDat = 1;
	break;
      case 'o':
        outFileBaseStr = optarg;
	break;
      case 'r':
        if((refObjFileStr = AlcStrDup(optarg)) == NULL)
	{
	  ok = 0;
	  (void )fprintf(stderr, "%s Failed to allocate enough memory.\n",
	     	         *argv);
	}
        break;
      case 'Y':
        multipleFiles = 1;
	break;
      case 't':
        inTrFileStr = optarg;
	break;
      case 'x':
        if(sscanf(optarg, "%lg", &(inTrPrim.tx)) != 1)
	{
	  usage = 1;
	}
	break;
      case 'y':
        if(sscanf(optarg, "%lg", &(inTrPrim.ty)) != 1)
	{
	  usage = 1;
	}
	break;
      case 'a':
        if(sscanf(optarg, "%lg", &(inTrPrim.theta)) != 1)
	{
	  usage = 1;
	}
	else
	{
	  inTrPrim.theta *= ALG_M_PI / 180.0;
	}
	break;
      case 's':
        if(sscanf(optarg, "%lg", &(inTrPrim.scale)) != 1)
	{
	  usage = 1;
	}
	break;
      case 'e':
        useCOfM = 1;
	break;
      case 'f':
        removeRefOrg = 0;
	break;
      case 'b':
	binFlg = 1;
        thrType = WLZ_THRESH_LOW;
        usage = WlzMatchICPPlaneParseDPair(optarg, &refThr, &srcThr) != 3;
	break;
      case 'B':
	binFlg = 1;
        thrType = WLZ_THRESH_HIGH;
        usage = WlzMatchICPPlaneParseDPair(optarg, &refThr, &srcThr) != 3;
	break;
      case 'g':
        usage = WlzMatchICPPlaneParseDPair(optarg, &refCThr, &srcCThr) != 3;
	break;
      case 'k':
        usage = WlzMatchICPPlaneParseDPair(optarg, &tD0, &tD1) != 3;
	refMedianSz = WLZ_NINT(tD0);
	srcMedianSz = WLZ_NINT(tD1);
	break;
      case 'u':
        usage = WlzMatchICPPlaneParseDPair(optarg,
					   &refSmooth, &srcSmooth) != 3;
	break;
      case 'i':
        if((sscanf(optarg, "%d", &maxItr) != 1) || (maxItr <= 0))
	{
	  usage = 1;
	}
	break;
      case 'p':
        if((sscanf(optarg, "%d", &minSpx) != 1) || (minSpx <= 10))
	{
	  usage = 1;
	}
	break;
      case 'P':
        if(sscanf(optarg, "%d", &minSegSpx) != 1)
	{
	  usage = 1;
	}
	break;
      case 'A':
        if((sscanf(optarg, "%lg", &maxAng) != 1) ||
	   (maxAng < 0.0) || (maxAng > 180.0))
	{
	  usage = 1;
	}
	else
	{
	  maxAng *= ALG_M_PI / 180;
	}
	break;
      case 'E':
        if((sscanf(optarg, "%lg", &delta) != 1) || (delta < 0.0))
	{
	  usage = 1;
	}
      case 'F':
        if((sscanf(optarg, "%lg", &maxDeform) != 1) || (maxDeform < 0.0))
	{
	  usage = 1;
	}
	break;
      case 'S':
        if((sscanf(optarg, "%lg", &maxDisp) != 1) || (maxDisp <= 0.0))
	{
	  usage = 1;
	}
	break;
      case 'm':
        if((sscanf(optarg, "%lg", &matchImpThr) != 1) || (matchImpThr < 0.0))
	{
	  usage = 1;
	}
	break;
      case 'n':
        if((sscanf(optarg, "%d", &matchImpNN) != 1) || (matchImpNN < 1))
	{
	  usage = 1;
	}
	break;
      case 'c':
        ctrFileBaseStr = optarg;
        if(strlen(ctrFileBaseStr) > (FILENAME_MAX - 16))
	{
	  usage = 1;
	}
	break;
      case 'N':
        noMatching = 1;
	break;
      case 'L':
        interp = WLZ_INTERPOLATION_LINEAR;
	break;
      default:
        usage = 1;
	break;
    }
  }
  if(usage)
  {
    ok = 0;
  }
  if(ok)
  {
    if((inFileStr == NULL) || (*inFileStr == '\0') ||
       (outFileBaseStr == NULL) || (*outFileBaseStr == '\0'))
    {
      ok = 0;
      usage = 1;
    }
    if(ok && (optind < argc))
    {
      if((optind + 1) != argc)
      {
        usage = 1;
	ok = 0;
      }
      else
      {
        inFileStr = *(argv + optind);
      }
    }
  }
  if(verbose)
  {
    (void )fprintf(stderr, "Parameter and other internal variable values:\n");
    (void )fprintf(stderr, "  ok = %d\n", ok);
    (void )fprintf(stderr, "  debug = %d\n", debug);
    (void )fprintf(stderr, "  verbose = %d\n", verbose);
    (void )fprintf(stderr, "  verboseDat = %d\n", verboseDat);
    (void )fprintf(stderr, "  outFileBaseStr = %s\n",
		   outFileBaseStr? outFileBaseStr: nullStr);
    (void )fprintf(stderr, "  refObjFileStr = %s\n",
		   refObjFileStr? refObjFileStr: nullStr);
    (void )fprintf(stderr, "  multipleFiles = %d\n", multipleFiles);
    (void )fprintf(stderr, "  inTrFileStr = %s\n",
                   inTrFileStr? inTrFileStr: nullStr);
    (void )fprintf(stderr, "  inTrPrim.tx = %g\n", inTrPrim.tx);
    (void )fprintf(stderr, "  inTrPrim.ty = %g\n", inTrPrim.ty);
    (void )fprintf(stderr, "  inTrPrim.theta = %g (Radians)\n",
    		   inTrPrim.theta);
    (void )fprintf(stderr, "  inTrPrim.scale = %g\n", inTrPrim.scale);
    (void )fprintf(stderr, "  useCOfM = %d\n", useCOfM);
    (void )fprintf(stderr, "  removeRefOrg = %d\n", removeRefOrg);
    (void )fprintf(stderr, "  binFlg = %d\n", binFlg);
    (void )fprintf(stderr, "  thrType = %s\n",
	    (thrType == WLZ_THRESH_LOW)? "WLZ_THRESH_LOW": "WLZ_THRESH_HIGH");
    (void )fprintf(stderr, "  refThr = %g\n", refThr);
    (void )fprintf(stderr, "  srcThr = %g\n", srcThr);
    (void )fprintf(stderr, "  refCThr = %g\n", refCThr);
    (void )fprintf(stderr, "  srcCThr = %g\n", srcCThr);
    (void )fprintf(stderr, "  refMedianSz = %d\n", refMedianSz);
    (void )fprintf(stderr, "  srcMedianSz = %d\n", srcMedianSz);
    (void )fprintf(stderr, "  refSmooth = %g\n", refSmooth);
    (void )fprintf(stderr, "  srcSmooth = %g\n", srcSmooth);
    (void )fprintf(stderr, "  delta = %g\n", delta);
    (void )fprintf(stderr, "  maxItr = %d\n", maxItr);
    (void )fprintf(stderr, "  minSpx = %d\n", minSpx);
    (void )fprintf(stderr, "  maxAng = %g (Radians)\n", maxAng);
    (void )fprintf(stderr, "  maxDeform = %g\n", maxDeform);
    (void )fprintf(stderr, "  maxDisp = %g\n", maxDisp);
    (void )fprintf(stderr, "  matchImpThr = %g\n", matchImpThr);
    (void )fprintf(stderr, "  matchImpNN = %d\n", matchImpNN);
    (void )fprintf(stderr, "  ctrFileBaseStr = %s\n",
		   ctrFileBaseStr? ctrFileBaseStr: nullStr);
    (void )fprintf(stderr, "  noMatching = %d\n", noMatching);
    (void )fprintf(stderr, "  usage = %d\n", usage);
  }
  /* Create the initial affine transform and it's inverse. */
  if(ok)
  {
    if(inTrFileStr)
    {
      tObj0 = NULL;
      if(((fP = fopen(inTrFileStr, "r")) == NULL) ||
         ((tObj0 = WlzReadObj(fP, &errNum)) == NULL) ||
	 (tObj0->type != WLZ_AFFINE_TRANS) ||
	 (tObj0->domain.core == NULL))
      {
        errNum = WLZ_ERR_READ_INCOMPLETE;
      }
      else
      {
        inTr = WlzAffineTransformCopy(tObj0->domain.t, &errNum);
      }
      if(fP)
      {
        (void )fclose(fP);
	fP = NULL;
      }
      if(tObj0)
      {
        WlzFreeObj(tObj0);
	tObj0 = NULL;
      }
    }
    else
    {
      inTr = WlzMakeAffineTransform(WLZ_TRANSFORM_2D_AFFINE, &errNum);
      if(errNum == WLZ_ERR_NONE)
      {
	errNum = WlzAffineTransformPrimSet(inTr, inTrPrim);
      }
    }
    if(errNum == WLZ_ERR_NONE)
    {
      if(verbose)
      {
        (void )fprintf(stderr, "Affine transform inTr = \n");
	(void )AlcDouble2WriteAsci(stderr, inTr->mat, 3, 3);
      }
    }
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
      		     "%s: Failed to set initial affine transform (%s).\n",
		     *argv, errMsg);
    }
  }
  /* If the reference file name was given on the command line then it use it
   * in place of the reference file name in the section parameters bibfile. */
  if(ok && refObjFileStr)
  {
    if(((refObj3D = WlzAssignObject(
		    WlzEffReadObj(NULL, refObjFileStr, refObjFileType,
				  0, 0, 0, &errNum), NULL)) == NULL) ||
       (errNum != WLZ_ERR_NONE))
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
      "%s Failed to read the reference object from file %s (%s).\n",
      *argv, refObjFileStr, errMsg);
    }
  }
  if(ok)
  {
    if((lFP = (strcmp(inFileStr, "-")?
             fopen(inFileStr, "r"): stdin)) == NULL)
    {
      ok = 0;
      (void )fprintf(stderr,
		   "%s Failed to open the input section parameters file %s.\n",
		    *argv, inFileStr);
    }
  }
  /* Get each input section parameters file and process it. */
  index = 0;
  while(ok &&
        ((fP = WlzMatchICPPlaneSecParFile(lFP, multipleFiles, index,
					  secParFile)) != NULL))
  {
    errNum = WlzMatchICPPlaneReadSecParam(fP, &view,
	refObjFileStr? NULL: &refObjFileStr, &refObjFileType,
	refObj3D? NULL: &refObj3D,
	&srcObjFileStr, &srcObjFileType, &srcObj2D);
    /* Note: srcObj2D assigned in WlzMatchICPPlaneReadSecParam(). */
    if(errNum == WLZ_ERR_NONE)
    {
      if(verboseDat)
      {
	if(verbose)
	{
	  (void )fprintf(stderr,
			 "Writing srcObj2D to dbg-srcObj2D.wlz.\n");
	}
	if((vFP = fopen("dbg-srcObj2D.wlz", "w")) != NULL)
	{
	  (void )WlzWriteObj(vFP, srcObj2D);
	  (void )fclose(vFP);
	}
      }
      errNum = WlzInit3DViewStruct(view, refObj3D);
    }
    if(fP)
    {
      fclose(fP);
      fP = NULL;
    }
    if(errNum != WLZ_ERR_NONE)
    {
      ok = 0;
      (void )WlzStringFromErrorNum(errNum, &errMsg);
      (void )fprintf(stderr,
       "%s Failed to read input section parameters from file %s (%s).\n",
       argv[0], secParFile, errMsg);
    }
    /* Create the section object. */
    if(ok)
    {
      refObj2D = WlzAssignObject(
      		 WlzMatchICPPlaneGetSection(refObj3D, view, interp,
		 		            &errNum), NULL);
      if((errNum == WLZ_ERR_NONE) && (refObj2D != NULL) &&
	  (refObj2D->type = WLZ_2D_DOMAINOBJ) && (refObj2D->domain.core))
      {
	refObj2DOrg.vtX = refObj2D->domain.i->kol1;
	refObj2DOrg.vtY = refObj2D->domain.i->line1;
	if(verboseDat)
	{
	  if(verbose)
	  {
	    (void )fprintf(stderr,
			   "Writing refObj2D to dbg-refObj2D.wlz.\n");
	  }
	  if((vFP = fopen("dbg-refObj2D.wlz", "w")) != NULL)
	  {
	    (void )WlzWriteObj(vFP, refObj2D);
	    (void )fclose(vFP);
	  }
	}
      }
      else
      {
	ok = 0;
        (void )WlzStringFromErrorNum(errNum, &errMsg);
	(void )fprintf(stderr,
	"%s Failed to get section from reference object (%s).\n",
	argv[0], errMsg);
      }
    }
    /* Create the contour objects. */
    if(ok)
    {
      refCObj2D = WlzMatchICPPlaneCreateContourObj(refObj2D,
				binFlg, thrType, refThr,
      				refMedianSz, refSmooth,
				refCThr, minSpx, debug,
				verboseDat? "dbg-refObj2D.wlz": NULL,
				&errNum);
      if(errNum == WLZ_ERR_NONE)
      {
	srcCObj2D = WlzMatchICPPlaneCreateContourObj(srcObj2D,
				binFlg, thrType, srcThr,
				srcMedianSz, srcSmooth,
				srcCThr, minSpx, debug,
				verboseDat? "dbg-srcObj2D.wlz": NULL,
				&errNum);
      }
      if(errNum != WLZ_ERR_NONE)
      {
	ok = 0;
        (void )WlzStringFromErrorNum(errNum, &errMsg);
	(void )fprintf(stderr, "%s Failed to compute contours (%s).\n",
		       argv[0], errMsg);
      }
    }
    /* Compute translation using centre of mass if required. Then create
     * modified initial and inverse transforms for this plane. */
    if(ok)
    {
      if(useCOfM)
      {
	if(verbose)
	{
	  (void )fprintf(stderr,
	  "Using centre of mass to refine initial affine transform.\n");
	}
	refCOfM = WlzCentreOfMass2D(refCObj2D, 0, NULL, &errNum);
	tObj0 = NULL;
	if(errNum == WLZ_ERR_NONE)
	{
	  tObj0 = WlzAssignObject(
		  WlzAffineTransformObj(srcCObj2D, inTr,
					WLZ_INTERPOLATION_NEAREST,
					&errNum), NULL);
	}
	if(errNum == WLZ_ERR_NONE)
	{
	  srcCOfM = WlzCentreOfMass2D(tObj0, 0, NULL, &errNum);
	}
	(void )WlzFreeObj(tObj0);
	if(errNum == WLZ_ERR_NONE)
	{
	  if(verbose)
	  {
	    (void )fprintf(stderr,
	    "centres of mass are: refCOfM = {%g,%g}, srcCOfM = {%g,%g}.\n",
	    refCOfM.vtX, refCOfM.vtY, srcCOfM.vtX, srcCOfM.vtY);
	  }
	  inPTr = WlzAffineTransformCopy(inTr, &errNum);
	}
	if(errNum == WLZ_ERR_NONE)
	{
	  WLZ_VTX_2_SUB(tDV0, refCOfM, srcCOfM);
	  inPTr->mat[0][2] += tDV0.vtX;
	  inPTr->mat[1][2] += tDV0.vtY;
	}
	if(errNum != WLZ_ERR_NONE)
	{
	  ok = 0;
	  (void )WlzStringFromErrorNum(errNum, &errMsg);
	  (void )fprintf(stderr,
	  "%s Failed to modify transform using centre of mass (%s).\n",
			 argv[0], errMsg);
	}
      }
      if(errNum == WLZ_ERR_NONE)
      {
	if(verbose)
	{
	  (void )fprintf(stderr, "Affine transform inPTr = ");
	  if(inPTr)
	  {
	    (void )fprintf(stderr, "\n");
	    (void )AlcDouble2WriteAsci(stderr, inPTr->mat, 3, 3);
	  }
	  else
	  {
	    (void )fprintf(stderr, "Identity\n");
	  }
	}
      }
    }
    if(ok && ctrFileBaseStr)
    {
      if(multipleFiles)
      {
        sprintf(fileNameBuf, "%s_%06d_ctr_ref.wlz", ctrFileBaseStr, index);
      }
      else
      {
        sprintf(fileNameBuf, "%s_ctr_ref.wlz", ctrFileBaseStr);
      }
      errNum = WLZ_ERR_FILE_OPEN;
      ok = (fP = fopen(fileNameBuf, "w")) != NULL;
      if(ok)
      {
	ok = (errNum = WlzWriteObj(fP, refCObj2D)) == WLZ_ERR_NONE;
      }
      if(fP)
      {
	(void )fclose(fP);
	fP = NULL;
      }
      if(ok)
      {
	if(multipleFiles)
	{
	  sprintf(fileNameBuf, "%s_%06d_ctr_src.wlz", ctrFileBaseStr, index);
	}
	else
	{
	  sprintf(fileNameBuf, "%s_ctr_src.wlz", ctrFileBaseStr);
	}
	ok = (fP = fopen(fileNameBuf, "w")) != NULL;
      }
      if(ok)
      {
	ok = (errNum = WlzWriteObj(fP, srcCObj2D)) == WLZ_ERR_NONE;
      }
      if(fP)
      {
	(void )fclose(fP);
	fP = NULL;
      }
      tObj0 = NULL;
      if(ok)
      {
        tObj0 = WlzAffineTransformObj(srcCObj2D, inPTr,
				      WLZ_INTERPOLATION_NEAREST, &errNum);
        ok = errNum == WLZ_ERR_NONE;
      }
      if(ok)
      {
        if(multipleFiles)
	{
	  sprintf(fileNameBuf, "%s_%06d_ctr_itrsrc.wlz", ctrFileBaseStr,
	  	  index);
	}
	else
	{
	  sprintf(fileNameBuf, "%s_ctr_itrsrc.wlz", ctrFileBaseStr);
	}
	ok = (fP = fopen(fileNameBuf, "w")) != NULL;
      }
      if(ok)
      {
	ok = (errNum = WlzWriteObj(fP, tObj0)) == WLZ_ERR_NONE;
      }
      (void )WlzFreeObj(tObj0);
      if(fP)
      {
        (void )fclose(fP);
	fP = NULL;
      }
      if(!ok)
      {
	(void )WlzStringFromErrorNum(errNum, &errMsg);
	(void )fprintf(stderr,
		       "%s Failed to write contour to file %s (%s)\n",
		       argv[0], fileNameBuf, errMsg);
      }
    }
    if(ok && (noMatching == 0))
    {
      /* Set up weighting function callback data. */
      cbData.tGM = refCObj2D->domain.ctr->model;
      cbData.sGM = srcCObj2D->domain.ctr->model;
      cbData.maxDisp = maxDisp;
      cbData.nScatter = nScatter;
      errNum = WlzMatchICPCtr(refCObj2D->domain.ctr, srcCObj2D->domain.ctr,
			      inPTr, maxItr, minSpx, minSegSpx,
			      &nMatch, &matchRP, &matchSP, decompLimit,
			      maxDisp, maxAng, maxDeform,
			      matchImpNN, matchImpThr,
			      WlzMatchICPWeightMatches, &cbData,
			      delta);
      if(errNum != WLZ_ERR_NONE)
      {
	ok = 0;
	(void )WlzStringFromErrorNum(errNum, &errMsg);
	(void )fprintf(stderr,
		       "%s Failed to compute tie-points from contours (%s).\n",
		       argv[0], errMsg);
      }
    }
    if(ok && verboseDat)
    {
	if(verbose)
	{
	  (void )fprintf(stderr,
			 "Writing tie points to dbg-tiepoints.num.\n");
	}
	if((vFP = fopen("dbg-tiepoints.num", "w")) != NULL)
	{
	  for(idx0 = 0; idx0 < nMatch; ++ idx0)
	  {
	    (void )fprintf(vFP, "%g %g %g %g\n",
		       (matchSP.d2 + idx0)->vtX,
		       (matchSP.d2 + idx0)->vtY,
		       (matchRP.d2 + idx0)->vtX - (matchSP.d2 + idx0)->vtX,
		       (matchRP.d2 + idx0)->vtY - (matchSP.d2 + idx0)->vtY);
	  }
	  (void )fclose(vFP);
	}
    }
    if(ok && ctrFileBaseStr)
    {
      if(multipleFiles)
      {
	sprintf(fileNameBuf, "%s_%06d_ctr_dcp.wlz", ctrFileBaseStr, index);
      }
      else
      {
	sprintf(fileNameBuf, "%s_ctr_dcp.wlz", ctrFileBaseStr);
      }
      if((fP = fopen(fileNameBuf, "w")) == NULL)
      {
	ok = 0;
	(void )fprintf(stderr, "%s Failed to open contour file %s\n",
		       argv[0], fileNameBuf);
      }
      else
      {
	if((errNum = WlzWriteObj(fP, srcCObj2D)) != WLZ_ERR_NONE)
	{
	  ok = 0;
	  (void )WlzStringFromErrorNum(errNum, &errMsg);
	  (void )fprintf(stderr,
	  		 "%s Failed to write contour to file %s (%s)\n",
			 argv[0], fileNameBuf, errMsg);
	}
	(void )fclose(fP);
	fP = NULL;
      }
    }
    /* Write the new section parameters file together with the computed
     * tie-points. */
    if(ok)
    {
      if(multipleFiles)
      {
        sprintf(fileNameBuf, "%s_%06d.bib", outFileBaseStr, index);
      }
      else
      {
        sprintf(fileNameBuf, "%s.bib", outFileBaseStr);
      }
      if((fP = fopen(fileNameBuf, "w")) == NULL)
      {
	ok = 0;
	(void )fprintf(stderr,
		 "%s Failed to open the output section parameters file %s.\n",
		 *argv, fileNameBuf);
      }
    }
    if(ok)
    {
      if(verbose)
      {
	(void )fprintf(stderr, "Writing section parameters.\n");
      }
      errNum = WlzMatchICPPlaneWriteSecParam(fP, view,
	  refObjFileStr, refObjFileType,
	  srcObjFileStr, srcObjFileType,
	  nMatch, matchRP.d2, matchSP.d2,
	  removeRefOrg? &refObj2DOrg: NULL);
      if(fP && strcmp(outFileBaseStr, "-"))
      {
	fclose(fP);
	fP = NULL;
      }
      if(errNum != WLZ_ERR_NONE)
      {
	ok = 0;
	(void )WlzStringFromErrorNum(errNum, &errMsg);
	(void )fprintf(stderr,
	"%s Failed to write output section parameters to file %s (%s).\n",
	argv[0], fileNameBuf, errMsg);
      }
    }
    WlzFreeAffineTransform(inPTr); inPTr = NULL;
    ++index;
  }
  (void )WlzFree3DViewStruct(view);
  AlcFree(refObjFileStr);
  AlcFree(srcObjFileStr);
  AlcFree(matchRP.v);
  AlcFree(matchSP.v);
  (void )WlzFreeAffineTransform(inTr);
  (void )WlzFreeObj(refObj3D);
  (void )WlzFreeObj(refObj2D);
  (void )WlzFreeObj(srcObj2D);
  (void )WlzFreeObj(refCObj2D);
  (void )WlzFreeObj(srcCObj2D);
  if(usage)
  {
      (void )fprintf(stderr,
      "Usage: %s%s%s%s",
      *argv,
      " [-h] [-d] [-v] [-V]\n"
      "                        [-o<output file base>] [-r <reference file>]\n"
      "                        [-Y] [-t#] [-x#] [-y#] [-a#] [-s#] [-e]\n"
      "                        [-g#,#] [-k#,#] [-u#,#] [-b #] [-B #]\n"
      "                        [-f] [-i#] [-s#] [-A#] [-S#] [-F#] [-m#] [-n#]\n"
      "                        [-c<contour file base>] [-N] [-L]\n"
      "                        [<section parameters file>]\n"
      "Version: ",
      WlzVersion(),
      "\n"
      "Options:\n"
      "  -h  Prints this usage information.\n"
      "  -d  Perform extra tests to aid debuging.\n"
      "  -E  Tolerance in mean registration metric value.\n"
      "  -v  Be verbose, lots of text output to the standard error output!\n"
      "  -V  Be verbose with Woolz objects and data, with file name names\n"
      "      prefixed by dbg-.\n"
      "  -o  Output file base.\n"
      "  -r  Reference file.\n"
      "  -Y  The section parameters file is a list of section parameters\n"
      "      files, one per line.\n"
      "  -e  Use centres of mass of geometric models to compute translation,\n"
      "      with this translaton being applied after the optional initial\n"
      "      affine transform.\n"
      "  -t  Initial affine transform (if given all initial affine\n"
      "      transform primitives are ignored).\n"
      "  -x  Initial horizontal translation.\n"
      "  -y  Initial vertical translation.\n"
      "  -a  Initial angle of rotation (degrees).\n"
      "  -s  Initial scale factor.\n"
      "  -g  Maximal gradient contour thresholds, with the format:\n"
      "      <ref threshold>,<src threshold>, either may be omitted.\n"
      "  -k  Median filter size, with the format:\n"
      "      <ref size>,<src size>, either may be omitted.\n"
      "  -u  Gaussian smoothing factors, with the format:\n"
      "      <ref smooth>,<src smooth>, either may be omitted.\n"
      "  -b  Low threshold values used to produce binary mask images for\n"
      "      matching instead of the grey valued images, with objects\n"
      "      having values at or below the given thresholds.\n"
      "  -B  High threshold values used to produce binary mask images for\n"
      "      matching instead of the grey valued images, with objects\n"
      "      having values above the given thresholds.\n"
      "  -f  Keep the reference offset in the reference tie-points (MAPaint\n"
      "      doesn't do this).\n"
      "  -i  Maximum number of iterations.\n"
      "  -p  Minimum number of simplices per shell.\n"
      "  -P  Minimum number of simplices per matched shell segment, with a\n"
      "      pair of correspondence points possibly being generated per\n"
      "      matched shell segment.\n"
      "  -A  Maximum angle (degrees) from a global transformation.\n"
      "  -S  Maximum displacement from a global transformed position.\n"
      "  -F  Maximum deformation from a global transformation.\n"
      "  -m  Implausibility threshold for rejecting implausible\n"
      "      correspondence points which should be greater than zero,\n"
      "      although the useful range is probably [0.5-5.0]. Higher\n"
      "      values allow more implausible matches to be returned.\n"
      "  -n  Number of match points in neighbourhood when checking the\n"
      "	     plausibility of the correspondence points.\n"
      "  -c  Outputs the computed and decomposed geometric models using\n"
      "	     the given file base.\n"
      "  -N  Don't compute the tie-points.\n"
      "  -L  Use linear interpolation (instead of nearest neighbour) when\n"
      "      cuting sections.\n"
      "  Reads either a 2D or 3D reference object and an MAPaint section\n"
      "parameters file. Computes tie-points and then writes a new MAPaint\n"
      "section parameters file which includes the tie-points.\n"
      "  An initial affine transform is computed from the (optional) initial\n"
      "translation, rotation and scale parameters. A centre of mass can be\n"
      "computed to improve the initial translation estimates. If a centre of\n"
      "mass computation is used then the images must have background with\n"
      "high values and foreground with low values. This initial affine\n"
      "transform is appiled to the source image before computing the\n"
      "tie-points. Once computed, the tie-points are transformed using the\n"
      "inverse of the intial transform, before output.\n"
      "  The tie-points are computed using an ICP based matching algorithm\n"
      "in which geometric models built from the maximal gradient edges\n"
      "extracted from the computed section of the reference object and\n"
      "the source object (refered to in the section parameters file).\n"
      "  To aid rejection of poor tie-points, the tie-points are ranked by\n"
      "plausibility, with the most plausible first.\n");
  }
  return(!ok);
}
Example #12
0
/*!
* \return	Woolz error code.
* \brief	Read the input section parameters file to find the reference
* 		and source file object file names, read the reference and
* 		source objects from these files and parse the section view
* 		parameters.
* \param	fP			Input section parameters file.
* \param	dstView			Destination pointer for the 3D view
*					transform.
* \param	dstRefFileStr		Destination pointer for the reference
* 					object file name. If the reference file
* 					string is NULL and the reference object
* 					is not NULL then the reference object
* 					is assumed valid.
* \param	dstRefFileType		Destination pointer for the reference
*					object file type.
* \param	dstRefObj		Destination pointer for the reference
*					object.
* \param	dstSrcFileStr		Destination pointer for the source
* 					object file name. If the source file
*					string is NULL and the source object
*					is not NULL then the source object is
*					assumed valid.
* \param	dstSrcFileType		Destination pointer for the source
*					object file type.
* \param	dstsrcObj		Destination pointer for the source
*					object.
*/
static WlzErrorNum WlzMatchICPPlaneReadSecParam(FILE *fP,
		      WlzThreeDViewStruct **dstView,
		      char **dstRefFileStr, WlzEffFormat *dstRefFileType,
		      WlzObject **dstRefObj, 
		      char **dstSrcFileStr, WlzEffFormat *dstSrcFileType,
		      WlzObject **dstSrcObj)
{
  int		idx;
  char		*fileStr;
  WlzEffFormat	fileType;
  BibFileRecord	*bibRec;
  BibFileError  bibErr = BIBFILE_ER_NONE;
  WlzErrorNum	errNum = WLZ_ERR_NONE;

  *dstView = WlzMake3DViewStruct(WLZ_3D_VIEW_STRUCT, &errNum);
  if(errNum == WLZ_ERR_NONE)
  {
    bibErr = BibFileRecordRead(&bibRec, NULL, fP);
  }
  while((bibErr == BIBFILE_ER_NONE) && (errNum == WLZ_ERR_NONE))
  {
    if(!strcmp(bibRec->name, "Wlz3DSectionViewParams"))
    {
      errNum = WlzEffBibParse3DSectionViewParamsRecord(bibRec, *dstView);
    }
    if(!strcmp(bibRec->name, "MAPaintWarpInputSourceFile"))
    {
      errNum = WlzEffBibParseFileRecord(bibRec, &idx, &fileStr, &fileType);
      if(dstSrcFileStr)
      {
        *dstSrcFileStr = fileStr;
	if(dstSrcFileType)
	{
	  *dstSrcFileType = fileType;
	}
	if(dstSrcObj)
	{
	  *dstSrcObj = WlzAssignObject(
		       WlzEffReadObj(NULL, fileStr, fileType,
		       		     0, 0, 0, &errNum), NULL);
	}
      }
    }
    if(!strcmp(bibRec->name, "MAPaintWarpInputReferenceFile"))
    {
      errNum = WlzEffBibParseFileRecord(bibRec, &idx, &fileStr, &fileType);
      if(dstRefFileStr)
      {
        *dstRefFileStr = fileStr;
	if(dstRefFileType)
	{
	  *dstRefFileType = fileType;
	}
	if(dstRefObj)
	{
	  *dstRefObj = WlzAssignObject(
		       WlzEffReadObj(NULL, fileStr, fileType,
		       		     0, 0, 0, &errNum), NULL);
	}
      }
    }
    BibFileRecordFree(&bibRec);
    bibErr = BibFileRecordRead(&bibRec, NULL, fP);
    if((errNum == WLZ_ERR_NONE) && (bibErr != BIBFILE_ER_NONE))
    {
      if(bibErr != BIBFILE_ER_EOF)
      {
        errNum = WLZ_ERR_READ_INCOMPLETE;
      }
    }
  }
  return(errNum);
}