AddObserver on DataObject

Hi,

I want to add an observer to an image to know when it is modified. I tried the code below based on this example.

#include <itkImage.h>
#include <itkRandomImageSource.h>
#include <itkCommand.h>

class MyCommand : public itk::Command
{
public:
	itkNewMacro(MyCommand);

	void
		Execute(itk::Object * caller, const itk::EventObject & event) override
	{
		Execute((const itk::Object *)caller, event);
	}

	void
		Execute(const itk::Object * caller, const itk::EventObject & event) override
	{
		std::cout << "Event happened" << std::endl;
	}
};


int main(int, char *[])
{
	using ImageType = itk::Image<unsigned char, 3>;
	ImageType::Pointer image = ImageType::New();

	MyCommand::Pointer myCommand = MyCommand::New();
	image->AddObserver(itk::ModifiedEvent(), myCommand);

	ImageType::IndexType start;
	start.Fill(0);

	ImageType::SizeType size;
	size.Fill(100);

	ImageType::RegionType region;
	region.SetSize(size);
	region.SetIndex(start);

	image->SetRegions(region);
	image->Allocate();

	//using RandomImageSourceType = itk::RandomImageSource<ImageType>;
	//RandomImageSourceType::Pointer randomImageSource = RandomImageSourceType::New();
	//randomImageSource->SetNumberOfWorkUnits(1);
	//randomImageSource->SetSize(size);
	//randomImageSource->Update();
	//image = randomImageSource->GetOutput();

	return EXIT_SUCCESS;
}

The output of this code prints twice Event happened but I don’t understand why. And if I uncomment the RandomImageSource part I have the same output as before.

I think the problem comes from the fact that it is not the good event I am observing but when does this event triggers then? Also, I found standard EventObjects in the itkEventObject.h file and from what I understand, the events are declared using the itkEventMacroDeclaration but who is invoking those events (for example who is invoking the ModifiedEvent).

Thank you for your help!
Côme

Hello,

I would recommend building ITK and your code in debug mode. Then launch your debugger and set a break point at the Execute method of your command. When the code is executed it’ll stop at the command’s Execute and you will be able to see the call stack in the debug to answer your questions.

2 Likes

I think these two calls invoke modified event. randomImageSource->Update(); does not need to update or otherwise modify the image because image is already up to date.

1 Like

Yes, I found the functions that invoke the event using the debugger (thanks @blowekamp). It comes from the itk::ImageBase when SetBufferedRegion and SetLargestPossibleRegion are called (when using image->SetRegion(region)) which then run the Modified method that invokes the envent ModifiedEvent.

That helped me a lot, thank you very much for your answers!!

1 Like