compute_traps_mask now returns a traps mask, as expected
- to do this I had to split test_template_matcher into 2 unit tests (one of them being a unit test just for template matching)
This commit is contained in:
parent
9ce4823e7a
commit
777db445be
|
@ -132,6 +132,8 @@ class Sequence(object):
|
|||
""" returns a subset of the sequence as an hyperstack
|
||||
|
||||
:param list(str) selected_channel_ids:
|
||||
:param list(int) selected_frames:
|
||||
:param list(int) selected_slices:
|
||||
:return IHyperStack: the resulting hyperstack
|
||||
"""
|
||||
if selected_frames is None:
|
||||
|
|
|
@ -40,7 +40,10 @@ class PixelType:
|
|||
class IImage(ABC):
|
||||
|
||||
@abc.abstractmethod
|
||||
def clone(self):
|
||||
def clone(self, clone_pixel_type=None):
|
||||
"""
|
||||
:param int clone_pixel_type: PixelType enum. If None, then the clone's pixel type is the same as the pixel type of the source image
|
||||
"""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
|
@ -80,6 +83,12 @@ class IImage(ABC):
|
|||
"""
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_mean_value(self):
|
||||
"""
|
||||
:rtype float: the mean pixel value in the image
|
||||
"""
|
||||
pass
|
||||
|
||||
class IHyperStack(ABC):
|
||||
|
||||
|
|
|
@ -43,9 +43,18 @@ class IJImage(IImage):
|
|||
stack_name = ''
|
||||
self.ij_image = IJ.createHyperStack(stack_name, width, height, 1, 1, 1, PixelType.get_num_bits(pixel_type))
|
||||
|
||||
def clone(self):
|
||||
copy = IJImage(self.image_engine, width=self.width(), height=self.height(), pixel_type=self.get_pixel_type())
|
||||
copy.ij_image.setProcessor( self.ij_image.getProcessor().duplicate() )
|
||||
def clone(self, clone_pixel_type=None):
|
||||
if clone_pixel_type == None:
|
||||
clone_pixel_type = self.get_pixel_type()
|
||||
copy = IJImage(self.image_engine, width=self.width(), height=self.height(), pixel_type=clone_pixel_type)
|
||||
src_processor = self.ij_image.getProcessor()
|
||||
clone_processor = {
|
||||
PixelType.U8: src_processor.convertToByteProcessor(),
|
||||
PixelType.U16: src_processor.convertToShortProcessor(),
|
||||
PixelType.F32: src_processor.convertToFloatProcessor(),
|
||||
}[clone_pixel_type]
|
||||
copy.ij_image.setProcessor( clone_processor )
|
||||
assert copy.get_pixel_type() == clone_pixel_type
|
||||
return copy
|
||||
|
||||
def width(self):
|
||||
|
@ -78,11 +87,15 @@ class IJImage(IImage):
|
|||
processor = self.ij_image.getProcessor()
|
||||
# processor.getMin() and processor.getMax() give a higher min and a lower max, probably because they only consider a subpart of the image (this is badly documented)
|
||||
# so we use processor.getStats instead
|
||||
image_stats = processor.getStats() # :type ImageStatistics is:
|
||||
image_stats = processor.getStats() # :type ImageStatistics image_stats:
|
||||
min_value = image_stats.min
|
||||
max_value = image_stats.max
|
||||
return (min_value, max_value)
|
||||
|
||||
def get_mean_value(self):
|
||||
processor = self.ij_image.getProcessor()
|
||||
image_stats = processor.getStats() # :type ImageStatistics image_stats:
|
||||
return image_stats.mean
|
||||
|
||||
class IJHyperStack(IHyperStack):
|
||||
|
||||
|
@ -303,7 +316,13 @@ class IJImageEngine(IImageEngine):
|
|||
return image # pylint: disable=unreachable
|
||||
|
||||
def match_template(self, src_image, template_image):
|
||||
|
||||
cv_match_template_supported_pixel_types = [PixelType.U8, PixelType.F32]
|
||||
if src_image.get_pixel_type() not in cv_match_template_supported_pixel_types:
|
||||
print('converting src_image')
|
||||
src_image = src_image.clone(PixelType.F32)
|
||||
if template_image.get_pixel_type() not in cv_match_template_supported_pixel_types:
|
||||
print('converting template_image')
|
||||
template_image = template_image.clone(PixelType.F32)
|
||||
# import org.opencv.imgproc.Imgproc;
|
||||
#
|
||||
# /*
|
||||
|
|
|
@ -116,5 +116,5 @@ class TrapsDetector(object):
|
|||
#non_uniform_stack = sequence.as_stack()
|
||||
#uniform_stack = IImageEngine.get_instance().divide(non_uniform_stack, white_estimate)
|
||||
# IImageEngine.get_instance().save_as_tiff(white_estimate, './white_estimate.tiff')
|
||||
return matches
|
||||
return traps_mask
|
||||
|
|
@ -45,6 +45,30 @@ class TestLipase(unittest.TestCase):
|
|||
non_uniform_sequence = self.catalog.sequences['res_soleil2018/GGH/GGH_2018_cin2_phiG_I_327_vis_-40_1/Pos0']
|
||||
uniform_sequence = correct_non_uniform_lighting(non_uniform_sequence, 'DM300_nofilter_vis', white_estimator=WhiteEstimator(open_size=75, close_size=75, average_size=75))
|
||||
|
||||
def test_template_matcher(self):
|
||||
sequence = self.catalog.sequences['res_soleil2018/GGH/GGH_2018_cin2_phiG_I_327_vis_-40_1/Pos0']
|
||||
stack = sequence.as_hyperstack(['DM300_nofilter_vis'], selected_frames=[0])
|
||||
first_image = stack.get_image(frame_index=0)
|
||||
x_min = 423
|
||||
x_max = 553
|
||||
y_min = 419
|
||||
y_max = 533
|
||||
template_trap_aabb = Aabb(x_min, y_min, x_max, y_max)
|
||||
template_trap_image = first_image.get_subimage(template_trap_aabb)
|
||||
for image in [first_image, template_trap_image]:
|
||||
print(image.get_pixel_type(), image.width(), image.height())
|
||||
# the typical value of peaks is -2.e10 and the value between peaks is below -8.0e10
|
||||
threshold = -3.0e10
|
||||
tolerance = 1.0e10
|
||||
maxima_finder = MaximaFinder(threshold, tolerance)
|
||||
template_matcher = TemplateMatcher(maxima_finder)
|
||||
matches = template_matcher.match_template(first_image, template_trap_image)
|
||||
num_traps = len(matches)
|
||||
print("number of traps found : %d" % num_traps)
|
||||
num_expected_traps = 13 # 13 traps are completely visible in the first image
|
||||
self.assertAlmostEqual(len(matches), num_expected_traps, delta=1.0)
|
||||
|
||||
|
||||
def test_traps_detector(self):
|
||||
# the typical value of peaks is -500 and the value between peaks is below -2500
|
||||
threshold = -1500.0
|
||||
|
@ -58,12 +82,14 @@ class TestLipase(unittest.TestCase):
|
|||
y_min = 419
|
||||
y_max = 533
|
||||
trap_aabb = Aabb(x_min, y_min, x_max, y_max)
|
||||
matches = traps_detector.compute_traps_mask(sequence, 'DM300_nofilter_vis', trap_aabb)
|
||||
|
||||
num_traps = len(matches)
|
||||
print("number of traps found : %d" % num_traps)
|
||||
num_expected_traps = 13 # 13 traps are completely visible in the
|
||||
self.assertAlmostEqual(len(matches), num_expected_traps, delta=1.0)
|
||||
traps_mask = traps_detector.compute_traps_mask(sequence, 'DM300_nofilter_vis', trap_aabb)
|
||||
measured_mean_value = traps_mask.get_mean_value()
|
||||
expected_traps_coverage = 0.07909
|
||||
traps_pixel_value = 255.0
|
||||
expected_mean_value = expected_traps_coverage * traps_pixel_value
|
||||
print("expected_mean_value: %f" % expected_mean_value)
|
||||
print("measured_mean_value: %f" % measured_mean_value)
|
||||
self.assertAlmostEqual(measured_mean_value, expected_mean_value, delta=0.01)
|
||||
|
||||
def run_script():
|
||||
|
||||
|
|
Loading…
Reference in New Issue