improved trap binarizer : it now uses a manual threshold value to allow the user to adjust it.
As a result, both sides of the trap are now detected
This commit is contained in:
		
							parent
							
								
									b4458c0697
								
							
						
					
					
						commit
						9ce4823e7a
					
				|  | @ -73,6 +73,12 @@ class IImage(ABC): | |||
|         """ | ||||
|         pass | ||||
| 
 | ||||
|     @abc.abstractmethod | ||||
|     def get_value_range(self): | ||||
|         """ | ||||
|         :rtype (float, float): the min and the max value | ||||
|         """ | ||||
|         pass | ||||
|      | ||||
| 
 | ||||
| class IHyperStack(ABC): | ||||
|  | @ -372,6 +378,13 @@ class IImageEngine(ABC): | |||
|         :return list(Match): maxima | ||||
|         """ | ||||
| 
 | ||||
|     @abc.abstractmethod | ||||
|     def threshold(self, src_image, threshold_value): | ||||
|         """ | ||||
|         :param float threshold_value: | ||||
|         :rtype IImage: | ||||
|         """ | ||||
| 
 | ||||
|     @abc.abstractmethod | ||||
|     def auto_threshold(self, src_image): | ||||
|         """ | ||||
|  |  | |||
|  | @ -74,6 +74,16 @@ class IJImage(IImage): | |||
|         dst_processor = self.ij_image.getProcessor() | ||||
|         dst_processor.copyBits(src_processor, x, y, Blitter.COPY) | ||||
| 
 | ||||
|     def get_value_range(self): | ||||
|         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: | ||||
|         min_value = image_stats.min | ||||
|         max_value = image_stats.max | ||||
|         return (min_value, max_value) | ||||
| 
 | ||||
| 
 | ||||
| class IJHyperStack(IHyperStack): | ||||
| 
 | ||||
|     def __init__(self, image_engine, width, height, num_channels, num_slices, num_frames, pixel_type): | ||||
|  | @ -367,6 +377,12 @@ class IJImageEngine(IImageEngine): | |||
|             matches.append(match) | ||||
|         return matches | ||||
| 
 | ||||
|     def threshold(self, src_image, threshold_value): | ||||
|         binary_image = src_image.clone() | ||||
|         IJ.setThreshold(binary_image.ij_image, threshold_value, 1.e30)  # TODO:remove hardcoded value (1.0e30 is the value imagej chooses when the user moves the threshold slider to the right) | ||||
|         IJ.run(binary_image.ij_image, "Convert to Mask", "") | ||||
|         return binary_image | ||||
| 
 | ||||
|     def auto_threshold(self, src_image): | ||||
|         # Image/Adjust/Threshold, choose auto, then click apply | ||||
|         # IJ.setAutoThreshold(imp, "Default dark"); | ||||
|  |  | |||
|  | @ -27,7 +27,12 @@ class TrapBinarizer(object): | |||
|         # after find edges, the walls are dark lines surrounded by 2 lines of clear pixels. | ||||
|         # Image/Adjust/Threshold, choose auto, then click apply | ||||
|         # IJ.setAutoThreshold(imp, "Default dark"); | ||||
|         is_edge = ie.auto_threshold( edge_image ) | ||||
|         (min_value, max_value) = edge_image.get_value_range() | ||||
|         print('min_value = %f' % min_value) | ||||
|         print('max_value = %f' % max_value) | ||||
|         threshold_value = 0.20  # TODO: remove hardcoded value | ||||
|         is_edge = ie.threshold( edge_image, max_value * threshold_value) | ||||
|         # is_edge = ie.auto_threshold( edge_image) | ||||
|         ie.save_as_tiff(is_edge, './is_trap_edge.tiff') | ||||
|         # convert image to mask | ||||
|         # at this point, the walls are black lines surrounded by 2 thick lines of white pixels | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue