@@ -64,7 +64,7 @@ def __init__(self, stackWidget):
6464 """
6565 super ().__init__ (stackWidget )
6666
67- self ._myStack = stackWidget .getStack ()
67+ self ._myStack : pymapmanager . stack = stackWidget .getStack ()
6868 self ._displayOptionsDict = stackWidget ._displayOptionsDict
6969
7070 self ._currentSlice = 0
@@ -634,10 +634,11 @@ def _setColorLut(self, update=False):
634634
635635 def _setContrast (self ):
636636 if self ._channelIsRGB ():
637+ logger .warning (f'TODO: hard coding min/max for rgb -->> fix' )
637638 tmpLevelList = [] # list of [min,max]
638639 for channelIdx in self ._myStack .getChannelKeys ():
639- # oneMinContrast = self._myStack.contrast.getValue(channelIdx, 'minAutoContrast-rgb ')
640- # oneMaxContrast = self._myStack.contrast.getValue(channelIdx, 'maxAutoContrast-rgb ')
640+ # oneMinContrast = self._myStack.contrast.getValue(channelIdx, 'minAutoContrast_rgb ')
641+ # oneMaxContrast = self._myStack.contrast.getValue(channelIdx, 'maxAutoContrast_rgb ')
641642 oneMinContrast = 0
642643 oneMaxContrast = 200
643644
@@ -659,8 +660,8 @@ def _setContrast(self):
659660 self ._myImage .setLevels (levelList , update = True )
660661
661662 else :
662- logger .warning ('abb turned off contrast, using auto contrast' )
663- return
663+ # logger.warning('abb turned off contrast, using auto contrast')
664+ # return
664665
665666 # one channel
666667 minUserContrast , maxUserContrast = \
@@ -694,7 +695,7 @@ def _setSlice(self, sliceNumber : int, doEmit = True):
694695 TODO: get rid of doEmit, use _blockSlots
695696 """
696697
697- logger .warning (f'xxx EXPENSIVE ONLY CALL ONCE sliceNumber:{ sliceNumber } doEmit:{ doEmit } ' )
698+ # logger.warning(f'xxx EXPENSIVE ONLY CALL ONCE sliceNumber:{sliceNumber} doEmit:{doEmit}')
698699
699700 if isinstance (sliceNumber , float ):
700701 sliceNumber = int (sliceNumber )
@@ -707,58 +708,69 @@ def _setSlice(self, sliceNumber : int, doEmit = True):
707708 upDownSlices = self ._displayOptionsDict ['windowState' ]['zPlusMinus' ]
708709
709710 if self ._channelIsRGB ():
710- logger .warning ('TODO: remove hard coded two channel assumption for rgb' )
711- logger .warning (' use core loader channel metadata to get actual channel keys.' )
711+ logger .info (f'-->> setSlice rgb sliceNumber:{ sliceNumber } ' )
712+ # logger.warning('TODO: remove hard coded two channel assumption for rgb')
713+ # logger.warning(' use core loader channel metadata to get actual channel keys.')
712714
713- # ch1_image = self._myStack.getImageSlice(imageSlice=sliceNumber, channelIdx=0)
714- # ch2_image = self._myStack.getImageSlice(imageSlice=sliceNumber, channelIdx=1)
715- ch0_image = self ._myStack .getMaxProjectSlice (sliceNumber ,
716- channelIdx = 1 ,
717- upSlices = upDownSlices , downSlices = upDownSlices ,
718- func = np .max )
719- ch1_image = self ._myStack .getMaxProjectSlice (sliceNumber ,
720- channelIdx = 2 ,
721- upSlices = upDownSlices , downSlices = upDownSlices ,
722- func = np .max )
715+ channelKeys = self ._myStack .getChannelKeys ()
723716
724- # logger.info(f"check ch0_image min {ch1_image.min()} max {ch1_image.max()}")
717+ if len (channelKeys ) < 2 :
718+ logger .error (f'Expected at least 2 channels for RGB, found { len (channelKeys )} ' )
719+ return
725720
726- # rgb requires 8-bit images
727- ch0_image = ch0_image / ch0_image .max () * 2 ** 8
728- ch1_image = ch1_image / ch1_image .max () * 2 ** 8
729-
730- ch0_image = ch0_image .astype (np .uint8 )
731- ch1_image = ch1_image .astype (np .uint8 )
721+ _shape = self ._myStack .getMetadata ().shape # (z, y, x)
722+ _xShape = _shape [2 ]
723+ _yShape = _shape [1 ]
732724
733- # print('2) ch1_image:', ch1_image.shape, ch1_image.dtype)
725+ # make the 3d slice we will return
726+ sliceImage = np .zeros ((_xShape ,_yShape ,3 ), dtype = np .uint8 )
727+
728+ _redIdx = 0
729+ _greenIdx = 1
730+ _blueIdx = 2
731+
732+ maxImageDict = {}
733+ channelColorDict = {}
734+ for sliceChannel , channelKey in enumerate (channelKeys ):
735+ ch_image = self ._myStack .getMaxProjectSlice (sliceNumber ,
736+ channelIdx = channelKey ,
737+ upSlices = upDownSlices , downSlices = upDownSlices ,
738+ func = np .max )
739+ # rgb requires 8-bit images
740+ ch_image = ch_image / ch_image .max () * 2 ** 8
741+ ch_image = ch_image .astype (np .uint8 )
742+
743+ # here is where we need a user option for channel color
744+ sliceImage [:,:,sliceChannel ] = ch_image
734745
735- _xShape = ch0_image .shape [0 ]
736- _yShape = ch0_image .shape [1 ]
737- sliceImage = np .ndarray ((_xShape ,_yShape ,3 ))
746+ maxImageDict [channelKey ] = ch_image
747+
748+ # redundant, all channels have same shape
749+ # _xShape = ch_image.shape[0]
750+ # _yShape = ch_image.shape[1]
751+
752+ _color = self ._myStack .getChannelColor (channelKey )
753+ _color = self .colorToHex (_color )
754+ _color = to_rgb (_color ) # for ch0_image
755+ channelColorDict [channelKey ] = _color
738756
739757 # # magenta is blue + red
740758 # sliceImage[:,:,0] = ch1_image # red
741759 # sliceImage[:,:,1] = ch0_image # green
742760 # sliceImage[:,:,2] = ch1_image # blue
743761
744- # Get first two channel colors
745- color0 = self ._myStack .getChannelColor (1 )
746- color1 = self ._myStack .getChannelColor (2 )
747-
748- color0 = self .colorToHex (color0 )
749- color1 = self .colorToHex (color1 )
750- logger .info (f"color0 { color0 } color1 { color1 } " )
751-
752- # Convert hex color to RGB arrays
753- rgb0 = to_rgb (color0 ) # for ch0_image
754- rgb1 = to_rgb (color1 ) # for ch1_image
755-
756762 brightness_factor = 2
757763 for i in range (3 ): # R, G, B
764+ # channelKeys is a list (we don't care if it is [int] or [str])
765+ if i == 2 :
766+ _channelKey = channelKeys [1 ]
767+ else :
768+ _channelKey = channelKeys [i ]
769+
758770 sliceImage [:,:,i ] = (
759771 brightness_factor *
760- (ch0_image * (rgb0 [ i ])) +
761- (ch1_image * (rgb1 [ i ])) * i
772+ (maxImageDict [ _channelKey ] * (channelColorDict [ _channelKey ][ 0 ])) +
773+ (maxImageDict [ _channelKey ] * (channelColorDict [ _channelKey ][ 1 ])) * i
762774 ).clip (0 , 255 ).astype (np .uint8 )
763775
764776 else :
0 commit comments