
    Yh"o                     |    d Z ddlZddlZddlZddlmZ ddlZddlZ	ddl
Z
ddlZddlZddlmZ  G d d          ZdS )z
Created by Jaided AI
Released Date: 18/08/2022
Description:
DBNet text detection module. 
Many parts of the codes are adapted from https://github.com/MhLiao/DB
    N)Polygon   )Configurablec                       e Zd Z	 	 	 	 	 	 	 ddZd Zd	 Zd
 Zd Zd Zd dZ	d Z
d Zd!dZd dZ	 	 	 	 	 d"dZd Z	 	 	 d#dZ	 	 	 d#dZd$dZd Zd Zd Z	 	 	 	 	 	 	 d%dZdS )&DBNetresnet18N
pretrainedTcudar   c                 p   || _         t          j                            t          j                            t
                    dd          }t          |d          5 }	t          j        |	          | _	        ddd           n# 1 swxY w Y   | | 
                    | j	        |          | _	        || j	                                        v r|| _        nLt          d                    d                    | j	                                                                      ||| _        nGt          j                            t          j                            t
                    d          | _        |r|| j	        |         d                                         v r?t          j                            | j        | j	        |         d         |                   }
d	}n't          j                            | j        |          }
d
}t          j                            |
          s#t#          |                    ||
                    |                     | j	        |         d         |
           nd| _        t)          j        | j	        d                   | _        | j	        d         | _        | j	        d         | _        dS )a  
        DBNet text detector class

        Parameters
        ----------
        backbone : str, optional
            Backbone to use. Options are "resnet18" and "resnet50". The default is "resnet18".
        weight_dir : str, optional
            Path to directory that contains weight files. If set to None, the path will be set
            to "../weights/". The default is None.
        weight_name : str, optional
            Name of the weight to use as specified in DBNet_inference.yaml or a filename 
            in weight_dir. The default is 'pretrained'.
        initialize_model : Boolean, optional
            If True, construct the model and load weight at class initialization.
            Otherwise, only initial the class without constructing the model.
            The default is True.
        dynamic_import_relative_path : str, optional
            Relative path to 'model/detector.py'. This option is for supporting
            integrating this module into other modules. For example, easyocr/DBNet
            This should be left as None when calling this module as a standalone. 
            The default is None.
        device : str, optional
            Device to use. Options are "cuda" and "cpu". The default is 'cuda'.
        verbose : int, optional
            Verbosity level. The default is 0.

        Raises
        ------
        ValueError
            Raised when backbone is invalid.
        FileNotFoundError
            Raised when weight file is not found.

        Returns
        -------
        None.
        configszDBNet_inference.yamlrNz2Invalid backbone. Current support backbone are {}.,weightsweightzUA weight with a name {} is found in DBNet_inference.yaml but cannot be find file: {}.zYA weight with a name {} is not found in DBNet_inference.yaml and cannot be find file: {}.modelBGR_MEANmin_detection_sizemax_detection_size)deviceospathjoindirname__file__openyaml	safe_loadr   set_relative_import_pathkeysbackbone
ValueErrorformat
weight_dirisfileFileNotFoundErrorinitialize_modelr   nparrayr   r   r   )selfr    r#   weight_namer&   dynamic_import_relative_pathr   verboseconfig_pathfidweight_patherror_messages               e/var/www/tools.fuzzalab.pt/emblema-extractor/venv/lib/python3.11/site-packages/easyocr/DBNet/DBNet.py__init__zDBNet.__init__   sr   \ gll27??8#<#<iI_``+s## 	/s>#..DL	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ 	/ (388GcddDLt|((****$DMMQXXY\YaYabfbnbsbsbubuYvYvwwxxx!(DOO gll27??8+D+DiPPDO 	dl84X>CCEEEE gll4?DL<RS[<\]h<ijj w gll4?KHH {7>>+.. X'(<(<[+(V(VWWW!!$,x"8"A;OOOO DJj!9::"&,/C"D"&,/C"Ds   BBBc           
      f   |J |                     t          j                  }|                                D ]x\  }}|dk    rA|                    |d                    ||                     d          z             i           Lt          |t                    r|                     ||          }xy|S )a  
        Create relative import paths for modules specified in class. This method
        is recursive.

        Parameters
        ----------
        configs : dict
            Configuration dictionary from .yaml file.
        dynamic_import_relative_path : str, optional
            Relative path to 'model/detector/'. This option is for supporting
            integrating this module into other modules. For example, easyocr/DBNet
            This should be left as None when calling this module as a standalone. 
            The default is None.
        
        Returns
        -------
        configs : dict
            Configuration dictionary with correct relative path.
        Nclass.)	splitr   sepitemsupdater   
isinstancedictr   )r)   r   r+   preficeskeyvalues         r1   r   zDBNet.set_relative_import_pathj   s    ( ,777/55bf==  	 	ICg~~SXXhS9I9I.I%J%JKLLLLeT**  99%A]^^EE    c                     | j         t          d          | j                             t          j        || j                  d           | j                                          dS )a.  
        Load weight to model.

        Parameters
        ----------
        weight_path : str
            Path to trained weight.

        Raises
        ------
        RuntimeError
            Raised when the model has not yet been contructed.

        Returns
        -------
        None.
        Nz#model has not yet been constructed.)map_locationF)strict)r   RuntimeErrorload_state_dicttorchloadr   eval)r)   r/   s     r1   load_weightzDBNet.load_weight   s`    $ :DEEE
""5:k#T#T#T]b"ccc
r?   c                 |    t          j        |          j        j                            | j                  | _        dS )z
        Contruct text detection model based on the configuration in .yaml file.

        Parameters
        ----------
        config : dict
            Configuration dictionary.

        Returns
        -------
        None.
        N)r   construct_class_from_config	structurebuilderbuildr   r   )r)   configs     r1   construct_modelzDBNet.construct_model   s2     "=fEEOW]]^b^ijj


r?   c                 0   |                      |           |                     |           t          | j        j        t          j        j                  r@| j        dk    r7| j        j        j        	                    | j                  | j        _        dS dS dS )aO  
        Wrapper to initialize text detection model. This model includes contructing
        and weight loading.

        Parameters
        ----------
        model_config : dict
            Configuration dictionary.
        weight_path : str
            Path to trained weight.

        Returns
        -------
        None.
        cpuN)
rO   rH   r:   r   rE   nnDataParallelr   moduleto)r)   model_configr/   s      r1   r&   zDBNet.initialize_model   s      	\***%%%dj&(=>> 	G4;RWCWCW#z/699$+FFDJ	G 	GCWCWr?   c                    t          |t                    rtt          j                            |          r3t          j        |t
          j                                      d          }nt          d
                    |                    t          |t          j                  r|                    d          }nSt          |t          j        j                  r%t          j        |          dddddddf         }nt!          d          |S )a  
        Load or convert input to OpenCV BGR image numpy array.

        Parameters
        ----------
        image : str, PIL.Image, or np.ndarray
            Image to load or convert.

        Raises
        ------
        FileNotFoundError
            Raised when the input is a path to file (str), but the file is not found.
        TypeError
            Raised when the data type of the input is not supported.

        Returns
        -------
        image : np.ndarray
            OpenCV BGR image.
        float32zCannot find {}NzYUnsupport image format. Only path-to-file, opencv BGR image, and PIL image are supported.)r:   strr   r   r$   cv2imreadIMREAD_COLORastyper%   r"   r'   ndarrayPILImageasarray	TypeErrorr)   images     r1   get_cv2_imagezDBNet.get_cv2_image   s    * eS!! 
	yw~~e$$ H
5#*:;;BB9MM'(8(?(?(F(FGGGrz** 	yLL++EEsy// 	yJu%%aaaDDbDj1EEwxxxr?   c                    |j         \  }}}|)t          | j        t          ||| j                            }||k     rUt          t          j        |dz            dz            }t          t          j        ||z  |z  dz            dz            }nTt          t          j        |dz            dz            }t          t          j        ||z  |z  dz            dz            }t          j	        |||f          }|||ffS )a  
        Resize image such that the shorter side of the image is equal to the 
        closest multiple of 32 to the provided detection_size. If detection_size
        is not provided, it will be resized to the closest multiple of 32 each
        side. If the original size exceeds the min-/max-detection sizes 
        (specified in configs.yaml), it will be resized to be within the 
        min-/max-sizes.

        Parameters
        ----------
        img : np.ndarray
            OpenCV BGR image.
        detection_size : int, optional
            Target detection size. The default is None.

        Returns
        -------
        np.ndarray
            Resized OpenCV BGR image. The width and height of this image should
            be multiple of 32.
        N    )
shapemaxr   minr   intmathceilr[   resize)	r)   imgdetection_sizeheightwidth_
new_height	new_widthresized_imgs	            r1   resize_imagezDBNet.resize_image   s   , 9q! !8#feTMd:e:effNE>>TY~':;;b@AAJDIj6&9E&AB&FGG"LMMIIDInr&9::R?@@ITYy5'86'AB'FGG"LMMJjy*&=>>VUO++r?   c                     t          j        |                              ddd                                                              d          S )a4  
        Convert image array (assuming OpenCV BGR format) to image tensor.

        Parameters
        ----------
        image : np.ndarray
            OpenCV BGR image.

        Returns
        -------
        torch.tensor
            Tensor image with 4 dimension [batch, channel, width, height].
           r   r   )rE   
from_numpypermutefloat	unsqueezerd   s     r1   image_array2tensorzDBNet.image_array2tensor  sA     &&..q!Q77==??II!LLLr?   c                     || j         z
  dz  S )z
        Normalize image by substracting BGR mean and divided by 255

        Parameters
        ----------
        image : np.ndarray
            OpenCV BGR image.

        Returns
        -------
        np.ndarray
            OpenCV BGR image.
        g     o@)r   rd   s     r1   normalize_imagezDBNet.normalize_image  s     %u,,r?   c                     |                      |          }|                     ||          \  }}|                     |          }|                     |          }||fS )a$  
        Wrapper to load and convert an image to an image tensor

        Parameters
        ----------
        image : path-to-file, PIL.Image, or np.ndarray
            Image to load or convert.
        detection_size : int, optional
            Target detection size. The default is None.

        Returns
        -------
        img : torch.tensor
            Tensor image with 4 dimension [batch, channel, width, height]..
        original_shape : tuple
            A tuple (height, width) of the original input image before resizing.
        rq   )rf   rx   r   r   )r)   
image_pathrq   rp   original_shapes        r1   
load_imagezDBNet.load_image,  se    $ 
++"//n/UU^""3''%%c**N""r?   c                 h     t           fd|D              \  }}t          j        |d          |fS )a  
        Wrapper to load or convert list of multiple images to a single image 
        tensor. Multiple images are concatenated together on the first dimension.
        
        Parameters
        ----------
        images : a list of path-to-file, PIL.Image, or np.ndarray
            Image to load or convert.
        detection_size : int, optional
            Target detection size. The default is None.

        Returns
        -------
        img : torch.tensor
            A single tensor image with 4 dimension [batch, channel, width, height].
        original_shape : tuple
            A list of tuples (height, width) of the original input image before resizing.
        c                 >    g | ]}                     |           S )r   )r   ).0re   rq   r)   s     r1   
<listcomp>z%DBNet.load_images.<locals>.<listcomp>X  s:     (= (= (=,1 )-P^(_(_ (= (= (=r?   r   )dim)ziprE   cat)r)   imagesrq   original_shapess   ` ` r1   load_imageszDBNet.load_imagesE  sZ    & #& (= (= (= (= (=5;(= (= (= #>yq)))?::r?   皙?   Fc	           
         |                      ||          }	g }
g }t          |                    d                    D ]}||         \  }}|r,|                     ||         |	|         |||||          \  }}n+|                     ||         |	|         |||||          \  }}|
                    |           |                    |           t          d t          |
|          D              \  }
}|
|fS )a  
        Translate probability heatmap tensor to text region boudning boxes.

        Parameters
        ----------
        image_tensor : torch.tensor
            Image tensor.
        original_shapes : tuple
            Original size of the image (height, width) of the input image (before
            rounded to the closest multiple of 32).
        hmap : torch.tensor
            Probability heatmap tensor.
        text_threshold : float, optional
            Minimum probability for each pixel of heatmap tensor to be considered
            as a valid text pixel. The default is 0.2.
        bbox_min_score : float, optional
            Minimum score for each detected bounding box to be considered as a
            valid text bounding box. The default is 0.2.
        bbox_min_size : int, optional
            Minimum size for each detected bounding box to be considered as a
            valid text bounding box. The default is 3.
        max_candidates : int, optional
            Maximum number of detected bounding boxes to be considered as 
            candidates for valid text bounding box. Setting it to 0 implies
            no maximum. The default is 0.
        as_polygon : boolean, optional
            If True, return the bounding box as polygon (fine vertrices), 
            otherwise return as rectangular. The default is False.

        Returns
        -------
        boxes_batch : list of lists
            Bounding boxes of each text box.
        scores_batch : list of floats
            Confidence scores of each text box.

        )	thresholdr   )bbox_min_scorebbox_min_sizemax_candidatesc           	          g | ]=\  }}t          |d k              r!t          d t          ||          D              nddg>S )r   c                 (    g | ]\  }}|d k    ||fS r    )r   boxscores      r1   r   z.DBNet.hmap2bbox.<locals>.<listcomp>.<listcomp>  s9     0d 0d 0d4?SY^abYbYb 25eYbYbYbr?   r   )anyr   )r   boxesscoress      r1   r   z#DBNet.hmap2bbox.<locals>.<listcomp>  s     *` *` *` .=eV 36fqj//+O# 0d 0dCFufCUCU0d 0d 0d +/ +/HJ2w*` *` *`r?   )binarizerangesizepolygons_from_bitmapboxes_from_bitmapappendr   )r)   image_tensorr   hmaptext_thresholdr   r   r   
as_polygonsegmentationboxes_batchscores_batchbatch_indexrr   rs   r   r   s                    r1   	hmap2bboxzDBNet.hmap2bbox\  s[   \ }}T~}FF !2!21!5!566 	( 	(K+K8MFE I $ 9 9(,[(9(4[(A(-(.9G8E9G !: !I !Ivv !% 6 6(,[(9(4[(A(-(.9G8E9G !7 !I !Iv u%%%''''$' *` *` ADKQ]@^@^*` *` *` %)!\ L((r?   c                     ||k    S )a  
        Apply threshold to return boolean tensor.

        Parameters
        ----------
        tensor : torch.tensor
            input tensor.
        threshold : float
            Threshold.

        Returns
        -------
        torch.tensor
            Boolean tensor.

        r   )r)   tensorr   s      r1   r   zDBNet.binarize  s    " 	!!r?   c                    |                     d          dk    sJ |                                                                d         }|                                                                                                d         }|j        \  }	}
g }g }t          j        |dz                      t          j	                  t
          j
        t
          j                  \  }}|dk    r
|d|         }|D ]
}dt          j        |d          z  }t          j        ||d          }|                    d          }|j        d         dk     rX|                     ||                    d	d
                    }||k     r|j        d         d
k    r,|                     |d          }t#          |          dk    rn|                    d	d
          }|                     |                    d                    \  }}||d
z   k     rt'          |t(                    s(|                                }|                                }t          j        t          j        |dddf         |
z  |z            d|          |dddf<   t          j        t          j        |dddf         |	z  |z            d|          |dddf<   |                    |                                           |                    |           ||fS )a  
        Translate boolean tensor to fine polygon indicating text bounding boxes

        Parameters
        ----------
        hmap : torch.tensor
            Probability heatmap tensor.
        segmentation : torch.tensor
            Segmentataion tensor.
        dest_width : TYPE
            target width of the output.
        dest_height : TYPE
            target width of the output.
        bbox_min_score : float, optional
            Minimum score for each detected bounding box to be considered as a
            valid text bounding box. The default is 0.2.
        bbox_min_size : int, optional
            Minimum size for each detected bounding box to be considered as a
            valid text bounding box. The default is 3.
        max_candidates : int, optional
            Maximum number of detected bounding boxes to be considered as 
            candidates for valid text bounding box. Setting it to 0 implies
            no maximum. The default is 0.
        
        Returns
        -------
        boxes_batch : list of lists
            Polygon bounding boxes of each text box.
        scores_batch : list of floats
            Confidence scores of each text box.

        r   r      NgMb`?T)rY   rz      rY   rz   g       @)unclip_ratio)rY   r   rz   )r   rQ   numpydetachri   r[   findContoursr^   r'   uint8	RETR_LISTCHAIN_APPROX_SIMPLE	arcLengthapproxPolyDPreshapebox_score_fastuncliplenget_mini_boxesr:   rl   itemcliproundr   tolist)r)   r   r   
dest_widthdest_heightr   r   r   bitmaprr   rs   r   r   contoursrt   contourepsilonapproxpointsr   r   ssides                         r1   r   zDBNet.polygons_from_bitmap  s   P   ##q((((!!##))++A.xxzz  ""((**1-&CZ))M324 4! A0H !	! !	!GcmGT:::G%gw==F^^G,,F|A""''fnnR.C.CDDE~%%|A""kk&sk;;s88a<<   ++b!$$C**3;;z+B+BCCHAu}q(((j#.. 1'__..
)..00QQQTU*Z788!ZI IC1IQQQTV+k9::A{L LC1ILL&&&MM%    f}r?   c                 f   |                     d          dk    sJ |                                                                d         }|                                                                                                d         }|j        \  }	}
t          j        |dz                      t          j	                  t
          j
        t
          j                  \  }}|dk    rt          t          |          |          }nt          |          }t          j        |ddft          j                  }t          j        |ft          j                  }t#          |          D ]}||         }|                     |          \  }}||k     r*t          j        |          }|                     ||                    dd                    }||k     ro|                     |                              ddd          }|                     |          \  }}||dz   k     rt          j        |          }t/          |t0                    s(|                                }|                                }t          j        t          j        |dddf         |
z  |z            d|          |dddf<   t          j        t          j        |dddf         |	z  |z            d|          |dddf<   |                    t          j                  ||ddddf<   |||<   |                                |fS )	a  
        Translate boolean tensor to fine polygon indicating text bounding boxes

        Parameters
        ----------
        hmap : torch.tensor
            Probability heatmap tensor.
        segmentation : torch.tensor
            Segmentataion tensor.
        dest_width : TYPE
            target width of the output.
        dest_height : TYPE
            target width of the output.
        bbox_min_score : float, optional
            Minimum score for each detected bounding box to be considered as a
            valid text bounding box. The default is 0.2.
        bbox_min_size : int, optional
            Minimum size for each detected bounding box to be considered as a
            valid text bounding box. The default is 3.
        max_candidates : int, optional
            Maximum number of detected bounding boxes to be considered as 
            candidates for valid text bounding box. Setting it to 0 implies
            no maximum. The default is 0.
        
        Returns
        -------
        boxes_batch : list of lists
            Polygon bounding boxes of each text box.
        scores_batch : list of floats
            Confidence scores of each text box.
        r   r   r   r   rz   dtyperY   N)r   rQ   r   r   ri   r[   r   r^   r'   r   r   r   rk   r   zerosint16rX   r   r   r(   r   r   r   r:   rl   r   r   r   r   )r)   r   r   r   r   r   r   r   r   rr   rs   r   rt   num_contoursr   r   indexr   r   r   r   r   s                         r1   r   zDBNet.boxes_from_bitmap  s   N   ##q((((!!##))++A.xxzz  ""((**1-&#CZ//99M3+BD D! As8}}n==LLx==L,1-RX>>></<<<<(( 	" 	"EuoG //88MFE}$$Xf%%F''fnnR.C.CDDE~%%++f%%--b!Q77C,,S11JC}q((((3--Cj#.. 1'__..
)..00QQQTU*Z788!ZI IC1IQQQTV+k9::A{L LC1I!$BH!5!5E%AAA+!F5MM||~~v%%r?         ?c                    t          |          }|j        |z  |j        z  }t          j                    }|                    |t          j        t          j                   t          j	        |
                    |                    }|S N)r   arealength	pyclipperPyclipperOffsetAddPathJT_ROUNDET_CLOSEDPOLYGONr'   r(   Execute)r)   r   r   polydistanceoffsetexpandeds          r1   r   zDBNet.unclipo  sj    s||9|+dk9*,,sI.	0JKKK8FNN84455r?   c                    t          j        |          }t          t          t          j        |                    d           }d\  }}}}|d         d         |d         d         k    rd}d}nd}d}|d         d         |d         d         k    rd}d}nd}d}||         ||         ||         ||         g}|t          |d                   fS )Nc                     | d         S )Nr   r   )xs    r1   <lambda>z&DBNet.get_mini_boxes.<locals>.<lambda>z  s
    1 r?   )r=   )r   r   rz   r   r   r   r   rz   )r[   minAreaRectsortedlist	boxPointsrk   )	r)   r   bounding_boxr   index_1index_2index_3index_4r   s	            r1   r   zDBNet.get_mini_boxesx  s    w//S]<8899~~NNN-7*'7!9Q<&)A,&&GGGGG!9Q<&)A,&&GGGGGgwgw1 CQ((((r?   c                    |j         dd         \  }}|                                }t          j        t          j        |dddf                                                                       t          j                  d|dz
            }t          j        t          j        |dddf         	                                                              t          j                  d|dz
            }t          j        t          j        |dddf                                                                       t          j                  d|dz
            }t          j        t          j        |dddf         	                                                              t          j                  d|dz
            }	t          j
        |	|z
  dz   ||z
  dz   ft          j                  }
|dddf         |z
  |dddf<   |dddf         |z
  |dddf<   t          j        |
|                    ddd                              t          j                  d           t          j        |||	dz   ||dz   f         |
          d         S )a-  
        Calculate total score of each bounding box

        Parameters
        ----------
        hmap : torch.tensor
            Probability heatmap tensor.
        box_ : list
            Rectanguar bounding box.

        Returns
        -------
        float
            Confidence score.
        Nrz   r   r   r   rY   )ri   copyr'   r   floorrk   r^   int32rn   rj   r   r   r[   fillPolyr   mean)r)   r   box_hwr   xminxmaxyminymaxmasks              r1   r   zDBNet.box_score_fast  s     z"1"~1iikkwrxAAAqD	0077AA1a!eLLwrws111a4y}}//66rx@@!QUKKwrxAAAqD	0077AA1a!eLLwrws111a4y}}//66rx@@!QUKKxq$+/:"(KKK1I$AAAqD	1I$AAAqD	T3;;q"a0077AA1EEExT$q&[$tAv+56==a@@r?   c                 :    | j                             |d          S )ap  
        Run the model to obtain a heatmap tensor from a image tensor. The heatmap
        tensor indicates the probability of each pixel being a part of text area.

        Parameters
        ----------
        image_tensor : torch.tensor
            Image tensor.

        Returns
        -------
        torch.tensor
            Probability heatmap tensor.
        F)training)r   forward)r)   r   s     r1   
image2hmapzDBNet.image2hmap  s     z!!,!???r?   c	                 6   t          |t                    s|g}|                     ||          \  }	}
t          j                    5  |                     |	          }|                     |	|
||||||          \  }}ddd           n# 1 swxY w Y   |r||fS |S )az  
        Wrapper to run the model on an input image to get text bounding boxes.

        Parameters
        ----------
        image : path-to-file, PIL.Image, or np.ndarray
            Image to load or convert.
        text_threshold : float, optional
            Minimum probability for each pixel of heatmap tensor to be considered
            as a valid text pixel. The default is 0.2.
        bbox_min_score : float, optional
            Minimum score for each detected bounding box to be considered as a
            valid text bounding box. The default is 0.2.
        bbox_min_size : int, optional
            Minimum size for each detected bounding box to be considered as a
            valid text bounding box. The default is 3.
        max_candidates : int, optional
            Maximum number of detected bounding boxes to be considered as 
            candidates for valid text bounding box. Setting it to 0 implies
            no maximum. The default is 0.
        detection_size : int, optional
            Target detection size. Please see docstring under method resize_image()
            for explanation. The default is None.
        as_polygon : boolean, optional
            If true, return the bounding boxes as find polygons, otherwise, return
            as rectagular. The default is False.
        return_scores : boolean, optional
            If true, return confidence score along with the text bounding boxes.
            The default is False.

        Returns
        -------
        list of lists
            Text bounding boxes. If return_scores is set to true, another list
            of lists will also be returned.

        r   )r   r   r   r   r   N)r:   r   r   rE   no_gradr  r   )r)   re   r   r   r   r   rq   r   return_scoresr   r   r   batch_boxesbatch_scoress                 r1   	inferencezDBNet.inference  s   \ %&& 	GE(,(8(8Q_(8(`(`%o]__ 		N 		N??<00D(,|7F7;HVHVGTHVBL )7 )N )N%K		N 		N 		N 		N 		N 		N 		N 		N 		N 		N 		N 		N 		N 		N 		N  	,,s   6BBB)r   Nr	   TNr
   r   r   r   )r   r   r   r   F)r   r   r   )r   )r   r   r   r   NFF)__name__
__module____qualname__r2   r   rH   rO   r&   rf   rx   r   r   r   r   r   r   r   r   r   r   r   r  r
  r   r?   r1   r   r      s       &"+$(04 SE SE SE SEj  @  .k k kG G G*! ! !F", ", ", ",HM M M - - - # # # #2; ; ; ;6 $'#&"##$"O) O) O) O)b" " "0 /2-../Y Y Y Y@ ,/*++,R& R& R& R&h   ) ) ).A A A<@ @ @& $'#&"##$#'$"'@ @ @ @ @ @r?   r   )__doc__r   rm   r   shapely.geometryr   	PIL.Imager`   r   r'   r[   r   rE   model.constructorr   r   r   r?   r1   <module>r     s     
			   $ $ $ $ $ $         



      + + + + + +j j j j j j j j j jr?   