see-insight / see-segment

Simple Evolutionary Exploration - Image Segmentation
MIT License
6 stars 21 forks source link

Fix the error in print_best_algorithm_code and improve code readability #23

Closed kai-pinckard closed 3 years ago

kai-pinckard commented 4 years ago

Resolves issue #6

How it was fixed: The previous code assumed that the first occurrence of ']' in the file would always immediately follow the first occurrence of "self.params" in the file. However, this is assumption is invalid for some segmenters since they use ']'s for other purposes. Now code looks for the first ']' that occurs after the first occurrence of "self.params" in the file.

colbrydi commented 4 years ago

@kai-pinckard Could you provide an example in a comment of where the [ is used? I am not sure what problem is being solved. Also, is this something we should add to the unit testing?

kai-pinckard commented 4 years ago

Both the original function and my updated version use `ind_algo = Segmentors.algoFromParams(individual)

original_function = inspect.getsource(ind_algo.evaluate)`

To output the source code for the algorithm. Running: print(original_function) Yields: ` def evaluate(self, img): #XX """Evaluate segmentation algorithm on training image.

    Keyword arguments:
    img -- Original training image.

    Output:
    output -- resulting segmentation mask from algorithm.

    """
    channel_num = self.params["Channel"]
    if len(img.shape) > 2:
        num_channels = img.shape[2]
        if channel_num < num_channels:
            channel = img[:, :, int(channel_num)]
        else:
            hsv = skimage.color.rgb2hsv(img)
            #print(f"working with hsv channel {channel_num-3}")
            channel = hsv[:, :, int(channel_num)-3]
    else:
        channel = img
    pscale = np.max(channel)
    my_mx = self.params["sigma"] * pscale
    my_mn = self.params["mu"] * pscale

    output = None

    if my_mn < my_mx:
        output = np.ones(channel.shape)
        output[channel < my_mn] = 0
        output[channel > my_mx] = 0
    else:
        output = np.zeros(channel.shape)
        output[channel > my_mn] = 1
        output[channel < my_mx] = 1

    return output

The old code successfully replaceschannel_num = self.params["Channel"]withchannel_num = 3. However it fails to replacemy_mx = self.params["sigma"] pscalewith my_mx = 0.87 pscale

It fails because it first finds the index of self.params as in my_mx = self.params["sigma"] * pscale

However it then looks for the index of the first] in the file which is on the line num_channels = img.shape[2]

It then takes a substring from the index of self.params as in my_mx = self.params["sigma"] * pscale to the index of this ]

However this substring is empty because the second index (which is supposed to occur after the first) occurs before the first.

This causes the function to try to access the value of self.params[""] which is undefined and causes the crash

The fix: Look for the first ] that occurs after the index of self.params as in my_mx = self.params["sigma"] * pscale

kai-pinckard commented 4 years ago

The updated function was produced by separating the original function into multiple lines and making the one change described and should produce the same output that the original function did in all cases with exception to crashing due to the ] issue described above. The updated function passes the current unit test that was made for the old version of this function.

colbrydi commented 3 years ago

Lets give it a go.