[ITK] Error in itk::BinaryImageToLabelMapFilter for images with 1 row and N columns

Bradley Lowekamp blowekamp at mail.nih.gov
Thu Jul 31 11:53:13 EDT 2014


Awesome! Thanks for taking the effort to contribute!

That is very interesting that the problem relates to the number of threads!

You will need push access to Gerrit, so that you can push your patch to gerrit for review.

The next step is to create a topic, and work locally to add you code as an ITK test. This will involve modifying the CMakeLists[1] file and creating a new cxx say called itkBinaryIMageToLabelMapFilterTest2.cxx something like [2].

Hope that get you started,
Brad

[1] https://github.com/InsightSoftwareConsortium/ITK/blob/master/Modules/Filtering/LabelMap/test/CMakeLists.txt
[2] https://github.com/InsightSoftwareConsortium/ITK/blob/master/Modules/Filtering/LabelMap/test/itkBinaryImageToLabelMapFilterTest.cxx


On Jul 31, 2014, at 11:40 AM, Girish Mallya Udupi <indianzeppelin at gmail.com> wrote:

> 1) Thanks for this. Will go through it.
> 
> 2) If I am not wrong, the number of threads used by default is the number of CPU cores in my machine? If so, it would be 4 in my case. As expected, setting the number of threads to 1 fixes the issue, while the error is thrown for values other than 1.
> 
> 3) Sure. I went through that page and have performed the initial setup, except the git push access, which I suppose I wouldn't need?
> 
> 
> 
> On Thu, Jul 31, 2014 at 3:50 PM, Bradley Lowekamp <blowekamp at mail.nih.gov> wrote:
> OK,
> 
> That is great progress in narrowing down the bug.
> 
> 1) Here is a little snipped where two images are manually created:
> https://github.com/InsightSoftwareConsortium/ITK/blob/master/Modules/Filtering/ImageIntensity/test/itkMaskImageFilterTest.cxx#L45-L91
> 
> 2) How many threads are you using for this algorithm?  The BinaryImageToLabelMapFilter has a "SetNumberOfThreads" method inherited from the ProcessObject class. Try setting this value to 1, and see if the issue is there... try other values too.
> http://www.itk.org/Doxygen/html/classitk_1_1ProcessObject.html#ae5ccbe3a8c5687b4a82d3638b9e49409
> 
> 3) Are you interested in learning how to use git to contribute this test to facilitate fixing this bug?
> http://www.itk.org/Wiki/ITK/Git/Develop
> 
> Brad
> 
> 
> On Jul 31, 2014, at 10:34 AM, Girish Mallya Udupi <indianzeppelin at gmail.com> wrote:
> 
>> Thanks for your reply, Brad!
>> 
>> 1) No, the OtsuThreshold isn't required. It's there just to create a binary input image which is required by BinaryImageToLabelMapFilter. I did as you said (writing out the resulting binary image, loading it and then providing it as input), and the error is still there.
>> 
>> 2) Yes, it fails with all images which are 1 x N (rows x cols), except when N = 1 (i.e., it works fine with 1 x 1 images). I am not sure how to create an image procedurally, but I created a simple 1 x 10 image in MATLAB and saved it as bmp, jpg and tiff. The test case produces the error for all three.
>> 
>> Also, there is no error if the image is N x 1. 
>> 
>> Basically, the following shorter piece of code can reproduce the error.
>> 
>> // start code
>> 
>> typedef itk::Image< unsigned char, 2 >  ScalarImageType;
>> typedef itk::ImageFileReader< ScalarImageType > ReaderType;
>> typedef itk::BinaryImageToLabelMapFilter< ScalarImageType > BinaryImageToLabelMapFilterType;
>> 
>> ReaderType::Pointer reader = ReaderType::New();
>> reader->SetFileName("test_bw.jpg");
>> try {
>>     reader->Update();
>> }
>> catch ( itk::ExceptionObject & err ) {
>>     std::cerr << "ExceptionObject caught !" << std::endl;
>>     std::cerr << err << std::endl;
>> }
>> 
>> BinaryImageToLabelMapFilterType::Pointer binarytoLabelmapFilter = BinaryImageToLabelMapFilterType::New();
>> binarytoLabelmapFilter->SetInput(reader->GetOutput());
>> try {
>>     binarytoLabelmapFilter->Update();
>> }
>> catch ( itk::ExceptionObject & err ) {
>>     std::cerr << "ExceptionObject caught !" << std::endl;
>>     std::cerr << err << std::endl;
>> }
>> 
>> // end code
>> 
>> Let me know if there is anything else I could try.
>> 
>> 
>> On Thu, Jul 31, 2014 at 2:34 PM, Bradley Lowekamp <blowekamp at mail.nih.gov> wrote:
>> Hello,
>> 
>> Thank you for reporting this. This looks like it may be a bug inside ITK. However it would be good to make this a little more reproducible to aid in debugging.
>> 
>> 1) Is the OtsuThreshold required? If you write out the results of the otsu to a file, then just loaded them in this test case will it still have the error?
>> 2) I don't have your data which causes this failure. How big is it? Does it fail with all data this shape? Could you change this test case to have a hard coded image? One that is procedurally created? 
>> 
>> Thanks again for reporting this issue.
>> 
>> Brad
>> 
>> 
>> 
>> 
>> 
>> 
>> 
>> On Jul 31, 2014, at 5:35 AM, Girish Mallya Udupi <indianzeppelin at gmail.com> wrote:
>> 
>>> Hi all,
>>> 
>>> I am new to both C++ and ITK, and have been fiddling with test code for learning purposes.
>>> 
>>> The following is a simple piece of code to read in a grayscale image, threshold it to get a binary image, and get a label map out of it. I use MS VS2010 and ITK v4.5.1.
>>> 
>>> 
>>> typedef itk::Image< unsigned char, 2 >  ScalarImageType;
>>> 
>>> typedef itk::ImageFileWriter< ScalarImageType > WriterType;
>>> typedef itk::ImageFileReader< ScalarImageType > ReaderType;
>>> 
>>> typedef itk::OtsuThresholdImageFilter< ScalarImageType, ScalarImageType > OtsuThresholdImageFilterType;
>>> typedef itk::BinaryImageToLabelMapFilter< ScalarImageType > BinaryImageToLabelMapFilterType;
>>> 
>>> // read a grayscale image
>>> ReaderType::Pointer reader = ReaderType::New();
>>> reader->SetFileName("test_grey.jpg");
>>> try
>>> {
>>>     reader->Update();
>>> }
>>> catch( itk::ExceptionObject &err )
>>> {
>>>     std::cerr << "ExceptionObject caught !" << std::endl;
>>>     std::cerr << err << std::endl;
>>>     return(FALSE);
>>> }
>>> 
>>> // threshold the grayscale image
>>> OtsuThresholdImageFilterType::Pointer otsuThresImgFilter = OtsuThresholdImageFilterType::New();
>>> otsuThresImgFilter->SetInput(reader->GetOutput());
>>> otsuThresImgFilter->SetInsideValue(255);
>>> otsuThresImgFilter->SetOutsideValue(0);
>>> try
>>> {
>>>     otsuThresImgFilter->Update();
>>> }
>>> catch( itk::ExceptionObject &err )
>>> {
>>>     std::cerr << "ExceptionObject caught !" << std::endl;
>>>     std::cerr << err << std::endl;
>>>     return(FALSE);
>>> }
>>> 
>>> // get a label map from the binary image
>>> BinaryImageToLabelMapFilterType::Pointer binarytoLabelmapFilter = BinaryImageToLabelMapFilterType::New();
>>> binarytoLabelmapFilter->SetInput(otsuThresImgFilter->GetOutput());
>>> try
>>> {
>>>     binarytoLabelmapFilter->Update();
>>> }
>>> catch( itk::ExceptionObject &err )
>>> {
>>>     std::cerr << "ExceptionObject caught !" << std::endl;
>>>     std::cerr << err << std::endl;
>>>     return(FALSE);
>>> }
>>> 
>>> This works fine for all images, except those which have only 1 row and N columns (interestingly, 1 x 1 images go through fine).
>>> 
>>> So, for 1 x N images, the program crashes in release mode. In debug mode, I get the "vector subscript out of range" error. Stepping through the code, I found that the crash happens on the line binarytoLabelmapFilter->Update(); of my code.
>>> 
>>> Call stack:
>>> 
>>> 
>>> msvcr100d.dll!_CrtDbgBreak()  Line 85   C
>>> msvcr100d.dll!_VCrtDbgReportW(int nRptType, const wchar_t * szFile, int nLine, const wchar_t * szModule, const wchar_t * szFormat, char * arglist)  Line 502    C
>>> msvcr100d.dll!_CrtDbgReportWV(int nRptType, const wchar_t * szFile, int nLine, const wchar_t * szModule, const wchar_t * szFormat, char * arglist)  Line 241 + 0x1d bytes   C++
>>> msvcr100d.dll!_CrtDbgReportW(int nRptType, const wchar_t * szFile, int nLine, const wchar_t * szModule, const wchar_t * szFormat, ...)  Line 258 + 0x1d bytes   C++
>>> msvcp100d.dll!std::_Debug_message(const wchar_t * message, const wchar_t * file, unsigned int line)  Line 13 + 0x16 bytes   C++
>>> HelloWorld.exe!std::vector<std::vector<itk::BinaryImageToLabelMapFilter<itk::Image<unsigned char,2>,itk::LabelMap<itk::LabelObject<unsigned long,2> > >::runLength,std::allocator<itk::BinaryImageToLabelMapFilter<itk::Image<unsigned char,2>,itk::LabelMap<itk::LabelObject<unsigned long,2> > >::runLength> >,std::allocator<std::vector<itk::BinaryImageToLabelMapFilter<itk::Image<unsigned char,2>,itk::LabelMap<itk::LabelObject<unsigned long,2> > >::runLength,std::allocator<itk::BinaryImageToLabelMapFilter<itk::Image<unsigned char,2>,itk::LabelMap<itk::LabelObject<unsigned long,2> > >::runLength> > > >::operator[](unsigned int _Pos)  Line 932 + 0x17 bytes C++
>>> HelloWorld.exe!itk::BinaryImageToLabelMapFilter<itk::Image<unsigned char,2>,itk::LabelMap<itk::LabelObject<unsigned long,2> > >::ThreadedGenerateData(const itk::ImageRegion<2> & outputRegionForThread, unsigned int threadId)  Line 190 + 0x1c bytes  C++
>>> HelloWorld.exe!itk::ImageSource<itk::LabelMap<itk::LabelObject<unsigned long,2> > >::ThreaderCallback(void * arg)  Line 295 + 0x25 bytes    C++
>>> HelloWorld.exe!itk::MultiThreader::SingleMethodProxy(void * arg)  Line 375 + 0xe bytes  C++
>>> msvcr100d.dll!_callthreadstartex()  Line 
> ...
> 
> [Message clipped]  
> 
> 
> 
> -- 
> Regards,
> Girish

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://public.kitware.com/pipermail/community/attachments/20140731/ede600fd/attachment-0002.html>


More information about the Community mailing list