20
Image processing Image processing algorithm regression algorithm regression testing framework testing framework Soumik Ukil

Image processing algorithm regression testing framework Soumik Ukil

Embed Size (px)

Citation preview

Page 1: Image processing algorithm regression testing framework Soumik Ukil

Image processing algorithm Image processing algorithm regression testing frameworkregression testing framework

Soumik Ukil

Page 2: Image processing algorithm regression testing framework Soumik Ukil

Testing Ground RulesTesting Ground Rules

Objectives:Objectives:

Testing is the process of executing a program Testing is the process of executing a program with the intent of finding errorswith the intent of finding errors

A good test case is one that has a high A good test case is one that has a high probability of finding an errorprobability of finding an error

A successful test is one that uncovers an errorA successful test is one that uncovers an error

However, testing cannot show the absence However, testing cannot show the absence of defectsof defects

Page 3: Image processing algorithm regression testing framework Soumik Ukil

Unit Testing: Testing to determine that individual program

modules perform to specification Basic units of software tested in isolation

Regression Testing: Selective retesting to detect faults introduced

during modification of system Should be performed after any changes in

software like bug fixes

Page 4: Image processing algorithm regression testing framework Soumik Ukil

MotivationMotivation

Projects like NETT and BRP Projects like NETT and BRP Complex algorithms which run on hundreds of Complex algorithms which run on hundreds of

datasetsdatasets Source is being constantly modified to fix bugs etcSource is being constantly modified to fix bugs etc Manual testing infeasibleManual testing infeasible

Need automated regression testing Need automated regression testing

Page 5: Image processing algorithm regression testing framework Soumik Ukil

Testing StrategiesTesting Strategies

Dynamic AnalysisDynamic Analysis Exercise the software in its execution environmentExercise the software in its execution environment Black BoxBlack Box

Treat the system as black -box, ie no Treat the system as black -box, ie no knowledge of internal structureknowledge of internal structure

Only need to know legal input and expected Only need to know legal input and expected outputoutput

White BoxWhite Box Depends on Internal structure of programDepends on Internal structure of program Test all paths through code Test all paths through code

Page 6: Image processing algorithm regression testing framework Soumik Ukil

Testing StrategiesTesting Strategies

Static AnalysisStatic Analysis Code ReviewsCode Reviews WalkthroughsWalkthroughs InspectionsInspections

Page 7: Image processing algorithm regression testing framework Soumik Ukil

Tests on image dataTests on image data Gold-standard data used as basis for Gold-standard data used as basis for

correctness of outputcorrectness of output

Black box testsBlack box tests:: Already know 'correct' outputAlready know 'correct' output Generate data from algorithmGenerate data from algorithm Define tests that compare the two sets of dataDefine tests that compare the two sets of data

Page 8: Image processing algorithm regression testing framework Soumik Ukil

Tests on image dataTests on image data Generic Tests:Generic Tests:

Check output is of correct datatypeCheck output is of correct datatype Check image dimensionsCheck image dimensions

Specific tests: Specific tests: Depends on application being testedDepends on application being tested For airway tree validation we may want to compare For airway tree validation we may want to compare

distance between branchpointsdistance between branchpoints For Lung Segmentation we need to compare For Lung Segmentation we need to compare

volumes and/or distance between contours volumes and/or distance between contours

Page 9: Image processing algorithm regression testing framework Soumik Ukil

Objectives of test frameworkObjectives of test framework

Different applications:Different applications: Regression testing after any changesRegression testing after any changes Validation of dataValidation of data

Flexible:Flexible: Testers only plug in specific testsTesters only plug in specific tests Test data generation and reporting of test results Test data generation and reporting of test results

taken care by frameworktaken care by framework

Page 10: Image processing algorithm regression testing framework Soumik Ukil

ImplementationImplementation

Built on top of PyUnitBuilt on top of PyUnit:: Part of standard Python library for Python 2.1 and Part of standard Python library for Python 2.1 and

laterlater

Based on JUnit, a proven testing architectureBased on JUnit, a proven testing architecture

Allows creation of user defined tests, aggregation Allows creation of user defined tests, aggregation into suites, running tests in textual or GUI modeinto suites, running tests in textual or GUI mode

Page 11: Image processing algorithm regression testing framework Soumik Ukil

Writing tests with PyUnit:Writing tests with PyUnit:

Basic building blocks called Test CasesBasic building blocks called Test Cases Created by deriving from base class unittest.TestCaseCreated by deriving from base class unittest.TestCase An instance of a TestCase class is an object that can completely run An instance of a TestCase class is an object that can completely run

a single test method a single test method

FixturesFixtures A set-up and tear down method for each test caseA set-up and tear down method for each test case Many different test cases can use the same fixtureMany different test cases can use the same fixture

Test SuitesTest Suites Test case instances can be grouped together according to the Test case instances can be grouped together according to the

features they test features they test All tests can be executed together as part of a suiteAll tests can be executed together as part of a suite

Test RunnerTest Runner A class whose instances run tests and report resultsA class whose instances run tests and report results Can be used in text or GUI modeCan be used in text or GUI mode

Page 12: Image processing algorithm regression testing framework Soumik Ukil

Example:Example:class LungSegTestCase(unittest.TestCase):class LungSegTestCase(unittest.TestCase):

def initialize(self,fname1,fname2): def initialize(self,fname1,fname2):

A = AnaFile.AnaFile() # Anafile object for reading imagesA = AnaFile.AnaFile() # Anafile object for reading images

self.data,hdr=A.read(fname1) # segmentation resultself.data,hdr=A.read(fname1) # segmentation resultself.ref_data,ref_hdr = A.read(fname2) # reference maskself.ref_data,ref_hdr = A.read(fname2) # reference mask

def setUp(self):def setUp(self): self.labels=[20,30] # left and right lung labelsself.labels=[20,30] # left and right lung labels

def tearDown(self):def tearDown(self): self.data = Noneself.data = None self.ref_data= Noneself.ref_data= None

def test1(self):## test method names begin 'test*'def test1(self):## test method names begin 'test*' """Test to see if mask image datatype is uint8.""""""Test to see if mask image datatype is uint8."""

self.assertEquals(self.data.typecode(),'b')self.assertEquals(self.data.typecode(),'b')

def test2(self):def test2(self): """Test to check that correct labels are present in mask file.""""""Test to check that correct labels are present in mask file."""

for n in self.labels:for n in self.labels: errormsg="label" + str(n) + "missing"errormsg="label" + str(n) + "missing" self.assertNotEquals(sum(ravel(equal(self.data, n))),0,errormsg)self.assertNotEquals(sum(ravel(equal(self.data, n))),0,errormsg)

Page 13: Image processing algorithm regression testing framework Soumik Ukil

Example:Example:class LungSegTestCase(unittest.TestCase):class LungSegTestCase(unittest.TestCase):

def initialize(self,fname1,fname2): def initialize(self,fname1,fname2):

A = AnaFile.AnaFile() # Anafile object for reading imagesA = AnaFile.AnaFile() # Anafile object for reading images

self.data,hdr=A.read(fname1) # segmentation resultself.data,hdr=A.read(fname1) # segmentation resultself.ref_data,ref_hdr = A.read(fname2) # reference maskself.ref_data,ref_hdr = A.read(fname2) # reference mask

def setUp(self):def setUp(self): self.labels=[20,30] # left and right lung labelsself.labels=[20,30] # left and right lung labels

def tearDown(self):def tearDown(self): self.data = Noneself.data = None self.ref_data= Noneself.ref_data= None

def test1(self):## test method names begin 'test*'def test1(self):## test method names begin 'test*' """Test to see if mask image datatype is uint8.""""""Test to see if mask image datatype is uint8."""

self.assertEquals(self.data.typecode(),'b')self.assertEquals(self.data.typecode(),'b')

def test2(self):def test2(self): """Test to check that correct labels are present in mask file.""""""Test to check that correct labels are present in mask file."""

for n in self.labels:for n in self.labels: errormsg="label" + str(n) + "missing"errormsg="label" + str(n) + "missing" self.assertNotEquals(sum(ravel(equal(self.data, n))),0,errormsg)self.assertNotEquals(sum(ravel(equal(self.data, n))),0,errormsg)

Page 14: Image processing algorithm regression testing framework Soumik Ukil

Example:Example:class LungSegTestCase(unittest.TestCase):class LungSegTestCase(unittest.TestCase):

def initialize(self,fname1,fname2): def initialize(self,fname1,fname2):

A = AnaFile.AnaFile() # Anafile object for reading imagesA = AnaFile.AnaFile() # Anafile object for reading images

self.data,hdr=A.read(fname1) # segmentation resultself.data,hdr=A.read(fname1) # segmentation resultself.ref_data,ref_hdr = A.read(fname2) # reference maskself.ref_data,ref_hdr = A.read(fname2) # reference mask

def setUp(self):def setUp(self): self.labels=[20,30] # left and right lung labelsself.labels=[20,30] # left and right lung labels

def tearDown(self):def tearDown(self): self.data = Noneself.data = None self.ref_data= Noneself.ref_data= None

def test1(self):## test method names begin 'test*'def test1(self):## test method names begin 'test*' """Test to see if mask image datatype is uint8.""""""Test to see if mask image datatype is uint8."""

self.assertEquals(self.data.typecode(),'b')self.assertEquals(self.data.typecode(),'b')

def test2(self):def test2(self): """Test to check that correct labels are present in mask file.""""""Test to check that correct labels are present in mask file."""

for n in self.labels:for n in self.labels: errormsg="label" + str(n) + "missing"errormsg="label" + str(n) + "missing" self.assertNotEquals(sum(ravel(equal(self.data, n))),0,errormsg)self.assertNotEquals(sum(ravel(equal(self.data, n))),0,errormsg)

Page 15: Image processing algorithm regression testing framework Soumik Ukil

Application dependent tests:Application dependent tests:

For lung segmentation we use an area overlap For lung segmentation we use an area overlap measure to test correctness:measure to test correctness:

Check that value is above a given threshold to Check that value is above a given threshold to 'pass' test'pass' test

Similar tests can be defined with distance Similar tests can be defined with distance measures between contoursmeasures between contours

User has to plug-in appropriate testsUser has to plug-in appropriate tests

Page 16: Image processing algorithm regression testing framework Soumik Ukil

Flow diagram:Flow diagram:

Page 17: Image processing algorithm regression testing framework Soumik Ukil

Sample configuration file:Sample configuration file:[DEFAULT][DEFAULT]# Directory of gold-standard data# Directory of gold-standard dataRefdir = ../ValidationDataRefdir = ../ValidationData

#Directory of data generated by algorithm #Directory of data generated by algorithm Maskdir = ../NewDataMaskdir = ../NewData

# Output file extension# Output file extensionMaskExt = mask.imgMaskExt = mask.img

# Name of logfile directory# Name of logfile directoryLogdir = ../logfilesLogdir = ../logfiles

[ALGORITHM][ALGORITHM]# Dir. of raw image data to run algorithm on # Dir. of raw image data to run algorithm on Inputdir = /home/xyz/lung/DataInputdir = /home/xyz/lung/Data

# Path to executable for algorithm# Path to executable for algorithmExecpath = ../lungExecpath = ../lung

# Input file extension# Input file extensionInputExt = imgInputExt = img

Page 18: Image processing algorithm regression testing framework Soumik Ukil

Reporting test results:Reporting test results: Textual output directed to log filesTextual output directed to log files

Success:Success:------------------------------------------------------------------------------------------------------------------------------------------Ran 6 tests in 88.337sRan 6 tests in 88.337sOKOK

Failure:Failure:FAIL: Left lung pixel count test (slice by slice).FAIL: Left lung pixel count test (slice by slice).--------------------------------------------------------------------------------------------------------------------------------------------Traceback (most recent call last):Traceback (most recent call last): File "lungsegtests.py", line 101, in test6File "lungsegtests.py", line 101, in test6 self.failIf(fail==1,errormsg)self.failIf(fail==1,errormsg) File "unittest.py", line 264, in failIfFile "unittest.py", line 264, in failIf if expr: raise self.failureException, msgif expr: raise self.failureException, msgAssertionError: significant segmentation mismatch for left lung on slices:AssertionError: significant segmentation mismatch for left lung on slices:[458, 462][458, 462]

Page 19: Image processing algorithm regression testing framework Soumik Ukil

Status:Status:

Testing for Lung segmentation/smoothing has Testing for Lung segmentation/smoothing has been implemented with the following tests:been implemented with the following tests:

Type checking of output masksType checking of output masks Checking that all expected labels are presentChecking that all expected labels are present Slice by slice area comparison for both lungsSlice by slice area comparison for both lungs

Can be used by segmentation algorithms on Can be used by segmentation algorithms on ANALYZE images which produce labeled ANALYZE images which produce labeled masksmasks

Framework can be extended to handle other Framework can be extended to handle other formats like airway tree definitions etcformats like airway tree definitions etc

Page 20: Image processing algorithm regression testing framework Soumik Ukil

References:References:

1. http://pyunit.sourceforge.net

2.2. http://www.xprogramming.com/testfram.htmhttp://www.xprogramming.com/testfram.htm

Documentation and source code:

CVS repository: pulmonary/TestFrameWork