def FindAdaptiveROIversion2(image, center_ROI, aspr_ROI, array_ROI, displayImages, debug = True):
    """Using Kernel Density Estimate analysis, relative amount of foreground and background regions within a given ROI can be estimated.
    If the roi is varied across the viewing area, an optimum relative strength can be found when the foreground and background area are nearly equal. This sets the value of adaptive threshold.
    Since we know certain properties about our object of interest like the approximate center of object and the aspect ratio of object area, the ROI can be set accordingly"""
    #inputfilename = 'img6.png'
    #outputfilename = 'edge2.png'
    #nucleation_down = 1 # 0 for nucleation up
    #center_ROI  = (511,672)  #center of the object to be identified
    #aspr_ROI    = 2/3   # x_width/y_width for ROI. This is found by TRAINING
    #debug       = True  # flag to output ERRRORs
    #remove the strip at the bottom
    #cropsequence = ((0,44),(0,0))
    #img = ReadImage(inputfilename)
    #img = CropImage(img,cropsequence,0)
    #to mainain the aspect ratio of roi to be same as that of image, set the aspect ratio
    #asp_ratio = int(1344/(1066-44))
    #list of pad sizes to be removed along x axis
    array_x_ROI     =   array_ROI
    array_y_ROI     =   (array_x_ROI*aspr_ROI).astype(int)
    n           =   array_x_ROI.size
    optimum_x_ROI    =  0
    optimum_y_ROI   =   0
    #set the array for relative strengths and maxima positions for the unimodal or bimodal distributions.
    array_rel_strength  =   np.zeros(n)
    array_maximum       =   np.zeros((n,2))
    #displayImages = 0
    for i in np.arange(n):
        x_width = array_x_ROI[i]
        y_width = array_y_ROI[i]
        #set up the cropsequence so that pads are removed centered around the center of the image.
        cropsequence = CropSequenceGenerate(image,(center_ROI,(x_width,y_width)))
        cropimg = CropImage(image,cropsequence,0)
        imgbyte = Img2Ubyte(cropimg,0)
        img_med = MedianFilter(imgbyte,displayImages)
        maximum,rel_strength    =   modal_analysis(img_med,displayImages,debug)    #strength is zero if distribution is unimodal and close to zero if the foreground is very small compared to background or vice versa
        array_rel_strength[i]   =   rel_strength   
        array_maximum[i]        =   maximum
    #displayImages = 1
    if displayImages==1:
        #plot the relative strength variation  and choose the appropriate ROI
        plt.figure(),plt.title("Finding Optimum ROI by varying xROI"),plt.plot(array_x_ROI,array_rel_strength)
    #if all are unimodal distributions, then there either is no object to be found or object is beyond the ROI. This means that we need to check for bigger ROIs with progressive increase in y axis width
    max_rel_strength = np.max(array_rel_strength)
    if debug: print("maximum relative strength is " + str(max_rel_strength))
    if max_rel_strength < 0.001:
        optimum_x_ROI = 902
    else:
        #find the optimum ROI from maximum of the relative strength vs ROI variation
        optimum_x_ROI = array_x_ROI[array_rel_strength.argsort()[-1]]
        optimum_y_ROI = array_y_ROI[array_rel_strength.argsort()[-1]]
        #proceed with further processing with optimum ROI
    optimum_ROI = (optimum_x_ROI,optimum_y_ROI)
    if debug: print("Optimum ROI is ",optimum_ROI)
    return optimum_ROI
예제 #2
0
def FindEllipseFitLeastSquares(img, nucleation_down, center_ROI, aspr_ROI,
                               array_ROI, max_norm_err_sq, new_controls):
    global debug
    global displayImages
    global doNotDisplayImagesLowLevel
    #Find the optimumROI
    optimumROI = FindAdaptiveROIversion2(img, center_ROI, aspr_ROI, array_ROI,
                                         displayImages,
                                         debug)  #find optimum ROI
    ##############
    #now that the optimumROI is found, proceed with the Otsu binarization and subsequent image processing routines to find the edges of the image and fit the ellipse.
    #However sometimes it is observed the optimum ROI is not able to bound the ellipse leading to undersampling of edge points for the fitting.
    #So it is required to iterate over the array of ROI after the optimum ROI so that sufficiently large ROI is chosen so that the ellipse is bounded completely
    ##############
    #
    #Start with iteration at the optimumROI. For that first find position of optimumROI in array_ROI
    #
    position = [i for i, each in enumerate(array_ROI) if each == optimumROI[0]]
    subarray_ROI = array_ROI[position[0]:]
    n = subarray_ROI.size
    for i in np.arange(n):
        cropsequence = CropSequenceGenerate(
            img, (center_ROI, (subarray_ROI[i], subarray_ROI[i] * aspr_ROI)))
        if doNotDisplayImagesLowLevel: displayImages = 0
        cropimg = CropImage(img, cropsequence, displayImages)
        imgbyte = Img2Ubyte(cropimg, displayImages)
        img_med = MedianFilter(imgbyte, displayImages)
        maximum, rel_strength = modal_analysis(img_med, displayImages, debug)
        #find threshold for binarization from adaptive ROI; average of the peak positions of bimodal distribution
        threshold_adaptiveROI = maximum.mean()
        threshold_global_otsu, img_otsu = GlobalOtsuThreshold(
            img_med,
            displayImages)  #Global Otsu is better than custom thresholding
        if debug:
            print("Threshold from Adaptive ROI is " +
                  str(threshold_adaptiveROI) +
                  " and that from Global Otsu is " +
                  str(threshold_global_otsu))
        img_speckless = RemoveSpeckles(img_otsu,
                                       displayImages)  #remove speckles
        img_edges, contours = CannyEdgesAndContoursOpenCV(
            img_speckless, nucleation_down, displayImages,
            debug)  #canny edge detection using openCV
        pnts = np.transpose(np.nonzero(img_edges))
        roi = img_speckless
        best_ellipse = FitEllipse_LeastSquares(pnts, roi, displayImages)
        rel_center = np.int32((best_ellipse[0][0], best_ellipse[0][1]))
        axes = np.int32([best_ellipse[1][1], best_ellipse[1][0]])
        if debug: print("At iteration : " + str(i))
        if debug: print("relative center of ellipse is : " + str(rel_center))
        if debug: print("With axes : " + str(axes))
        #find the center coordinates in old coordinate system
        #what is the origin of the ROI in old coordinate system
        origin_ROI = np.array(center_ROI) - 0.5 * np.array(
            [subarray_ROI[i], subarray_ROI[i] * aspr_ROI], dtype=np.int32)
        abs_center = rel_center + origin_ROI
        if debug: print("absoluter center of ellipse is : " + str(abs_center))
        #check if the ROI bounds the fit ellipse ; else choose the next ROI
        xwidth = subarray_ROI[i]
        ywidth = subarray_ROI[i] * aspr_ROI
        fit_xwidth = best_ellipse[1][1]
        fit_ywidth = best_ellipse[1][0]

        if ((center_ROI[0] + xwidth / 2 > abs_center[0] + fit_xwidth / 2) and
            (center_ROI[0] - xwidth / 2 < abs_center[0] - fit_xwidth / 2) and
            (center_ROI[1] + ywidth / 2 > abs_center[1] + fit_ywidth / 2) and
            (center_ROI[1] - ywidth / 2 < abs_center[1] - fit_ywidth / 2)
            ) or i == (n - 1):
            if debug: print("iteration is :" + str(i))
            #Find confidence of fit
            perc_inliers, inliers, norm_err = ConfidenceInFit(
                pnts, best_ellipse, max_norm_err_sq, debug)
            #parameters to return as an 6-channel array element
            params = np.int32([
                perc_inliers, abs_center[0], abs_center[1], best_ellipse[1][0],
                best_ellipse[1][1], best_ellipse[2]
            ])
            displayImages = 1
            #bundle the confidence parameters to avoid sending too many parameters to overlay fit
            confidence_parameters = [best_ellipse, pnts, norm_err, inliers]
            globalflags = [debug, displayImages]
            img_color = OverlayFitEllipse(img_edges, confidence_parameters,
                                          new_controls, globalflags)
            return params, img_color