#include <processor.h>
Inheritance diagram for EMAN::AutoMask3D2Processor:


Public Member Functions | |
| virtual void | process_inplace (EMData *image) |
| To process an image in-place. | |
| virtual string | get_name () const |
| Get the processor's name. | |
| virtual string | get_desc () const |
| Get the descrition of this specific processor. | |
| virtual TypeDict | get_param_types () const |
| Get processor parameter information in a dictionary. | |
Static Public Member Functions | |
| Processor * | NEW () |
Static Public Attributes | |
| const string | NAME = "mask.auto3d" |
| radius | Pixel radius of a ball which is used to seed the flood filling operation | |
| threshold | An isosurface threshold that suitably encases the mass | |
| nshells | The number of dilation operations | |
| nshellsgauss | number of Gaussian pixels to expand, following the dilation operations If true the result of the operation will produce the mask, not the masked volume |
Definition at line 4980 of file processor.h.
|
|
Get the descrition of this specific processor. This function must be overwritten by a subclass.
Implements EMAN::Processor. Definition at line 4995 of file processor.h. 04996 {
04997 return "Tries to mask out only interesting density using something akin to a flood file approach.";
04998 }
|
|
|
Get the processor's name. Each processor is identified by a unique name.
Implements EMAN::Processor. Definition at line 4985 of file processor.h. 04986 {
04987 return NAME;
04988 }
|
|
|
Get processor parameter information in a dictionary. Each parameter has one record in the dictionary. Each record contains its name, data-type, and description.
Reimplemented from EMAN::Processor. Definition at line 5000 of file processor.h. References EMAN::TypeDict::put(). 05001 {
05002 TypeDict d;
05003 d.put("radius", EMObject::INT,"Pixel radius of a ball which is used to seed the flood filling operation. ");
05004 d.put("nmaxseed",EMObject::INT,"Use the n highest valued pixels in the map as a seed. Alternative to radius. Useful for viruses.");
05005 d.put("threshold", EMObject::FLOAT, "An isosurface threshold that suitably encases the mass.");
05006 d.put("sigma", EMObject::FLOAT, "Alternative to threshold based on mean + x*sigma");
05007 d.put("nshells", EMObject::INT, "The number of dilation operations");
05008 d.put("nshellsgauss", EMObject::INT, "number of Gaussian pixels to expand, following the dilation operations");
05009 d.put("return_mask", EMObject::BOOL, "If true the result of the operation will produce the mask, not the masked volume.");
05010 d.put("verbose", EMObject::INT, "How verbose to be (stdout)");
05011 return d;
05012 }
|
|
|
Definition at line 4990 of file processor.h. 04991 {
04992 return new AutoMask3D2Processor();
04993 }
|
|
|
To process an image in-place. For those processors which can only be processed out-of-place, override this function to just print out some error message to remind user call the out-of-place version.
Implements EMAN::Processor. Definition at line 6439 of file processor.cpp. References abs, EMAN::EMData::calc_n_highest_locations(), EMAN::EMData::get_attr(), EMAN::EMData::get_data(), EMAN::EMData::get_ndim(), EMAN::EMData::get_size(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), EMAN::EMData::get_zsize(), EMAN::Dict::has_key(), ImageDimensionException, LOGWARN, EMAN::EMData::mult(), nx, ny, EMAN::EMData::process_inplace(), EMAN::Dict::set_default(), EMAN::EMData::set_size(), EMAN::EMData::set_value_at(), and EMAN::EMData::update(). 06440 {
06441 if (!image) {
06442 LOGWARN("NULL Image");
06443 return;
06444 }
06445
06446 if (image->get_ndim() != 3) {
06447 throw ImageDimensionException("This processor was only ever designed to work on 3D images.");
06448 }
06449
06450 /*
06451 The mask writing functionality was removed to comply with an EMAN2 policy which dictates that file io is not allowed from within a processor
06452 To get around this just use the return_mask parameter.
06453 string mask_output = params.set_default("write_mask", "");
06454 if ( mask_output != "") {
06455 if (Util::is_file_exist(mask_output) ) throw InvalidParameterException("The mask output file name already exists. Please remove it if you don't need it.");
06456 if (!EMUtil::is_valid_filename(mask_output)) throw InvalidParameterException("The mask output file name type is invalid or unrecognized");
06457 }
06458 */
06459
06460 int radius=0;
06461 if (params.has_key("radius")) {
06462 radius = params["radius"];
06463 }
06464 int nmaxseed=0;
06465 if (params.has_key("nmaxseed")) {
06466 nmaxseed = params["nmaxseed"];
06467 }
06468
06469 float threshold=0.0;
06470 if (params.has_key("sigma")) threshold=(float)(image->get_attr("mean"))+(float)(image->get_attr("sigma"))*(float)params["sigma"];
06471 else threshold=params["threshold"];
06472
06473 int nshells = params["nshells"];
06474 int nshellsgauss = params["nshellsgauss"];
06475 int verbose=params.set_default("verbose",0);
06476
06477 int nx = image->get_xsize();
06478 int ny = image->get_ysize();
06479 int nz = image->get_zsize();
06480 int nxy=nx*ny;
06481
06482 EMData *amask = new EMData();
06483 amask->set_size(nx, ny, nz);
06484
06485 float *dat = image->get_data();
06486 float *dat2 = amask->get_data();
06487 int i,j,k;
06488 size_t l = 0;
06489
06490 // Seeds with the highest valued pixels
06491 if (nmaxseed>0) {
06492 vector<Pixel> maxs=image->calc_n_highest_locations(nmaxseed);
06493
06494 for (vector<Pixel>::iterator i=maxs.begin(); i<maxs.end(); i++) {
06495 amask->set_value_at((*i).x,(*i).y,(*i).z,1.0);
06496 if (verbose) printf("Seed at %d,%d,%d (%1.3f)\n",(*i).x,(*i).y,(*i).z,(*i).value);
06497 }
06498 }
06499
06500 // Seeds with a sphere
06501 if (radius>0) {
06502 // start with an initial sphere
06503 for (k = -nz / 2; k < nz / 2; ++k) {
06504 for (j = -ny / 2; j < ny / 2; ++j) {
06505 for (i = -nx / 2; i < nx / 2; ++i,++l) {
06506 if (abs(k) > radius || abs(j) > radius || abs(i) > radius) continue;
06507 if ( (k * k + j * j + i * i) > (radius*radius) || dat[l] < threshold) continue;
06508 dat2[l] = 1.0f;
06509 }
06510 }
06511 }
06512 }
06513
06514
06515 // iteratively 'flood fills' the map... recursion would be better
06516 int done=0;
06517 int iter=0;
06518 while (!done) {
06519 iter++;
06520 done=1;
06521 if (verbose && iter%10==0) printf("%d iterations\n",iter);
06522 for (k=1; k<nz-1; ++k) {
06523 for (j=1; j<ny-1; ++j) {
06524 for (i=1; i<nx-1; ++i) {
06525 l=i+j*nx+k*nx*ny;
06526 if (dat2[l]) continue;
06527 if (dat[l]>threshold && (dat2[l-1]||dat2[l+1]||dat2[l+nx]||dat2[l-nx]||dat2[l-nxy]||dat2[l+nxy])) {
06528 dat2[l]=1.0;
06529 done=0;
06530 }
06531 }
06532 }
06533 }
06534 }
06535
06536 amask->update();
06537
06538 if (verbose) printf("extending mask\n");
06539 amask->process_inplace("mask.addshells.gauss", Dict("val1", nshells, "val2", nshellsgauss));
06540
06541 bool return_mask = params.set_default("return_mask",false);
06542 if (return_mask) {
06543 // Yes there is probably a much more efficient way of getting the mask itself, but I am only providing a stop gap at the moment.
06544 memcpy(dat,dat2,image->get_size()*sizeof(float));
06545 } else {
06546 image->mult(*amask);
06547 }
06548
06549 // EMAN2 policy is not to allow file io from with a processor
06550 //if (mask_output != "") {
06551 // amask->write_image(mask_output);
06552 //}
06553
06554
06555 delete amask;
06556 }
|
|
|
Definition at line 174 of file processor.cpp. |
1.3.9.1