@@ -273,6 +273,7 @@ def initialize(self, name, data):
273273
274274 def update_snr (self ):
275275 """Updates the signal-to-noise ratio."""
276+
276277 pass
277278
278279 def set_mode (self , mode = "" ):
@@ -374,6 +375,13 @@ def toggle_min_max_buttons(self, display=False):
374375 def try_to_display_image (self , image ):
375376 """Try to display an image.
376377
378+ Note
379+ ----
380+ This function is called when an image is acquired. The image is passed to the
381+ display function. If the display function is already displaying an image, the
382+ function will return. Thus, if imaging is faster than the display, the display
383+ will skip frames.
384+
377385 Parameters
378386 ----------
379387 image : numpy.ndarray
@@ -558,18 +566,59 @@ def digital_zoom(self):
558566 return zoom_image
559567
560568 def detect_saturation (self , image ):
561- """Look for any pixels at the maximum intensity allowable for the camera."""
569+ """Look for any pixels at the maximum intensity allowable for the camera.
570+
571+ Note
572+ ----
573+ The camera is set to 16-bit depth, so the maximum intensity is 2^16 - 1. If
574+ another camera is used, this function should be updated to reflect the maximum
575+ intensity value.
576+
577+ Parameters
578+ ----------
579+ image : numpy.ndarray
580+ Image data.
581+
582+ Returns
583+ -------
584+ saturated_pixels : numpy.ndarray
585+ Saturated pixels in the image.
586+ """
562587 saturation_value = 2 ** 16 - 1
563588 self .saturated_pixels = image [image > saturation_value ]
564589
565590 def down_sample_image (self , image ):
566- """Down-sample the data for image display according to widget size."""
591+ """Down-sample the data for image display according to widget size.
592+
593+ Interpolation type is cv2.INTER_LINEAR by default.
594+
595+ Parameters
596+ ----------
597+ image : numpy.ndarray
598+ Image data.
599+
600+ Returns
601+ -------
602+ down_sampled_image : numpy.ndarray
603+ Down-sampled image data.
604+ """
567605 sx , sy = self .canvas_width , self .canvas_height
568606 down_sampled_image = cv2 .resize (image , (sx , sy ))
569607 return down_sampled_image
570608
571609 def scale_image_intensity (self , image ):
572- """Scale the data to the min/max counts, and adjust bit-depth."""
610+ """Scale the data to the min/max counts, and adjust bit-depth.
611+
612+ Parameters
613+ ----------
614+ image : numpy.ndarray
615+ Image data.
616+
617+ Returns
618+ -------
619+ image : numpy.ndarray
620+ Scaled image data.
621+ """
573622 if self .autoscale is True :
574623 self .max_counts = np .max (image )
575624 self .min_counts = np .min (image )
@@ -609,6 +658,11 @@ def add_crosshair(self, image):
609658 def array_to_image (self , image ):
610659 """Convert a numpy array to a PIL Image
611660
661+ Parameters
662+ ----------
663+ image : numpy.ndarray
664+ Image data.
665+
612666 Returns
613667 -------
614668 image : Image
@@ -617,17 +671,26 @@ def array_to_image(self, image):
617671 return Image .fromarray (image .astype (np .uint8 ))
618672
619673 def populate_image (self , image ):
620- """Converts image to an ImageTk.PhotoImage and populates the Tk Canvas"""
674+ """Converts image to an ImageTk.PhotoImage and populates the Tk Canvas
675+
676+ Note
677+ ----
678+ When calling ImageTk.PhotoImage() to generate a new image, it will destroy
679+ what the canvas is showing, causing it to blink. This problem is solved by
680+ creating two images and alternating between them.
681+
682+ Parameters
683+ ----------
684+ image : numpy.ndarray
685+ Image data.
686+ """
621687 temp_img = self .array_to_image (image )
622- # when calling ImageTk.PhotoImage() to generate a new image, it will destroy
623- # what the canvas is showing, causing it to blink.
624688 if self .image_cache_flag :
625689 self .tk_image = ImageTk .PhotoImage (temp_img )
626690 self .canvas .create_image (0 , 0 , image = self .tk_image , anchor = "nw" )
627691 else :
628692 self .tk_image2 = ImageTk .PhotoImage (temp_img )
629693 self .canvas .create_image (0 , 0 , image = self .tk_image2 , anchor = "nw" )
630-
631694 self .image_cache_flag = not self .image_cache_flag
632695
633696 def process_image (self ):
@@ -647,7 +710,13 @@ def process_image(self):
647710 self .populate_image (image )
648711
649712 def left_click (self , * args ):
650- """Toggles cross-hair on image upon left click event."""
713+ """Toggles cross-hair on image upon left click event.
714+
715+ Parameters
716+ ----------
717+ args : tuple
718+ Arguments.
719+ """
651720 if self .image is not None :
652721 self .apply_cross_hair = not self .apply_cross_hair
653722 self .process_image ()
@@ -701,6 +770,11 @@ def update_min_max_counts(self, display=False):
701770
702771 When the min and max counts are toggled in the GUI, this function is called.
703772 Updates the min and max values.
773+
774+ Parameters
775+ ----------
776+ display : bool
777+ Flag to display the image.
704778 """
705779 if self .image_palette ["Min" ].get () != "" :
706780 self .min_counts = float (self .image_palette ["Min" ].get ())
@@ -886,7 +960,13 @@ def update_snr(self):
886960 self .image_palette ["SNR" ].grid (row = 3 , column = 0 , sticky = tk .NSEW , pady = 3 )
887961
888962 def slider_update (self , * args ):
889- """Updates the image when the slider is moved."""
963+ """Updates the image when the slider is moved.
964+
965+ Parameters
966+ ----------
967+ args : tuple
968+ Arguments.
969+ """
890970
891971 slider_index = self .view .slider .get ()
892972 channel_index = self .view .live_frame .channel .get ()
@@ -909,9 +989,13 @@ def slider_update(self, *args):
909989 def update_display_state (self , * args ):
910990 """Image Display Combobox Called.
911991
912- Sets self.display_state to desired display format.
913- Toggles state of slider widget.
914- Sets number of positions.
992+ Sets self.display_state to desired display format. Toggles state of slider
993+ widget. Sets number of positions.
994+
995+ Parameters
996+ ----------
997+ args : tuple
998+ Arguments.
915999 """
9161000 if self .number_of_slices == 0 :
9171001 return
@@ -1140,6 +1224,11 @@ def array_to_image(self, image):
11401224
11411225 If a color mask is present, it will apply the mask to the image.
11421226
1227+ Parameters
1228+ ----------
1229+ image : numpy.ndarray
1230+ Image data.
1231+
11431232 Returns
11441233 -------
11451234 image : Image
@@ -1189,11 +1278,6 @@ def set_mask_color_table(self, colors):
11891278 ----------
11901279 colors : list
11911280 List of colors to use for the segmentation mask
1192-
1193- Returns
1194- -------
1195- self.mask_color_table : np.array
1196- Array of colors to use for the segmentation mask
11971281 """
11981282 self .mask_color_table = np .zeros ((256 , 1 , 3 ), dtype = np .uint8 )
11991283 self .mask_color_table [0 ] = [0 , 0 , 0 ]
@@ -1238,14 +1322,29 @@ def __init__(self, view, parent_controller=None):
12381322 The parent controller of the camera view controller.
12391323 """
12401324 super ().__init__ (view , parent_controller )
1325+
1326+ #: tkinter.Canvas: The tkinter canvas that displays the image.
12411327 self .view = view
1328+
1329+ #: np.ndarray: The image data.
12421330 self .image = None
1331+
1332+ #: np.ndarray: The maximum intensity projection in the ZY plane.
12431333 self .zx_mip = None
1334+
1335+ #: np.ndarray: The maximum intensity projection in the ZY plane.
12441336 self .zy_mip = None
1337+
1338+ #: np.ndarray: The maximum intensity projection in the XY plane.
12451339 self .xy_mip = None
1340+
1341+ #: bool: The autoscale flag.
12461342 self .autoscale = True
1343+
1344+ #: str: The perspective of the image.
12471345 self .perspective = "XY"
12481346
1347+ #: dict: The render widgets.
12491348 self .render_widgets = self .view .render .get_widgets ()
12501349
12511350 if platform .system () == "Windows" :
@@ -1254,13 +1353,10 @@ def __init__(self, view, parent_controller=None):
12541353 def initialize (self , name , data ):
12551354 """Initialize the MIP view.
12561355
1257- Sets the min and max intensity values for the image.
1258- Disables the min and max widgets.
1259- Invokes the gray and autoscale widgets.
1260- Hides the SNR widget.
1261- Sets the perspective widget values.
1262- Sets the perspective widget to XY.
1263- Sets the channel widget to CH0.
1356+ Sets the min and max intensity values for the image.Disables the min and max
1357+ widgets. Invokes the gray and autoscale widgets.Hides the SNR widget.
1358+ Sets the perspective widget values. Sets the perspective widget to XY. Sets
1359+ the channel widget to CH0.
12641360
12651361 Parameters
12661362 ----------
@@ -1422,7 +1518,13 @@ def display_image(self, image):
14221518 is_displaying_image .value = False
14231519
14241520 def display_mip_image (self , * args ):
1425- """Display MIP image in non-live view"""
1521+ """Display MIP image in non-live view.
1522+
1523+ Parameters
1524+ ----------
1525+ args : tuple
1526+ Arguments.
1527+ """
14261528 if self .perspective != self .render_widgets ["perspective" ].get ():
14271529 self .update_perspective ()
14281530 if self .mode != "stop" :
@@ -1432,6 +1534,15 @@ def display_mip_image(self, *args):
14321534 self .process_image ()
14331535
14341536 def update_perspective (self , * args , display = False ):
1537+ """Update the perspective of the image.
1538+
1539+ Parameters
1540+ ----------
1541+ args : tuple
1542+ Arguments.
1543+ display : bool
1544+ Flag to display the image.
1545+ """
14351546 display_mode = self .render_widgets ["perspective" ].get ()
14361547 self .perspective = display_mode
14371548 if display_mode == "XY" :
@@ -1448,7 +1559,15 @@ def update_perspective(self, *args, display=False):
14481559 self .reset_display (False )
14491560
14501561 def down_sample_image (self , image , reset_original = False ):
1451- """Down-sample the data for image display according to widget size."""
1562+ """Down-sample the data for image display according to widget size.
1563+
1564+ Parameters
1565+ ----------
1566+ image : numpy.ndarray
1567+ Image data.
1568+ reset_original : bool
1569+ Flag to reset the original image size.
1570+ """
14521571 sx , sy = self .canvas_width , self .canvas_height
14531572 down_sampled_image = cv2 .resize (image , (sx , sy ))
14541573 if reset_original :
@@ -1458,6 +1577,7 @@ def down_sample_image(self, image, reset_original=False):
14581577 self .canvas_height_scale = 1
14591578 return down_sampled_image
14601579
1580+
14611581class SpooledImageLoader :
14621582 """A class to lazily load images from disk using a spooled temporary file."""
14631583
0 commit comments