RegionProposalGenerator (version 1.0.5, 2020-November-30)

RegionProposalGenerator.py
 
Version: 1.0.5
   
Author: Avinash Kak (kak@purdue.edu)
 
Date: 2020-November-30
 
 

Download Version 1.0.5:  gztar  

 
     Total number of downloads (all versions): 591
     This count is automatically updated at every rotation of
     the weblogs (normally once every two to four days)
     Last updated: Fri Feb 23 06:01:01 EST 2024

View the main module code file in your browser  
 
 
SWITCH TO VERSION 2.0.1
 
CHANGES:

  Version 1.0.5:
 
     In keeping with the tutorial nature of this module, this version
     includes methods that come in handy for batch-based processing of
     images. These methods carry names like "displaying_and_histogramming_
     images_in_batchX()" where X is 1, 2, and 3.  The rest of the module, 
     especially the part that deals with constructing region proposals 
     remains unchanged.
 
  Version 1.0.4:
 
    This is the first public release version of the module.
 
 
INTRODUCTION:
 
    This module was created with two objectives in mind: (1) To provide a
    platform for experimenting with the logic used for constructing region
    proposals for object detection; and (2) to provide an educational tool
    for becoming familiar with the basic PyTorch functionality for image
    processing.  In order to fulfill these objectives, the module provides
    a self-documenting implementation of the algorithms that should be
    relatively easy to change, rather than a highly optimized
    implementation that would be good mostly for production work.  For
    high-speed production work, it would be best to use the implementations
    provided by the original authors of the algorithms that are
    incorporated in this module.
 
    At this point, the reader might ask: What is a region proposal?  To
    respond, let's say you want to detect an object in an image, but you
    know neither the exact location of the object nor the scale at which
    the object has manifested itself --- assuming the object is present at
    all in the image.  Under these conditions, in the old days, at each
    scale of detection, you would run a sliding window through the image,
    moving it from one pixel to the next, and, at each position of the
    window, test whether the pixels inside the window speak to the presence
    of the object.  The main problem with this approach to object detection
    is its high computational overhead, especially when the occurrence of
    the object inside a window is a rare occurrence.  Detecting objects in
    a 500x500 image at, say, 4 different scales would involve testing for
    the presence of the object in a million different windows.  Assuming
    that at most one of these windows contains the object fully, all of the
    computations in all the other windows would be wasted.
 
    To get around this computational overhead, more recently research in
    object detection has taken to first creating region proposals in an
    image, these being pixel blobs that look different from the general
    background in the image, and then applying the object detection
    algorithm to just those regions.  This is the approach that was used in
    the first deep-learning based object-detection framework called R-CNN
    by Girshick, Donahue, Darrell, and Malik. Although this approach was
    subsequently abandoned in later variants of the algorithm (by using a
    CNN to also form the region proposals), finding region proposals with
    non-CNN based methods is of continued importance in several problem
    domains that do not lend themselves to deep-learning based methods.
    That is, becoming familiar with the older non-learning based methods
    for constructing region proposals still has considerable value.
    Consider, for example, the problem of detecting objects in satellite
    images where you simply do not have access to the amount of training
    data you would need for a CNN based approach to work.
 
    That brings me to the presentation of this module. From an algorithmic
    standpoint, RegionProposalGenerator (RPG) implements elements of the
    Selective Search (SS) algorithm for object detection as proposed by
    Uijlings, van de Sande, Gevers, and Smeulders.  The Selective Search
    algorithm sits on top of the graph-based image segmentation algorithm
    of Felzenszwalb and Huttenlocher (FH) whose implementation is also
    included in the RPG module.
 
    It is important to note that the RegionProposalGenerator module is not
    intended for production work. The code is not at all optimized since
    the goal is merely to provide a rather easy-to-understand
    self-documenting implementation for experimenting with the logic of
    Selective Search.  For highly efficient and optimized implementations
    of both the Selective Search algorithm and the graph-based image
    segmentation algorithm (FH), the reader should use the original
    implementations as provided by the authors of those algorithms.
 
    The RPG module first processes an image with the FH graph-based
    algorithm for image segmentation to divide an image into pixel blobs.
    The module subsequently invokes elements of the SS algorithm to
    selectively merge the blobs on the basis of three properties:
    homogeneity of the color, grayscale variance, and texture homogeneity.
 
    The FH algorithm is based on creating a graph-based representation of
    an image in which, at the beginning, each pixel is a single vertex and
    the edge between two vertices that stand for two adjacent pixels
    represents the difference between some pixel property (such as the
    color difference) at the two pixels.  Subsequently, for the vertex
    merging logic, each vertex u, that after the first iteration stands for
    a grouping of pixels, is characterized by a property called Int(u),
    which is the largest value of the inter-pixel color difference between
    the adjacent pixels.  In order to account for the fact that, at the
    beginning, each vertex consists of only one pixel [which would not
    allow for the calculation of Int(u)], the unary property of the pixels
    at a vertex is extended from Int(u) to MInt(u) with the addition of a
    vertex-size dependent number equal to k/|C| where "k" is a
    user-specified parameter and |C| the cardinality of the set of pixels
    represented by the vertex u in the graph.
 
    As mentioned above, initially the edges in the graph representation of
    an image are set to the color difference between the two 8-adjacent
    pixels that correspond to two different vertices.  Subsequently, as the
    vertices are merged, an edge, E(u,v), between two vertices u and v is
    set to the smallest value of the inter-pixel color difference for two
    adjacent pixels that belong to the two vertices. At each iteration of
    the algorithm, two vertices u and v are merged provided E(u,v) is less
    than the smaller of the MInt(u) or MInt(v) attributes at the two
    vertices.  My experience is that for most images the algorithm
    terminates of its own accord after a small number of iterations while
    the vertex merging condition can be satisfied.
 
    Since the algorithm is driven by the color differences between
    8-adjacent pixels, the FH algorithm is likely to create too fine a
    segmentation of an image.  The segments produced by FH can be made
    larger by using the logic of SS that allows blobs of pixels to merge
    into larger blobs provided doing so makes sense based on the inter-blob
    values for mean color levels, color variances, texture values, etc.
 
    With regard to the other objective of this module, the two scripts
    in the Examples subdirectory of the distribution with names that
    begin with 'torchvision' speak for themselves.
 
 
INSTALLATION:
 
    The RegionProposalGenerator class was packaged using setuptools.  For
    installation, execute the following command in the source directory
    (this is the directory that contains the setup.py file after you have
    downloaded and uncompressed the package):
 
            sudo python setup.py install
 
    and/or, for the case of Python3, 
 
            sudo python3 setup.py install
 
    On Linux distributions, this will install the module file at a location
    that looks like
 
             /usr/local/lib/python2.7/dist-packages/
 
    and, for the case of Python3, at a location that looks like
 
             /usr/local/lib/python3.6/dist-packages/
 
    If you do not have root access, you have the option of working directly
    off the directory in which you downloaded the software by simply
    placing the following statements at the top of your scripts that use
    the RegionProposalGenerator class:
 
            import sys
            sys.path.append( "pathname_to_RegionProposalGenerator_directory" )
 
    To uninstall the module, simply delete the source directory, locate
    where the RegionProposalGenerator module was installed with "locate
    RegionProposalGenerator" and delete those files.  As mentioned above,
    the full pathname to the installed version is likely to look like
    /usr/local/lib/python2.7/dist-packages/RegionProposalGenerator*
 
    If you want to carry out a non-standard install of the
    RegionProposalGenerator module, look up the on-line information on
    Disutils by pointing your browser to
 
              http://docs.python.org/dist/dist.html
 
USAGE:
 
    To generate region proposals, you would need to construct an instance
    of the RegionProposalGenerator class and invoke the methods shown below
    on this instance:
 
        from RegionProposalGenerator import *
 
        rpg = RegionProposalGenerator(
                       ###  The first 6 options affect only the Graph-Based part of the algo
                       sigma = 1.0,
                       max_iterations = 40,
                       kay = 0.05,
                       image_normalization_required = True,
                       image_size_reduction_factor = 4,
                       min_size_for_graph_based_blobs = 4,
 
                       ###  The next 4 options affect only the Selective Search part of the algo
                       color_homogeneity_thresh = [20,20,20],
                       gray_var_thresh = 16000,           
                       texture_homogeneity_thresh = 120,
                       max_num_blobs_expected = 8,
              )
        
        image_name = "images/mondrian.jpg"
        segmented_graph,color_map = rpg.graph_based_segmentation(image_name)
        rpg.visualize_segmentation_in_pseudocolor(segmented_graph[0], color_map, "graph_based" )
        merged_blobs, color_map = rpg.selective_search_for_region_proposals( segmented_graph, image_name )
        rpg.visualize_segmentation_with_mean_gray(merged_blobs, "ss_based_segmentation_in_bw" )
 
 
CONSTRUCTOR PARAMETERS: 
 
    Of the 10 constructor parameters listed below, the first six are meant for
    the FH algorithm and the last four for the SS algorithm.
 
    sigma: Controls the size of the Gaussian kernel used for smoothing the
                    image before its gradient is calculated.  Assuming the
                    pixel sampling interval to be unity, a sigma of 1 gives
                    you a 7x7 smoothing operator with Gaussian weighting.
                    The default for this parameter is 1.
 
    max_iterations: Sets an upper limit on the number of iterations of the
                    graph-based FH algorithm for image segmentation.
 
    kay: This is the same as the "k" parameter in the FH algorithm.  As
                    mentioned in the Introduction above, the Int(u)
                    property of the pixels represented by each vertex in
                    the graph representation of the image is extended to
                    MInt(u) by the addition of a number k/|C| where |C| is
                    the cardinality of the set of pixels at that vertex.
 
    image_normalization_required: This applies Torchvision's image
                    normalization to the pixel values in the image.
 
    image_size_reduction_factor: As mentioned at the beginning of this
                    document, RegionProposalGenerator is really not meant
                    for production work.  The code is pure Python and, even
                    with that, not at all optimized.  The focus of the
                    module is primarily on easy understandability of what
                    the code is doing so that you can experiment with the
                    algorithm itself.  For the module to produce results
                    within a reasonable length of time, you can use this
                    constructor parameter to downsize the array of pixels
                    that the module must work with.  Set this parameter to
                    a value so that the initial graph constructed from the
                    image has no more than around 3500 vertices if you
                    don't want to wait too long for the results.
 
    min_size_for_graph_based_blobs: This declares a threshold on the
                   smallest size you'd like to see (in terms of the number
                   of pixels) in a segmented blob in the output of the
                   graph-based segmenter.  (I typically use values from 1
                   to 4 for this parameter.)
 
    color_homogeneity_thresh:  
 
                    This and the next three constructor options are meant
                    specifically for the SS algorithm that sits on top of
                    the FH algorithm for further merging of the pixel blobs
                    produced by FH.  This constructor option specifies the
                    maximum allowable difference between the mean color
                    values in two pixel blobs for them to be merged.
 
    gray_var_thresh:
 
                   This option declares the maximum allowable difference in 
                   the variances in the grayscale in two blobs if they are
                   to be merged. 
 
    texture_homogeneity_thresh:
 
                   The RegionProposalGenerator module characterizes the
                   texture of the pixels in each segmented blob by its LBP
                   (Local Binary Patterns) texture.  We want the LBP
                   texture values for two different blobs to be within the
                   value specified by this constructor option if those
                   blobs are to be merged.
 
    max_num_blobs_expected:
 
                   If you only want to extract a certain number of the
                   largest possible blobs, you can do that by giving a
                   value to this constructor option.
 
PUBLIC METHODS:
 
    (1)  selective_search_for_region_proposals()
 
         This method implements elements of the Selective Search (SS)
         algorithm proposed by Uijlings, van de Sande, Gevers, and
         Smeulders for creating region proposals for object detection.
         As mentioned elsewhere here, this algorithm sits on top of
         the graph based image segmentation algorithm that was
         proposed by Felzenszwalb and Huttenlocher. 
 
    (2)  graph_based_segmentation()
 
         This is an implementation of the Felzenszwalb and Huttenlocher
         (FH) algorithm for graph-based segmentation of images.  At the
         moment, it is limited to working on grayscale images.
 
    (3)  display_tensor_as_image()
 
         This method converts the argument tensor into a photo image that
         you can display in your terminal screen. It can convert tensors of
         three different shapes into images: (3,H,W), (1,H,W), and (H,W),
         where H, for height, stands for the number of pixel in the
         vertical direction and W, for width, the same along the horizontal
         direction. When the first element of the shape is 3, that means
         that the tensor represents a color image in which each pixel in
         the (H,W) plane has three values for the three color channels.  On
         the other hand, when the first element is 1, that stands for a
         tensor that will be shown as a grayscale image.  And when the
         shape is just (H,W), that is automatically taken to be for a
         grayscale image.
 
    (4)  graying_resizing_binarizing()
 
         This is a demonstration of some of the more basic and commonly
         used image transformations from the torchvision.transformations
         module.  The large comment blocks are meant to serve as tutorial
         introduction to the syntax used for invoking these
         transformations.  The transformations shown can be used for
         converting a color image into a grayscale image, for resizing an
         image, for converting a PIL.Image into a tensor and a tensor back
         into an PIL.Image object, and so on.
 
    (5)  accessing_one_color_plane()
 
         This method shows how can access the n-th color plane of the
         argument color image.
 
    (6)  working_with_hsv_color_space()
 
         Illustrates converting an RGB color image into its HSV
         representation.
 
    (7)  histogramming_the_image()
 
         PyTorch based experiments with histogramming the grayscale
         and the color values in an image
 
    (8)  histogramming_and_thresholding():
 
         This method illustrates using the PyTorch functionality for
         histogramming and thresholding individual images.
 
    (9)  convolutions_with_pytorch()
 
         This method calls on torch.nn.functional.conv2d() for
         demonstrating a single image convolution with a specified
         kernel.
 
    (10) gaussian_smooth()
 
         This method smooths an image with a Gaussian of specified
         sigma.  You can do the same much faster by using the
         functionality programmed into torch.nn.functional.
 
    (11) visualize_segmentation_in_pseudocolor()
 
         After an image has been segmented, this method can be used to
         assign a random color to each blob in the segmented output
         for a better visualization of the segmentation.
 
    (12) visualize_segmentation_with_mean_gray()
 
         If the visualization produced by the previous method appears
         too chaotic, you can use this method to assign the mean color
         to each each blob in the output of an image segmentation
         algorithm.  The mean color is derived from the pixel values
         in the blob.
 
    (13) extract_image_region_interactively_by_dragging_mouse()
 
         You can use this method to apply the graph-based segmentation
         and the selective search algorithms to just a portion of your
         image.  This method extract the portion you want.  You click
         at the upper left corner of the rectangular portion of the
         image you are interested in and you then drag the mouse
         pointer to the lower right corner.  Make sure that you click
         on "save" and "exit" after you have delineated the area.
 
    (14) extract_image_region_interactively_through_mouse_clicks()
 
         This method allows a user to use a sequence of mouse clicks in
         order to specify a region of the input image that should be
         subject to further processing.  The mouse clicks taken together
         define a polygon. The method encloses the polygonal region by a
         minimum bounding rectangle, which then becomes the new input image
         for the rest of processing.
 
    (15) displaying_and_histogramming_images_in_batch1(image_dir, batch_size)
 
         This method is the first of three such methods in this module for
         illustrating the functionality of matplotlib for simultaneously
         displaying multiple images and the results obtained on them in
         gridded arrangements.  The core idea in this method is to call
         "plt.subplots(2,batch_size)" to create 'batch_size' number of
         subplot objects, called "axes", in the form of a '2xbatch_size'
         array. We use the first row of this grid to display each image in
         its own subplot object.  And we use the second row the grid to
         display the histogram of the corresponding image in the first row.
 
    (16) displaying_and_histogramming_images_in_batch2(image_dir, batch_size)
 
         I now show a second approach to displaying multiple images and their
         corresponding histograms in a gridded display.  In this method we
         call on "torchvision.utils.make_grid()" to construct a grid for
         us.  The grid is created by giving an argument like "nrow=4" to
         it.  The grid object returned by the call to make_grid() is a
         tensor unto itself. Such a tensor object is converted into a numpy
         array so that it can be displayed by matplotlib's "imshow()"
         function.
 
    (17) displaying_and_histogramming_images_in_batch3(image_dir, batch_size)
 
         This method illustrates two things: (1) The syntax used for the
         'singular' version of the subplot function "plt.subplot()" ---
         although I'll be doing so by actually calling "fig.add_subplot()".
         And (2) How you can put together multiple multi-image plots by
         creating multiple Figure objects.  'Figure' is the top-level
         container of plots in matplotlib.  This method creates two
         separate Figure objects, one as a container for all the images in
         a batch and the other as a container for all the histograms for
         the images.  The two Figure containers are displayed in two
         separate windows on your computer screen.
 
 
THE Examples DIRECTORY:
 
    The Examples subdirectory in the distribution illustrates the sort
    of region proposal results you can obtain with this module.  The
    specific illustrations are in the following subdirectories of the
    Examples directory:
 
        Examples/color_blobs/
 
        Examples/mondrian/
 
        Examples/wallpic2/
 
    Each subdirectory contains at least the following two files:
    the function 
 
        selective_search.py
        and
        the image file specific for that subdirectory.
 
    All you have to do is to execute selective_search.py in that directory to
    see the results on the image in that directory.
 
    In addition to the above, the Examples directory also contains the following
    Python scripts:
 
        selective_search.py
 
            This is the same script that you will see in the three subdirectories
            (color_blobs, mondrian, and wallpic2) mentioned above.
 
        interactive_graph_based_segmentation.py
 
            This allows you to extract a portion of an image for applying
            graph-based segmentation logic and selective-search based
            region-proposal formation to.
 
            This interactive script can be used in two different modes: you
            can extract a portion of the image by dragging your mouse over
            the portion, or by clicking the mouse at the vertices of an
            imaginary polygon that defines the portion you would like to
            extract from the image.
 
        torchvision_some_basic_transformations.py    
 
            This is a demonstration of some of the more basic and commonly
            used image transformations from the torchvision.transformations
            module.  The transformations shown can be used for converting a
            color image into a grayscale image, for resizing an image, for
            converting a PIL.Image into a tensor and a tensor back into an
            PIL.Image object, and so on.
 
        torchvision_based_image_processing.py
 
            This script illustrates some single-image image processing
            operations you can carry out with the capabilities built
            into some of the PyTorch classes.  Examples shown include
            constructing a histogram for each color channel by
            invoking 'torch.hist()' on the channel; using
            torch.nn.functional.conv2d() for demonstrating a single
            image convolution with a specified kernel; and so on.
 
        multi_image_histogramming_and_display.py  
 
            To the extent that batch-based processing of images has become
            central to what goes on in most deep-learning algorithms, it is
            good to play with code that can be used for simultaneously
            displaying multiple images along with the results obtained from
            them.  This example script invokes three different versions
            of a method that uses a gridded display to show all the images
            in a batch and their corresponding histograms.
 
 
CAVEATS:
 
    As mentioned earlier, this module is NOT meant for production work
    for constructing region proposals --- simply because it would be
    much too slow for full-sized images.  Yes, you can work with
    images of any size provided you set the constructor option
    image_size_reduction_factor appropriately.  However, note that
    setting this parameter to a large value causes a significant loss
    of resolution in the image, which reduces the quality of the
    output results.
 
    For full sized images, you will be better off using the
    implementations provided by the original authors of the
    algorithms.
 
    The goal of this module is solely to provide code that is a
    self-documented implementation of the algorithms involved.  This
    is to make it easy to experiment with the logic of the algorithms.
    
 
BUGS:
 
    Please notify the author if you encounter any bugs.  When sending
    email, please place the string 'RegionProposalGenerator' in the
    subject line to get past the author's spam filter.
 
 
ABOUT THE AUTHOR:
 
    The author, Avinash Kak, is a professor of Electrical and Computer
    Engineering at Purdue University.  For all issues related to this
    module, contact the author at kak@purdue.edu If you send email,
    please place the string "RegionProposalGenerator" in your subject
    line to get past the author's spam filter.
 
COPYRIGHT:
 
    Python Software Foundation License
 
    Copyright 2020 Avinash Kak
 
@endofdocs

 
Imported Modules
       
BitVector
PIL.Image
PIL.ImageDraw
PIL.ImageTk
tkinter
copy
functools
glob
math
torch.nn
numpy
os
matplotlib.pyplot
random
re
signal
sys
time
torch
torchvision.utils
torchvision.transforms

 
Classes
       
builtins.object
RegionProposalGenerator

 
class RegionProposalGenerator(builtins.object)
    RegionProposalGenerator(*args, **kwargs)
 

 
  Methods defined here:
__init__(self, *args, **kwargs)
Initialize self.  See help(type(self)) for accurate signature.
accessing_one_color_plane(self, image_file, n)
This method shows how can access the n-th color plane of the argument color image.
convolutions_with_pytorch(self, image_file, kernel)
Using torch.nn.functional.conv2d() for demonstrating a single image convolution with
a specified kernel
displayImage(self, argimage, title='')
Displays the argument image.  The display stays on for the number of seconds
that is the first argument in the call to tk.after() divided by 1000.
displayImage2(self, argimage, title='')
Displays the argument image.  The display stays on until the user closes the
window.  If you want a display that automatically shuts off after a certain
number of seconds, use the previous method displayImage().
displayImage3(self, argimage, title='')
Displays the argument image (which must be of type Image) in its actual size.  The 
display stays on until the user closes the window.  If you want a display that 
automatically shuts off after a certain number of seconds, use the method 
displayImage().
displayImage4(self, argimage, title='')
Displays the argument image (which must be of type Image) in its actual size without 
imposing the constraint that the larger dimension of the image be at most half the 
corresponding screen dimension.
displayImage5(self, argimage, title='')
This does the same thing as displayImage4() except that it also provides for
"save" and "exit" buttons.  This method displays the argument image with more 
liberal sizing constraints than the previous methods.  This method is 
recommended for showing a composite of all the segmented objects, with each
object displayed separately.  Note that 'argimage' must be of type Image.
displayImage6(self, argimage, title='')
For the argimge which must be of type PIL.Image, this does the same thing as
displayImage3() except that it also provides for "save" and "exit" buttons.
display_tensor_as_image(self, tensor, title='')
This method converts the argument tensor into a photo image that you can display
in your terminal screen. It can convert tensors of three different shapes
into images: (3,H,W), (1,H,W), and (H,W), where H, for height, stands for the
number of pixels in the vertical direction and W, for width, for the same
along the horizontal direction.  When the first element of the shape is 3,
that means that the tensor represents a color image in which each pixel in
the (H,W) plane has three values for the three color channels.  On the other
hand, when the first element is 1, that stands for a tensor that will be
shown as a grayscale image.  And when the shape is just (H,W), that is
automatically taken to be for a grayscale image.
display_tensor_as_image2(self, tensor, title='')
This method converts the argument tensor into a photo image that you can display
in your terminal screen. It can convert tensors of three different shapes
into images: (3,H,W), (1,H,W), and (H,W), where H, for height, stands for the
number of pixels in the vertical direction and W, for width, for the same
along the horizontal direction.  When the first element of the shape is 3,
that means that the tensor represents a color image in which each pixel in
the (H,W) plane has three values for the three color channels.  On the other
hand, when the first element is 1, that stands for a tensor that will be
shown as a grayscale image.  And when the shape is just (H,W), that is
automatically taken to be for a grayscale image.
displaying_and_histogramming_images_in_batch1(self, dir_name, batch_size)
This method is the first of three such methods in this module for illustrating the
functionality of matplotlib for simultaneously displaying multiple images and
the results obtained on them in gridded arrangements.  In the implementation
shown below, the core idea in this method is to call
"plt.subplots(2,batch_size)" to create 'batch_size' number of subplot
objects, called "axes", in the form of a '2xbatch_size' array. We use the first
row of this grid to display each image in its own subplot object.  And we use
the second row the grid to display the histogram of the corresponding image
in the first row.
displaying_and_histogramming_images_in_batch2(self, dir_name, batch_size)
I now show a second approach to display multiple images and their corresponding
histograms in a gridded display.  Unlike in the previous implementation of
this method, now we do not call on "plt.subplots()" to create a grid
structure for displaying the images.  On the other hand, we now call on
"torchvision.utils.make_grid()" to construct a grid for us.  The grid is
created by giving an argument like "nrow=4" to it.  When using this method,
an important thing to keep in mind is that the first argument to make_grip()
must be a tensor of shape "(B, C, H, W)" where B stands for batch_size, C for
channels (3 for color, 1 for gray), and (H,W) for the height and width of the
image. What that means in our example is that we need to synthesize a tensor
of shape "(8,1,64,64)" in order to be able to call the "make_grid()"
function. Note that the object returned by the call to make_grid() is a
tensor unto itself.  For the example shown, if we had called
"print(grid.shape)" on the "grid" returned by "make_grid()", the answer would
be "torch.Size([3, 158, 306])" which, after it is converted into a numpy
array, can be construed by a plotting function as a color image of size
158x306.
displaying_and_histogramming_images_in_batch3(self, dir_name, batch_size)
The core idea here is to illustrate two things: (1) The syntax used for the
'singular' version of the subplot function "plt.subplot()" --- although I'll
be doing so by actually calling "fig.add_subplot()".  And (2) How you can put
together multiple multi-image plots by creating multiple Figure objects.
Figure is the top-level container of plots in matplotlib.  In the 
implementation shown below, the key statements are: 
 
    fig1 = plt.figure(1)    
    axis = fig1.add_subplot(241)              
                                                                                                              
Calling "add_subplot()" on a Figure object returns an "axis" object.  The
word "axis" is a misnomer for what should really be called a "subplot".
Subsequently, you can call display functions lime "imshow()", "bar()", etc.,
on the axis object to display an individual plot in a gridded arrangement.
 
The argument "241" in the first call to "add_subplot()" means that your
larger goal is to create a 2x4 display of plots and that you are supplying
the 1st plot for that grid.  Similarly, the argument "242" in the next call
to "add_subplot()" means that for your goal of creating a 2x4 gridded
arrangement of plots, you are now supplying the second plot.  Along the same
lines, the argument "248" toward the end of the code block that you are now
supplying the 8th plot for the 2x4 arrangement of plots.
 
Note how we create a second Figure object in the second major code block.  We
use it to display the histograms for each of the images shown in the first
Figure object.  The two Figure containers will be shown in two separate
windows on your laptop screen.
extract_data_pixels_in_bb(self, image_file, bounding_box)
Mainly used for testing
extract_image_region_interactively_by_dragging_mouse(self, image_name)
This is one method you can use to apply selective search algorithm to just a
portion of your image.  This method extract the portion you want.  You click
at the upper left corner of the rectangular portion of the image you are
interested in and you then drag the mouse pointer to the lower right corner.
Make sure that you click on "save" and "exit" after you have delineated the
area.
extract_image_region_interactively_through_mouse_clicks(self, image_file)
This method allows a user to use a sequence of mouse clicks in order to specify a
region of the input image that should be subject to furhter processing.  The
mouse clicks taken together define a polygon. The method encloses the
polygonal region by a minimum bounding rectangle, which then becomes the new
input image for the rest of processing.
extract_rectangular_masked_segment_of_image(self, horiz_start, horiz_end, vert_start, vert_end)
Keep in mind the following convention used in the PIL's Image class: the first
coordinate in the args supplied to the getpixel() and putpixel() methods is for
the horizontal axis (the x-axis, if you will) and the second coordinate for the
vertical axis (the y-axis).  On the other hand, in the args supplied to the
array and matrix processing functions, the first coordinate is for the row
index (meaning the vertical) and the second coordinate for the column index
(meaning the horizontal).  In what follows, I use the index 'i' with its
positive direction going down for the vertical coordinate and the index 'j'
with its positive direction going to the right as the horizontal coordinate. 
The origin is at the upper left corner of the image.
gaussian_smooth(self, pil_grayscale_image)
This method smooths an image with a Gaussian of specified sigma.
graph_based_segmentation(self, image_name, num_blobs_wanted=None)
This is an implementation of the Felzenszwalb and Huttenlocher algorithm for
graph-based segmentation of images.  At the moment, it is limited to working
on grayscale images.
graph_based_segmentation_for_arrays(self, which_one)
This method is provided to enable the user to play with small arrays when
experimenting with graph-based logic for image segmentation.  At the moment, it
provides three small arrays, one under the "which_one==1" option, one under the
"which_one==2" option, and the last under the "which_one==3" option.
graying_resizing_binarizing(self, image_file, polarity=1, area_threshold=0, min_brightness_level=100)
This is a demonstration of some of the more basic and commonly used image
transformations from the torchvision.transformations module.  The large comments
blocks are meant to serve as tutorial introduction to the syntax used for invoking
these transformations.  The transformations shown can be used for converting a
color image into a grayscale image, for resizing an image, for converting a
PIL.Image into a tensor and a tensor back into an PIL.Image object, and so on.
histogramming_and_thresholding(self, image_file)
PyTorch based experiments with histogramming and thresholding
histogramming_the_image(self, image_file)
PyTorch based experiments with histogramming the grayscale and the color values in an
image
repair_blobs(self, merged_blobs, color_map, all_pairwise_similarities)
The goal here to do a final clean-up of the blob by merging tiny pixel blobs with
an immediate neighbor, etc.  Such a cleanup requires adjacency info regarding the
blobs in order to figure out which larger blob to merge a small blob with.
selective_search_for_region_proposals(self, graph, image_name)
This method implements the Selective Search (SS) algorithm proposed by Uijlings,
van de Sande, Gevers, and Smeulders for creating region proposals for object
detection.  As mentioned elsewhere here, that algorithm sits on top of the graph
based image segmentation algorithm that was proposed by Felzenszwalb and
Huttenlocher.  The parameter 'pixel_blobs' required by the method presented here
is supposed to be the pixel blobs produced by the Felzenszwalb and Huttenlocher
algorithm.
visualize_segmentation_in_pseudocolor(self, pixel_blobs, color_map, label='')
Assigns a random color to each blob in the output of an image segmentation algorithm
visualize_segmentation_with_mean_gray(self, pixel_blobs, label='')
Assigns the mean color to each each blob in the output of an image segmentation algorithm
working_with_hsv_color_space(self, image_file, test=False)
Shows color image conversion to HSV

Data descriptors defined here:
__dict__
dictionary for instance variables (if defined)
__weakref__
list of weak references to the object (if defined)

Data and other attributes defined here:
canvas = None
drawEnable = 0
region_mark_coords = {}
startX = 0
startY = 0

 
Functions
       
ctrl_c_handler(signum, frame)

p
        __author__ = 'Avinash Kak (kak@purdue.edu)'
__copyright__ = '(C) 2020 Avinash Kak. Python Software Foundation.'
__date__ = '2020-November-30'
__url__ = 'https://engineering.purdue.edu/kak/distRPG/RegionProposalGenerator-1.0.5.html'
__version__ = '1.0.5'
 
Author
        Avinash Kak (kak@purdue.edu)