Example #1
0
int main(int argc, char **argv) {
    args::ArgumentParser parser("Generates masks in stages.\n"
                                "Stage 1 - Otsu thresholding to generate binary mask\n"
                                "Stage 2 - RATs (optional)\n"
                                "Stage 3 - Hole filling (optional)\n"
                                "http://github.com/spinicist/QUIT");

    args::Positional<std::string> input_path(parser, "INPUT_FILE", "Input file");

    args::HelpFlag help(parser, "HELP", "Show this help menu", {'h', "help"});
    args::Flag     verbose(parser, "VERBOSE", "Print more information", {'v', "verbose"});
    args::ValueFlag<std::string> outarg(
        parser, "OUTPUT FILE", "Set output filename, default is input + _mask", {'o', "out"});
    args::ValueFlag<int> volume(
        parser, "VOLUME",
        "Choose volume to mask in multi-volume file. Default 1, -1 selects last volume",
        {'v', "volume"}, 0);
    args::Flag is_complex(parser, "COMPLEX", "Input data is complex, take magnitude first",
                          {'x', "complex"});
    args::ValueFlag<float> lower_threshold(
        parser, "LOWER THRESHOLD",
        "Specify lower intensity threshold for 1st stage, otherwise Otsu's method is used",
        {'l', "lower"}, 0.);
    args::ValueFlag<float> upper_threshold(
        parser, "UPPER THRESHOLD",
        "Specify upper intensity threshold for 1st stage, otherwise Otsu's method is used",
        {'u', "upper"}, std::numeric_limits<float>::infinity());
    args::ValueFlag<float> rats(
        parser, "RATS", "Perform the RATS step, argument is size threshold for connected component",
        {'r', "rats"}, 0.);
    args::ValueFlag<int> fillh_radius(
        parser, "FILL HOLES", "Fill holes in thresholded mask with radius N", {'F', "fillh"}, 0);

    QI::ParseArgs(parser, argc, argv, verbose);

    QI::SeriesF::Pointer vols = ITK_NULLPTR;
    if (is_complex) {
        vols = QI::ReadMagnitudeImage<QI::SeriesF>(QI::CheckPos(input_path), verbose);
    } else {
        vols = QI::ReadImage<QI::SeriesF>(QI::CheckPos(input_path), verbose);
    }

    std::string out_path;
    if (outarg.Get() == "") {
        out_path = QI::StripExt(input_path.Get()) + "_mask" + QI::OutExt();
    } else {
        out_path = outarg.Get();
    }

    // Extract one volume to process
    auto region = vols->GetLargestPossibleRegion();
    if (static_cast<size_t>(std::abs(volume.Get())) < region.GetSize()[3]) {
        int volume_to_get = (region.GetSize()[3] + volume.Get()) % region.GetSize()[3];
        QI::Log(verbose, "Masking volume {}...", volume_to_get);
        region.GetModifiableIndex()[3] = volume_to_get;
    } else {
        QI::Fail("Specified mask volume was invalid {} ", volume.Get());
    }
    region.GetModifiableSize()[3] = 0;
    auto vol                      = itk::ExtractImageFilter<QI::SeriesF, QI::VolumeF>::New();
    vol->SetExtractionRegion(region);
    vol->SetInput(vols);
    vol->SetDirectionCollapseToSubmatrix();
    vol->Update();
    QI::VolumeF::Pointer intensity_image = vol->GetOutput();
    intensity_image->DisconnectPipeline();

    /*
     *  Stage 1 - Otsu or Threshold
     */
    QI::VolumeI::Pointer mask_image = ITK_NULLPTR;
    if (lower_threshold || upper_threshold) {
        QI::Log(verbose, "Thresholding range: {}-{}", lower_threshold.Get(), upper_threshold.Get());
        mask_image =
            QI::ThresholdMask(intensity_image, lower_threshold.Get(), upper_threshold.Get());
    } else {
        QI::Log(verbose, "Generating Otsu mask");
        mask_image = QI::OtsuMask(intensity_image);
    }

    /*
     *  Stage 2 - RATS
     */
    if (rats) {
        typedef itk::BinaryBallStructuringElement<int, 3>                     TBall;
        typedef itk::BinaryErodeImageFilter<QI::VolumeI, QI::VolumeI, TBall>  TErode;
        typedef itk::BinaryDilateImageFilter<QI::VolumeI, QI::VolumeI, TBall> TDilate;
        float mask_volume  = std::numeric_limits<float>::infinity();
        float voxel_volume = QI::VoxelVolume(mask_image);
        QI::Log(verbose, "Voxel volume: {}", voxel_volume);
        int                  radius = 0;
        QI::VolumeI::Pointer mask_rats;
        while (mask_volume > rats.Get()) {
            radius++;
            TBall           ball;
            TBall::SizeType radii;
            radii.Fill(radius);
            ball.SetRadius(radii);
            ball.CreateStructuringElement();
            TErode::Pointer erode = TErode::New();
            erode->SetInput(mask_image);
            erode->SetForegroundValue(1);
            erode->SetBackgroundValue(0);
            erode->SetKernel(ball);
            erode->Update();
            std::vector<float> kept_sizes = QI::FindLabels(erode->GetOutput(), 0, 1, mask_rats);
            mask_volume                   = kept_sizes[0] * voxel_volume;
            auto dilate                   = TDilate::New();
            dilate->SetKernel(ball);
            dilate->SetInput(mask_rats);
            dilate->SetForegroundValue(1);
            dilate->SetBackgroundValue(0);
            dilate->Update();
            mask_rats = dilate->GetOutput();
            mask_rats->DisconnectPipeline();
            QI::Log(verbose, "Ran RATS iteration, radius = {} volume = {}", radius, mask_volume);
        }
        mask_image = mask_rats;
    }

    /*
     *  Stage 3 - Hole Filling
     */
    QI::VolumeI::Pointer finalMask = ITK_NULLPTR;
    if (fillh_radius) {
        QI::Log(verbose, "Filling holes");
        auto fillHoles = itk::VotingBinaryIterativeHoleFillingImageFilter<QI::VolumeI>::New();
        itk::VotingBinaryIterativeHoleFillingImageFilter<QI::VolumeI>::InputSizeType radius;
        radius.Fill(fillh_radius.Get());
        fillHoles->SetInput(mask_image);
        fillHoles->SetRadius(radius);
        fillHoles->SetMajorityThreshold(2); // Corresponds to (rad^3-1)/2 + 2 threshold
        fillHoles->SetBackgroundValue(0);
        fillHoles->SetForegroundValue(1);
        fillHoles->SetMaximumNumberOfIterations(3);
        fillHoles->Update();
        mask_image = fillHoles->GetOutput();
        mask_image->DisconnectPipeline();
    }

    QI::WriteImage(mask_image, out_path, verbose);
    QI::Log(verbose, "Finished.");
    return EXIT_SUCCESS;
}
CPieceProjectile::CPieceProjectile(const float3& pos,const float3& speed, LocalS3DO * piece, int flags,CUnit* owner,float radius)
: CProjectile(pos,speed,owner, true),
  flags(flags),
  dispList(piece?piece->displist:0),
	drawTrail(true),
	oldSmoke(pos),
	curCallback(0),
	spinPos(0),
	age(0)
{
	checkCol=false;
	if(owner){
		/* If we're an S3O unit, this is where ProjectileHandler
		   fetches our texture from. */
		s3domodel=owner->model;
		/* If we're part of an S3O unit, save this so we can
		   draw with the right teamcolour. */
		colorTeam=owner->team;
	}

	/* Don't store piece; owner may be a dying unit, so piece could be freed. */

	/* //if (piece->texturetype == 0) {
	   Great. LocalPiece doesn't carry the texture name.

	   HACK TODO PieceProjectile shouldn't need to know about
	   different model formats; push it into Rendering/UnitModels.

	   If this needs to change, also modify Sim/Units/COB/CobInstance.cpp::Explosion.

	   Nothing else wants to draw just one part without PieceInfo, so this
	   polymorphism can stay put for the moment.
	   */
	if (piece) {
		if (piece->original3do != NULL){
			piece3do = piece->original3do;
			pieces3o = NULL;
		} else if (piece->originals3o != NULL){
			piece3do = NULL;
			pieces3o = piece->originals3o;
		}
	} else {
		piece3do = NULL;
		pieces3o = NULL;
	}

	castShadow=true;

	if(pos.y-ground->GetApproximateHeight(pos.x,pos.z)>10)
		useAirLos=true;

	ENTER_MIXED;
	numCallback=SAFE_NEW int;
	*numCallback=0;
	oldSmokeDir=speed;
	oldSmokeDir.Normalize();
	float3 camDir=(pos-camera->pos).Normalize();
	if(camera->pos.distance(pos)+(1-fabs(camDir.dot(oldSmokeDir)))*3000 < 200)
		drawTrail=false;

	spinVec=gu->usRandVector();
	spinVec.Normalize();
	spinSpeed=gu->usRandFloat()*20;
	//logOutput.Print("New pp with %d", dispList);

	for(int a=0;a<8;++a){
		oldInfos[a]=SAFE_NEW OldInfo;
		oldInfos[a]->pos=pos;
		oldInfos[a]->size=gu->usRandFloat()*2+2;
	}
	ENTER_SYNCED;

	SetRadius(radius);
	drawRadius=32;
#ifdef TRACE_SYNC
	tracefile << "New pieceexplosive: ";
	tracefile << pos.x << " " << pos.y << " " << pos.z << " " << speed.x << " " << speed.y << " " << speed.z << "\n";
#endif
}
Example #3
0
void CFeature::Initialize(const float3& _pos, const FeatureDef* _def, short int _heading,
	int facing, int _team, int _allyteam, std::string fromUnit, const float3& speed, int _smokeTime)
{
	pos = _pos;
	def = _def;
	defName = def->myName;
	heading = _heading;
	buildFacing = facing;
	team = _team;
	allyteam = _allyteam;
	emitSmokeTime = _smokeTime;
	createdFromUnit = fromUnit;

	ChangeTeam(team); // maybe should not be here, but it prevents crashes caused by team = -1

	pos.CheckInBounds();

	health   = def->maxHealth;
	blocking = def->blocking;
	xsize    = ((facing & 1) == 0) ? def->xsize : def->zsize;
	zsize    = ((facing & 1) == 1) ? def->xsize : def->zsize;
	mass     = def->mass;
	noSelect = def->noSelect;

	if (def->drawType == DRAWTYPE_MODEL) {
		model = LoadModel(def);
		if (!model) {
			logOutput.Print("Features: Couldn't load model for " + defName);
			SetRadius(0.0f);
			midPos = pos;
		} else {
			height = model->height;
			SetRadius(model->radius);
			midPos = pos + model->relMidPos;
			collisionVolume = new CollisionVolume(def->collisionVolume, model->radius);
		}
	}
	else if (def->drawType >= DRAWTYPE_TREE) {
		SetRadius(TREE_RADIUS);
		midPos = pos + (UpVector * TREE_RADIUS);
		height = 2 * TREE_RADIUS;

		// LoadFeaturesFromMap() doesn't set a scale for trees
		collisionVolume = new CollisionVolume(def->collisionVolume, TREE_RADIUS);
	}
	else {
		// geothermal (no collision volume)
		SetRadius(0.0f);
		midPos = pos;
	}

	featureHandler->AddFeature(this);
	qf->AddFeature(this);

	CalculateTransform();

	if (blocking) {
		Block();
	}

	if (def->floating) {
		finalHeight = ground->GetHeight(pos.x, pos.z);
	} else {
		finalHeight = ground->GetHeight2(pos.x, pos.z);
	}

	if (def->drawType >= DRAWTYPE_TREE) {
		treeDrawer->AddTree(def->drawType - 1, pos, 1);
	}


	if (speed != ZeroVector) {
		deathSpeed = speed;
	}
}
Example #4
0
 /**
  * Set length property
  *
  * @param new_length Length (m) of line
  */
 void SetLength(const fixed new_length) {
   SetRadius(half(new_length));
 }
Example #5
0
Monster::Monster() {
    SetName("Unnamed monster");
    SetRadius(0.3);
	SetType(MONSTER);
}
Example #6
0
CPieceProjectile::CPieceProjectile(const float3& pos, const float3& speed, LocalModelPiece* piece, int f, CUnit* owner, float radius GML_PARG_C):
	CProjectile(pos, speed, owner, true, false, true GML_PARG_P),
	flags(f),
	dispList(piece? piece->displist: 0),
	omp(NULL),
	spinAngle(0.0f),
	alphaThreshold(0.1f),
	oldSmoke(pos),
	drawTrail(true),
	curCallback(0),
	age(0)
{
	checkCol = false;

	if (owner) {
		// choose a (synced) random tag-postfix string k from the
		// range given in UnitDef and stick it onto pieceTrailCEGTag
		// (assumes all possible "tag + k" CEG identifiers are valid)
		// if this piece does not override the FBI and wants a trail
		if ((flags & PF_NoCEGTrail) == 0) {
			const int size = owner->unitDef->pieceTrailCEGTag.size();
			const int range = owner->unitDef->pieceTrailCEGRange;
			const int num = gs->randInt() % range;
			const char* tag = owner->unitDef->pieceTrailCEGTag.c_str();

			if (size > 0) {
				char cegTag[1024];
				SNPRINTF(cegTag, sizeof(cegTag) - 1, "%s%d", tag, num);
				cegTag[1023] = 0;
				ceg.Load(explGenHandler, cegTag);
			} else {
				flags |= PF_NoCEGTrail;
			}
		}

		/* If we're an S3O unit, this is where ProjectileHandler
		   fetches our texture from. */
		s3domodel = owner->model;
		/* If we're part of an S3O unit, save this so we can
		   draw with the right teamcolour. */
		colorTeam = owner->team;
		// copy the owner's alphaThreshold value
		alphaThreshold = owner->alphaThreshold;
	}

	/* Don't store piece; owner may be a dying unit, so piece could be freed. */

	/* //if (piece->texturetype == 0) {
	   Great. LocalPiece doesn't carry the texture name.

	   HACK TODO PieceProjectile shouldn't need to know about
	   different model formats; push it into Rendering/UnitModels.

	   If this needs to change, also modify Sim/Units/COB/CobInstance.cpp::Explosion.

	   Nothing else wants to draw just one part without PieceInfo, so this
	   polymorphism can stay put for the moment.
	   */
	if (piece) {
		if (piece->type == MODELTYPE_3DO) {
			piece3do = (S3DOPiece*) piece->original;
			pieces3o = NULL;
		} else if (piece->type == MODELTYPE_S3O) {
			piece3do = NULL;
			pieces3o = (SS3OPiece*) piece->original;
		}
		omp = piece->original;
	} else {
		piece3do = NULL;
		pieces3o = NULL;
	}

	castShadow = true;

	if (pos.y - ground->GetApproximateHeight(pos.x, pos.z) > 10) {
		useAirLos = true;
	}

	numCallback = new int;
	*numCallback = 0;
	oldSmokeDir = speed;
	oldSmokeDir.Normalize();
	float3 camDir = (pos-camera->pos).Normalize();

	if (camera->pos.distance(pos) + (1 - fabs(camDir.dot(oldSmokeDir))) * 3000 < 200) {
		drawTrail = false;
	}

	//! neither spinVec nor spinSpeed technically
	//! needs to be synced, but since instances of
	//! this class are themselves synced and have
	//! LuaSynced{Ctrl, Read} exposure we treat
	//! them that way for consistency
	spinVec = gs->randVector();
	spinVec.Normalize();
	spinSpeed = gs->randFloat() * 20;

	for (int a = 0; a < 8; ++a) {
		oldInfos[a] = new OldInfo;
		oldInfos[a]->pos = pos;
		oldInfos[a]->size = gu->usRandFloat() * 2 + 2;
	}

	SetRadius(radius);
	drawRadius = 32;

#ifdef TRACE_SYNC
	tracefile << "New CPieceProjectile: ";
	tracefile << pos.x << " " << pos.y << " " << pos.z << " " << speed.x << " " << speed.y << " " << speed.z << "\n";
#endif

	ph->AddProjectile(this);
}
Example #7
0
CMissileProjectile::CMissileProjectile(
		const float3& pos, const float3& speed,
		CUnit* owner,
		float areaOfEffect, float maxSpeed, int ttl,
		CUnit* target, const WeaponDef* weaponDef,
		float3 targetPos)
	: CWeaponProjectile(pos, speed, owner, target, targetPos, weaponDef, NULL, ttl)
	, maxSpeed(maxSpeed)
	, areaOfEffect(areaOfEffect)
	, age(0)
	, oldSmoke(pos)
	, target(target)
	, decoyTarget(NULL)
	, drawTrail(true)
	, numParts(0)
	, targPos(targetPos)
	, isWobbling(weaponDef? (weaponDef->wobble > 0): false)
	, wobbleDir(ZeroVector)
	, wobbleTime(1)
	, wobbleDif(ZeroVector)
	, isDancing(weaponDef? (weaponDef->dance > 0): false)
	, danceTime(1)
	, danceMove(ZeroVector)
	, danceCenter(ZeroVector)
	, extraHeightTime(0)
{
	projectileType = WEAPON_MISSILE_PROJECTILE;
	curSpeed = speed.Length();
	dir = speed / curSpeed;
	oldDir = dir;

	if (target) {
		AddDeathDependence(target);
	}

	SetRadius(0.0f);

	if (weaponDef) {
		model = LoadModel(weaponDef);
		if (model) {
			SetRadius(model->radius);
		}
	}

	drawRadius = radius + maxSpeed * 8;

	float3 camDir = (pos - camera->pos).Normalize();
	if ((camera->pos.distance(pos) * 0.2f + (1 - fabs(camDir.dot(dir))) * 3000) < 200) {
		drawTrail = false;
	}

	castShadow = true;

#ifdef TRACE_SYNC
	tracefile << "New missile: ";
	tracefile << pos.x << " " << pos.y << " " << pos.z << " " << speed.x << " " << speed.y << " " << speed.z << "\n";
#endif

	if (target) {
		target->IncomingMissile(this);
	}

	if ((weaponDef) && (weaponDef->trajectoryHeight > 0)) {
		float dist = pos.distance(targPos);
		extraHeight = (dist * weaponDef->trajectoryHeight);

		if (dist < maxSpeed) {
			dist = maxSpeed;
		}

		extraHeightTime = (int)(dist / maxSpeed);
		extraHeightDecay = extraHeight / extraHeightTime;
	}


	cegID = gCEG->Load(explGenHandler, cegTag);
}
Example #8
0
/*
================
idLight::Event_SetRadius
================
*/
void idLight::Event_SetRadius( float radius ) {
	SetRadius( radius );
}
Example #9
0
void CFeature::Initialize(const float3& _pos, const FeatureDef* _def, short int _heading,
	int facing, int _team, std::string fromUnit, const float3& speed)
{
	pos = _pos;
	def = _def;
	defName = def->myName;
	heading = _heading;
	buildFacing = facing;
	team = _team;
	createdFromUnit = fromUnit;

	ChangeTeam(team);

	pos.CheckInBounds();

	health   = def->maxHealth;
	blocking = def->blocking;
	xsize    = def->xsize;
	ysize    = def->ysize;
	mass     = def->mass;
	noSelect = def->noSelect;

	if (def->drawType == DRAWTYPE_3DO) {
		model = def->LoadModel(team);
		height = model->height;
		SetRadius(model->radius);
		midPos = pos + model->relMidPos;

		// copy the FeatureDef volume archetype data
		collisionVolume = SAFE_NEW CollisionVolume(def->collisionVolume);

		// CFeatureHandler left this volume's axis-scales uninitialized
		// (ie. no "collisionVolumeScales" tag was defined in FeatureDef)
		if (collisionVolume->GetScale(COLVOL_AXIS_X) <= 1.0f &&
			collisionVolume->GetScale(COLVOL_AXIS_Y) <= 1.0f &&
			collisionVolume->GetScale(COLVOL_AXIS_Z) <= 1.0f) {
			collisionVolume->SetDefaultScale(model->radius);
		}
	}
	else if (def->drawType == DRAWTYPE_TREE) {
		SetRadius(TREE_RADIUS);
		midPos = pos + (UpVector * TREE_RADIUS);
		height = 2 * TREE_RADIUS;

		// copy the FeatureDef volume archetype data
		collisionVolume = SAFE_NEW CollisionVolume(def->collisionVolume);
		collisionVolume->SetDefaultScale(TREE_RADIUS);
	}
	else {
		// geothermal (no collision volume)
		SetRadius(0.0f);
		midPos = pos;
	}

	featureHandler->AddFeature(this);
	qf->AddFeature(this);

	CalculateTransform();

	if (blocking) {
		Block();
	}

	if (def->floating) {
		finalHeight = ground->GetHeight(pos.x, pos.z);
	} else {
		finalHeight = ground->GetHeight2(pos.x, pos.z);
	}

	if (def->drawType == DRAWTYPE_TREE) {
		treeDrawer->AddTree(def->modelType, pos, 1);
	}


	if (speed != ZeroVector) {
		deathSpeed = speed;
	}
}
Example #10
0
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void CNPC_Blob::InputSetRadius( inputdata_t &inputdata )
{
	float flNewRadius = inputdata.value.Float();

	SetRadius( flNewRadius );
}
Example #11
0
CPieceProjectile::CPieceProjectile(const float3& pos, const float3& speed, LocalModelPiece* lmp, int f, CUnit* owner, float radius):
	CProjectile(pos, speed, owner, true, false, true),
	flags(f),
	dispList(lmp? lmp->dispListID: 0),
	omp(NULL),
	spinAngle(0.0f),
	alphaThreshold(0.1f),
	oldSmoke(pos),
	drawTrail(true),
	curCallback(0),
	age(0)
{
	checkCol = false;

	if (owner) {
		if ((flags & PF_NoCEGTrail) == 0) {
			const std::vector<std::string>& pieceCEGs = owner->unitDef->pieceCEGTags;
			const std::string& cegTag = !pieceCEGs.empty()? pieceCEGs[gs->randInt() % pieceCEGs.size()]: "";

			if (!cegTag.empty()) {
				cegID = gCEG->Load(explGenHandler, cegTag.c_str());
			} else {
				flags |= PF_NoCEGTrail;
			}
		}

		/* If we're an S3O unit, this is where ProjectileHandler
		   fetches our texture from. */
		model = owner->model;
		/* If we're part of an S3O unit, save this so we can
		   draw with the right teamcolour. */
		colorTeam = owner->team;
		// copy the owner's alphaThreshold value
		alphaThreshold = owner->alphaThreshold;
	}

	if (lmp) {
		omp = lmp->original;
	} else {
		omp = NULL;
	}

	castShadow = true;

	if (pos.y - ground->GetApproximateHeight(pos.x, pos.z) > 10) {
		useAirLos = true;
	}

	numCallback = new int;
	*numCallback = 0;
	oldSmokeDir = speed;
	oldSmokeDir.Normalize();
	float3 camDir = (pos-camera->pos).Normalize();

	if (camera->pos.distance(pos) + (1 - fabs(camDir.dot(oldSmokeDir))) * 3000 < 200) {
		drawTrail = false;
	}

	//! neither spinVec nor spinSpeed technically
	//! needs to be synced, but since instances of
	//! this class are themselves synced and have
	//! LuaSynced{Ctrl, Read} exposure we treat
	//! them that way for consistency
	spinVec = gs->randVector();
	spinVec.Normalize();
	spinSpeed = gs->randFloat() * 20;

	for (int a = 0; a < 8; ++a) {
		oldInfos[a] = new OldInfo;
		oldInfos[a]->pos = pos;
		oldInfos[a]->size = gu->usRandFloat() * 2 + 2;
	}

	SetRadius(radius);
	drawRadius = 32;

#ifdef TRACE_SYNC
	tracefile << "New CPieceProjectile: ";
	tracefile << pos.x << " " << pos.y << " " << pos.z << " " << speed.x << " " << speed.y << " " << speed.z << "\n";
#endif

	ph->AddProjectile(this);
}
CFireBallProjectile::CFireBallProjectile(const float3& pos,const float3& speed, CUnit* owner, CUnit *target, const float3 &targetPos, WeaponDef *weaponDef)
	: CWeaponProjectile(pos,speed, owner, target, targetPos, weaponDef,damages,0)
{
	SetRadius(10.0f);
	drawRadius=15;
}
bool Location::SetRadius(iDataConnection* db, float radius)
{
    SetRadius(radius);

    return CreateUpdate(db);
}
Example #14
0
void CStar::Spawn()
{
	// 695500km, the radius of the sun
	SetRadius(CScalableFloat(695.5f, SCALE_MEGAMETER));
}
Example #15
0
	void ApplyLinearity(f64 linearity)
	{
		f64 radius = Linearity(r, linearity);
		SetRadius(radius);
	}