[Insight-users] to divide images
Zachary Pincus
zpincus@stanford.edu
Mon May 10 21:29:15 EDT 2004
David,
There are several problems here: One stems from the c++
pass-by-reference semantics. The others stem from not reading the
header file carefully.
(1) REFERENCE SEMANTICS
I suggest that you study a bit about c++ references -- they are
wonderful to use, and used in ITK quite a bit, but they can be a bit
confusing. (Here's a bit of information:
http://www.parashift.com/c++-faq-lite/references.html )
Basically, the idea with a reference is that you have a normal
variable, and when you tell the compiler to treat it as a reference,
the compiler does all the pointer stuff for you.
Example of the c-style way:
void ModifiesInput(int *a) {
*a = 1;
}
main() {
int a;
ModifiesInput(&a);
printf("%d", a); /* Prints '1' */
}
And the same with c++ references:
void ModifiesInput(int &a) {
a = 1;
}
main() {
int a;
ModifiesInput(a);
printf("%d", a); /* Prints '1' */
}
As you can see, doing things with references is much more natural (in
Java, for example, everything is a reference). Basically, the compiler
takes care of all of the pointer business. So you'll need to clean up
the extraneous & symbols in your code.
(2) Here's the function signature for the code I sent:
template<class TImage> void GetMasks(typename TImage::Pointer maskImage,
std::vector<typename TImage::Pointer > &submasks, bool fullyConnected
= false);
First, notice that the function is templated over image type, so you
call it as follows:
CellExplorer::CellExtractor::GetMasks<ImageType>(...);
(feel free to remove the namespace stuff from the code)
Next, note that the first parameter is an Image::Pointer object. In
your code, you pass in an ImageFileReader<...> object. You need to pass
the OUTPUT of that file reader, which is an Image::Pointer.
(3) Finally, note that the following line isn't quite right:
> submascara->SetInput( submascara->GetOutput() );
I assume that what you want to do here is to pass the submascara file
writer the output of the iterator. So that would be:
submascara->SetInput( *it );
Also, note that you will overwrite the image file again and again with
each loop of the iterator. You need to change the file name so that
it's unique each time. I like to use the stringstream class (from the
standard library) because it's easy to make file names: stringstream
name; name << "Base" << i << ".jpg"; or whatever. you then use
name.str(""); to clear the stringstream buffer, and name.str().c_str()
to get a c-style string to pass to the file writer.
Zach
On May 10, 2004, at 10:29 AM, David Llanos wrote:
> Hi Zach,
>
> I have been trying to use your method GetMasks in all the ways, but I
> am not
> able to get it.
> Please, I request you that you help me to correct the code that I
> attach you
> next, or that you send me an example of as using your bookstore and the
> method:
> -----------------------------------------------------------------------
> -----
> ----
> #include "itkImageFileReader.h"
> #include "itkImageFileWriter.h"
> #include "itkImage.h"
> #include "itkConnectedComponentImageFilter.h"
> #include "itkRelabelComponentImageFilter.h"
> #include "itkImageMomentsCalculator.h"
>
> #include "GetConnectedMasks.h"
>
> int main ( int argc, char * argv[] )
> {
> typedef unsigned char PixelType;
> const unsigned int dimension = 2;
> typedef itk::Image<PixelType,dimension> ImageType;
> typedef itk::ImageFileReader<ImageType> itkReaderType;
> typedef itk::ImageFileWriter<ImageType> itkWriterType;
> typedef itk::ConnectedComponentImageFilter<ImageType,ImageType>
> itkConnectedComponentFilterType;
> typedef itk::RelabelComponentImageFilter<ImageType,ImageType>
> itkRelabelComponentFilterType;
>
> typedef std::vector<ImageType> &objetos;
>
> itkReaderType::Pointer reader = itkReaderType::New();
> reader->SetFileName( argv[1] );
> reader->Update();
>
> CellExplorer::CellExtractor::GetMasks(reader, &objetos, TRUE);
>
> std::vector<unsigned long>::const_iterator it;
> int i;
> for(i = 0, it = objetos.begin(); it != objetos.end(); ++i, ++it) {
> itkWriterType::Pointer submascara = itkWriterType::New();
> submascara->SetInput( submascara->GetOutput() );
> submascara->SetFileName( "submascara.png" );
> submascara->Write();
> }
> return 0;
> }
> -----------------------------------------------------------------------
> -----
> -------------------
> E:\label\etiquetar.cxx(95) : error C2275: 'objetos' : illegal use of
> this
> type as an expression
> E:\label\etiquetar.cxx(36) : see declaration of 'objetos'
> E:\label\etiquetar.cxx(100) : error C2228: left of '.begin' must have
> class/struct/union type
> E:\label\etiquetar.cxx(100) : error C2228: left of '.end' must have
> class/struct/union type
> E:\label\etiquetar.cxx(103) : error C2661: 'GetOutput' : no overloaded
> function takes 0 parameters
> Error executing cl.exe.
>
> etiquetar.exe - 4 error(s), 0 warning(s)
> -----------------------------------------------------------------------
> -----
> ---------------------
>
> Also, I attach you the image that I am trying to divide and the
> bookstores
> that you sent me, for if somebody also wants to take them a look. I am
> learning studying them a lot.
>
>
> ----- Original Message -----
> From: "Zachary Pincus" <zpincus@stanford.edu>
> To: "David Llanos" <gva02@elai.upm.es>
> Sent: Wednesday, May 05, 2004 8:05 PM
> Subject: Re: [Insight-users] to divide images
>
>
>> Here again is the source for my simple masked region extractor.
>>
>> The header has just one function: GetMasks. You call this function,
>> passing in:
>> (1) A mask image where the foreground is value 1 and the background is
>> value 0
>> (2) A vector that the "submasks" will be placed in. Each submask is a
>> new image of the same type. The regions set on the submask image tell
>> you where those images came from in the original.
>> (3) Optionally, a boolean value that tells the function whether to
>> look
>> for "face" or "fully" connected blobs. (face = 4-connected, fully =
>> 8-connected, in 2D.) If you are looking for wide blobs that cover some
>> area, the default of "false" is fine. If you are trying to extract
>> single-pixel wide lines, you should use fully connected mode. (That
>> is,
>> send "true").
>>
>> Zach
> <binar.png><GetConnectedMasks.h><GetConnectedMasks.txx>
More information about the Insight-users
mailing list